blob: a40694579a81b3fe8a8d7a19bb70e77f3fca8f4b [file] [log] [blame]
jeffliuec1c4782006-05-24 14:16:24 +00001/*******************************************************************************
csalterdfe7e552007-06-12 19:59:21 +00002 * Copyright (c) 2002, 2007 IBM Corporation and others.
jeffliuec1c4782006-05-24 14:16:24 +00003 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Jens Lukowski/Innoopract - initial renaming/restructuring
11 *
12 *******************************************************************************/
david_williamsc06c86f2005-03-18 18:23:41 +000013package org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl;
david_williams95990ef2005-03-18 07:20:23 +000014
15import java.util.Hashtable;
16import java.util.Iterator;
17import java.util.List;
18import java.util.Vector;
19
20import org.eclipse.core.runtime.IProgressMonitor;
21import org.eclipse.core.runtime.IStatus;
22import org.eclipse.core.runtime.Status;
23import org.eclipse.core.runtime.jobs.Job;
nsandonato5593b572009-10-13 19:03:44 +000024import org.eclipse.wst.sse.core.internal.util.AbstractMemoryListener;
nitindc380c032005-11-01 19:43:27 +000025import org.eclipse.wst.xml.core.internal.Logger;
david_williams5f2420f2005-04-12 12:23:57 +000026import org.eclipse.wst.xml.core.internal.XMLCoreMessages;
david_williamsc06c86f2005-03-18 18:23:41 +000027import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
28import org.eclipse.wst.xml.core.internal.contentmodel.ContentModelManager;
29import org.eclipse.wst.xml.core.internal.contentmodel.internal.annotation.AnnotationUtility;
30import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManager;
31import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManagerListener;
32import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentReferenceProvider;
33import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDocumentCache;
nsandonato5593b572009-10-13 19:03:44 +000034import org.osgi.service.event.Event;
csalterdfe7e552007-06-12 19:59:21 +000035
david_williams95990ef2005-03-18 07:20:23 +000036/**
37 *
38 */
nsandonato5593b572009-10-13 19:03:44 +000039public class CMDocumentManagerImpl implements CMDocumentManager {
40 protected CMDocumentCache cmDocumentCache;
41 protected CMDocumentReferenceProvider cmDocumentReferenceProvider;
42 protected List listenerList = new Vector();
43 protected Hashtable propertyTable = new Hashtable();
44 protected Hashtable publicIdTable = new Hashtable();
45
46 /**
47 * Used to keep the {@link Entry} cache clean when memory is low
48 */
49 private MemoryListener fMemoryListener;
david_williams95990ef2005-03-18 07:20:23 +000050
nsandonato5593b572009-10-13 19:03:44 +000051 public CMDocumentManagerImpl(CMDocumentCache cmDocumentCache, CMDocumentReferenceProvider cmDocumentReferenceProvider) {
52 this.cmDocumentCache = cmDocumentCache;
53 this.cmDocumentReferenceProvider = cmDocumentReferenceProvider;
54 setPropertyEnabled(PROPERTY_AUTO_LOAD, true);
55 setPropertyEnabled(PROPERTY_USE_CACHED_RESOLVED_URI, false);
56 setPropertyEnabled(PROPERTY_PERFORM_URI_RESOLUTION, true);
57
58 fMemoryListener = new MemoryListener();
59 fMemoryListener.connect();
60 }
david_williams95990ef2005-03-18 07:20:23 +000061
62
63 public CMDocumentCache getCMDocumentCache()
64 {
65 return cmDocumentCache;
66 }
67
68
69 public void setPropertyEnabled(String propertyName, boolean value)
70 {
david_williams5f2420f2005-04-12 12:23:57 +000071 propertyTable.put(propertyName, value ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
david_williams95990ef2005-03-18 07:20:23 +000072 for (Iterator i = listenerList.iterator(); i.hasNext(); )
73 {
74 CMDocumentManagerListener listener = (CMDocumentManagerListener)i.next();
75 listener.propertyChanged(this, propertyName);
76 }
77 }
78
79
80 public boolean getPropertyEnabled(String propertyName)
81 {
82 Object object = propertyTable.get(propertyName);
david_williams5f2420f2005-04-12 12:23:57 +000083 return object != null && object.equals("true"); //$NON-NLS-1$
david_williams95990ef2005-03-18 07:20:23 +000084 }
85
86
87 public void addListener(CMDocumentManagerListener listener)
88 {
89 listenerList.add(listener);
90 cmDocumentCache.addListener(listener);
91 }
92
93
94 public void removeListener(CMDocumentManagerListener listener)
95 {
96 listenerList.remove(listener);
97 cmDocumentCache.removeListener(listener);
98 }
99
100
101 protected String lookupResolvedURI(String publicId)
102 {
david_williams5f2420f2005-04-12 12:23:57 +0000103 String key = publicId != null ? publicId : ""; //$NON-NLS-1$
david_williams95990ef2005-03-18 07:20:23 +0000104 return (String)publicIdTable.get(key);
105 }
106
107
108 protected String lookupOrCreateResolvedURI(String publicId, String systemId)
109 {
110 String resolvedURI = null;
111
david_williams5f2420f2005-04-12 12:23:57 +0000112 String key = publicId != null ? publicId : ""; //$NON-NLS-1$
david_williams95990ef2005-03-18 07:20:23 +0000113
114 if (getPropertyEnabled(PROPERTY_USE_CACHED_RESOLVED_URI))
115 {
116 resolvedURI = (String)publicIdTable.get(key);
117 }
118
119 if (resolvedURI == null)
120 {
121 resolvedURI = cmDocumentReferenceProvider.resolveGrammarURI(publicId, systemId);
122 if (resolvedURI == null)
123 {
david_williams5f2420f2005-04-12 12:23:57 +0000124 resolvedURI = ""; //$NON-NLS-1$
david_williams95990ef2005-03-18 07:20:23 +0000125 }
126 publicIdTable.put(key, resolvedURI);
127 }
128
129 return resolvedURI;
130 }
131
132
133 public int getCMDocumentStatus(String publicId)
134 {
135 int status = CMDocumentCache.STATUS_NOT_LOADED;
136 String resolvedURI = lookupResolvedURI(publicId);
137 if (resolvedURI != null)
138 {
139 status = cmDocumentCache.getStatus(resolvedURI);
140 }
141 return status;
142 }
143
144
145 public CMDocument getCMDocument(String publicId)
146 {
147 CMDocument result = null;
148 String resolvedURI = lookupResolvedURI(publicId);
149 if (resolvedURI != null)
150 {
151 result = cmDocumentCache.getCMDocument(resolvedURI);
152 }
153 return result;
154 }
155
156
david_williamsc28788a2005-04-11 21:27:15 +0000157 /* (non-Javadoc)
158 * @see org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManager#getCMDocument(java.lang.String, java.lang.String, java.lang.String)
159 */
160public CMDocument getCMDocument(String publicId, String systemId, String type)
david_williams95990ef2005-03-18 07:20:23 +0000161 {
162 CMDocument cmDocument = null;
163 String resolvedURI = null;
164
165 if (getPropertyEnabled(PROPERTY_AUTO_LOAD))
166 {
vbaciu40aa9632007-04-18 14:51:40 +0000167 // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=136399
csalterdfe7e552007-06-12 19:59:21 +0000168
vbaciu40aa9632007-04-18 14:51:40 +0000169 if (getPropertyEnabled(PROPERTY_PERFORM_URI_RESOLUTION))
170 {
171 resolvedURI = lookupOrCreateResolvedURI(publicId, systemId);
172 }
173 else
174 {
175 resolvedURI = systemId;
176 }
david_williams95990ef2005-03-18 07:20:23 +0000177 }
178 else
179 {
180 resolvedURI = lookupResolvedURI(publicId);
181 }
182
183 if (resolvedURI != null)
184 {
185 int status = cmDocumentCache.getStatus(resolvedURI);
186 if (status == CMDocumentCache.STATUS_LOADED)
187 {
188 cmDocument = cmDocumentCache.getCMDocument(resolvedURI);
189 }
190 else if (status == CMDocumentCache.STATUS_NOT_LOADED)
191 {
192 if (getPropertyEnabled(PROPERTY_AUTO_LOAD))
193 {
194 cmDocument = loadCMDocument(publicId, resolvedURI, type, getPropertyEnabled(PROPERTY_ASYNC_LOAD));
195 }
196 }
197 }
198 return cmDocument;
199 }
200
david_williams95990ef2005-03-18 07:20:23 +0000201 public void addCMDocumentReference(String publicId, String systemId, String type)
202 {
203 String resolvedURI = lookupOrCreateResolvedURI(publicId, systemId);
204 if (resolvedURI != null && resolvedURI.length() > 0)
205 {
206 int status = cmDocumentCache.getStatus(resolvedURI);
207 if (status == CMDocumentCache.STATUS_NOT_LOADED)
208 {
209 loadCMDocument(publicId, resolvedURI, type, getPropertyEnabled(PROPERTY_ASYNC_LOAD));
210 }
211 }
212 }
213
214
215 public void addCMDocument(String publicId, String systemId, String resolvedURI, String type, CMDocument cmDocument)
216 {
david_williams5f2420f2005-04-12 12:23:57 +0000217 String key = publicId != null ? publicId : ""; //$NON-NLS-1$
david_williams95990ef2005-03-18 07:20:23 +0000218 publicIdTable.put(key, resolvedURI);
219 cmDocumentCache.putCMDocument(resolvedURI, cmDocument);
220 }
221
222
223 protected CMDocument loadCMDocument(final String publicId, final String resolvedURI, final String type, boolean async)
224 {
225 CMDocument result = null;
226
227 //System.out.println("about to build CMDocument(" + publicId + ", " + unresolvedURI + " = " + resolvedURI + ")");
228 if (async)
229 {
230 cmDocumentCache.setStatus(resolvedURI, CMDocumentCache.STATUS_LOADING);
231 //Thread thread = new Thread(new AsyncBuildOperation(publicId, resolvedURI, type));
232 //thread.start();
david_williams5f2420f2005-04-12 12:23:57 +0000233 Job job = new Job(XMLCoreMessages.loading + resolvedURI)
david_williams95990ef2005-03-18 07:20:23 +0000234 {
235 public boolean belongsTo(Object family)
236 {
237 boolean result = (family == CMDocumentManager.class);
238 return result;
239 }
240
241 protected IStatus run(IProgressMonitor monitor)
242 {
243 try
244 {
nitindc380c032005-11-01 19:43:27 +0000245 buildCMDocument(publicId, resolvedURI, type);
david_williams95990ef2005-03-18 07:20:23 +0000246 }
247 catch (Exception e)
248 {
nitindc380c032005-11-01 19:43:27 +0000249 Logger.logException(e);
david_williams95990ef2005-03-18 07:20:23 +0000250 }
251 return Status.OK_STATUS;
252 }
253 };
254 job.schedule();
255 }
256 else
257 {
258 result = buildCMDocument(publicId, resolvedURI, type);
259 }
260 return result;
261 }
262
263
264
david_williams95990ef2005-03-18 07:20:23 +0000265 public synchronized CMDocument buildCMDocument(String publicId, String resolvedURI, String type)
266 {
267 cmDocumentCache.setStatus(resolvedURI, CMDocumentCache.STATUS_LOADING);
268
269 CMDocument result = null;
david_williams95990ef2005-03-18 07:20:23 +0000270 if (resolvedURI != null && resolvedURI.length() > 0)
271 {
csalterdfe7e552007-06-12 19:59:21 +0000272 // TODO... pass the TYPE thru to the CMDocumentBuilder
273 result = ContentModelManager.getInstance().createCMDocument(resolvedURI, type);
david_williams95990ef2005-03-18 07:20:23 +0000274 }
275 if (result != null)
276 {
csalterdfe7e552007-06-12 19:59:21 +0000277 // load the annotation files for the document
278 if (publicId != null)
279 {
280 AnnotationUtility.loadAnnotationsForGrammar(publicId, result);
281 }
david_williams95990ef2005-03-18 07:20:23 +0000282 cmDocumentCache.putCMDocument(resolvedURI, result);
283 }
284 else
285 {
286 cmDocumentCache.setStatus(resolvedURI, CMDocumentCache.STATUS_ERROR);
287 }
288 return result;
289 }
290
291 public void removeAllReferences()
292 {
293 // TODO... initiate a timed release of the entries in the CMDocumentCache
294 publicIdTable = new Hashtable();
295 }
nsandonato5593b572009-10-13 19:03:44 +0000296
297 /**
298 * <p>A {@link AbstractMemoryListener} that clears the {@link CMDocumentCache} cache
299 * whenever specific memory events are received.</p>
300 *
301 * <p>Events:
302 * <ul>
303 * <li>{@link AbstractMemoryListener#SEV_SERIOUS}</li>
304 * <li>{@link AbstractMemoryListener#SEV_CRITICAL}</li>
305 * </ul>
306 * </p>
307 */
308 private class MemoryListener extends AbstractMemoryListener {
309 /**
310 * <p>Constructor causes this listener to listen for specific memory events.</p>
311 * <p>Events:
312 * <ul>
313 * <li>{@link AbstractMemoryListener#SEV_CRITICAL}</li>
314 * </ul>
315 * </p>
316 */
317 MemoryListener() {
318 super(new String[] { SEV_CRITICAL });
319 }
320
321 /**
322 * On any memory event we handle clear out the project descriptions
323 *
324 * @see org.eclipse.wst.sse.core.internal.util.AbstractMemoryListener#handleMemoryEvent(org.osgi.service.event.Event)
325 */
326 protected void handleMemoryEvent(Event event) {
327 //we should only clear the cache if we are responsible for it
328 if (getPropertyEnabled(PROPERTY_AUTO_LOAD)) {
329 cmDocumentCache.clear();
330 }
331 }
332
333 }
david_williams95990ef2005-03-18 07:20:23 +0000334}