|
Lines 40-45
Link Here
|
| 40 |
import org.eclipse.core.runtime.IPath; |
40 |
import org.eclipse.core.runtime.IPath; |
| 41 |
import org.eclipse.core.runtime.IStatus; |
41 |
import org.eclipse.core.runtime.IStatus; |
| 42 |
import org.eclipse.core.runtime.NullProgressMonitor; |
42 |
import org.eclipse.core.runtime.NullProgressMonitor; |
|
|
43 |
import org.eclipse.core.runtime.OperationCanceledException; |
| 43 |
import org.eclipse.core.runtime.Path; |
44 |
import org.eclipse.core.runtime.Path; |
| 44 |
import org.eclipse.core.runtime.Platform; |
45 |
import org.eclipse.core.runtime.Platform; |
| 45 |
import org.eclipse.core.runtime.QualifiedName; |
46 |
import org.eclipse.core.runtime.QualifiedName; |
|
Lines 47-55
Link Here
|
| 47 |
import org.eclipse.core.runtime.content.IContentDescription; |
48 |
import org.eclipse.core.runtime.content.IContentDescription; |
| 48 |
import org.eclipse.core.runtime.jobs.ILock; |
49 |
import org.eclipse.core.runtime.jobs.ILock; |
| 49 |
import org.eclipse.core.runtime.jobs.Job; |
50 |
import org.eclipse.core.runtime.jobs.Job; |
|
|
51 |
import org.eclipse.core.runtime.preferences.ConfigurationScope; |
| 52 |
import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| 53 |
import org.eclipse.core.runtime.preferences.IPreferencesService; |
| 54 |
import org.eclipse.core.runtime.preferences.IScopeContext; |
| 55 |
import org.eclipse.core.runtime.preferences.InstanceScope; |
| 56 |
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; |
| 50 |
import org.eclipse.jface.text.BadLocationException; |
57 |
import org.eclipse.jface.text.BadLocationException; |
| 51 |
import org.eclipse.jface.text.IDocument; |
58 |
import org.eclipse.jface.text.IDocument; |
| 52 |
import org.eclipse.jface.text.IRegion; |
59 |
import org.eclipse.jface.text.IRegion; |
|
|
60 |
import org.eclipse.osgi.service.runnable.ParameterizedRunnable; |
| 61 |
import org.eclipse.osgi.util.NLS; |
| 53 |
import org.eclipse.text.edits.MultiTextEdit; |
62 |
import org.eclipse.text.edits.MultiTextEdit; |
| 54 |
import org.eclipse.text.edits.ReplaceEdit; |
63 |
import org.eclipse.text.edits.ReplaceEdit; |
| 55 |
import org.eclipse.text.edits.TextEdit; |
64 |
import org.eclipse.text.edits.TextEdit; |
|
Lines 83-143
Link Here
|
| 83 |
import org.eclipse.wst.sse.core.internal.util.Utilities; |
92 |
import org.eclipse.wst.sse.core.internal.util.Utilities; |
| 84 |
|
93 |
|
| 85 |
/** |
94 |
/** |
| 86 |
* Not intended to be subclassed, referenced or instantiated by clients. |
95 |
* This class is not intended to be: sub-classed, referenced or instantiated by |
|
|
96 |
* clients. |
| 87 |
* |
97 |
* |
| 88 |
* This class is responsible for creating, retrieving, and caching |
98 |
* This class is responsible for creating, retrieving, and caching |
| 89 |
* StructuredModels It retrieves the cached objects by an id which is |
99 |
* StructuredModels It retrieves the cached objects by an id which is typically |
| 90 |
* typically a String representing the resources URI. Note: Its important that |
100 |
* a String representing the resources URI. Note: Its important that all clients |
| 91 |
* all clients that share a resource do so using <b>identical </b> |
101 |
* that share a resource do so using <b>identical </b> identifiers, or else |
| 92 |
* identifiers, or else different instances will be created and retrieved, |
102 |
* different instances will be created and retrieved, even if they all |
| 93 |
* even if they all technically point to the same resource on the file system. |
103 |
* technically point to the same resource on the file system. This class also |
| 94 |
* This class also provides a convenient place to register Model Loaders and |
104 |
* provides a convenient place to register Model Loaders and Dumpers based on |
| 95 |
* Dumpers based on 'type'. |
105 |
* 'type'. |
| 96 |
*/ |
106 |
*/ |
| 97 |
public class ModelManagerImpl implements IModelManager { |
107 |
public class ModelManagerImpl implements IModelManager { |
| 98 |
|
108 |
|
| 99 |
static class ReadEditType { |
109 |
private static int WAIT_DELAY = getInt("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad"); |
| 100 |
ReadEditType(String type) { |
110 |
private static boolean ALLOW_INTERRUPT_WAITING_THREAD = getBoolean("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad"); |
|
|
111 |
private static IEclipsePreferences.IPreferenceChangeListener LISTENER; |
| 112 |
static { |
| 113 |
InstanceScope scope = new InstanceScope(); |
| 114 |
IEclipsePreferences instancePrefs = scope.getNode(SSECorePlugin.ID); |
| 115 |
LISTENER = new IEclipsePreferences.IPreferenceChangeListener() { |
| 116 |
|
| 117 |
public void preferenceChange(PreferenceChangeEvent event) { |
| 118 |
|
| 119 |
if ("modelmanager.maxWaitDuringConcurrentLoad".equals(event.getKey())) { |
| 120 |
WAIT_DELAY = getInt("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad"); |
| 121 |
} |
| 122 |
else if ("modelmanager.allowInterruptsDuringConcurrentLoad".equals(event.getKey())) { |
| 123 |
ALLOW_INTERRUPT_WAITING_THREAD = getBoolean("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad"); |
| 124 |
} |
| 125 |
} |
| 126 |
}; |
| 127 |
instancePrefs.addPreferenceChangeListener(LISTENER); |
| 128 |
} |
| 129 |
|
| 130 |
class FileLoader implements ParameterizedRunnable { |
| 131 |
private final IFile file; |
| 132 |
private final String id; |
| 133 |
private final IModelHandler handler; |
| 134 |
private final URIResolver resolver; |
| 135 |
private final ReadEditType rwType; |
| 136 |
private final EncodingRule encodingRule; |
| 137 |
|
| 138 |
public FileLoader(IFile file, String id, IModelHandler handler, URIResolver resolver, |
| 139 |
ReadEditType rwType, EncodingRule encodingRule) { |
| 140 |
this.file = file; |
| 141 |
this.id = id; |
| 142 |
this.handler = handler; |
| 143 |
this.resolver = resolver; |
| 144 |
this.rwType = rwType; |
| 145 |
this.encodingRule = encodingRule; |
| 146 |
|
| 147 |
} |
| 148 |
|
| 149 |
public Object run(Object context) throws Exception { |
| 150 |
SharedObject sharedObject = (SharedObject) context; |
| 151 |
_doCommonCreateModel(file, id, handler, resolver, rwType, encodingRule, sharedObject); |
| 152 |
return null; |
| 153 |
} |
| 154 |
} |
| 155 |
|
| 156 |
class InputStreamLoader implements ParameterizedRunnable { |
| 157 |
|
| 158 |
private final InputStream inputStream; |
| 159 |
private final String id; |
| 160 |
private final IModelHandler handler; |
| 161 |
private final URIResolver resolver; |
| 162 |
private final ReadEditType rwType; |
| 163 |
private final String encoding; |
| 164 |
private final String lineDelimiter; |
| 165 |
|
| 166 |
public InputStreamLoader(InputStream inputStream, String id, IModelHandler handler, |
| 167 |
URIResolver resolver, ReadEditType rwType, String encoding, String lineDelimiter) { |
| 168 |
this.inputStream = inputStream; |
| 169 |
this.id = id; |
| 170 |
this.handler = handler; |
| 171 |
this.resolver = resolver; |
| 172 |
this.rwType = rwType; |
| 173 |
this.encoding = encoding; |
| 174 |
this.lineDelimiter = lineDelimiter; |
| 175 |
} |
| 176 |
|
| 177 |
public Object run(Object context) throws Exception { |
| 178 |
SharedObject sharedObject = (SharedObject) context; |
| 179 |
_doCommonCreateModel(inputStream, id, handler, resolver, rwType, encoding, |
| 180 |
lineDelimiter, sharedObject); |
| 181 |
return null; |
| 182 |
} |
| 183 |
} |
| 184 |
|
| 185 |
class FileBufferDocumentLoader implements ParameterizedRunnable { |
| 186 |
private final IStructuredDocument document; |
| 187 |
private final ReadEditType rwType; |
| 188 |
|
| 189 |
public FileBufferDocumentLoader(IStructuredDocument document, ReadEditType rwType) { |
| 190 |
this.document = document; |
| 191 |
this.rwType = rwType; |
| 192 |
} |
| 193 |
|
| 194 |
public Object run(Object context) throws Exception { |
| 195 |
SharedObject sharedObject = (SharedObject) context; |
| 196 |
synchronized (sharedObject.loadLock) { |
| 197 |
IStructuredModel model = FileBufferModelManager.getInstance().getModel(document); |
| 198 |
synchronized (sharedObject) { |
| 199 |
sharedObject.theSharedModel = model; |
| 200 |
_initCount(sharedObject, rwType); |
| 201 |
sharedObject.setLoaded(); |
| 202 |
} |
| 203 |
} |
| 204 |
return null; |
| 205 |
} |
| 206 |
} |
| 207 |
|
| 208 |
class FileBufferIFileLoader implements ParameterizedRunnable { |
| 209 |
|
| 210 |
private final IFile file; |
| 211 |
private final String id; |
| 212 |
private final ReadEditType rwType; |
| 213 |
|
| 214 |
public FileBufferIFileLoader(IFile file, String id, ReadEditType rwType) { |
| 215 |
this.file = file; |
| 216 |
this.id = id; |
| 217 |
this.rwType = rwType; |
| 218 |
|
| 219 |
} |
| 220 |
|
| 221 |
public Object run(Object context) throws Exception { |
| 222 |
SharedObject sharedObject = (SharedObject) context; |
| 223 |
_doCommonGetModel(file, id, sharedObject, rwType); |
| 224 |
return null; |
| 101 |
} |
225 |
} |
| 102 |
} |
226 |
} |
| 103 |
|
227 |
|
|
|
228 |
static class ReadEditType { |
| 229 |
ReadEditType(String type) {} |
| 230 |
} |
| 231 |
|
| 104 |
/** |
232 |
/** |
| 105 |
* A Data class to track our shared objects |
233 |
* A Data class to track our shared objects |
| 106 |
*/ |
234 |
*/ |
| 107 |
static class SharedObject { |
235 |
static class SharedObject { |
| 108 |
int referenceCountForEdit; |
236 |
int referenceCountForEdit; |
| 109 |
int referenceCountForRead; |
237 |
int referenceCountForRead; |
| 110 |
IStructuredModel theSharedModel; |
238 |
IStructuredModel theSharedModel; |
| 111 |
boolean initializing = true; |
239 |
boolean initializing = true; |
| 112 |
boolean doWait = true; |
240 |
volatile boolean doWait = true; |
| 113 |
|
241 |
final Object loadLock = new Object(); |
|
|
242 |
|
| 114 |
SharedObject(IStructuredModel sharedModel) { |
243 |
SharedObject(IStructuredModel sharedModel) { |
| 115 |
theSharedModel = sharedModel; |
244 |
theSharedModel = sharedModel; |
| 116 |
referenceCountForRead = 0; |
245 |
referenceCountForRead = 0; |
| 117 |
referenceCountForEdit = 0; |
246 |
referenceCountForEdit = 0; |
| 118 |
} |
247 |
} |
| 119 |
|
248 |
|
| 120 |
/** |
249 |
/** |
| 121 |
* Waits until this shared object has been attempted to be loaded. |
250 |
* Waits until this shared object has been attempted to be loaded. The |
| 122 |
* The load is "attempted" because not all loads result in a model. |
251 |
* load is "attempted" because not all loads result in a model. However, |
| 123 |
* However, upon leaving this method, theShareModel variable |
252 |
* upon leaving this method, theShareModel variable is up-to-date. |
| 124 |
* is up-to-date. |
|
|
| 125 |
*/ |
253 |
*/ |
| 126 |
public synchronized void waitForLoadAttempt() { |
254 |
public synchronized void waitForLoadAttempt() { |
| 127 |
while(initializing) { |
255 |
long start = System.currentTimeMillis(); |
|
|
256 |
// Note: A WAIT_DELAY of 0 is infinite |
| 257 |
int maxTimeMs = Math.max(0, WAIT_DELAY); |
| 258 |
final int waitInterval = Math.min(250, maxTimeMs); |
| 259 |
boolean interrupted = false; |
| 260 |
while (initializing && maxTimeMs >= 0) { |
| 128 |
try { |
261 |
try { |
| 129 |
wait(); |
262 |
wait(waitInterval); |
|
|
263 |
maxTimeMs -= waitInterval; |
| 130 |
} |
264 |
} |
| 131 |
catch (InterruptedException e) { |
265 |
catch (InterruptedException e) { |
| 132 |
// ignore interruption! |
266 |
interrupted = true; |
|
|
267 |
if (ALLOW_INTERRUPT_WAITING_THREAD) { |
| 268 |
break; |
| 269 |
} |
| 133 |
} |
270 |
} |
| 134 |
} |
271 |
} |
|
|
272 |
if (initializing) { |
| 273 |
long totalWaitTime = System.currentTimeMillis() - start; |
| 274 |
if (interrupted) { |
| 275 |
throw new OperationCanceledException( |
| 276 |
"Waiting thread interrupted during simultenous model load. Load aborted. (Waited " |
| 277 |
+ totalWaitTime + "ms)"); |
| 278 |
} |
| 279 |
else { |
| 280 |
throw new OperationCanceledException( |
| 281 |
"Waiting thread timed-out during simultenous model load. Load aborted. (Waited " |
| 282 |
+ totalWaitTime + "ms)"); |
| 283 |
} |
| 284 |
} |
| 285 |
if (interrupted) { |
| 286 |
// Propagate (don't swallow) the interrupt |
| 287 |
Thread.currentThread().interrupt(); |
| 288 |
} |
| 135 |
} |
289 |
} |
| 136 |
|
290 |
|
| 137 |
/** |
291 |
/** |
| 138 |
* Flags this model as loaded. All waiting methods on |
292 |
* Flags this model as loaded. All waiting methods on |
| 139 |
* {@link #waitForLoadAttempt()} will proceed after this |
293 |
* {@link #waitForLoadAttempt()} will proceed after this method returns. |
| 140 |
* method returns. |
|
|
| 141 |
*/ |
294 |
*/ |
| 142 |
public synchronized void setLoaded() { |
295 |
public synchronized void setLoaded() { |
| 143 |
initializing = false; |
296 |
initializing = false; |
|
Lines 150-156
Link Here
|
| 150 |
/** |
303 |
/** |
| 151 |
* Our singleton instance |
304 |
* Our singleton instance |
| 152 |
*/ |
305 |
*/ |
| 153 |
private static ModelManagerImpl instance; |
306 |
private static LotsOfEditsModelManager instance; |
| 154 |
private final static int READ_BUFFER_SIZE = 4096; |
307 |
private final static int READ_BUFFER_SIZE = 4096; |
| 155 |
|
308 |
|
| 156 |
/** |
309 |
/** |
|
Lines 161-171
Link Here
|
| 161 |
public synchronized static IModelManager getInstance() { |
314 |
public synchronized static IModelManager getInstance() { |
| 162 |
|
315 |
|
| 163 |
if (instance == null) { |
316 |
if (instance == null) { |
| 164 |
instance = new ModelManagerImpl(); |
317 |
instance = new LotsOfEditsModelManager(); |
| 165 |
} |
318 |
} |
| 166 |
return instance; |
319 |
return instance; |
| 167 |
} |
320 |
} |
| 168 |
|
321 |
|
|
|
322 |
public void removePreferenceListener() { |
| 323 |
InstanceScope scope = new InstanceScope(); |
| 324 |
IEclipsePreferences instancePrefs = scope.getNode(SSECorePlugin.ID); |
| 325 |
instancePrefs.removePreferenceChangeListener(LISTENER); |
| 326 |
} |
| 327 |
|
| 169 |
/** |
328 |
/** |
| 170 |
* Our cache of managed objects |
329 |
* Our cache of managed objects |
| 171 |
*/ |
330 |
*/ |
|
Lines 174-181
Link Here
|
| 174 |
private ModelHandlerRegistry fModelHandlerRegistry; |
333 |
private ModelHandlerRegistry fModelHandlerRegistry; |
| 175 |
private final ReadEditType READ = new ReadEditType("read"); //$NON-NLS-1$ |
334 |
private final ReadEditType READ = new ReadEditType("read"); //$NON-NLS-1$ |
| 176 |
private final ReadEditType EDIT = new ReadEditType("edit"); //$NON-NLS-1$ |
335 |
private final ReadEditType EDIT = new ReadEditType("edit"); //$NON-NLS-1$ |
| 177 |
|
336 |
|
| 178 |
private final ILock SYNC = Job.getJobManager().newLock(); |
337 |
private final ILock SYNC = Job.getJobManager().newLock(); |
|
|
338 |
|
| 179 |
/** |
339 |
/** |
| 180 |
* Intentionally default access only. |
340 |
* Intentionally default access only. |
| 181 |
* |
341 |
* |
|
Lines 183-257
Link Here
|
| 183 |
ModelManagerImpl() { |
343 |
ModelManagerImpl() { |
| 184 |
super(); |
344 |
super(); |
| 185 |
fManagedObjects = new HashMap(); |
345 |
fManagedObjects = new HashMap(); |
| 186 |
// To prevent deadlocks: always acquire multiple locks in this order: SYNC, sharedObject. |
346 |
/** |
| 187 |
// DO NOT acquire a SYNC within a sharedObject lock, unless you already own the SYNC lock |
347 |
* NOTES: To prevent deadlocks: always acquire multiple locks in this |
| 188 |
// Tip: Try to hold the smallest number of locks you can |
348 |
* order: SYNC->sharedObject.loadLock->sharedObject DO NOT acquire a |
|
|
349 |
* SYNC within a sharedObject lock, unless you already own the SYNC lock |
| 350 |
* Tip: Try to hold the smallest number of locks you can |
| 351 |
*/ |
| 189 |
} |
352 |
} |
| 190 |
|
353 |
|
| 191 |
private IStructuredModel _commonCreateModel(IFile file, String id, IModelHandler handler, URIResolver resolver, ReadEditType rwType, EncodingRule encodingRule) throws IOException,CoreException { |
354 |
private IStructuredModel doLoad(String id, ReadEditType rwType, ParameterizedRunnable loader) |
|
|
355 |
throws CoreException, IOException { |
| 192 |
SharedObject sharedObject = null; |
356 |
SharedObject sharedObject = null; |
| 193 |
|
357 |
|
| 194 |
SYNC.acquire(); |
358 |
SYNC.acquire(); |
| 195 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
359 |
try { |
| 196 |
SYNC.release(); |
360 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
| 197 |
|
361 |
} |
| 198 |
while(true) { |
362 |
finally { |
| 199 |
if (sharedObject!=null) { |
363 |
SYNC.release(); |
|
|
364 |
} |
| 365 |
|
| 366 |
while (true) { |
| 367 |
if (sharedObject != null) { |
| 200 |
sharedObject.waitForLoadAttempt(); |
368 |
sharedObject.waitForLoadAttempt(); |
| 201 |
} |
369 |
} |
|
|
370 |
boolean createModel = false; |
| 202 |
SYNC.acquire(); |
371 |
SYNC.acquire(); |
| 203 |
// we know this object's model has passed the load, however, we don't know |
372 |
try { |
| 204 |
// it's reference count status. It might have already been disposed. Or it could have |
373 |
// we know this object's model has passed the load, however, we |
| 205 |
// been disposed and a concurrent thread has already begun loading it, in which case |
374 |
// don't know it's reference count status. It might have already |
| 206 |
// we should use the sharedobject they are loading. |
375 |
// been disposed. Or it could have been disposed and a |
| 207 |
// NOTE: This pattern is applied 3 times in this class, but only doc'd once. The logic is |
376 |
// concurrent thread has already begun |
| 208 |
// exactly the same. |
377 |
// loading it, in which case we should use the SharedObject they |
| 209 |
SharedObject testObject = (SharedObject) fManagedObjects.get(id); |
378 |
// are loading. |
| 210 |
if (testObject==null) { |
379 |
|
| 211 |
// null means it's been disposed, we need to do the work to reload it. |
380 |
SharedObject testObject = (SharedObject) fManagedObjects.get(id); |
| 212 |
sharedObject = new SharedObject(null); |
381 |
if (testObject == null) { |
| 213 |
fManagedObjects.put(id, sharedObject); |
382 |
// null means it's been disposed, we need to do the work to |
| 214 |
SYNC.release(); |
383 |
// reload it. |
| 215 |
_doCommonCreateModel(file, id, handler, resolver, rwType, encodingRule, |
384 |
sharedObject = new SharedObject(null); |
| 216 |
sharedObject); |
385 |
fManagedObjects.put(id, sharedObject); |
| 217 |
break; |
386 |
createModel = true; |
| 218 |
} else if (sharedObject == testObject) { |
387 |
break; |
| 219 |
// if nothing happened, just increment the could and return the shared model |
388 |
} |
| 220 |
synchronized(sharedObject) { |
389 |
else if (sharedObject == testObject) { |
| 221 |
if (sharedObject.theSharedModel!=null) { |
390 |
// if nothing happened, just increment the could and return |
| 222 |
_incrCount(sharedObject, rwType); |
391 |
// the shared model |
|
|
392 |
synchronized (sharedObject) { |
| 393 |
Assert.isTrue(sharedObject.referenceCountForEdit |
| 394 |
+ sharedObject.referenceCountForRead > 0); |
| 395 |
if (sharedObject.theSharedModel != null) { |
| 396 |
_incrCount(sharedObject, rwType); |
| 397 |
} |
| 223 |
} |
398 |
} |
|
|
399 |
break; |
| 224 |
} |
400 |
} |
|
|
401 |
else { |
| 402 |
// sharedObject != testObject which means the object we were |
| 403 |
// waiting on has been disposed a replacement has already |
| 404 |
// been placed in the managedObjects table. Through away our |
| 405 |
// stale sharedObject and continue on with the one we got |
| 406 |
// from the queue. Note: We don't know its state, so |
| 407 |
// continue the waitForLoad-check loop. |
| 408 |
sharedObject = testObject; |
| 409 |
} |
| 410 |
} |
| 411 |
finally { |
| 225 |
SYNC.release(); |
412 |
SYNC.release(); |
| 226 |
break; |
413 |
if (createModel) { |
| 227 |
} else { |
414 |
try { |
| 228 |
// sharedObject != testObject which means the object we were waiting on has been disposed |
415 |
loader.run(sharedObject); |
| 229 |
// a replacement has already been placed in the managedObjects table. Through away our |
416 |
} |
| 230 |
// stale sharedObject and continue on with the one we got from the queue. Note: We don't know its |
417 |
catch (CoreException e) { |
| 231 |
// state, so continue the waitForLoad-check loop. |
418 |
// rethrow, since the exception came from the loader's |
| 232 |
SYNC.release(); |
419 |
throw e; |
| 233 |
sharedObject = testObject; |
420 |
} |
|
|
421 |
catch (IOException e) { |
| 422 |
// rethrow, since the exception came from the loader |
| 423 |
throw e; |
| 424 |
} |
| 425 |
catch (Exception e) { |
| 426 |
// log this unspecified exception |
| 427 |
Logger.logException("Exception during load of model", e); |
| 428 |
} |
| 429 |
} |
| 234 |
} |
430 |
} |
| 235 |
} |
431 |
} |
| 236 |
|
432 |
|
| 237 |
// we expect to always return something |
433 |
// we expect to always return something |
| 238 |
if (sharedObject == null) { |
434 |
if (sharedObject == null) { |
| 239 |
debugException = new Exception("instance only for stack trace"); //$NON-NLS-1$ |
435 |
debugException = new Exception("instance only for stack trace"); //$NON-NLS-1$ |
| 240 |
Logger.logException("Program Error: no model recorded for id " + id, debugException); //$NON-NLS-1$ |
436 |
Logger.logException("Program Error: no model recorded for id " + id, debugException); //$NON-NLS-1$ |
| 241 |
} |
437 |
} |
| 242 |
|
438 |
|
| 243 |
// note: clients must call release for each time they call get. |
439 |
// note: clients must call release for each time they call get. |
| 244 |
return sharedObject==null ? null : sharedObject.theSharedModel; |
440 |
return sharedObject == null ? null : sharedObject.theSharedModel; |
|
|
441 |
} |
| 442 |
|
| 443 |
private IStructuredModel _commonCreateModel(IFile file, String id, IModelHandler handler, |
| 444 |
URIResolver resolver, ReadEditType rwType, EncodingRule encodingRule) |
| 445 |
throws IOException, CoreException { |
| 446 |
FileLoader loader = new FileLoader(file, id, handler, resolver, rwType, encodingRule); |
| 447 |
return doLoad(id, rwType, loader); |
| 245 |
} |
448 |
} |
| 246 |
|
449 |
|
| 247 |
private void _decrCount(SharedObject sharedObject, ReadEditType type) { |
450 |
private void _decrCount(SharedObject sharedObject, ReadEditType type) { |
| 248 |
if (type == READ) { |
451 |
if (type == READ) { |
| 249 |
sharedObject.referenceCountForRead--; |
452 |
sharedObject.referenceCountForRead--; |
| 250 |
FileBufferModelManager.getInstance().disconnect(sharedObject.theSharedModel.getStructuredDocument()); |
453 |
FileBufferModelManager.getInstance().disconnect( |
|
|
454 |
sharedObject.theSharedModel.getStructuredDocument()); |
| 251 |
} |
455 |
} |
| 252 |
else if (type == EDIT) { |
456 |
else if (type == EDIT) { |
| 253 |
sharedObject.referenceCountForEdit--; |
457 |
sharedObject.referenceCountForEdit--; |
| 254 |
FileBufferModelManager.getInstance().disconnect(sharedObject.theSharedModel.getStructuredDocument()); |
458 |
FileBufferModelManager.getInstance().disconnect( |
|
|
459 |
sharedObject.theSharedModel.getStructuredDocument()); |
| 255 |
} |
460 |
} |
| 256 |
else |
461 |
else |
| 257 |
throw new IllegalArgumentException(); |
462 |
throw new IllegalArgumentException(); |
|
Lines 261-270
Link Here
|
| 261 |
URIResolver resolver, ReadEditType rwType, EncodingRule encodingRule, |
466 |
URIResolver resolver, ReadEditType rwType, EncodingRule encodingRule, |
| 262 |
SharedObject sharedObject) throws CoreException, IOException { |
467 |
SharedObject sharedObject) throws CoreException, IOException { |
| 263 |
// XXX: Does not integrate with FileBuffers |
468 |
// XXX: Does not integrate with FileBuffers |
| 264 |
boolean doRemove = false; |
469 |
IStructuredModel model = null; |
| 265 |
synchronized(sharedObject) { |
470 |
synchronized (sharedObject.loadLock) { |
| 266 |
InputStream inputStream = null; |
471 |
InputStream inputStream = null; |
| 267 |
IStructuredModel model = null; |
472 |
|
| 268 |
try { |
473 |
try { |
| 269 |
model = _commonCreateModel(id, handler, resolver); |
474 |
model = _commonCreateModel(id, handler, resolver); |
| 270 |
IModelLoader loader = handler.getModelLoader(); |
475 |
IModelLoader loader = handler.getModelLoader(); |
|
Lines 274-362
Link Here
|
| 274 |
catch (ResourceInUse e) { |
479 |
catch (ResourceInUse e) { |
| 275 |
// impossible, since we've already found |
480 |
// impossible, since we've already found |
| 276 |
handleProgramError(e); |
481 |
handleProgramError(e); |
| 277 |
} finally { |
482 |
} |
| 278 |
if (inputStream!=null) { |
483 |
finally { |
| 279 |
try { |
484 |
if (inputStream != null) { |
|
|
485 |
try { |
| 280 |
inputStream.close(); |
486 |
inputStream.close(); |
| 281 |
} catch(IOException e) { |
|
|
| 282 |
} |
487 |
} |
|
|
488 |
catch (IOException e) {} |
| 283 |
} |
489 |
} |
| 284 |
} |
490 |
} |
| 285 |
if (model != null) { |
491 |
if (model != null) { |
| 286 |
// add to our cache |
492 |
synchronized (sharedObject) { |
| 287 |
sharedObject.theSharedModel=model; |
493 |
// add to our cache |
| 288 |
_initCount(sharedObject, rwType); |
494 |
sharedObject.theSharedModel = model; |
| 289 |
} else { |
495 |
_initCount(sharedObject, rwType); |
| 290 |
doRemove = true; |
496 |
} |
| 291 |
} |
497 |
} |
| 292 |
} |
498 |
} |
| 293 |
if (doRemove) { |
499 |
if (model == null) { |
| 294 |
SYNC.acquire(); |
500 |
SYNC.acquire(); |
| 295 |
fManagedObjects.remove(id); |
501 |
try { |
| 296 |
SYNC.release(); |
502 |
fManagedObjects.remove(id); |
|
|
503 |
} |
| 504 |
finally { |
| 505 |
SYNC.release(); |
| 506 |
} |
| 297 |
} |
507 |
} |
| 298 |
sharedObject.setLoaded(); |
508 |
sharedObject.setLoaded(); |
| 299 |
} |
509 |
} |
| 300 |
|
510 |
|
| 301 |
private IStructuredModel _commonCreateModel(InputStream inputStream, String id, IModelHandler handler, URIResolver resolver, ReadEditType rwType, String encoding, String lineDelimiter) throws IOException { |
511 |
private IStructuredModel _commonCreateModel(InputStream inputStream, String id, |
| 302 |
|
512 |
IModelHandler handler, URIResolver resolver, ReadEditType rwType, String encoding, |
| 303 |
if (id == null) { |
513 |
String lineDelimiter) throws IOException { |
| 304 |
throw new IllegalArgumentException("Program Error: id may not be null"); //$NON-NLS-1$ |
514 |
org.eclipse.core.runtime.Assert.isLegal(id != null, "Program Error: id may not be null"); //$NON-NLS-1$ |
|
|
515 |
|
| 516 |
InputStreamLoader loader = new InputStreamLoader(inputStream, id, handler, resolver, |
| 517 |
rwType, encoding, lineDelimiter); |
| 518 |
try { |
| 519 |
return doLoad(id, rwType, loader); |
| 305 |
} |
520 |
} |
| 306 |
SharedObject sharedObject = null; |
521 |
catch (CoreException e) { |
| 307 |
|
522 |
// This CoreException is a least-common-denominator side effect. The |
| 308 |
SYNC.acquire(); |
523 |
// loader needs to call methods that sometimes return CoreException. |
| 309 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
524 |
// However, the CoreException is only possible if it is invoked via |
| 310 |
SYNC.release(); |
525 |
// FileLoader. |
| 311 |
|
526 |
return null; |
| 312 |
while(true) { |
|
|
| 313 |
if (sharedObject!=null) { |
| 314 |
sharedObject.waitForLoadAttempt(); |
| 315 |
} |
| 316 |
SYNC.acquire(); |
| 317 |
SharedObject testObject = (SharedObject) fManagedObjects.get(id); |
| 318 |
if (testObject==null) { |
| 319 |
// it was removed ,so lets create it |
| 320 |
sharedObject = new SharedObject(null); |
| 321 |
fManagedObjects.put(id, sharedObject); |
| 322 |
SYNC.release(); |
| 323 |
_doCommonCreateModel(inputStream, id, handler, resolver, rwType, |
| 324 |
encoding, lineDelimiter, sharedObject); |
| 325 |
break; |
| 326 |
} else if (sharedObject == testObject) { |
| 327 |
synchronized(sharedObject) { |
| 328 |
if (sharedObject.theSharedModel!=null) { |
| 329 |
_incrCount(sharedObject, rwType); |
| 330 |
} |
| 331 |
} |
| 332 |
SYNC.release(); |
| 333 |
break; |
| 334 |
} else { |
| 335 |
SYNC.release(); |
| 336 |
sharedObject = testObject; |
| 337 |
} |
| 338 |
} |
527 |
} |
| 339 |
|
|
|
| 340 |
// we expect to always return something |
| 341 |
Assert.isNotNull(sharedObject, "Program Error: no model recorded for id " + id); //$NON-NLS-1$ |
| 342 |
// note: clients must call release for each time they call get. |
| 343 |
return sharedObject.theSharedModel; |
| 344 |
|
| 345 |
} |
528 |
} |
| 346 |
|
529 |
|
| 347 |
private void _doCommonCreateModel(InputStream inputStream, String id, IModelHandler handler, |
530 |
private void _doCommonCreateModel(InputStream inputStream, String id, IModelHandler handler, |
| 348 |
URIResolver resolver, ReadEditType rwType, String encoding, String lineDelimiter, |
531 |
URIResolver resolver, ReadEditType rwType, String encoding, String lineDelimiter, |
| 349 |
SharedObject sharedObject) throws IOException { |
532 |
SharedObject sharedObject) throws IOException { |
| 350 |
boolean doRemove = false; |
533 |
IStructuredModel model = null; |
| 351 |
synchronized(sharedObject) { |
534 |
synchronized (sharedObject.loadLock) { |
| 352 |
IStructuredModel model = null; |
535 |
|
| 353 |
try { |
536 |
try { |
| 354 |
model = _commonCreateModel(id, handler, resolver); |
537 |
model = _commonCreateModel(id, handler, resolver); |
| 355 |
IModelLoader loader = handler.getModelLoader(); |
538 |
IModelLoader loader = handler.getModelLoader(); |
| 356 |
if (inputStream == null) { |
539 |
if (inputStream == null) { |
| 357 |
Logger.log(Logger.WARNING, "model was requested for id " + id + " without a content InputStream"); //$NON-NLS-1$ //$NON-NLS-2$ |
540 |
Logger.log(Logger.WARNING, |
|
|
541 |
"model was requested for id " + id + " without a content InputStream"); //$NON-NLS-1$ //$NON-NLS-2$ |
| 358 |
} |
542 |
} |
| 359 |
loader.load(id, Utilities.getMarkSupportedStream(inputStream), model, encoding, lineDelimiter); |
543 |
loader.load(id, Utilities.getMarkSupportedStream(inputStream), model, encoding, |
|
|
544 |
lineDelimiter); |
| 360 |
} |
545 |
} |
| 361 |
catch (ResourceInUse e) { |
546 |
catch (ResourceInUse e) { |
| 362 |
// impossible, since we've already found |
547 |
// impossible, since we've already found |
|
Lines 366-402
Link Here
|
| 366 |
/** |
551 |
/** |
| 367 |
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=264228 |
552 |
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=264228 |
| 368 |
* |
553 |
* |
| 369 |
* Ensure that the content type identifier field of the model |
554 |
* Ensure that the content type identifier field of the model is |
| 370 |
* is properly set. This is normally handled by the |
555 |
* properly set. This is normally handled by the |
| 371 |
* FileBufferModelManager when working with files as it knows |
556 |
* FileBufferModelManager when working with files as it knows |
| 372 |
* the content type in advance; here is where we handle it for |
557 |
* the content type in advance; here is where we handle it for |
| 373 |
* streams. |
558 |
* streams. |
| 374 |
*/ |
559 |
*/ |
| 375 |
if (model instanceof AbstractStructuredModel) { |
560 |
if (model instanceof AbstractStructuredModel) { |
| 376 |
DocumentReader reader = new DocumentReader(model.getStructuredDocument()); |
561 |
DocumentReader reader = new DocumentReader(model.getStructuredDocument()); |
| 377 |
IContentDescription description = Platform.getContentTypeManager().getDescriptionFor(reader, id, new QualifiedName[0]); |
562 |
IContentDescription description = Platform.getContentTypeManager() |
|
|
563 |
.getDescriptionFor(reader, id, new QualifiedName[0]); |
| 378 |
reader.close(); |
564 |
reader.close(); |
| 379 |
if (description != null && description.getContentType() != null) { |
565 |
if (description != null && description.getContentType() != null) { |
| 380 |
((AbstractStructuredModel) model).setContentTypeIdentifier(description.getContentType().getId()); |
566 |
((AbstractStructuredModel) model).setContentTypeIdentifier(description |
|
|
567 |
.getContentType().getId()); |
| 381 |
} |
568 |
} |
| 382 |
} |
569 |
} |
| 383 |
|
570 |
synchronized (sharedObject) { |
| 384 |
sharedObject.theSharedModel = model; |
571 |
sharedObject.theSharedModel = model; |
| 385 |
_initCount(sharedObject, rwType); |
572 |
_initCount(sharedObject, rwType); |
| 386 |
} else { |
573 |
} |
| 387 |
doRemove = true; |
|
|
| 388 |
} |
574 |
} |
| 389 |
} |
575 |
} |
| 390 |
if (doRemove) { |
576 |
if (model == null) { |
| 391 |
SYNC.acquire(); |
577 |
SYNC.acquire(); |
| 392 |
// remove it if we didn't get one back |
578 |
try { |
| 393 |
fManagedObjects.remove(id); |
579 |
// remove it if we didn't get one back |
| 394 |
SYNC.release(); |
580 |
fManagedObjects.remove(id); |
|
|
581 |
} |
| 582 |
finally { |
| 583 |
SYNC.release(); |
| 584 |
} |
| 395 |
} |
585 |
} |
| 396 |
sharedObject.setLoaded(); |
586 |
sharedObject.setLoaded(); |
| 397 |
} |
587 |
} |
| 398 |
|
588 |
|
| 399 |
private IStructuredModel _commonCreateModel(String id, IModelHandler handler, URIResolver resolver) throws ResourceInUse { |
589 |
private IStructuredModel _commonCreateModel(String id, IModelHandler handler, |
|
|
590 |
URIResolver resolver) throws ResourceInUse { |
| 400 |
|
591 |
|
| 401 |
IModelLoader loader = handler.getModelLoader(); |
592 |
IModelLoader loader = handler.getModelLoader(); |
| 402 |
IStructuredModel result = loader.createModel(); |
593 |
IStructuredModel result = loader.createModel(); |
|
Lines 417-423
Link Here
|
| 417 |
return result; |
608 |
return result; |
| 418 |
} |
609 |
} |
| 419 |
|
610 |
|
| 420 |
private IStructuredModel _commonGetModel(IFile iFile, ReadEditType rwType, EncodingRule encodingRule) throws UnsupportedEncodingException, IOException, CoreException { |
611 |
private IStructuredModel _commonGetModel(IFile iFile, ReadEditType rwType, |
|
|
612 |
EncodingRule encodingRule) throws UnsupportedEncodingException, IOException, |
| 613 |
CoreException { |
| 421 |
IStructuredModel model = null; |
614 |
IStructuredModel model = null; |
| 422 |
|
615 |
|
| 423 |
if (iFile != null && iFile.exists()) { |
616 |
if (iFile != null && iFile.exists()) { |
|
Lines 430-517
Link Here
|
| 430 |
return model; |
623 |
return model; |
| 431 |
} |
624 |
} |
| 432 |
|
625 |
|
| 433 |
private IStructuredModel _commonGetModel(IFile iFile, ReadEditType rwType, String encoding, String lineDelimiter) throws UnsupportedEncodingException, IOException, CoreException { |
626 |
private IStructuredModel _commonGetModel(IFile iFile, ReadEditType rwType, String encoding, |
|
|
627 |
String lineDelimiter) throws UnsupportedEncodingException, IOException, CoreException { |
| 434 |
String id = calculateId(iFile); |
628 |
String id = calculateId(iFile); |
| 435 |
IModelHandler handler = calculateType(iFile); |
629 |
IModelHandler handler = calculateType(iFile); |
| 436 |
URIResolver resolver = calculateURIResolver(iFile); |
630 |
URIResolver resolver = calculateURIResolver(iFile); |
| 437 |
IStructuredModel model = _commonGetModel(iFile, id, handler, resolver, rwType, encoding, lineDelimiter); |
631 |
IStructuredModel model = _commonGetModel(iFile, id, handler, resolver, rwType, encoding, |
|
|
632 |
lineDelimiter); |
| 438 |
|
633 |
|
| 439 |
return model; |
634 |
return model; |
| 440 |
} |
635 |
} |
| 441 |
|
636 |
|
| 442 |
private IStructuredModel _commonGetModel(IFile file, String id, IModelHandler handler, URIResolver resolver, ReadEditType rwType, String encoding, String lineDelimiter) throws IOException, CoreException { |
637 |
private IStructuredModel _commonGetModel(IFile file, String id, IModelHandler handler, |
| 443 |
if (id == null) |
638 |
URIResolver resolver, ReadEditType rwType, String encoding, String lineDelimiter) |
| 444 |
throw new IllegalArgumentException("Program Error: id may not be null"); //$NON-NLS-1$ |
639 |
throws IOException, CoreException { |
|
|
640 |
org.eclipse.core.runtime.Assert.isLegal(id != null, "Program Error: id may not be null"); //$NON-NLS-1$ |
| 445 |
|
641 |
|
| 446 |
SharedObject sharedObject = null; |
|
|
| 447 |
if (file != null && file.exists()) { |
642 |
if (file != null && file.exists()) { |
| 448 |
SYNC.acquire(); |
643 |
FileBufferIFileLoader loader = new FileBufferIFileLoader(file, id, rwType); |
| 449 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
644 |
return doLoad(id, rwType, loader); |
| 450 |
SYNC.release(); |
|
|
| 451 |
|
| 452 |
while(true) { |
| 453 |
if (sharedObject!=null) { |
| 454 |
sharedObject.waitForLoadAttempt(); |
| 455 |
} |
| 456 |
SYNC.acquire(); |
| 457 |
SharedObject testObject = (SharedObject) fManagedObjects.get(id); |
| 458 |
if (testObject==null) { |
| 459 |
// it was removed ,so lets create it |
| 460 |
sharedObject = new SharedObject(null); |
| 461 |
fManagedObjects.put(id, sharedObject); |
| 462 |
|
| 463 |
SYNC.release(); |
| 464 |
_doCommonGetModel(file, id, sharedObject,rwType); |
| 465 |
break; |
| 466 |
} else if (sharedObject == testObject) { |
| 467 |
synchronized(sharedObject) { |
| 468 |
if (sharedObject.theSharedModel!=null) { |
| 469 |
_incrCount(sharedObject, rwType); |
| 470 |
} |
| 471 |
} |
| 472 |
SYNC.release(); |
| 473 |
break; |
| 474 |
} else { |
| 475 |
// we got a different object than what we were expecting |
| 476 |
SYNC.release(); |
| 477 |
// two threads were interested in models for the same id. |
| 478 |
// The other thread one, so lets back off and try again. |
| 479 |
sharedObject = testObject; |
| 480 |
} |
| 481 |
} |
| 482 |
} |
645 |
} |
| 483 |
|
646 |
|
| 484 |
// if we don't know how to create a model |
647 |
return null; |
| 485 |
// for this type of file, return null |
648 |
} |
| 486 |
|
649 |
|
| 487 |
// note: clients must call release for each time they call |
650 |
private void _doCommonGetModel(IFile file, String id, SharedObject sharedObject, |
| 488 |
// get. |
651 |
ReadEditType rwType) { |
| 489 |
|
652 |
|
| 490 |
return sharedObject==null ? null : sharedObject.theSharedModel; |
653 |
IStructuredModel model = null; |
| 491 |
} |
654 |
synchronized (sharedObject.loadLock) { |
| 492 |
|
655 |
sharedObject.doWait = false; |
| 493 |
private void _doCommonGetModel(IFile file, String id, SharedObject sharedObject,ReadEditType rwType) { |
656 |
try { |
| 494 |
boolean doRemove = false; |
657 |
model = FileBufferModelManager.getInstance().getModel(file); |
| 495 |
synchronized(sharedObject) { |
658 |
} |
| 496 |
sharedObject.doWait=false; |
659 |
finally { |
| 497 |
IStructuredModel model = FileBufferModelManager.getInstance().getModel(file); |
660 |
sharedObject.doWait = true; |
| 498 |
sharedObject.doWait=true; |
661 |
} |
| 499 |
if (model != null) { |
662 |
if (model != null) { |
| 500 |
sharedObject.theSharedModel=model; |
663 |
synchronized (sharedObject) { |
| 501 |
_initCount(sharedObject, rwType); |
664 |
sharedObject.theSharedModel = model; |
| 502 |
} else { |
665 |
_initCount(sharedObject, rwType); |
| 503 |
doRemove = true; |
666 |
} |
| 504 |
} |
667 |
} |
| 505 |
} |
668 |
} |
| 506 |
if (doRemove) { |
669 |
if (model == null) { |
| 507 |
SYNC.acquire(); |
670 |
SYNC.acquire(); |
| 508 |
fManagedObjects.remove(id); |
671 |
try { |
| 509 |
SYNC.release(); |
672 |
fManagedObjects.remove(id); |
|
|
673 |
} |
| 674 |
finally { |
| 675 |
SYNC.release(); |
| 676 |
} |
| 510 |
} |
677 |
} |
| 511 |
sharedObject.setLoaded(); |
678 |
sharedObject.setLoaded(); |
| 512 |
} |
679 |
} |
| 513 |
|
680 |
|
| 514 |
private SharedObject _commonNewModel(IFile iFile, boolean force) throws ResourceAlreadyExists, ResourceInUse, IOException, CoreException { |
681 |
private SharedObject _commonNewModel(IFile iFile, boolean force) throws ResourceAlreadyExists, |
|
|
682 |
ResourceInUse, IOException, CoreException { |
| 515 |
IStructuredModel aSharedModel = null; |
683 |
IStructuredModel aSharedModel = null; |
| 516 |
// First, check if resource already exists on file system. |
684 |
// First, check if resource already exists on file system. |
| 517 |
// if is does, then throw Resource in Use iff force==false |
685 |
// if is does, then throw Resource in Use iff force==false |
|
Lines 519-554
Link Here
|
| 519 |
if (iFile.exists() && !force) { |
687 |
if (iFile.exists() && !force) { |
| 520 |
throw new ResourceAlreadyExists(); |
688 |
throw new ResourceAlreadyExists(); |
| 521 |
} |
689 |
} |
| 522 |
|
690 |
|
| 523 |
SharedObject sharedObject = null; |
691 |
SharedObject sharedObject = null; |
| 524 |
String id = calculateId(iFile); |
692 |
String id = calculateId(iFile); |
| 525 |
try { |
693 |
try { |
| 526 |
SYNC.acquire(); |
694 |
SYNC.acquire(); |
| 527 |
|
695 |
|
| 528 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
696 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
| 529 |
|
697 |
|
| 530 |
if (sharedObject != null && !force) { |
698 |
if (sharedObject != null && !force) { |
| 531 |
// if in cache already, and force is not true, then this is an |
699 |
// if in cache already, and force is not true, then this is an |
| 532 |
// error |
700 |
// error |
| 533 |
// in call |
701 |
// in call |
| 534 |
throw new ResourceInUse(); |
702 |
throw new ResourceInUse(); |
| 535 |
} |
703 |
} |
| 536 |
|
704 |
|
| 537 |
sharedObject = new SharedObject(null); |
705 |
sharedObject = new SharedObject(null); |
| 538 |
fManagedObjects.put(id, sharedObject); |
706 |
fManagedObjects.put(id, sharedObject); |
| 539 |
|
707 |
|
| 540 |
} finally { |
708 |
} |
|
|
709 |
finally { |
| 541 |
SYNC.release(); |
710 |
SYNC.release(); |
| 542 |
} |
711 |
} |
| 543 |
|
712 |
|
| 544 |
// if we get to here without above exceptions, then all is ok |
713 |
// if we get to here without above exceptions, then all is ok |
| 545 |
// to get model like normal, but set 'new' attribute (where the |
714 |
// to get model like normal, but set 'new' attribute (where the |
| 546 |
// 'new' attribute means this is a model without a corresponding |
715 |
// 'new' attribute means this is a model without a corresponding |
| 547 |
// underlying resource. |
716 |
// underlying resource. |
| 548 |
aSharedModel = FileBufferModelManager.getInstance().getModel(iFile); |
717 |
aSharedModel = FileBufferModelManager.getInstance().getModel(iFile); |
| 549 |
aSharedModel.setNewState(true); |
718 |
aSharedModel.setNewState(true); |
| 550 |
|
719 |
|
| 551 |
sharedObject.theSharedModel=aSharedModel; |
720 |
sharedObject.theSharedModel = aSharedModel; |
| 552 |
// when resource is provided, we can set |
721 |
// when resource is provided, we can set |
| 553 |
// synchronization stamp ... otherwise client should |
722 |
// synchronization stamp ... otherwise client should |
| 554 |
// Note: one client which does this is FileModelProvider. |
723 |
// Note: one client which does this is FileModelProvider. |
|
Lines 556-620
Link Here
|
| 556 |
return sharedObject; |
725 |
return sharedObject; |
| 557 |
} |
726 |
} |
| 558 |
|
727 |
|
| 559 |
public IStructuredModel _getModelFor(IStructuredDocument document, ReadEditType accessType) { |
728 |
public IStructuredModel _getModelFor(IStructuredDocument document, ReadEditType rwType) { |
| 560 |
|
729 |
|
| 561 |
String id = FileBufferModelManager.getInstance().calculateId(document); |
730 |
String id = FileBufferModelManager.getInstance().calculateId(document); |
| 562 |
if (id == null) { |
731 |
if (id == null) { |
| 563 |
if (READ == accessType) |
732 |
if (READ == rwType) |
| 564 |
return getExistingModelForRead(document); |
733 |
return getExistingModelForRead(document); |
| 565 |
if (EDIT == accessType) |
734 |
if (EDIT == rwType) |
| 566 |
return getExistingModelForEdit(document); |
735 |
return getExistingModelForEdit(document); |
| 567 |
Assert.isNotNull(id, "unknown IStructuredDocument " + document); //$NON-NLS-1$ |
736 |
Assert.isNotNull(id, "unknown IStructuredDocument " + document); //$NON-NLS-1$ |
| 568 |
} |
737 |
} |
| 569 |
|
738 |
|
| 570 |
SharedObject sharedObject = null; |
739 |
FileBufferDocumentLoader loader = new FileBufferDocumentLoader(document, rwType); |
| 571 |
SYNC.acquire(); |
740 |
try { |
| 572 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
741 |
return doLoad(id, rwType, loader); |
| 573 |
SYNC.release(); |
742 |
} |
| 574 |
|
743 |
catch (Exception e) { |
| 575 |
while(true) { |
744 |
// Safe to ignore. FileBufferDocumentLoader#run does not throw |
| 576 |
if (sharedObject!=null) { |
745 |
// exceptions. |
| 577 |
sharedObject.waitForLoadAttempt(); |
746 |
return null; |
| 578 |
} |
|
|
| 579 |
SYNC.acquire(); |
| 580 |
SharedObject testObject = (SharedObject) fManagedObjects.get(id); |
| 581 |
if (testObject==null) { |
| 582 |
sharedObject = new SharedObject(null); |
| 583 |
fManagedObjects.put(id, sharedObject); |
| 584 |
SYNC.release(); |
| 585 |
synchronized(sharedObject) { |
| 586 |
sharedObject.theSharedModel = FileBufferModelManager.getInstance().getModel(document); |
| 587 |
_initCount(sharedObject, accessType); |
| 588 |
sharedObject.setLoaded(); |
| 589 |
} |
| 590 |
break; |
| 591 |
} else if (sharedObject == testObject) { |
| 592 |
synchronized(sharedObject) { |
| 593 |
Assert.isTrue(sharedObject.referenceCountForEdit + sharedObject.referenceCountForRead > 0); |
| 594 |
if (sharedObject.theSharedModel!=null) { |
| 595 |
_incrCount(sharedObject, accessType); |
| 596 |
} |
| 597 |
} |
| 598 |
SYNC.release(); |
| 599 |
break; |
| 600 |
} else { |
| 601 |
SYNC.release(); |
| 602 |
sharedObject = testObject; |
| 603 |
} |
| 604 |
} |
747 |
} |
| 605 |
|
748 |
|
| 606 |
return sharedObject==null ? null : sharedObject.theSharedModel; |
|
|
| 607 |
} |
749 |
} |
| 608 |
|
750 |
|
| 609 |
private void _incrCount(SharedObject sharedObject, ReadEditType type) { |
751 |
private void _incrCount(SharedObject sharedObject, ReadEditType type) { |
| 610 |
synchronized(sharedObject) { |
752 |
synchronized (sharedObject) { |
| 611 |
if (type == READ) { |
753 |
if (type == READ) { |
| 612 |
sharedObject.referenceCountForRead++; |
754 |
sharedObject.referenceCountForRead++; |
| 613 |
FileBufferModelManager.getInstance().connect(sharedObject.theSharedModel.getStructuredDocument()); |
755 |
FileBufferModelManager.getInstance().connect( |
|
|
756 |
sharedObject.theSharedModel.getStructuredDocument()); |
| 614 |
} |
757 |
} |
| 615 |
else if (type == EDIT) { |
758 |
else if (type == EDIT) { |
| 616 |
sharedObject.referenceCountForEdit++; |
759 |
sharedObject.referenceCountForEdit++; |
| 617 |
FileBufferModelManager.getInstance().connect(sharedObject.theSharedModel.getStructuredDocument()); |
760 |
FileBufferModelManager.getInstance().connect( |
|
|
761 |
sharedObject.theSharedModel.getStructuredDocument()); |
| 618 |
} |
762 |
} |
| 619 |
else |
763 |
else |
| 620 |
throw new IllegalArgumentException(); |
764 |
throw new IllegalArgumentException(); |
|
Lines 622-634
Link Here
|
| 622 |
} |
766 |
} |
| 623 |
|
767 |
|
| 624 |
private void _initCount(SharedObject sharedObject, ReadEditType type) { |
768 |
private void _initCount(SharedObject sharedObject, ReadEditType type) { |
| 625 |
synchronized(sharedObject) { |
769 |
synchronized (sharedObject) { |
| 626 |
if (type == READ) { |
770 |
if (type == READ) { |
| 627 |
FileBufferModelManager.getInstance().connect(sharedObject.theSharedModel.getStructuredDocument()); |
771 |
FileBufferModelManager.getInstance().connect( |
|
|
772 |
sharedObject.theSharedModel.getStructuredDocument()); |
| 628 |
sharedObject.referenceCountForRead = 1; |
773 |
sharedObject.referenceCountForRead = 1; |
| 629 |
} |
774 |
} |
| 630 |
else if (type == EDIT) { |
775 |
else if (type == EDIT) { |
| 631 |
FileBufferModelManager.getInstance().connect(sharedObject.theSharedModel.getStructuredDocument()); |
776 |
FileBufferModelManager.getInstance().connect( |
|
|
777 |
sharedObject.theSharedModel.getStructuredDocument()); |
| 632 |
sharedObject.referenceCountForEdit = 1; |
778 |
sharedObject.referenceCountForEdit = 1; |
| 633 |
} |
779 |
} |
| 634 |
else |
780 |
else |
|
Lines 659-669
Link Here
|
| 659 |
} |
805 |
} |
| 660 |
} |
806 |
} |
| 661 |
|
807 |
|
| 662 |
|
|
|
| 663 |
/** |
808 |
/** |
| 664 |
* Calculate id provides a common way to determine the id from the input |
809 |
* Calculate id provides a common way to determine the id from the input ... |
| 665 |
* ... needed to get and save the model. It is a simple class utility, but |
810 |
* needed to get and save the model. It is a simple class utility, but is an |
| 666 |
* is an instance method so can be accessed via interface. |
811 |
* instance method so can be accessed via interface. |
| 667 |
*/ |
812 |
*/ |
| 668 |
public String calculateId(IFile file) { |
813 |
public String calculateId(IFile file) { |
| 669 |
return FileBufferModelManager.getInstance().calculateId(file); |
814 |
return FileBufferModelManager.getInstance().calculateId(file); |
|
Lines 677-683
Link Here
|
| 677 |
return cd; |
822 |
return cd; |
| 678 |
} |
823 |
} |
| 679 |
|
824 |
|
| 680 |
private IModelHandler calculateType(String filename, InputStream inputStream) throws IOException { |
825 |
private IModelHandler calculateType(String filename, InputStream inputStream) |
|
|
826 |
throws IOException { |
| 681 |
ModelHandlerRegistry cr = getModelHandlerRegistry(); |
827 |
ModelHandlerRegistry cr = getModelHandlerRegistry(); |
| 682 |
IModelHandler cd = cr.getHandlerFor(filename, inputStream); |
828 |
IModelHandler cd = cr.getHandlerFor(filename, inputStream); |
| 683 |
return cd; |
829 |
return cd; |
|
Lines 712-718
Link Here
|
| 712 |
// Note: calculateType(iFile) returns a default xml model handler if |
858 |
// Note: calculateType(iFile) returns a default xml model handler if |
| 713 |
// content type is null. |
859 |
// content type is null. |
| 714 |
String contentTypeId = calculateType(iFile).getAssociatedContentTypeId(); |
860 |
String contentTypeId = calculateType(iFile).getAssociatedContentTypeId(); |
| 715 |
String endOfLineCode = ContentBasedPreferenceGateway.getPreferencesString(contentTypeId, CommonEncodingPreferenceNames.END_OF_LINE_CODE); |
861 |
String endOfLineCode = ContentBasedPreferenceGateway.getPreferencesString(contentTypeId, |
|
|
862 |
CommonEncodingPreferenceNames.END_OF_LINE_CODE); |
| 716 |
// endOfLineCode == null means the content type does not support this |
863 |
// endOfLineCode == null means the content type does not support this |
| 717 |
// function (e.g. DTD) |
864 |
// function (e.g. DTD) |
| 718 |
// endOfLineCode == "" means no translation |
865 |
// endOfLineCode == "" means no translation |
|
Lines 736-743
Link Here
|
| 736 |
|
883 |
|
| 737 |
if (i < lineCount - 1) { |
884 |
if (i < lineCount - 1) { |
| 738 |
String currentLineDelimiter = document.getLineDelimiter(i); |
885 |
String currentLineDelimiter = document.getLineDelimiter(i); |
| 739 |
if (currentLineDelimiter != null && currentLineDelimiter.compareTo(lineDelimiterToUse) != 0) |
886 |
if (currentLineDelimiter != null |
| 740 |
multiTextEdit.addChild(new ReplaceEdit(lineEndOffset, currentLineDelimiter.length(), lineDelimiterToUse)); |
887 |
&& currentLineDelimiter.compareTo(lineDelimiterToUse) != 0) |
|
|
888 |
multiTextEdit.addChild(new ReplaceEdit(lineEndOffset, |
| 889 |
currentLineDelimiter.length(), lineDelimiterToUse)); |
| 741 |
} |
890 |
} |
| 742 |
} |
891 |
} |
| 743 |
|
892 |
|
|
Lines 798-805
Link Here
|
| 798 |
throw new ResourceInUse(); |
947 |
throw new ResourceInUse(); |
| 799 |
} |
948 |
} |
| 800 |
sharedObject = new SharedObject(null); |
949 |
sharedObject = new SharedObject(null); |
| 801 |
fManagedObjects.put(newId,sharedObject); |
950 |
fManagedObjects.put(newId, sharedObject); |
| 802 |
} finally { |
951 |
} |
|
|
952 |
finally { |
| 803 |
SYNC.release(); |
953 |
SYNC.release(); |
| 804 |
} |
954 |
} |
| 805 |
// get loader based on existing type (note the type assumption) |
955 |
// get loader based on existing type (note the type assumption) |
|
Lines 808-829
Link Here
|
| 808 |
// IModelLoader loader = (IModelLoader) getModelLoaders().get(type); |
958 |
// IModelLoader loader = (IModelLoader) getModelLoaders().get(type); |
| 809 |
// IModelLoader loader = (IModelLoader) getModelLoaders().get(type); |
959 |
// IModelLoader loader = (IModelLoader) getModelLoaders().get(type); |
| 810 |
// ask the loader to copy |
960 |
// ask the loader to copy |
| 811 |
synchronized(sharedObject) { |
961 |
synchronized (sharedObject) { |
| 812 |
sharedObject.doWait = false; |
962 |
sharedObject.doWait = false; |
| 813 |
newModel = copy(model, newId); |
963 |
try { |
| 814 |
sharedObject.doWait = true; |
964 |
newModel = copy(model, newId); |
|
|
965 |
} |
| 966 |
finally { |
| 967 |
sharedObject.doWait = true; |
| 968 |
} |
| 815 |
} |
969 |
} |
| 816 |
if (newModel != null) { |
970 |
if (newModel != null) { |
| 817 |
// add to our cache |
971 |
// add to our cache |
| 818 |
synchronized(sharedObject) { |
972 |
synchronized (sharedObject) { |
| 819 |
sharedObject.theSharedModel=newModel; |
973 |
sharedObject.theSharedModel = newModel; |
| 820 |
sharedObject.referenceCountForEdit = 1; |
974 |
sharedObject.referenceCountForEdit = 1; |
| 821 |
trace("copied model", newId, sharedObject.referenceCountForEdit); //$NON-NLS-1$ |
975 |
trace("copied model", newId, sharedObject.referenceCountForEdit); //$NON-NLS-1$ |
| 822 |
} |
976 |
} |
| 823 |
} else { |
977 |
} |
|
|
978 |
else { |
| 824 |
SYNC.acquire(); |
979 |
SYNC.acquire(); |
| 825 |
fManagedObjects.remove(newId); |
980 |
try { |
| 826 |
SYNC.release(); |
981 |
fManagedObjects.remove(newId); |
|
|
982 |
} |
| 983 |
finally { |
| 984 |
SYNC.release(); |
| 985 |
} |
| 827 |
} |
986 |
} |
| 828 |
sharedObject.setLoaded(); |
987 |
sharedObject.setLoaded(); |
| 829 |
return newModel; |
988 |
return newModel; |
|
Lines 831-838
Link Here
|
| 831 |
|
990 |
|
| 832 |
/** |
991 |
/** |
| 833 |
* Similar to clone, except the new instance has no content. Note: this |
992 |
* Similar to clone, except the new instance has no content. Note: this |
| 834 |
* produces an unmanaged model, for temporary use. If a true shared model |
993 |
* produces an unmanaged model, for temporary use. If a true shared model is |
| 835 |
* is desired, use "copy". |
994 |
* desired, use "copy". |
| 836 |
*/ |
995 |
*/ |
| 837 |
public IStructuredModel createNewInstance(IStructuredModel oldModel) throws IOException { |
996 |
public IStructuredModel createNewInstance(IStructuredModel oldModel) throws IOException { |
| 838 |
IModelHandler handler = oldModel.getModelHandler(); |
997 |
IModelHandler handler = oldModel.getModelHandler(); |
|
Lines 840-846
Link Here
|
| 840 |
IStructuredModel newModel = loader.createModel(oldModel); |
999 |
IStructuredModel newModel = loader.createModel(oldModel); |
| 841 |
newModel.setModelHandler(handler); |
1000 |
newModel.setModelHandler(handler); |
| 842 |
if (newModel instanceof AbstractStructuredModel) { |
1001 |
if (newModel instanceof AbstractStructuredModel) { |
| 843 |
((AbstractStructuredModel) newModel).setContentTypeIdentifier(oldModel.getContentTypeIdentifier()); |
1002 |
((AbstractStructuredModel) newModel).setContentTypeIdentifier(oldModel |
|
|
1003 |
.getContentTypeIdentifier()); |
| 844 |
} |
1004 |
} |
| 845 |
URIResolver oldResolver = oldModel.getResolver(); |
1005 |
URIResolver oldResolver = oldModel.getResolver(); |
| 846 |
newModel.setResolver(oldResolver); |
1006 |
newModel.setResolver(oldResolver); |
|
Lines 858-872
Link Here
|
| 858 |
|
1018 |
|
| 859 |
/** |
1019 |
/** |
| 860 |
* Factory method, since a proper IStructuredDocument must have a proper |
1020 |
* Factory method, since a proper IStructuredDocument must have a proper |
| 861 |
* parser assigned. Note: its assume that IFile does not actually exist as |
1021 |
* parser assigned. Note: its assume that IFile does not actually exist as a |
| 862 |
* a resource yet. If it does, ResourceAlreadyExists exception is thrown. |
1022 |
* resource yet. If it does, ResourceAlreadyExists exception is thrown. If |
| 863 |
* If the resource does already exist, then createStructuredDocumentFor is |
1023 |
* the resource does already exist, then createStructuredDocumentFor is the |
| 864 |
* the right API to use. |
1024 |
* right API to use. |
| 865 |
* |
1025 |
* |
| 866 |
* @throws ResourceInUse |
1026 |
* @throws ResourceInUse |
| 867 |
* |
1027 |
* |
| 868 |
*/ |
1028 |
*/ |
| 869 |
public IStructuredDocument createNewStructuredDocumentFor(IFile iFile) throws ResourceAlreadyExists, IOException, CoreException { |
1029 |
public IStructuredDocument createNewStructuredDocumentFor(IFile iFile) |
|
|
1030 |
throws ResourceAlreadyExists, IOException, CoreException { |
| 870 |
if (iFile.exists()) { |
1031 |
if (iFile.exists()) { |
| 871 |
throw new ResourceAlreadyExists(iFile.getFullPath().toOSString()); |
1032 |
throw new ResourceAlreadyExists(iFile.getFullPath().toOSString()); |
| 872 |
} |
1033 |
} |
|
Lines 892-898
Link Here
|
| 892 |
* |
1053 |
* |
| 893 |
* @throws ResourceInUse |
1054 |
* @throws ResourceInUse |
| 894 |
*/ |
1055 |
*/ |
| 895 |
public IStructuredDocument createStructuredDocumentFor(IFile iFile) throws IOException, CoreException { |
1056 |
public IStructuredDocument createStructuredDocumentFor(IFile iFile) throws IOException, |
|
|
1057 |
CoreException { |
| 896 |
if (!iFile.exists()) { |
1058 |
if (!iFile.exists()) { |
| 897 |
throw new FileNotFoundException(iFile.getFullPath().toOSString()); |
1059 |
throw new FileNotFoundException(iFile.getFullPath().toOSString()); |
| 898 |
} |
1060 |
} |
|
Lines 904-927
Link Here
|
| 904 |
IDocumentLoader loader = null; |
1066 |
IDocumentLoader loader = null; |
| 905 |
IModelHandler handler = calculateType(iFile); |
1067 |
IModelHandler handler = calculateType(iFile); |
| 906 |
loader = handler.getDocumentLoader(); |
1068 |
loader = handler.getDocumentLoader(); |
| 907 |
IStructuredDocument result = (IStructuredDocument) loader.createNewStructuredDocument(iFile); |
1069 |
IStructuredDocument result = (IStructuredDocument) loader |
|
|
1070 |
.createNewStructuredDocument(iFile); |
| 908 |
return result; |
1071 |
return result; |
| 909 |
} |
1072 |
} |
| 910 |
|
1073 |
|
| 911 |
/** |
1074 |
/** |
| 912 |
* Conveience method, since a proper IStructuredDocument must have a |
1075 |
* Conveience method, since a proper IStructuredDocument must have a proper |
| 913 |
* proper parser assigned. It should only be used when an empty |
1076 |
* parser assigned. It should only be used when an empty structuredDocument |
| 914 |
* structuredDocument is needed. Otherwise, use IFile form. |
1077 |
* is needed. Otherwise, use IFile form. |
| 915 |
* |
1078 |
* |
| 916 |
* @deprecated - TODO: to be removed by C4 do we really need this? I |
1079 |
* @deprecated - TODO: to be removed by C4 do we really need this? I |
| 917 |
* recommend to - use createStructuredDocumentFor(filename, |
1080 |
* recommend to - use createStructuredDocumentFor(filename, |
| 918 |
* null, null) - the filename does not need to represent a |
1081 |
* null, null) - the filename does not need to represent a real |
| 919 |
* real - file, but can take for form of dummy.jsp, test.xml, |
1082 |
* - file, but can take for form of dummy.jsp, test.xml, etc. - |
| 920 |
* etc. - That way we don't hard code the handler, but specify |
1083 |
* That way we don't hard code the handler, but specify we - |
| 921 |
* we - want the handler that "goes with" a certain type of - |
1084 |
* want the handler that "goes with" a certain type of - file. |
| 922 |
* file. |
|
|
| 923 |
*/ |
1085 |
*/ |
| 924 |
public IStructuredDocument createStructuredDocumentFor(String contentTypeId) { |
1086 |
public IStructuredDocument createStructuredDocumentFor(String contentTypeId) { |
| 925 |
IDocumentLoader loader = null; |
1087 |
IDocumentLoader loader = null; |
| 926 |
ModelHandlerRegistry cr = getModelHandlerRegistry(); |
1088 |
ModelHandlerRegistry cr = getModelHandlerRegistry(); |
| 927 |
IModelHandler handler = cr.getHandlerForContentTypeId(contentTypeId); |
1089 |
IModelHandler handler = cr.getHandlerForContentTypeId(contentTypeId); |
|
Lines 933-948
Link Here
|
| 933 |
} |
1095 |
} |
| 934 |
|
1096 |
|
| 935 |
/** |
1097 |
/** |
| 936 |
* Conveience method, since a proper IStructuredDocument must have a |
1098 |
* Conveience method, since a proper IStructuredDocument must have a proper |
| 937 |
* proper parser assigned. |
1099 |
* parser assigned. |
| 938 |
* |
1100 |
* |
| 939 |
* @deprecated -- - TODO: to be removed by C4 I marked as deprecated to |
1101 |
* @deprecated -- - TODO: to be removed by C4 I marked as deprecated to |
| 940 |
* discouage use of this method. It does not really work for |
1102 |
* discouage use of this method. It does not really work for JSP |
| 941 |
* JSP fragments, since JSP Fragments need an IFile to |
1103 |
* fragments, since JSP Fragments need an IFile to correctly |
| 942 |
* correctly look up the content settings. Use IFile form |
1104 |
* look up the content settings. Use IFile form instead. |
| 943 |
* instead. |
|
|
| 944 |
*/ |
1105 |
*/ |
| 945 |
public IStructuredDocument createStructuredDocumentFor(String filename, InputStream inputStream, URIResolver resolver) throws IOException { |
1106 |
public IStructuredDocument createStructuredDocumentFor(String filename, |
|
|
1107 |
InputStream inputStream, URIResolver resolver) throws IOException { |
| 946 |
IDocumentLoader loader = null; |
1108 |
IDocumentLoader loader = null; |
| 947 |
InputStream istream = Utilities.getMarkSupportedStream(inputStream); |
1109 |
InputStream istream = Utilities.getMarkSupportedStream(inputStream); |
| 948 |
if (istream != null) { |
1110 |
if (istream != null) { |
|
Lines 962-977
Link Here
|
| 962 |
|
1124 |
|
| 963 |
/** |
1125 |
/** |
| 964 |
* Special case method. This method was created for the special case where |
1126 |
* Special case method. This method was created for the special case where |
| 965 |
* there is an encoding for input stream that should override all the |
1127 |
* there is an encoding for input stream that should override all the normal |
| 966 |
* normal rules for encoding. For example, if there is an encoding |
1128 |
* rules for encoding. For example, if there is an encoding (charset) |
| 967 |
* (charset) specified in HTTP response header, then that encoding is used |
1129 |
* specified in HTTP response header, then that encoding is used to |
| 968 |
* to translate the input stream to a string, but then the normal encoding |
1130 |
* translate the input stream to a string, but then the normal encoding |
| 969 |
* rules are ignored, so that the string is not translated twice (for |
1131 |
* rules are ignored, so that the string is not translated twice (for |
| 970 |
* example, if its an HTML "file", then even if it contains a charset in |
1132 |
* example, if its an HTML "file", then even if it contains a charset in |
| 971 |
* meta tag, its ignored since its assumed its all correctly decoded by |
1133 |
* meta tag, its ignored since its assumed its all correctly decoded by the |
| 972 |
* the HTTP charset. |
1134 |
* HTTP charset. |
| 973 |
*/ |
1135 |
*/ |
| 974 |
public IStructuredDocument createStructuredDocumentFor(String filename, InputStream inputStream, URIResolver resolver, String encoding) throws IOException { |
1136 |
public IStructuredDocument createStructuredDocumentFor(String filename, |
|
|
1137 |
InputStream inputStream, URIResolver resolver, String encoding) throws IOException { |
| 975 |
String content = readInputStream(inputStream, encoding); |
1138 |
String content = readInputStream(inputStream, encoding); |
| 976 |
IStructuredDocument result = createStructuredDocumentFor(filename, content, resolver); |
1139 |
IStructuredDocument result = createStructuredDocumentFor(filename, content, resolver); |
| 977 |
return result; |
1140 |
return result; |
|
Lines 979-990
Link Here
|
| 979 |
|
1142 |
|
| 980 |
/** |
1143 |
/** |
| 981 |
* Convenience method. This method can be used when the resource does not |
1144 |
* Convenience method. This method can be used when the resource does not |
| 982 |
* really exist (e.g. when content is being created, but hasn't been |
1145 |
* really exist (e.g. when content is being created, but hasn't been written |
| 983 |
* written to disk yet). Note that since the content is being provided as |
1146 |
* to disk yet). Note that since the content is being provided as a String, |
| 984 |
* a String, it is assumed to already be decoded correctly so no |
1147 |
* it is assumed to already be decoded correctly so no transformation is |
| 985 |
* transformation is done. |
1148 |
* done. |
| 986 |
*/ |
1149 |
*/ |
| 987 |
public IStructuredDocument createStructuredDocumentFor(String filename, String content, URIResolver resolver) throws IOException { |
1150 |
public IStructuredDocument createStructuredDocumentFor(String filename, String content, |
|
|
1151 |
URIResolver resolver) throws IOException { |
| 988 |
// TODO: avoid all these String instances |
1152 |
// TODO: avoid all these String instances |
| 989 |
StringBuffer contentBuffer = new StringBuffer(content); |
1153 |
StringBuffer contentBuffer = new StringBuffer(content); |
| 990 |
IDocumentLoader loader = null; |
1154 |
IDocumentLoader loader = null; |
|
Lines 1017-1033
Link Here
|
| 1017 |
// (even if it really is in use ... we don't care) |
1181 |
// (even if it really is in use ... we don't care) |
| 1018 |
// this may need to be re-examined. |
1182 |
// this may need to be re-examined. |
| 1019 |
if (Logger.DEBUG_MODELMANAGER) |
1183 |
if (Logger.DEBUG_MODELMANAGER) |
| 1020 |
Logger.log(Logger.INFO, "ModelMangerImpl::createUnManagedStructuredModelFor. Model unexpectedly in use."); //$NON-NLS-1$ //$NON-NLS-2$ |
1184 |
Logger |
|
|
1185 |
.log(Logger.INFO, |
| 1186 |
"ModelMangerImpl::createUnManagedStructuredModelFor. Model unexpectedly in use."); //$NON-NLS-1$ //$NON-NLS-2$ |
| 1021 |
} |
1187 |
} |
| 1022 |
|
1188 |
|
| 1023 |
return result; |
1189 |
return result; |
| 1024 |
} |
1190 |
} |
| 1025 |
|
1191 |
|
| 1026 |
/** |
1192 |
/** |
| 1027 |
* Conveience method. It depends on the loaders newModel method to return |
1193 |
* Conveience method. It depends on the loaders newModel method to return an |
| 1028 |
* an appropriate StrucuturedModel appropriately initialized. |
1194 |
* appropriate StrucuturedModel appropriately initialized. |
| 1029 |
*/ |
1195 |
*/ |
| 1030 |
public IStructuredModel createUnManagedStructuredModelFor(IFile iFile) throws IOException, CoreException { |
1196 |
public IStructuredModel createUnManagedStructuredModelFor(IFile iFile) throws IOException, |
|
|
1197 |
CoreException { |
| 1031 |
IStructuredModel result = null; |
1198 |
IStructuredModel result = null; |
| 1032 |
result = createUnManagedEmptyModelFor(iFile); |
1199 |
result = createUnManagedEmptyModelFor(iFile); |
| 1033 |
|
1200 |
|
|
Lines 1040-1057
Link Here
|
| 1040 |
} |
1207 |
} |
| 1041 |
|
1208 |
|
| 1042 |
/** |
1209 |
/** |
| 1043 |
* Conveience method. It depends on the loaders newModel method to return |
1210 |
* Conveience method. It depends on the loaders newModel method to return an |
| 1044 |
* an appropriate StrucuturedModel appropriately initialized. |
1211 |
* appropriate StrucuturedModel appropriately initialized. |
| 1045 |
*/ |
1212 |
*/ |
| 1046 |
public IStructuredModel createUnManagedStructuredModelFor(String contentTypeId) { |
1213 |
public IStructuredModel createUnManagedStructuredModelFor(String contentTypeId) { |
| 1047 |
return createUnManagedStructuredModelFor(contentTypeId, null); |
1214 |
return createUnManagedStructuredModelFor(contentTypeId, null); |
| 1048 |
} |
1215 |
} |
| 1049 |
|
1216 |
|
| 1050 |
/** |
1217 |
/** |
| 1051 |
* Conveience method. It depends on the loaders newModel method to return |
1218 |
* Conveience method. It depends on the loaders newModel method to return an |
| 1052 |
* an appropriate StrucuturedModel appropriately initialized. |
1219 |
* appropriate StrucuturedModel appropriately initialized. |
| 1053 |
*/ |
1220 |
*/ |
| 1054 |
public IStructuredModel createUnManagedStructuredModelFor(String contentTypeId, URIResolver resolver) { |
1221 |
public IStructuredModel createUnManagedStructuredModelFor(String contentTypeId, |
|
|
1222 |
URIResolver resolver) { |
| 1055 |
IStructuredModel result = null; |
1223 |
IStructuredModel result = null; |
| 1056 |
ModelHandlerRegistry cr = getModelHandlerRegistry(); |
1224 |
ModelHandlerRegistry cr = getModelHandlerRegistry(); |
| 1057 |
IModelHandler handler = cr.getHandlerForContentTypeId(contentTypeId); |
1225 |
IModelHandler handler = cr.getHandlerForContentTypeId(contentTypeId); |
|
Lines 1063-1133
Link Here
|
| 1063 |
// (even if it really is in use ... we don't care) |
1231 |
// (even if it really is in use ... we don't care) |
| 1064 |
// this may need to be re-examined. |
1232 |
// this may need to be re-examined. |
| 1065 |
if (Logger.DEBUG_MODELMANAGER) |
1233 |
if (Logger.DEBUG_MODELMANAGER) |
| 1066 |
Logger.log(Logger.INFO, "ModelMangerImpl::createUnManagedStructuredModelFor. Model unexpectedly in use."); //$NON-NLS-1$ //$NON-NLS-2$ |
1234 |
Logger |
|
|
1235 |
.log(Logger.INFO, |
| 1236 |
"ModelMangerImpl::createUnManagedStructuredModelFor. Model unexpectedly in use."); //$NON-NLS-1$ //$NON-NLS-2$ |
| 1067 |
} |
1237 |
} |
| 1068 |
return result; |
1238 |
return result; |
| 1069 |
} |
1239 |
} |
| 1070 |
|
1240 |
|
| 1071 |
private IStructuredModel getExistingModel(Object id) { |
1241 |
private IStructuredModel getExistingModel(Object id) { |
| 1072 |
IStructuredModel result = null; |
1242 |
IStructuredModel result = null; |
| 1073 |
|
1243 |
SharedObject sharedObject = null; |
|
|
1244 |
|
| 1074 |
SYNC.acquire(); |
1245 |
SYNC.acquire(); |
| 1075 |
/** |
1246 |
try { |
| 1076 |
* While a good check in theory, it's possible for an event fired to |
1247 |
/** |
| 1077 |
* cause a listener to access a method that calls this one. |
1248 |
* While a good check in theory, it's possible for an event fired to |
| 1078 |
*/ |
1249 |
* cause a listener to access a method that calls this one. |
| 1079 |
//Assert.isTrue(SYNC.getDepth()==1, "depth not equal to 1"); |
1250 |
* Assert.isTrue(SYNC.getDepth()==1, "depth not equal to 1"); |
| 1080 |
// let's see if we already have it in our cache |
1251 |
*/ |
| 1081 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
1252 |
|
| 1082 |
// if not, then we'll simply return null |
1253 |
// let's see if we already have it in our cache |
| 1083 |
if (sharedObject != null) { |
1254 |
// if not, then we'll simply return null |
| 1084 |
SYNC.release(); |
1255 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
| 1085 |
sharedObject.waitForLoadAttempt(); |
1256 |
|
| 1086 |
result = sharedObject.theSharedModel; |
1257 |
} |
| 1087 |
} else { |
1258 |
finally { |
| 1088 |
SYNC.release(); |
1259 |
SYNC.release(); |
|
|
1260 |
if (sharedObject != null) { |
| 1261 |
synchronized (sharedObject) { |
| 1262 |
sharedObject.waitForLoadAttempt(); |
| 1263 |
result = sharedObject.theSharedModel; |
| 1264 |
} |
| 1265 |
} |
| 1089 |
} |
1266 |
} |
| 1090 |
|
1267 |
|
| 1091 |
return result; |
1268 |
return result; |
| 1092 |
} |
1269 |
} |
| 1093 |
|
1270 |
|
| 1094 |
/** |
1271 |
/** |
| 1095 |
* Note: users of this 'model' must still release it when finished. |
1272 |
* Note: users of this 'model' must still release it when finished. Returns |
| 1096 |
* Returns null if there's not a model corresponding to document. |
1273 |
* null if there's not a model corresponding to document. |
| 1097 |
*/ |
1274 |
*/ |
| 1098 |
public IStructuredModel getExistingModelForEdit(IDocument document) { |
1275 |
public IStructuredModel getExistingModelForEdit(IDocument document) { |
| 1099 |
IStructuredModel result = null; |
1276 |
IStructuredModel result = null; |
| 1100 |
|
1277 |
Set ids; |
| 1101 |
SYNC.acquire(); |
1278 |
|
| 1102 |
// create a snapshot |
1279 |
SYNC.acquire(); |
| 1103 |
Set ids = new HashSet(fManagedObjects.keySet()); |
1280 |
try { |
| 1104 |
SYNC.release(); |
1281 |
// create a snapshot |
|
|
1282 |
ids = new HashSet(fManagedObjects.keySet()); |
| 1283 |
} |
| 1284 |
finally { |
| 1285 |
SYNC.release(); |
| 1286 |
} |
| 1105 |
for (Iterator iterator = ids.iterator(); iterator.hasNext();) { |
1287 |
for (Iterator iterator = ids.iterator(); iterator.hasNext();) { |
| 1106 |
Object potentialId = iterator.next(); |
1288 |
Object potentialId = iterator.next(); |
| 1107 |
SYNC.acquire(); |
1289 |
boolean containsKey; |
| 1108 |
if (fManagedObjects.containsKey(potentialId)) { |
1290 |
SYNC.acquire(); |
| 1109 |
// check to see if still valid |
1291 |
try { |
|
|
1292 |
containsKey = fManagedObjects.containsKey(potentialId); |
| 1293 |
} |
| 1294 |
finally { |
| 1110 |
SYNC.release(); |
1295 |
SYNC.release(); |
|
|
1296 |
} |
| 1297 |
if (containsKey) { |
| 1111 |
IStructuredModel tempResult = getExistingModel(potentialId); |
1298 |
IStructuredModel tempResult = getExistingModel(potentialId); |
| 1112 |
if (tempResult!=null && document == tempResult.getStructuredDocument()) { |
1299 |
if (tempResult != null && document == tempResult.getStructuredDocument()) { |
| 1113 |
result = getExistingModelForEdit(potentialId); |
1300 |
result = getExistingModelForEdit(potentialId); |
| 1114 |
break; |
1301 |
break; |
| 1115 |
} |
1302 |
} |
| 1116 |
} else { |
|
|
| 1117 |
SYNC.release(); |
| 1118 |
} |
1303 |
} |
| 1119 |
} |
1304 |
} |
| 1120 |
|
1305 |
|
| 1121 |
return result; |
1306 |
return result; |
| 1122 |
} |
1307 |
} |
| 1123 |
|
1308 |
|
| 1124 |
/** |
1309 |
/** |
| 1125 |
* This is similar to the getModel method, except this method does not |
1310 |
* This is similar to the getModel method, except this method does not |
| 1126 |
* create a model. This method does increment the reference count (if it |
1311 |
* create a model. This method does increment the reference count (if it |
| 1127 |
* exists). If the model does not already exist in the cache of models, |
1312 |
* exists). If the model does not already exist in the cache of models, null |
| 1128 |
* null is returned. |
1313 |
* is returned. |
| 1129 |
*/ |
1314 |
*/ |
| 1130 |
public IStructuredModel getExistingModelForEdit(IFile iFile) { |
1315 |
public IStructuredModel getExistingModelForEdit(IFile iFile) { |
| 1131 |
|
1316 |
|
| 1132 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
1317 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1133 |
Object id = calculateId(iFile); |
1318 |
Object id = calculateId(iFile); |
|
Lines 1138-1145
Link Here
|
| 1138 |
/** |
1323 |
/** |
| 1139 |
* This is similar to the getModel method, except this method does not |
1324 |
* This is similar to the getModel method, except this method does not |
| 1140 |
* create a model. This method does increment the reference count (if it |
1325 |
* create a model. This method does increment the reference count (if it |
| 1141 |
* exists). If the model does not already exist in the cache of models, |
1326 |
* exists). If the model does not already exist in the cache of models, null |
| 1142 |
* null is returned. |
1327 |
* is returned. |
| 1143 |
* |
1328 |
* |
| 1144 |
* @deprecated use IFile form - this one will become protected or private |
1329 |
* @deprecated use IFile form - this one will become protected or private |
| 1145 |
*/ |
1330 |
*/ |
|
Lines 1147-1212
Link Here
|
| 1147 |
|
1332 |
|
| 1148 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1333 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1149 |
IStructuredModel result = null; |
1334 |
IStructuredModel result = null; |
| 1150 |
boolean doRelease = true; |
1335 |
SharedObject sharedObject = null; |
| 1151 |
// let's see if we already have it in our cache |
1336 |
// let's see if we already have it in our cache |
|
|
1337 |
SYNC.acquire(); |
| 1152 |
try { |
1338 |
try { |
| 1153 |
SYNC.acquire(); |
1339 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
| 1154 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
1340 |
// if not found, then we'll simply return null |
| 1155 |
// if not, then we'll simply return null |
1341 |
} |
|
|
1342 |
finally { |
| 1343 |
SYNC.release(); |
| 1156 |
if (sharedObject != null) { |
1344 |
if (sharedObject != null) { |
| 1157 |
// if shared object is in our cache, then simply increment its ref |
1345 |
// if shared object is in our cache, then simply increment its |
|
|
1346 |
// ref |
| 1158 |
// count, |
1347 |
// count, |
| 1159 |
// and return the object. |
1348 |
// and return the object. |
| 1160 |
SYNC.release(); |
1349 |
synchronized (sharedObject) { |
| 1161 |
doRelease=false; |
|
|
| 1162 |
synchronized(sharedObject) { |
| 1163 |
if (sharedObject.doWait) { |
1350 |
if (sharedObject.doWait) { |
| 1164 |
sharedObject.waitForLoadAttempt(); |
1351 |
sharedObject.waitForLoadAttempt(); |
| 1165 |
} |
1352 |
} |
| 1166 |
if (sharedObject.theSharedModel!=null) { |
1353 |
if (sharedObject.theSharedModel != null) { |
| 1167 |
_incrCount(sharedObject, EDIT); |
1354 |
_incrCount(sharedObject, EDIT); |
| 1168 |
} |
1355 |
} |
| 1169 |
result = sharedObject.theSharedModel; |
1356 |
result = sharedObject.theSharedModel; |
| 1170 |
} |
1357 |
} |
| 1171 |
trace("got existing model for Edit: ", id); //$NON-NLS-1$ |
1358 |
trace("got existing model for Edit: ", id); //$NON-NLS-1$ |
| 1172 |
trace(" incremented referenceCountForEdit ", id, sharedObject.referenceCountForEdit); //$NON-NLS-1$ |
1359 |
trace( |
| 1173 |
} |
1360 |
" incremented referenceCountForEdit ", id, sharedObject.referenceCountForEdit); //$NON-NLS-1$ |
| 1174 |
} finally { |
|
|
| 1175 |
if (doRelease) { |
| 1176 |
SYNC.release(); |
| 1177 |
} |
1361 |
} |
| 1178 |
} |
1362 |
} |
| 1179 |
|
1363 |
|
| 1180 |
return result; |
1364 |
return result; |
| 1181 |
} |
1365 |
} |
| 1182 |
|
1366 |
|
| 1183 |
/** |
1367 |
/** |
| 1184 |
* Note: users of this 'model' must still release it when finished. |
1368 |
* Note: users of this 'model' must still release it when finished. Returns |
| 1185 |
* Returns null if there's not a model corresponding to document. |
1369 |
* null if there's not a model corresponding to document. |
| 1186 |
*/ |
1370 |
*/ |
| 1187 |
public IStructuredModel getExistingModelForRead(IDocument document) { |
1371 |
public IStructuredModel getExistingModelForRead(IDocument document) { |
| 1188 |
IStructuredModel result = null; |
1372 |
IStructuredModel result = null; |
| 1189 |
|
1373 |
|
| 1190 |
SYNC.acquire(); |
1374 |
Set ids; |
| 1191 |
// create a snapshot |
1375 |
SYNC.acquire(); |
| 1192 |
Set ids = new HashSet(fManagedObjects.keySet()); |
1376 |
try { |
| 1193 |
SYNC.release(); |
1377 |
// create a snapshot |
|
|
1378 |
ids = new HashSet(fManagedObjects.keySet()); |
| 1379 |
} |
| 1380 |
finally { |
| 1381 |
SYNC.release(); |
| 1382 |
} |
| 1194 |
for (Iterator iterator = ids.iterator(); iterator.hasNext();) { |
1383 |
for (Iterator iterator = ids.iterator(); iterator.hasNext();) { |
| 1195 |
Object potentialId = iterator.next(); |
1384 |
Object potentialId = iterator.next(); |
| 1196 |
SYNC.acquire(); |
1385 |
boolean containsKey; |
| 1197 |
if (fManagedObjects.containsKey(potentialId)) { |
1386 |
SYNC.acquire(); |
| 1198 |
// check to see if still valid |
1387 |
try { |
|
|
1388 |
containsKey = fManagedObjects.containsKey(potentialId); |
| 1389 |
} |
| 1390 |
finally { |
| 1199 |
SYNC.release(); |
1391 |
SYNC.release(); |
|
|
1392 |
} |
| 1393 |
if (containsKey) { |
| 1394 |
// check to see if still valid |
| 1200 |
IStructuredModel tempResult = getExistingModel(potentialId); |
1395 |
IStructuredModel tempResult = getExistingModel(potentialId); |
| 1201 |
if (tempResult!=null && document == tempResult.getStructuredDocument()) { |
1396 |
if (tempResult != null && document == tempResult.getStructuredDocument()) { |
| 1202 |
result = getExistingModelForRead(potentialId); |
1397 |
result = getExistingModelForRead(potentialId); |
| 1203 |
break; |
1398 |
break; |
| 1204 |
} |
1399 |
} |
| 1205 |
} else { |
|
|
| 1206 |
SYNC.release(); |
| 1207 |
} |
1400 |
} |
| 1208 |
} |
1401 |
} |
| 1209 |
|
1402 |
|
| 1210 |
return result; |
1403 |
return result; |
| 1211 |
} |
1404 |
} |
| 1212 |
|
1405 |
|
|
Lines 1221-1260
Link Here
|
| 1221 |
/** |
1414 |
/** |
| 1222 |
* This is similar to the getModel method, except this method does not |
1415 |
* This is similar to the getModel method, except this method does not |
| 1223 |
* create a model. This method does increment the reference count (if it |
1416 |
* create a model. This method does increment the reference count (if it |
| 1224 |
* exists). If the model does not already exist in the cache of models, |
1417 |
* exists). If the model does not already exist in the cache of models, null |
| 1225 |
* null is returned. |
1418 |
* is returned. |
| 1226 |
* |
1419 |
* |
| 1227 |
* @deprecated use IFile form - this one will become protected or private |
1420 |
* @deprecated use IFile form - this one will become protected or private |
| 1228 |
*/ |
1421 |
*/ |
| 1229 |
public IStructuredModel getExistingModelForRead(Object id) { |
1422 |
public IStructuredModel getExistingModelForRead(Object id) { |
| 1230 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1423 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1231 |
IStructuredModel result = null; |
1424 |
IStructuredModel result = null; |
| 1232 |
boolean doRelease = true; |
1425 |
SharedObject sharedObject = null; |
| 1233 |
// let's see if we already have it in our cache |
1426 |
SYNC.acquire(); |
| 1234 |
try { |
1427 |
try { |
| 1235 |
SYNC.acquire(); |
1428 |
// let's see if we already have it in our cache |
| 1236 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
1429 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
| 1237 |
// if not, then we'll simply return null |
1430 |
// if not found, then we'll simply return null |
|
|
1431 |
} |
| 1432 |
finally { |
| 1433 |
SYNC.release(); |
| 1238 |
if (sharedObject != null) { |
1434 |
if (sharedObject != null) { |
| 1239 |
// if shared object is in our cache, then simply increment its ref |
1435 |
// if shared object is in our cache, then simply increment its |
|
|
1436 |
// ref |
| 1240 |
// count, |
1437 |
// count, |
| 1241 |
// and return the object. |
1438 |
// and return the object. |
| 1242 |
SYNC.release(); |
1439 |
SYNC.release(); |
| 1243 |
doRelease=false; |
|
|
| 1244 |
|
1440 |
|
| 1245 |
synchronized(sharedObject) { |
1441 |
synchronized (sharedObject) { |
| 1246 |
if (sharedObject.doWait) { |
1442 |
if (sharedObject.doWait) { |
| 1247 |
sharedObject.waitForLoadAttempt(); |
1443 |
sharedObject.waitForLoadAttempt(); |
| 1248 |
} |
1444 |
} |
| 1249 |
if (sharedObject.theSharedModel!=null) { |
1445 |
if (sharedObject.theSharedModel != null) { |
| 1250 |
_incrCount(sharedObject, READ); |
1446 |
_incrCount(sharedObject, READ); |
| 1251 |
} |
1447 |
} |
| 1252 |
result = sharedObject.theSharedModel; |
1448 |
result = sharedObject.theSharedModel; |
| 1253 |
} |
1449 |
} |
| 1254 |
} |
1450 |
} |
| 1255 |
} finally { |
|
|
| 1256 |
if (doRelease) |
| 1257 |
SYNC.release(); |
| 1258 |
} |
1451 |
} |
| 1259 |
return result; |
1452 |
return result; |
| 1260 |
} |
1453 |
} |
|
Lines 1262-1278
Link Here
|
| 1262 |
/** |
1455 |
/** |
| 1263 |
* @deprecated DMW: Tom, this is "special" for links builder Assuming its |
1456 |
* @deprecated DMW: Tom, this is "special" for links builder Assuming its |
| 1264 |
* still needed, wouldn't it be better to change to |
1457 |
* still needed, wouldn't it be better to change to |
| 1265 |
* getExistingModels()? -- will be removed. Its not thread |
1458 |
* getExistingModels()? -- will be removed. Its not thread safe |
| 1266 |
* safe for one thread to get the Enumeration, when underlying |
1459 |
* for one thread to get the Enumeration, when underlying data |
| 1267 |
* data could be changed in another thread. |
1460 |
* could be changed in another thread. |
| 1268 |
*/ |
1461 |
*/ |
| 1269 |
public Enumeration getExistingModelIds() { |
1462 |
public Enumeration getExistingModelIds() { |
| 1270 |
try { |
1463 |
try { |
| 1271 |
SYNC.acquire(); |
1464 |
SYNC.acquire(); |
| 1272 |
// create a copy |
1465 |
// create a copy |
| 1273 |
Vector keys = new Vector( fManagedObjects.keySet() ); |
1466 |
Vector keys = new Vector(fManagedObjects.keySet()); |
| 1274 |
return keys.elements(); |
1467 |
return keys.elements(); |
| 1275 |
} finally { |
1468 |
} |
|
|
1469 |
finally { |
| 1276 |
SYNC.release(); |
1470 |
SYNC.release(); |
| 1277 |
} |
1471 |
} |
| 1278 |
} |
1472 |
} |
|
Lines 1298-1321
Link Here
|
| 1298 |
/** |
1492 |
/** |
| 1299 |
* One of the primary forms to get a managed model |
1493 |
* One of the primary forms to get a managed model |
| 1300 |
*/ |
1494 |
*/ |
| 1301 |
public IStructuredModel getModelForEdit(IFile iFile) throws IOException, CoreException { |
1495 |
public IStructuredModel getModelForEdit(IFile iFile) throws IOException, CoreException { |
| 1302 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
1496 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1303 |
return _commonGetModel(iFile, EDIT, null, null); |
1497 |
return _commonGetModel(iFile, EDIT, null, null); |
| 1304 |
} |
1498 |
} |
| 1305 |
|
1499 |
|
| 1306 |
public IStructuredModel getModelForEdit(IFile iFile, EncodingRule encodingRule) throws UnsupportedEncodingException, IOException, CoreException { |
1500 |
public IStructuredModel getModelForEdit(IFile iFile, EncodingRule encodingRule) |
|
|
1501 |
throws UnsupportedEncodingException, IOException, CoreException { |
| 1307 |
|
1502 |
|
| 1308 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
1503 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1309 |
return _commonGetModel(iFile, EDIT, encodingRule); |
1504 |
return _commonGetModel(iFile, EDIT, encodingRule); |
| 1310 |
} |
1505 |
} |
| 1311 |
|
1506 |
|
| 1312 |
public IStructuredModel getModelForEdit(IFile iFile, String encoding, String lineDelimiter) throws java.io.UnsupportedEncodingException, IOException, CoreException { |
1507 |
public IStructuredModel getModelForEdit(IFile iFile, String encoding, String lineDelimiter) |
|
|
1508 |
throws java.io.UnsupportedEncodingException, IOException, CoreException { |
| 1313 |
|
1509 |
|
| 1314 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
1510 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1315 |
return _commonGetModel(iFile, EDIT, encoding, lineDelimiter); |
1511 |
return _commonGetModel(iFile, EDIT, encoding, lineDelimiter); |
| 1316 |
} |
1512 |
} |
| 1317 |
|
1513 |
|
| 1318 |
public IStructuredModel getModelForEdit(IStructuredDocument document) { |
1514 |
public IStructuredModel getModelForEdit(IStructuredDocument document) { |
| 1319 |
return _getModelFor(document, EDIT); |
1515 |
return _getModelFor(document, EDIT); |
| 1320 |
} |
1516 |
} |
| 1321 |
|
1517 |
|
|
Lines 1323-1329
Link Here
|
| 1323 |
* @see IModelManager |
1519 |
* @see IModelManager |
| 1324 |
* @deprecated use IFile or String form |
1520 |
* @deprecated use IFile or String form |
| 1325 |
*/ |
1521 |
*/ |
| 1326 |
public IStructuredModel getModelForEdit(Object id, InputStream inputStream, URIResolver resolver) throws java.io.UnsupportedEncodingException, IOException { |
1522 |
public IStructuredModel getModelForEdit(Object id, InputStream inputStream, URIResolver resolver) |
|
|
1523 |
throws java.io.UnsupportedEncodingException, IOException { |
| 1327 |
|
1524 |
|
| 1328 |
Assert.isNotNull(id, "IFile parameter can not be null"); //$NON-NLS-1$ |
1525 |
Assert.isNotNull(id, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1329 |
String stringId = id.toString(); |
1526 |
String stringId = id.toString(); |
|
Lines 1334-1347
Link Here
|
| 1334 |
* @see IModelManager |
1531 |
* @see IModelManager |
| 1335 |
* @deprecated - use IFile or String form |
1532 |
* @deprecated - use IFile or String form |
| 1336 |
*/ |
1533 |
*/ |
| 1337 |
public IStructuredModel getModelForEdit(Object id, Object modelType, String encodingName, String lineDelimiter, InputStream inputStream, URIResolver resolver) throws java.io.UnsupportedEncodingException, IOException { |
1534 |
public IStructuredModel getModelForEdit(Object id, Object modelType, String encodingName, |
|
|
1535 |
String lineDelimiter, InputStream inputStream, URIResolver resolver) |
| 1536 |
throws java.io.UnsupportedEncodingException, IOException { |
| 1338 |
|
1537 |
|
| 1339 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1538 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1340 |
String stringId = id.toString(); |
1539 |
String stringId = id.toString(); |
| 1341 |
return getModelForEdit(stringId, Utilities.getMarkSupportedStream(inputStream), resolver); |
1540 |
return getModelForEdit(stringId, Utilities.getMarkSupportedStream(inputStream), resolver); |
| 1342 |
} |
1541 |
} |
| 1343 |
|
1542 |
|
| 1344 |
public IStructuredModel getModelForEdit(String id, InputStream inputStream, URIResolver resolver) throws IOException { |
1543 |
public IStructuredModel getModelForEdit(String id, InputStream inputStream, URIResolver resolver) |
|
|
1544 |
throws IOException { |
| 1345 |
if (id == null) { |
1545 |
if (id == null) { |
| 1346 |
throw new IllegalArgumentException("Program Error: id may not be null"); //$NON-NLS-1$ |
1546 |
throw new IllegalArgumentException("Program Error: id may not be null"); //$NON-NLS-1$ |
| 1347 |
} |
1547 |
} |
|
Lines 1361-1383
Link Here
|
| 1361 |
/** |
1561 |
/** |
| 1362 |
* One of the primary forms to get a managed model |
1562 |
* One of the primary forms to get a managed model |
| 1363 |
*/ |
1563 |
*/ |
| 1364 |
public IStructuredModel getModelForRead(IFile iFile) throws IOException, CoreException { |
1564 |
public IStructuredModel getModelForRead(IFile iFile) throws IOException, CoreException { |
| 1365 |
|
1565 |
|
| 1366 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
1566 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1367 |
return _commonGetModel(iFile, READ, null, null); |
1567 |
return _commonGetModel(iFile, READ, null, null); |
| 1368 |
} |
1568 |
} |
| 1369 |
|
1569 |
|
| 1370 |
public IStructuredModel getModelForRead(IFile iFile, EncodingRule encodingRule) throws UnsupportedEncodingException, IOException, CoreException { |
1570 |
public IStructuredModel getModelForRead(IFile iFile, EncodingRule encodingRule) |
|
|
1571 |
throws UnsupportedEncodingException, IOException, CoreException { |
| 1371 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
1572 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1372 |
return _commonGetModel(iFile, READ, encodingRule); |
1573 |
return _commonGetModel(iFile, READ, encodingRule); |
| 1373 |
} |
1574 |
} |
| 1374 |
|
1575 |
|
| 1375 |
public IStructuredModel getModelForRead(IFile iFile, String encodingName, String lineDelimiter) throws java.io.UnsupportedEncodingException, IOException, CoreException { |
1576 |
public IStructuredModel getModelForRead(IFile iFile, String encodingName, String lineDelimiter) |
|
|
1577 |
throws java.io.UnsupportedEncodingException, IOException, CoreException { |
| 1376 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
1578 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1377 |
return _commonGetModel(iFile, READ, encodingName, lineDelimiter); |
1579 |
return _commonGetModel(iFile, READ, encodingName, lineDelimiter); |
| 1378 |
} |
1580 |
} |
| 1379 |
|
1581 |
|
| 1380 |
public IStructuredModel getModelForRead(IStructuredDocument document) { |
1582 |
public IStructuredModel getModelForRead(IStructuredDocument document) { |
| 1381 |
return _getModelFor(document, READ); |
1583 |
return _getModelFor(document, READ); |
| 1382 |
} |
1584 |
} |
| 1383 |
|
1585 |
|
|
Lines 1385-1391
Link Here
|
| 1385 |
* @see IModelManager |
1587 |
* @see IModelManager |
| 1386 |
* @deprecated use IFile or String form |
1588 |
* @deprecated use IFile or String form |
| 1387 |
*/ |
1589 |
*/ |
| 1388 |
public IStructuredModel getModelForRead(Object id, InputStream inputStream, URIResolver resolver) throws java.io.UnsupportedEncodingException, IOException { |
1590 |
public IStructuredModel getModelForRead(Object id, InputStream inputStream, URIResolver resolver) |
|
|
1591 |
throws java.io.UnsupportedEncodingException, IOException { |
| 1389 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1592 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1390 |
String stringId = id.toString(); |
1593 |
String stringId = id.toString(); |
| 1391 |
return getModelForRead(stringId, Utilities.getMarkSupportedStream(inputStream), resolver); |
1594 |
return getModelForRead(stringId, Utilities.getMarkSupportedStream(inputStream), resolver); |
|
Lines 1395-1407
Link Here
|
| 1395 |
* @see IModelManager |
1598 |
* @see IModelManager |
| 1396 |
* @deprecated use IFile form |
1599 |
* @deprecated use IFile form |
| 1397 |
*/ |
1600 |
*/ |
| 1398 |
public IStructuredModel getModelForRead(Object id, Object modelType, String encodingName, String lineDelimiter, InputStream inputStream, URIResolver resolver) throws java.io.UnsupportedEncodingException, IOException { |
1601 |
public IStructuredModel getModelForRead(Object id, Object modelType, String encodingName, |
|
|
1602 |
String lineDelimiter, InputStream inputStream, URIResolver resolver) |
| 1603 |
throws java.io.UnsupportedEncodingException, IOException { |
| 1399 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1604 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1400 |
String stringId = id.toString(); |
1605 |
String stringId = id.toString(); |
| 1401 |
return getModelForRead(stringId, Utilities.getMarkSupportedStream(inputStream), resolver); |
1606 |
return getModelForRead(stringId, Utilities.getMarkSupportedStream(inputStream), resolver); |
| 1402 |
} |
1607 |
} |
| 1403 |
|
1608 |
|
| 1404 |
public IStructuredModel getModelForRead(String id, InputStream inputStream, URIResolver resolver) throws IOException { |
1609 |
public IStructuredModel getModelForRead(String id, InputStream inputStream, URIResolver resolver) |
|
|
1610 |
throws IOException { |
| 1405 |
InputStream istream = Utilities.getMarkSupportedStream(inputStream); |
1611 |
InputStream istream = Utilities.getMarkSupportedStream(inputStream); |
| 1406 |
IModelHandler handler = calculateType(id, istream); |
1612 |
IModelHandler handler = calculateType(id, istream); |
| 1407 |
IStructuredModel result = null; |
1613 |
IStructuredModel result = null; |
|
Lines 1422-1431
Link Here
|
| 1422 |
/** |
1628 |
/** |
| 1423 |
* @see IModelManager#getNewModelForEdit(IFile, boolean) |
1629 |
* @see IModelManager#getNewModelForEdit(IFile, boolean) |
| 1424 |
*/ |
1630 |
*/ |
| 1425 |
public IStructuredModel getNewModelForEdit(IFile iFile, boolean force) throws ResourceAlreadyExists, ResourceInUse, IOException, CoreException { |
1631 |
public IStructuredModel getNewModelForEdit(IFile iFile, boolean force) |
|
|
1632 |
throws ResourceAlreadyExists, ResourceInUse, IOException, CoreException { |
| 1426 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
1633 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1427 |
SharedObject sharedObject = _commonNewModel(iFile, force); |
1634 |
SharedObject sharedObject = _commonNewModel(iFile, force); |
| 1428 |
synchronized(sharedObject) { |
1635 |
synchronized (sharedObject) { |
| 1429 |
sharedObject.referenceCountForEdit = 1; |
1636 |
sharedObject.referenceCountForEdit = 1; |
| 1430 |
} |
1637 |
} |
| 1431 |
sharedObject.setLoaded(); |
1638 |
sharedObject.setLoaded(); |
|
Lines 1435-1451
Link Here
|
| 1435 |
/** |
1642 |
/** |
| 1436 |
* @see IModelManager#getNewModelForRead(IFile, boolean) |
1643 |
* @see IModelManager#getNewModelForRead(IFile, boolean) |
| 1437 |
*/ |
1644 |
*/ |
| 1438 |
public IStructuredModel getNewModelForRead(IFile iFile, boolean force) throws ResourceAlreadyExists, ResourceInUse, IOException, CoreException { |
1645 |
public IStructuredModel getNewModelForRead(IFile iFile, boolean force) |
|
|
1646 |
throws ResourceAlreadyExists, ResourceInUse, IOException, CoreException { |
| 1439 |
|
1647 |
|
| 1440 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
1648 |
Assert.isNotNull(iFile, "IFile parameter can not be null"); //$NON-NLS-1$ |
| 1441 |
SharedObject sharedObject = _commonNewModel(iFile, force); |
1649 |
SharedObject sharedObject = _commonNewModel(iFile, force); |
| 1442 |
SYNC.acquire(); |
1650 |
SYNC.acquire(); |
| 1443 |
synchronized(sharedObject) { |
1651 |
try { |
| 1444 |
if (sharedObject.theSharedModel!=null) { |
1652 |
synchronized (sharedObject) { |
| 1445 |
sharedObject.referenceCountForRead = 1; |
1653 |
if (sharedObject.theSharedModel != null) { |
|
|
1654 |
sharedObject.referenceCountForRead = 1; |
| 1655 |
} |
| 1446 |
} |
1656 |
} |
| 1447 |
} |
1657 |
} |
| 1448 |
SYNC.release(); |
1658 |
finally { |
|
|
1659 |
SYNC.release(); |
| 1660 |
} |
| 1449 |
sharedObject.setLoaded(); |
1661 |
sharedObject.setLoaded(); |
| 1450 |
return sharedObject.theSharedModel; |
1662 |
return sharedObject.theSharedModel; |
| 1451 |
} |
1663 |
} |
|
Lines 1454-1477
Link Here
|
| 1454 |
* This function returns the reference count of underlying model. |
1666 |
* This function returns the reference count of underlying model. |
| 1455 |
* |
1667 |
* |
| 1456 |
* @param id |
1668 |
* @param id |
| 1457 |
* Object The id of the model TODO: try to refine the design |
1669 |
* Object The id of the model TODO: try to refine the design not |
| 1458 |
* not to use this function |
1670 |
* to use this function |
| 1459 |
*/ |
1671 |
*/ |
| 1460 |
public int getReferenceCount(Object id) { |
1672 |
public int getReferenceCount(Object id) { |
| 1461 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1673 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1462 |
int count = 0; |
1674 |
int count = 0; |
| 1463 |
|
1675 |
|
|
|
1676 |
SharedObject sharedObject = null; |
| 1464 |
SYNC.acquire(); |
1677 |
SYNC.acquire(); |
| 1465 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
1678 |
try { |
| 1466 |
if (sharedObject != null) { |
1679 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
|
|
1680 |
} |
| 1681 |
finally { |
| 1467 |
SYNC.release(); |
1682 |
SYNC.release(); |
| 1468 |
sharedObject.waitForLoadAttempt(); |
1683 |
if (sharedObject != null) { |
| 1469 |
SYNC.acquire(); |
1684 |
sharedObject.waitForLoadAttempt(); |
| 1470 |
synchronized (sharedObject) { |
1685 |
SYNC.acquire(); |
| 1471 |
count = sharedObject.referenceCountForRead + sharedObject.referenceCountForEdit; |
1686 |
try { |
|
|
1687 |
synchronized (sharedObject) { |
| 1688 |
count = sharedObject.referenceCountForRead |
| 1689 |
+ sharedObject.referenceCountForEdit; |
| 1690 |
} |
| 1691 |
} |
| 1692 |
finally { |
| 1693 |
SYNC.release(); |
| 1694 |
} |
| 1472 |
} |
1695 |
} |
| 1473 |
} |
1696 |
} |
| 1474 |
SYNC.release(); |
|
|
| 1475 |
return count; |
1697 |
return count; |
| 1476 |
} |
1698 |
} |
| 1477 |
|
1699 |
|
|
Lines 1479-1500
Link Here
|
| 1479 |
* This function returns the reference count of underlying model. |
1701 |
* This function returns the reference count of underlying model. |
| 1480 |
* |
1702 |
* |
| 1481 |
* @param id |
1703 |
* @param id |
| 1482 |
* Object The id of the model TODO: try to refine the design |
1704 |
* Object The id of the model TODO: try to refine the design not |
| 1483 |
* not to use this function |
1705 |
* to use this function |
| 1484 |
*/ |
1706 |
*/ |
| 1485 |
public int getReferenceCountForEdit(Object id) { |
1707 |
public int getReferenceCountForEdit(Object id) { |
| 1486 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1708 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1487 |
int count = 0; |
1709 |
int count = 0; |
|
|
1710 |
SharedObject sharedObject = null; |
| 1488 |
SYNC.acquire(); |
1711 |
SYNC.acquire(); |
| 1489 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
1712 |
try { |
| 1490 |
if (sharedObject != null) { |
1713 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
|
|
1714 |
} |
| 1715 |
finally { |
| 1491 |
SYNC.release(); |
1716 |
SYNC.release(); |
| 1492 |
sharedObject.waitForLoadAttempt(); |
1717 |
if (sharedObject != null) { |
| 1493 |
synchronized(sharedObject) { |
1718 |
sharedObject.waitForLoadAttempt(); |
| 1494 |
count = sharedObject.referenceCountForEdit; |
1719 |
synchronized (sharedObject) { |
|
|
1720 |
count = sharedObject.referenceCountForEdit; |
| 1721 |
} |
| 1495 |
} |
1722 |
} |
| 1496 |
} else { |
|
|
| 1497 |
SYNC.release(); |
| 1498 |
} |
1723 |
} |
| 1499 |
return count; |
1724 |
return count; |
| 1500 |
} |
1725 |
} |
|
Lines 1503-1529
Link Here
|
| 1503 |
* This function returns the reference count of underlying model. |
1728 |
* This function returns the reference count of underlying model. |
| 1504 |
* |
1729 |
* |
| 1505 |
* @param id |
1730 |
* @param id |
| 1506 |
* Object The id of the model TODO: try to refine the design |
1731 |
* Object The id of the model TODO: try to refine the design not |
| 1507 |
* not to use this function |
1732 |
* to use this function |
| 1508 |
*/ |
1733 |
*/ |
| 1509 |
public int getReferenceCountForRead(Object id) { |
1734 |
public int getReferenceCountForRead(Object id) { |
| 1510 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1735 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1511 |
int count = 0; |
1736 |
int count = 0; |
|
|
1737 |
SharedObject sharedObject = null; |
| 1512 |
SYNC.acquire(); |
1738 |
SYNC.acquire(); |
| 1513 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
1739 |
try { |
| 1514 |
if (sharedObject != null) { |
1740 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
|
|
1741 |
} |
| 1742 |
finally { |
| 1515 |
SYNC.release(); |
1743 |
SYNC.release(); |
| 1516 |
sharedObject.waitForLoadAttempt(); |
1744 |
if (sharedObject != null) { |
| 1517 |
SYNC.acquire(); |
1745 |
sharedObject.waitForLoadAttempt(); |
| 1518 |
synchronized(sharedObject) { |
1746 |
SYNC.acquire(); |
| 1519 |
count = sharedObject.referenceCountForRead; |
1747 |
try { |
|
|
1748 |
synchronized (sharedObject) { |
| 1749 |
count = sharedObject.referenceCountForRead; |
| 1750 |
} |
| 1751 |
} |
| 1752 |
finally { |
| 1753 |
SYNC.release(); |
| 1754 |
} |
| 1520 |
} |
1755 |
} |
| 1521 |
} |
1756 |
} |
| 1522 |
SYNC.release(); |
|
|
| 1523 |
return count; |
1757 |
return count; |
| 1524 |
} |
1758 |
} |
| 1525 |
|
1759 |
|
| 1526 |
private void handleConvertLineDelimiters(IStructuredDocument structuredDocument, IFile iFile, EncodingRule encodingRule, EncodingMemento encodingMemento) throws CoreException, MalformedOutputExceptionWithDetail, UnsupportedEncodingException { |
1760 |
private void handleConvertLineDelimiters(IStructuredDocument structuredDocument, IFile iFile, |
|
|
1761 |
EncodingRule encodingRule, EncodingMemento encodingMemento) throws CoreException, |
| 1762 |
MalformedOutputExceptionWithDetail, UnsupportedEncodingException { |
| 1527 |
if (structuredDocument.getNumberOfLines() > 1) { |
1763 |
if (structuredDocument.getNumberOfLines() > 1) { |
| 1528 |
convertLineDelimiters(structuredDocument, iFile); |
1764 |
convertLineDelimiters(structuredDocument, iFile); |
| 1529 |
} |
1765 |
} |
|
Lines 1538-1558
Link Here
|
| 1538 |
* This function returns true if there are other references to the |
1774 |
* This function returns true if there are other references to the |
| 1539 |
* underlying model. |
1775 |
* underlying model. |
| 1540 |
*/ |
1776 |
*/ |
| 1541 |
public boolean isShared(Object id) { |
1777 |
public boolean isShared(Object id) { |
| 1542 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1778 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1543 |
int count = 0; |
1779 |
int count = 0; |
| 1544 |
boolean result = false; |
1780 |
boolean result = false; |
|
|
1781 |
SharedObject sharedObject = null; |
| 1545 |
SYNC.acquire(); |
1782 |
SYNC.acquire(); |
| 1546 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
1783 |
try { |
| 1547 |
if (sharedObject != null) { |
1784 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
|
|
1785 |
} |
| 1786 |
finally { |
| 1548 |
SYNC.release(); |
1787 |
SYNC.release(); |
| 1549 |
sharedObject.waitForLoadAttempt(); |
1788 |
if (sharedObject != null) { |
| 1550 |
SYNC.acquire(); |
1789 |
sharedObject.waitForLoadAttempt(); |
| 1551 |
synchronized(sharedObject) { |
1790 |
SYNC.acquire(); |
| 1552 |
count = sharedObject.referenceCountForRead + sharedObject.referenceCountForEdit; |
1791 |
try { |
|
|
1792 |
synchronized (sharedObject) { |
| 1793 |
count = sharedObject.referenceCountForRead |
| 1794 |
+ sharedObject.referenceCountForEdit; |
| 1795 |
} |
| 1796 |
} |
| 1797 |
finally { |
| 1798 |
SYNC.release(); |
| 1799 |
} |
| 1553 |
} |
1800 |
} |
| 1554 |
} |
1801 |
} |
| 1555 |
SYNC.release(); |
1802 |
|
| 1556 |
result = count > 1; |
1803 |
result = count > 1; |
| 1557 |
return result; |
1804 |
return result; |
| 1558 |
} |
1805 |
} |
|
Lines 1564-1583
Link Here
|
| 1564 |
* @param id |
1811 |
* @param id |
| 1565 |
* Object The id of the model |
1812 |
* Object The id of the model |
| 1566 |
*/ |
1813 |
*/ |
| 1567 |
public boolean isSharedForEdit(Object id) { |
1814 |
public boolean isSharedForEdit(Object id) { |
| 1568 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1815 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1569 |
int count = 0; |
1816 |
int count = 0; |
| 1570 |
boolean result = false; |
1817 |
boolean result = false; |
|
|
1818 |
SharedObject sharedObject = null; |
| 1571 |
SYNC.acquire(); |
1819 |
SYNC.acquire(); |
| 1572 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
1820 |
try { |
| 1573 |
if (sharedObject != null) { |
1821 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
|
|
1822 |
} |
| 1823 |
finally { |
| 1574 |
SYNC.release(); |
1824 |
SYNC.release(); |
| 1575 |
sharedObject.waitForLoadAttempt(); |
1825 |
if (sharedObject != null) { |
| 1576 |
synchronized(sharedObject) { |
1826 |
sharedObject.waitForLoadAttempt(); |
| 1577 |
count = sharedObject.referenceCountForEdit; |
1827 |
SYNC.acquire(); |
|
|
1828 |
try { |
| 1829 |
synchronized (sharedObject) { |
| 1830 |
count = sharedObject.referenceCountForEdit; |
| 1831 |
} |
| 1832 |
} |
| 1833 |
finally { |
| 1834 |
SYNC.release(); |
| 1835 |
} |
| 1578 |
} |
1836 |
} |
| 1579 |
} else { |
|
|
| 1580 |
SYNC.release(); |
| 1581 |
} |
1837 |
} |
| 1582 |
result = count > 1; |
1838 |
result = count > 1; |
| 1583 |
return result; |
1839 |
return result; |
|
Lines 1590-1610
Link Here
|
| 1590 |
* @param id |
1846 |
* @param id |
| 1591 |
* Object The id of the model |
1847 |
* Object The id of the model |
| 1592 |
*/ |
1848 |
*/ |
| 1593 |
public boolean isSharedForRead(Object id) { |
1849 |
public boolean isSharedForRead(Object id) { |
| 1594 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
1850 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1595 |
int count = 0; |
1851 |
int count = 0; |
| 1596 |
boolean result = false; |
1852 |
boolean result = false; |
|
|
1853 |
SharedObject sharedObject = null; |
| 1597 |
SYNC.acquire(); |
1854 |
SYNC.acquire(); |
| 1598 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
1855 |
try { |
| 1599 |
if (sharedObject != null) { |
1856 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
|
|
1857 |
} |
| 1858 |
finally { |
| 1600 |
SYNC.release(); |
1859 |
SYNC.release(); |
| 1601 |
sharedObject.waitForLoadAttempt(); |
1860 |
if (sharedObject != null) { |
| 1602 |
SYNC.acquire(); |
1861 |
sharedObject.waitForLoadAttempt(); |
| 1603 |
synchronized(sharedObject) { |
1862 |
SYNC.acquire(); |
| 1604 |
count = sharedObject.referenceCountForRead; |
1863 |
try { |
|
|
1864 |
synchronized (sharedObject) { |
| 1865 |
count = sharedObject.referenceCountForRead; |
| 1866 |
} |
| 1867 |
} |
| 1868 |
finally { |
| 1869 |
SYNC.release(); |
| 1870 |
} |
| 1605 |
} |
1871 |
} |
| 1606 |
} |
1872 |
} |
| 1607 |
SYNC.release(); |
|
|
| 1608 |
result = count > 1; |
1873 |
result = count > 1; |
| 1609 |
return result; |
1874 |
return result; |
| 1610 |
} |
1875 |
} |
|
Lines 1626-1644
Link Here
|
| 1626 |
* not to use this function |
1891 |
* not to use this function |
| 1627 |
*/ |
1892 |
*/ |
| 1628 |
public void moveModel(Object oldId, Object newId) { |
1893 |
public void moveModel(Object oldId, Object newId) { |
| 1629 |
org.eclipse.wst.sse.core.internal.util.Assert.isNotNull(oldId, "id parameter can not be null"); //$NON-NLS-1$ |
1894 |
org.eclipse.wst.sse.core.internal.util.Assert.isNotNull(oldId, |
|
|
1895 |
"id parameter can not be null"); //$NON-NLS-1$ |
| 1896 |
SharedObject sharedObject = null; |
| 1630 |
SYNC.acquire(); |
1897 |
SYNC.acquire(); |
| 1631 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(oldId); |
1898 |
try { |
| 1632 |
// if not found in cache, ignore request. |
1899 |
// if not found in cache, ignore request. |
| 1633 |
// this would normally be a program error |
1900 |
// this would normally be a program error |
| 1634 |
if (sharedObject != null) { |
1901 |
sharedObject = (SharedObject) fManagedObjects.get(oldId); |
| 1635 |
fManagedObjects.remove(oldId); |
1902 |
if (sharedObject != null) { |
| 1636 |
fManagedObjects.put(newId, sharedObject); |
1903 |
fManagedObjects.remove(oldId); |
|
|
1904 |
fManagedObjects.put(newId, sharedObject); |
| 1905 |
} |
| 1906 |
} |
| 1907 |
finally { |
| 1908 |
SYNC.release(); |
| 1637 |
} |
1909 |
} |
| 1638 |
SYNC.release(); |
|
|
| 1639 |
} |
1910 |
} |
| 1640 |
|
1911 |
|
| 1641 |
private String readInputStream(InputStream inputStream, String ianaEncodingName) throws UnsupportedEncodingException, IOException { |
1912 |
private String readInputStream(InputStream inputStream, String ianaEncodingName) |
|
|
1913 |
throws UnsupportedEncodingException, IOException { |
| 1642 |
|
1914 |
|
| 1643 |
String allText = null; |
1915 |
String allText = null; |
| 1644 |
if ((ianaEncodingName != null) && (ianaEncodingName.length() != 0)) { |
1916 |
if ((ianaEncodingName != null) && (ianaEncodingName.length() != 0)) { |
|
Lines 1699-1705
Link Here
|
| 1699 |
return model; |
1971 |
return model; |
| 1700 |
} |
1972 |
} |
| 1701 |
|
1973 |
|
| 1702 |
void releaseFromEdit(IStructuredModel structuredModel) { |
1974 |
void releaseFromEdit(IStructuredModel structuredModel) { |
| 1703 |
Object id = structuredModel.getId(); |
1975 |
Object id = structuredModel.getId(); |
| 1704 |
if (id.equals(UNMANAGED_MODEL) || id.equals(DUPLICATED_MODEL)) { |
1976 |
if (id.equals(UNMANAGED_MODEL) || id.equals(DUPLICATED_MODEL)) { |
| 1705 |
cleanupDiscardedModel(structuredModel); |
1977 |
cleanupDiscardedModel(structuredModel); |
|
Lines 1709-1716
Link Here
|
| 1709 |
} |
1981 |
} |
| 1710 |
|
1982 |
|
| 1711 |
} |
1983 |
} |
| 1712 |
|
1984 |
|
| 1713 |
void releaseFromRead(IStructuredModel structuredModel) { |
1985 |
void releaseFromRead(IStructuredModel structuredModel) { |
| 1714 |
Object id = structuredModel.getId(); |
1986 |
Object id = structuredModel.getId(); |
| 1715 |
if (id.equals(UNMANAGED_MODEL) || id.equals(DUPLICATED_MODEL)) { |
1987 |
if (id.equals(UNMANAGED_MODEL) || id.equals(DUPLICATED_MODEL)) { |
| 1716 |
cleanupDiscardedModel(structuredModel); |
1988 |
cleanupDiscardedModel(structuredModel); |
|
Lines 1720-1730
Link Here
|
| 1720 |
} |
1992 |
} |
| 1721 |
|
1993 |
|
| 1722 |
} |
1994 |
} |
|
|
1995 |
|
| 1723 |
/** |
1996 |
/** |
| 1724 |
* default for use in same package, not subclasses |
1997 |
* default for use in same package, not subclasses |
| 1725 |
* |
1998 |
* |
| 1726 |
*/ |
1999 |
*/ |
| 1727 |
private void releaseFromEdit(Object id) { |
2000 |
private void releaseFromEdit(Object id) { |
| 1728 |
// ISSUE: many of these asserts should be changed to "logs" |
2001 |
// ISSUE: many of these asserts should be changed to "logs" |
| 1729 |
// and continue to limp along? |
2002 |
// and continue to limp along? |
| 1730 |
|
2003 |
|
|
Lines 1736-1759
Link Here
|
| 1736 |
// to be called on them, for now, but the model manager |
2009 |
// to be called on them, for now, but the model manager |
| 1737 |
// doesn't need to do anything. |
2010 |
// doesn't need to do anything. |
| 1738 |
if (id.equals(UNMANAGED_MODEL) || id.equals(DUPLICATED_MODEL)) { |
2011 |
if (id.equals(UNMANAGED_MODEL) || id.equals(DUPLICATED_MODEL)) { |
| 1739 |
throw new IllegalArgumentException("Ids of UNMANAGED_MODEL or DUPLICATED_MODEL are illegal here"); |
2012 |
throw new IllegalArgumentException( |
|
|
2013 |
"Ids of UNMANAGED_MODEL or DUPLICATED_MODEL are illegal here"); |
| 1740 |
} |
2014 |
} |
| 1741 |
else { |
2015 |
else { |
| 1742 |
SYNC.acquire(); |
2016 |
SYNC.acquire(); |
| 1743 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
2017 |
try { |
| 1744 |
SYNC.release(); |
2018 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
| 1745 |
|
2019 |
} |
| 1746 |
Assert.isNotNull(sharedObject, "release was requested on a model that was not being managed"); //$NON-NLS-1$ |
2020 |
finally { |
|
|
2021 |
SYNC.release(); |
| 2022 |
} |
| 2023 |
|
| 2024 |
Assert.isNotNull(sharedObject, |
| 2025 |
"release was requested on a model that was not being managed"); //$NON-NLS-1$ |
| 1747 |
sharedObject.waitForLoadAttempt(); |
2026 |
sharedObject.waitForLoadAttempt(); |
| 1748 |
|
2027 |
|
| 1749 |
SYNC.acquire(); |
2028 |
SYNC.acquire(); |
| 1750 |
synchronized(sharedObject) { |
2029 |
try { |
| 1751 |
_decrCount(sharedObject, EDIT); |
2030 |
synchronized (sharedObject) { |
| 1752 |
if ((sharedObject.referenceCountForRead == 0) && (sharedObject.referenceCountForEdit == 0)) { |
2031 |
_decrCount(sharedObject, EDIT); |
| 1753 |
discardModel(id, sharedObject); |
2032 |
if ((sharedObject.referenceCountForRead == 0) |
|
|
2033 |
&& (sharedObject.referenceCountForEdit == 0)) { |
| 2034 |
discardModel(id, sharedObject); |
| 2035 |
} |
| 1754 |
} |
2036 |
} |
| 1755 |
} |
2037 |
} |
| 1756 |
SYNC.release(); |
2038 |
finally { |
|
|
2039 |
SYNC.release(); |
| 2040 |
} |
| 1757 |
// if edit goes to zero, but still open for read, |
2041 |
// if edit goes to zero, but still open for read, |
| 1758 |
// then we should reload here, so we are in synch with |
2042 |
// then we should reload here, so we are in synch with |
| 1759 |
// contents on disk. |
2043 |
// contents on disk. |
|
Lines 1762-1792
Link Here
|
| 1762 |
// flag for some reason. |
2046 |
// flag for some reason. |
| 1763 |
// we need to address * that * too. |
2047 |
// we need to address * that * too. |
| 1764 |
|
2048 |
|
| 1765 |
synchronized(sharedObject) { |
2049 |
synchronized (sharedObject) { |
| 1766 |
if ((sharedObject.referenceCountForRead > 0) && (sharedObject.referenceCountForEdit == 0) && sharedObject.theSharedModel.isDirty()) { |
2050 |
if ((sharedObject.referenceCountForRead > 0) |
|
|
2051 |
&& (sharedObject.referenceCountForEdit == 0) |
| 2052 |
&& sharedObject.theSharedModel.isDirty()) { |
| 1767 |
signalPreLifeCycleListenerRevert(sharedObject.theSharedModel); |
2053 |
signalPreLifeCycleListenerRevert(sharedObject.theSharedModel); |
| 1768 |
revertModel(id, sharedObject); |
2054 |
revertModel(id, sharedObject); |
| 1769 |
/* |
2055 |
/* |
| 1770 |
* Because model events are fired to notify about the |
2056 |
* Because model events are fired to notify about the |
| 1771 |
* revert's changes, and listeners can still get/release |
2057 |
* revert's changes, and listeners can still get/release the |
| 1772 |
* the model from this thread (locking prevents it being |
2058 |
* model from this thread (locking prevents it being done |
| 1773 |
* done from other threads), the reference counts could |
2059 |
* from other threads), the reference counts could have |
| 1774 |
* have changed since we entered this if block, and the |
2060 |
* changed since we entered this if block, and the model |
| 1775 |
* model could have been discarded. Check the counts again. |
2061 |
* could have been discarded. Check the counts again. |
| 1776 |
*/ |
2062 |
*/ |
| 1777 |
if (sharedObject.referenceCountForRead > 0 && sharedObject.referenceCountForEdit == 0) { |
2063 |
if (sharedObject.referenceCountForRead > 0 |
|
|
2064 |
&& sharedObject.referenceCountForEdit == 0) { |
| 1778 |
sharedObject.theSharedModel.setDirtyState(false); |
2065 |
sharedObject.theSharedModel.setDirtyState(false); |
| 1779 |
} |
2066 |
} |
| 1780 |
signalPostLifeCycleListenerRevert(sharedObject.theSharedModel); |
2067 |
signalPostLifeCycleListenerRevert(sharedObject.theSharedModel); |
| 1781 |
} |
2068 |
} |
| 1782 |
} |
2069 |
} |
| 1783 |
|
2070 |
|
| 1784 |
} |
2071 |
} |
| 1785 |
} |
2072 |
} |
| 1786 |
|
2073 |
|
| 1787 |
// private for now, though public forms have been requested, in past. |
2074 |
// private for now, though public forms have been requested, in past. |
| 1788 |
private void revertModel(Object id, SharedObject sharedObject) { |
2075 |
private void revertModel(Object id, SharedObject sharedObject) { |
| 1789 |
IStructuredDocument structuredDocument = sharedObject.theSharedModel.getStructuredDocument(); |
2076 |
IStructuredDocument structuredDocument = sharedObject.theSharedModel |
|
|
2077 |
.getStructuredDocument(); |
| 1790 |
FileBufferModelManager.getInstance().revert(structuredDocument); |
2078 |
FileBufferModelManager.getInstance().revert(structuredDocument); |
| 1791 |
} |
2079 |
} |
| 1792 |
|
2080 |
|
|
Lines 1806-1817
Link Here
|
| 1806 |
|
2094 |
|
| 1807 |
private void discardModel(Object id, SharedObject sharedObject) { |
2095 |
private void discardModel(Object id, SharedObject sharedObject) { |
| 1808 |
SYNC.acquire(); |
2096 |
SYNC.acquire(); |
| 1809 |
fManagedObjects.remove(id); |
2097 |
try { |
| 1810 |
SYNC.release(); |
2098 |
fManagedObjects.remove(id); |
| 1811 |
IStructuredDocument structuredDocument = sharedObject.theSharedModel.getStructuredDocument(); |
2099 |
} |
|
|
2100 |
finally { |
| 2101 |
SYNC.release(); |
| 2102 |
} |
| 2103 |
IStructuredDocument structuredDocument = sharedObject.theSharedModel |
| 2104 |
.getStructuredDocument(); |
| 1812 |
|
2105 |
|
| 1813 |
if (structuredDocument == null) { |
2106 |
if (structuredDocument == null) { |
| 1814 |
Platform.getLog(SSECorePlugin.getDefault().getBundle()).log(new Status(IStatus.ERROR, SSECorePlugin.ID, IStatus.ERROR, "Attempted to discard a structured model but the underlying document has already been set to null: " + sharedObject.theSharedModel.getBaseLocation(), null)); |
2107 |
Platform |
|
|
2108 |
.getLog(SSECorePlugin.getDefault().getBundle()) |
| 2109 |
.log( |
| 2110 |
new Status( |
| 2111 |
IStatus.ERROR, |
| 2112 |
SSECorePlugin.ID, |
| 2113 |
IStatus.ERROR, |
| 2114 |
"Attempted to discard a structured model but the underlying document has already been set to null: " |
| 2115 |
+ sharedObject.theSharedModel.getBaseLocation(), null)); |
| 1815 |
} |
2116 |
} |
| 1816 |
|
2117 |
|
| 1817 |
cleanupDiscardedModel(sharedObject.theSharedModel); |
2118 |
cleanupDiscardedModel(sharedObject.theSharedModel); |
|
Lines 1821-1841
Link Here
|
| 1821 |
IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); |
2122 |
IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); |
| 1822 |
/* |
2123 |
/* |
| 1823 |
* This call (and setting the StructuredDocument to null) were |
2124 |
* This call (and setting the StructuredDocument to null) were |
| 1824 |
* previously done within the model itself, but for concurrency it |
2125 |
* previously done within the model itself, but for concurrency it must |
| 1825 |
* must be done here during a synchronized release. |
2126 |
* be done here during a synchronized release. |
| 1826 |
*/ |
2127 |
*/ |
| 1827 |
structuredModel.getFactoryRegistry().release(); |
2128 |
structuredModel.getFactoryRegistry().release(); |
| 1828 |
|
2129 |
|
| 1829 |
/* |
2130 |
/* |
| 1830 |
* For structured documents originating from file buffers, disconnect |
2131 |
* For structured documents originating from file buffers, disconnect us |
| 1831 |
* us from the file buffer, now. |
2132 |
* from the file buffer, now. |
| 1832 |
*/ |
2133 |
*/ |
| 1833 |
FileBufferModelManager.getInstance().releaseModel(structuredDocument); |
2134 |
FileBufferModelManager.getInstance().releaseModel(structuredDocument); |
| 1834 |
|
2135 |
|
| 1835 |
/* |
2136 |
/* |
| 1836 |
* Setting the document to null is required since some subclasses of |
2137 |
* Setting the document to null is required since some subclasses of |
| 1837 |
* model might have "cleanup" of listeners, etc., to remove, which |
2138 |
* model might have "cleanup" of listeners, etc., to remove, which were |
| 1838 |
* were initialized during the initial setStructuredDocument. |
2139 |
* initialized during the initial setStructuredDocument. |
| 1839 |
* |
2140 |
* |
| 1840 |
* The model itself in particular may have internal listeners used to |
2141 |
* The model itself in particular may have internal listeners used to |
| 1841 |
* coordinate the document with its own "structure". |
2142 |
* coordinate the document with its own "structure". |
|
Lines 1843-1888
Link Here
|
| 1843 |
structuredModel.setStructuredDocument(null); |
2144 |
structuredModel.setStructuredDocument(null); |
| 1844 |
} |
2145 |
} |
| 1845 |
|
2146 |
|
| 1846 |
|
|
|
| 1847 |
/** |
2147 |
/** |
| 1848 |
* default for use in same package, not subclasses |
2148 |
* default for use in same package, not subclasses |
| 1849 |
* |
2149 |
* |
| 1850 |
*/ |
2150 |
*/ |
| 1851 |
private void releaseFromRead(Object id) { |
2151 |
private void releaseFromRead(Object id) { |
| 1852 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
2152 |
Assert.isNotNull(id, "id parameter can not be null"); //$NON-NLS-1$ |
| 1853 |
SharedObject sharedObject = null; |
2153 |
SharedObject sharedObject = null; |
| 1854 |
|
2154 |
|
| 1855 |
if (id.equals(UNMANAGED_MODEL) || id.equals(DUPLICATED_MODEL)) { |
2155 |
if (id.equals(UNMANAGED_MODEL) || id.equals(DUPLICATED_MODEL)) { |
| 1856 |
throw new IllegalArgumentException("Ids of UNMANAGED_MODEL or DUPLICATED_MODEL are illegal here"); |
2156 |
throw new IllegalArgumentException( |
|
|
2157 |
"Ids of UNMANAGED_MODEL or DUPLICATED_MODEL are illegal here"); |
| 1857 |
} |
2158 |
} |
| 1858 |
else { |
2159 |
else { |
| 1859 |
SYNC.acquire(); |
2160 |
SYNC.acquire(); |
| 1860 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
2161 |
try { |
| 1861 |
SYNC.release(); |
2162 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
| 1862 |
Assert.isNotNull(sharedObject, "release was requested on a model that was not being managed"); //$NON-NLS-1$ |
2163 |
} |
|
|
2164 |
finally { |
| 2165 |
SYNC.release(); |
| 2166 |
} |
| 2167 |
Assert.isNotNull(sharedObject, |
| 2168 |
"release was requested on a model that was not being managed"); //$NON-NLS-1$ |
| 1863 |
sharedObject.waitForLoadAttempt(); |
2169 |
sharedObject.waitForLoadAttempt(); |
| 1864 |
} |
2170 |
} |
| 1865 |
SYNC.acquire(); |
2171 |
SYNC.acquire(); |
| 1866 |
synchronized(sharedObject) { |
2172 |
try { |
| 1867 |
_decrCount(sharedObject, READ); |
2173 |
synchronized (sharedObject) { |
| 1868 |
if ((sharedObject.referenceCountForRead == 0) && (sharedObject.referenceCountForEdit == 0)) { |
2174 |
_decrCount(sharedObject, READ); |
| 1869 |
discardModel(id, sharedObject); |
2175 |
if ((sharedObject.referenceCountForRead == 0) |
|
|
2176 |
&& (sharedObject.referenceCountForEdit == 0)) { |
| 2177 |
discardModel(id, sharedObject); |
| 2178 |
} |
| 1870 |
} |
2179 |
} |
| 1871 |
} |
2180 |
} |
| 1872 |
SYNC.release(); |
2181 |
finally { |
|
|
2182 |
SYNC.release(); |
| 2183 |
} |
| 1873 |
} |
2184 |
} |
| 1874 |
|
2185 |
|
| 1875 |
/** |
2186 |
/** |
| 1876 |
* This is similar to the getModel method, except this method does not use |
2187 |
* This is similar to the getModel method, except this method does not use |
| 1877 |
* the cached version, but forces the cached version to be replaced with a |
2188 |
* the cached version, but forces the cached version to be replaced with a |
| 1878 |
* fresh, unchanged version. Note: this method does not change any |
2189 |
* fresh, unchanged version. Note: this method does not change any reference |
| 1879 |
* reference counts. Also, if there is not already a cached version of the |
2190 |
* counts. Also, if there is not already a cached version of the model, then |
| 1880 |
* model, then this call is essentially ignored (that is, it does not put |
2191 |
* this call is essentially ignored (that is, it does not put a model in the |
| 1881 |
* a model in the cache) and returns null. |
2192 |
* cache) and returns null. |
| 1882 |
* |
2193 |
* |
| 1883 |
* @deprecated - will become protected, use reload directly on model |
2194 |
* @deprecated - will become protected, use reload directly on model |
| 1884 |
*/ |
2195 |
*/ |
| 1885 |
public IStructuredModel reloadModel(Object id, java.io.InputStream inputStream) throws java.io.UnsupportedEncodingException { |
2196 |
public IStructuredModel reloadModel(Object id, java.io.InputStream inputStream) |
|
|
2197 |
throws java.io.UnsupportedEncodingException { |
| 1886 |
|
2198 |
|
| 1887 |
// get the existing model associated with this id |
2199 |
// get the existing model associated with this id |
| 1888 |
IStructuredModel structuredModel = getExistingModel(id); |
2200 |
IStructuredModel structuredModel = getExistingModel(id); |
|
Lines 1903-1951
Link Here
|
| 1903 |
return structuredModel; |
2215 |
return structuredModel; |
| 1904 |
} |
2216 |
} |
| 1905 |
|
2217 |
|
| 1906 |
public void saveModel(IFile iFile, String id, EncodingRule encodingRule) throws UnsupportedEncodingException, IOException, CoreException { |
2218 |
public void saveModel(IFile iFile, String id, EncodingRule encodingRule) |
|
|
2219 |
throws UnsupportedEncodingException, IOException, CoreException { |
| 1907 |
|
2220 |
|
| 1908 |
// let's see if we already have it in our cache |
2221 |
// let's see if we already have it in our cache |
| 1909 |
|
2222 |
SharedObject sharedObject = null; |
| 1910 |
SYNC.acquire(); |
2223 |
SYNC.acquire(); |
| 1911 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
2224 |
try { |
| 1912 |
if (sharedObject == null || sharedObject.theSharedModel == null) { |
2225 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
|
|
2226 |
} |
| 2227 |
finally { |
| 1913 |
SYNC.release(); |
2228 |
SYNC.release(); |
|
|
2229 |
} |
| 2230 |
if (sharedObject == null || sharedObject.theSharedModel == null) { |
| 1914 |
throw new IllegalStateException(SSECoreMessages.Program_Error__ModelManage_EXC_); //$NON-NLS-1$ = "Program Error: ModelManagerImpl::saveModel. Model should be in the cache" |
2231 |
throw new IllegalStateException(SSECoreMessages.Program_Error__ModelManage_EXC_); //$NON-NLS-1$ = "Program Error: ModelManagerImpl::saveModel. Model should be in the cache" |
| 1915 |
} |
2232 |
} |
| 1916 |
else { |
2233 |
|
| 1917 |
SYNC.release(); |
2234 |
// Note to self: not clear if this does anything. |
| 1918 |
sharedObject.waitForLoadAttempt(); |
2235 |
// sharedObject.theSharedModel cannot be null, so what are we waiting |
| 1919 |
|
2236 |
// for? |
| 1920 |
/** |
2237 |
sharedObject.waitForLoadAttempt(); |
| 1921 |
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=221610 |
2238 |
|
| 1922 |
* |
2239 |
/** |
| 1923 |
* Sync removed from here to prevent deadlock. Although the model |
2240 |
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=221610 |
| 1924 |
* instance may disappear or be made invalid while the save is |
2241 |
* |
| 1925 |
* happening, the document itself still has the contents we're |
2242 |
* Sync removed from here to prevent deadlock. Although the model |
| 1926 |
* trying to save. Simultaneous saves should be throttled by |
2243 |
* instance may disappear or be made invalid while the save is |
| 1927 |
* resource locking without our intervention. |
2244 |
* happening, the document itself still has the contents we're trying to |
| 1928 |
*/ |
2245 |
* save. Simultaneous saves should be throttled by resource locking |
| 1929 |
boolean saved = false; |
2246 |
* without our intervention. |
| 1930 |
// if this model was based on a File Buffer and we're writing back |
2247 |
*/ |
| 1931 |
// to the same location, use the buffer to do the writing |
2248 |
boolean saved = false; |
| 1932 |
if (FileBufferModelManager.getInstance().isExistingBuffer(sharedObject.theSharedModel.getStructuredDocument())) { |
2249 |
// if this model was based on a File Buffer and we're writing back |
| 1933 |
ITextFileBuffer buffer = FileBufferModelManager.getInstance().getBuffer(sharedObject.theSharedModel.getStructuredDocument()); |
2250 |
// to the same location, use the buffer to do the writing |
| 1934 |
IPath fileLocation = FileBuffers.normalizeLocation(iFile.getFullPath()); |
2251 |
if (FileBufferModelManager.getInstance().isExistingBuffer( |
| 1935 |
if (fileLocation.equals(buffer.getLocation())) { |
2252 |
sharedObject.theSharedModel.getStructuredDocument())) { |
| 1936 |
buffer.commit(new NullProgressMonitor(), true); |
2253 |
ITextFileBuffer buffer = FileBufferModelManager.getInstance().getBuffer( |
| 1937 |
saved = true; |
2254 |
sharedObject.theSharedModel.getStructuredDocument()); |
| 1938 |
} |
2255 |
IPath fileLocation = FileBuffers.normalizeLocation(iFile.getFullPath()); |
| 1939 |
} |
2256 |
if (fileLocation.equals(buffer.getLocation())) { |
| 1940 |
if (!saved) { |
2257 |
buffer.commit(new NullProgressMonitor(), true); |
| 1941 |
IStructuredModel model = sharedObject.theSharedModel; |
2258 |
saved = true; |
| 1942 |
IStructuredDocument document = model.getStructuredDocument(); |
|
|
| 1943 |
saveStructuredDocument(document, iFile, encodingRule); |
| 1944 |
trace("saving model", id); //$NON-NLS-1$ |
| 1945 |
} |
2259 |
} |
| 1946 |
sharedObject.theSharedModel.setDirtyState(false); |
2260 |
} |
| 1947 |
sharedObject.theSharedModel.setNewState(false); |
2261 |
if (!saved) { |
| 1948 |
} |
2262 |
IStructuredModel model = sharedObject.theSharedModel; |
|
|
2263 |
IStructuredDocument document = model.getStructuredDocument(); |
| 2264 |
saveStructuredDocument(document, iFile, encodingRule); |
| 2265 |
trace("saving model", id); //$NON-NLS-1$ |
| 2266 |
} |
| 2267 |
sharedObject.theSharedModel.setDirtyState(false); |
| 2268 |
sharedObject.theSharedModel.setNewState(false); |
| 2269 |
|
| 1949 |
} |
2270 |
} |
| 1950 |
|
2271 |
|
| 1951 |
/** |
2272 |
/** |
|
Lines 1958-2003
Link Here
|
| 1958 |
* @throws IOException |
2279 |
* @throws IOException |
| 1959 |
* @throws CoreException |
2280 |
* @throws CoreException |
| 1960 |
*/ |
2281 |
*/ |
| 1961 |
public void saveModel(String id, EncodingRule encodingRule) throws UnsupportedEncodingException, IOException, CoreException { |
2282 |
public void saveModel(String id, EncodingRule encodingRule) |
|
|
2283 |
throws UnsupportedEncodingException, IOException, CoreException { |
| 1962 |
|
2284 |
|
| 1963 |
// let's see if we already have it in our cache |
2285 |
// let's see if we already have it in our cache |
| 1964 |
|
2286 |
SharedObject sharedObject = null; |
| 1965 |
SYNC.acquire(); |
2287 |
SYNC.acquire(); |
| 1966 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
2288 |
try { |
| 1967 |
if (sharedObject == null) { |
2289 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
|
|
2290 |
} |
| 2291 |
finally { |
| 1968 |
SYNC.release(); |
2292 |
SYNC.release(); |
|
|
2293 |
} |
| 2294 |
if (sharedObject == null) { |
| 1969 |
throw new IllegalStateException(SSECoreMessages.Program_Error__ModelManage_EXC_); //$NON-NLS-1$ = "Program Error: ModelManagerImpl::saveModel. Model should be in the cache" |
2295 |
throw new IllegalStateException(SSECoreMessages.Program_Error__ModelManage_EXC_); //$NON-NLS-1$ = "Program Error: ModelManagerImpl::saveModel. Model should be in the cache" |
| 1970 |
} |
2296 |
} |
|
|
2297 |
|
| 2298 |
// Note to self: not clear if this does anything. |
| 2299 |
// sharedObject.theSharedModel cannot be null, so what are we waiting |
| 2300 |
// for? |
| 2301 |
sharedObject.waitForLoadAttempt(); |
| 2302 |
/** |
| 2303 |
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=221610 |
| 2304 |
* |
| 2305 |
* Sync removed from here to prevent deadlock. Although the model |
| 2306 |
* instance may disappear or be made invalid while the save is |
| 2307 |
* happening, the document itself still has the contents we're trying to |
| 2308 |
* save. Simultaneous saves should be throttled by resource locking |
| 2309 |
* without our intervention. |
| 2310 |
*/ |
| 2311 |
/* |
| 2312 |
* if this model was based on a File Buffer and we're writing back to |
| 2313 |
* the same location, use the buffer to do the writing |
| 2314 |
*/ |
| 2315 |
if (FileBufferModelManager.getInstance().isExistingBuffer( |
| 2316 |
sharedObject.theSharedModel.getStructuredDocument())) { |
| 2317 |
ITextFileBuffer buffer = FileBufferModelManager.getInstance().getBuffer( |
| 2318 |
sharedObject.theSharedModel.getStructuredDocument()); |
| 2319 |
buffer.commit(new NullProgressMonitor(), true); |
| 2320 |
} |
| 1971 |
else { |
2321 |
else { |
| 1972 |
SYNC.release(); |
2322 |
IFile iFile = getFileFor(sharedObject.theSharedModel); |
| 1973 |
sharedObject.waitForLoadAttempt(); |
2323 |
IStructuredModel model = sharedObject.theSharedModel; |
| 1974 |
/** |
2324 |
IStructuredDocument document = model.getStructuredDocument(); |
| 1975 |
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=221610 |
2325 |
saveStructuredDocument(document, iFile); |
| 1976 |
* |
2326 |
trace("saving model", id); //$NON-NLS-1$ |
| 1977 |
* Sync removed from here to prevent deadlock. Although the model |
|
|
| 1978 |
* instance may disappear or be made invalid while the save is |
| 1979 |
* happening, the document itself still has the contents we're |
| 1980 |
* trying to save. Simultaneous saves should be throttled by |
| 1981 |
* resource locking without our intervention. |
| 1982 |
*/ |
| 1983 |
/* |
| 1984 |
* if this model was based on a File Buffer and we're writing back |
| 1985 |
* to the same location, use the buffer to do the writing |
| 1986 |
*/ |
| 1987 |
if (FileBufferModelManager.getInstance().isExistingBuffer(sharedObject.theSharedModel.getStructuredDocument())) { |
| 1988 |
ITextFileBuffer buffer = FileBufferModelManager.getInstance().getBuffer(sharedObject.theSharedModel.getStructuredDocument()); |
| 1989 |
buffer.commit(new NullProgressMonitor(), true); |
| 1990 |
} |
| 1991 |
else { |
| 1992 |
IFile iFile = getFileFor(sharedObject.theSharedModel); |
| 1993 |
IStructuredModel model = sharedObject.theSharedModel; |
| 1994 |
IStructuredDocument document = model.getStructuredDocument(); |
| 1995 |
saveStructuredDocument(document, iFile); |
| 1996 |
trace("saving model", id); //$NON-NLS-1$ |
| 1997 |
} |
| 1998 |
sharedObject.theSharedModel.setDirtyState(false); |
| 1999 |
sharedObject.theSharedModel.setNewState(false); |
| 2000 |
} |
2327 |
} |
|
|
2328 |
sharedObject.theSharedModel.setDirtyState(false); |
| 2329 |
sharedObject.theSharedModel.setNewState(false); |
| 2330 |
|
| 2001 |
} |
2331 |
} |
| 2002 |
|
2332 |
|
| 2003 |
/** |
2333 |
/** |
|
Lines 2005-2043
Link Here
|
| 2005 |
* requires an extra "copy" of byte array, and should be avoid |
2335 |
* requires an extra "copy" of byte array, and should be avoid |
| 2006 |
* in favor of the IFile form. |
2336 |
* in favor of the IFile form. |
| 2007 |
*/ |
2337 |
*/ |
| 2008 |
public void saveModel(String id, OutputStream outputStream, EncodingRule encodingRule) throws UnsupportedEncodingException, CoreException, IOException { |
2338 |
public void saveModel(String id, OutputStream outputStream, EncodingRule encodingRule) |
|
|
2339 |
throws UnsupportedEncodingException, CoreException, IOException { |
| 2340 |
SharedObject sharedObject = null; |
| 2009 |
SYNC.acquire(); |
2341 |
SYNC.acquire(); |
| 2010 |
// let's see if we already have it in our cache |
2342 |
try { |
| 2011 |
SharedObject sharedObject = (SharedObject) fManagedObjects.get(id); |
2343 |
// let's see if we already have it in our cache |
| 2012 |
if (sharedObject == null) { |
2344 |
sharedObject = (SharedObject) fManagedObjects.get(id); |
|
|
2345 |
} |
| 2346 |
finally { |
| 2013 |
SYNC.release(); |
2347 |
SYNC.release(); |
|
|
2348 |
} |
| 2349 |
if (sharedObject == null) { |
| 2350 |
|
| 2014 |
throw new IllegalStateException(SSECoreMessages.Program_Error__ModelManage_EXC_); //$NON-NLS-1$ = "Program Error: ModelManagerImpl::saveModel. Model should be in the cache" |
2351 |
throw new IllegalStateException(SSECoreMessages.Program_Error__ModelManage_EXC_); //$NON-NLS-1$ = "Program Error: ModelManagerImpl::saveModel. Model should be in the cache" |
| 2015 |
} |
2352 |
} |
| 2016 |
else { |
2353 |
sharedObject.waitForLoadAttempt(); |
| 2017 |
SYNC.release(); |
2354 |
synchronized (sharedObject) { |
| 2018 |
sharedObject.waitForLoadAttempt(); |
2355 |
CodedStreamCreator codedStreamCreator = new CodedStreamCreator(); |
| 2019 |
synchronized(sharedObject) { |
2356 |
codedStreamCreator.set(sharedObject.theSharedModel.getId(), new DocumentReader( |
| 2020 |
CodedStreamCreator codedStreamCreator = new CodedStreamCreator(); |
2357 |
sharedObject.theSharedModel.getStructuredDocument())); |
| 2021 |
codedStreamCreator.set(sharedObject.theSharedModel.getId(), new DocumentReader(sharedObject.theSharedModel.getStructuredDocument())); |
2358 |
codedStreamCreator.setPreviousEncodingMemento(sharedObject.theSharedModel |
| 2022 |
codedStreamCreator.setPreviousEncodingMemento(sharedObject.theSharedModel.getStructuredDocument().getEncodingMemento()); |
2359 |
.getStructuredDocument().getEncodingMemento()); |
| 2023 |
ByteArrayOutputStream byteArrayOutputStream = codedStreamCreator.getCodedByteArrayOutputStream(encodingRule); |
2360 |
ByteArrayOutputStream byteArrayOutputStream = codedStreamCreator |
| 2024 |
byte[] outputBytes = byteArrayOutputStream.toByteArray(); |
2361 |
.getCodedByteArrayOutputStream(encodingRule); |
| 2025 |
outputStream.write(outputBytes); |
2362 |
byte[] outputBytes = byteArrayOutputStream.toByteArray(); |
| 2026 |
trace("saving model", id); //$NON-NLS-1$ |
2363 |
outputStream.write(outputBytes); |
| 2027 |
sharedObject.theSharedModel.setDirtyState(false); |
2364 |
trace("saving model", id); //$NON-NLS-1$ |
| 2028 |
sharedObject.theSharedModel.setNewState(false); |
2365 |
sharedObject.theSharedModel.setDirtyState(false); |
| 2029 |
} |
2366 |
sharedObject.theSharedModel.setNewState(false); |
| 2030 |
} |
2367 |
} |
|
|
2368 |
|
| 2031 |
} |
2369 |
} |
| 2032 |
|
2370 |
|
| 2033 |
public void saveStructuredDocument(IStructuredDocument structuredDocument, IFile iFile) throws UnsupportedEncodingException, CoreException, IOException { |
2371 |
public void saveStructuredDocument(IStructuredDocument structuredDocument, IFile iFile) |
|
|
2372 |
throws UnsupportedEncodingException, CoreException, IOException { |
| 2034 |
saveStructuredDocument(structuredDocument, iFile, EncodingRule.CONTENT_BASED); |
2373 |
saveStructuredDocument(structuredDocument, iFile, EncodingRule.CONTENT_BASED); |
| 2035 |
} |
2374 |
} |
| 2036 |
|
2375 |
|
| 2037 |
public void saveStructuredDocument(IStructuredDocument structuredDocument, IFile iFile, EncodingRule encodingRule) throws UnsupportedEncodingException, CoreException, IOException { |
2376 |
public void saveStructuredDocument(IStructuredDocument structuredDocument, IFile iFile, |
|
|
2377 |
EncodingRule encodingRule) throws UnsupportedEncodingException, CoreException, |
| 2378 |
IOException { |
| 2038 |
if (FileBufferModelManager.getInstance().isExistingBuffer(structuredDocument)) { |
2379 |
if (FileBufferModelManager.getInstance().isExistingBuffer(structuredDocument)) { |
| 2039 |
ITextFileBuffer buffer = FileBufferModelManager.getInstance().getBuffer(structuredDocument); |
2380 |
ITextFileBuffer buffer = FileBufferModelManager.getInstance().getBuffer( |
| 2040 |
if (buffer.getLocation().equals(iFile.getFullPath()) || buffer.getLocation().equals(iFile.getLocation())) { |
2381 |
structuredDocument); |
|
|
2382 |
if (buffer.getLocation().equals(iFile.getFullPath()) |
| 2383 |
|| buffer.getLocation().equals(iFile.getLocation())) { |
| 2041 |
buffer.commit(new NullProgressMonitor(), true); |
2384 |
buffer.commit(new NullProgressMonitor(), true); |
| 2042 |
} |
2385 |
} |
| 2043 |
} |
2386 |
} |
|
Lines 2059-2065
Link Here
|
| 2059 |
// before writing to output stream. |
2402 |
// before writing to output stream. |
| 2060 |
handleConvertLineDelimiters(structuredDocument, iFile, encodingRule, encodingMemento); |
2403 |
handleConvertLineDelimiters(structuredDocument, iFile, encodingRule, encodingMemento); |
| 2061 |
|
2404 |
|
| 2062 |
ByteArrayOutputStream codedByteStream = codedStreamCreator.getCodedByteArrayOutputStream(encodingRule); |
2405 |
ByteArrayOutputStream codedByteStream = codedStreamCreator |
|
|
2406 |
.getCodedByteArrayOutputStream(encodingRule); |
| 2063 |
InputStream codedStream = new ByteArrayInputStream(codedByteStream.toByteArray()); |
2407 |
InputStream codedStream = new ByteArrayInputStream(codedByteStream.toByteArray()); |
| 2064 |
if (iFile.exists()) |
2408 |
if (iFile.exists()) |
| 2065 |
iFile.setContents(codedStream, true, true, null); |
2409 |
iFile.setContents(codedStream, true, true, null); |
|
Lines 2088-2101
Link Here
|
| 2088 |
} |
2432 |
} |
| 2089 |
} |
2433 |
} |
| 2090 |
|
2434 |
|
| 2091 |
boolean isIdInUse(String newId) { |
2435 |
boolean isIdInUse(String newId) { |
| 2092 |
boolean inUse = false; |
2436 |
SharedObject object = null; |
| 2093 |
SYNC.acquire(); |
2437 |
SYNC.acquire(); |
| 2094 |
SharedObject object =(SharedObject) fManagedObjects.get(newId); |
2438 |
try { |
| 2095 |
if (object!=null) { |
2439 |
object = (SharedObject) fManagedObjects.get(newId); |
| 2096 |
inUse = object.theSharedModel!=null; |
2440 |
} |
| 2097 |
} |
2441 |
finally { |
| 2098 |
SYNC.release(); |
2442 |
SYNC.release(); |
| 2099 |
return inUse; |
|
|
| 2100 |
} |
2443 |
} |
|
|
2444 |
return object != null ? object.theSharedModel != null : false; |
| 2445 |
} |
| 2446 |
|
| 2447 |
private static String getProperty(String property) { |
| 2448 |
// Preference overrides system property overrides env-var |
| 2449 |
|
| 2450 |
IPreferencesService preferencesService = Platform.getPreferencesService(); |
| 2451 |
IScopeContext[] lookupOrder = new IScopeContext[] { |
| 2452 |
new InstanceScope(), new ConfigurationScope() |
| 2453 |
}; |
| 2454 |
String key = property; |
| 2455 |
if (property != null && property.startsWith(SSECorePlugin.ID)) { |
| 2456 |
// +1, include the "." |
| 2457 |
key = property.substring(SSECorePlugin.ID.length() + 1, property.length()); |
| 2458 |
} |
| 2459 |
String value = preferencesService.getString(SSECorePlugin.ID, key, null, lookupOrder); |
| 2460 |
if (value == null) { |
| 2461 |
value = System.getProperty(property); |
| 2462 |
} |
| 2463 |
if (value == null) { |
| 2464 |
value = System.getenv(property); |
| 2465 |
} |
| 2466 |
return value; |
| 2467 |
} |
| 2468 |
|
| 2469 |
private static String getDefault(String property) { |
| 2470 |
// this is the "default-default" |
| 2471 |
if ("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad".equals(property)) { |
| 2472 |
return "0"; |
| 2473 |
} |
| 2474 |
else if ("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad" |
| 2475 |
.equals(property)) { |
| 2476 |
return "false"; |
| 2477 |
} |
| 2478 |
return null; |
| 2479 |
} |
| 2480 |
|
| 2481 |
private static boolean getBoolean(String key) { |
| 2482 |
String property = getProperty(key); |
| 2483 |
// if (property != null) { |
| 2484 |
// System.out.println("Tweak: " + key + "=" + Boolean.parseBoolean(property)); //$NON-NLS-1$ //$NON-NLS-2$ |
| 2485 |
// } |
| 2486 |
return property != null ? Boolean.parseBoolean(property) : Boolean |
| 2487 |
.parseBoolean(getDefault(key)); |
| 2488 |
} |
| 2489 |
|
| 2490 |
private static int getInt(String key) { |
| 2491 |
String property = getProperty(key); |
| 2492 |
int size = 0; |
| 2493 |
if (property != null) { |
| 2494 |
try { |
| 2495 |
size = Integer.parseInt(property); |
| 2496 |
// System.out.println("Tweak: " + key + "=" + size); //$NON-NLS-1$ //$NON-NLS-2$ |
| 2497 |
} |
| 2498 |
catch (NumberFormatException e) { |
| 2499 |
size = getDefaultInt(key, property, size); |
| 2500 |
} |
| 2501 |
} |
| 2502 |
else { |
| 2503 |
size = getDefaultInt(key, property, size); |
| 2504 |
} |
| 2505 |
return size; |
| 2506 |
} |
| 2507 |
|
| 2508 |
private static int getDefaultInt(String key, String property, int size) { |
| 2509 |
// ignored |
| 2510 |
try { |
| 2511 |
size = Integer.parseInt(getDefault(key)); |
| 2512 |
} |
| 2513 |
catch (NumberFormatException e1) { |
| 2514 |
handleIntParseException(key, property, e1); |
| 2515 |
size = 0; |
| 2516 |
} |
| 2517 |
return size; |
| 2518 |
} |
| 2519 |
|
| 2520 |
private static void handleIntParseException(String key, String property, |
| 2521 |
NumberFormatException e1) { |
| 2522 |
Exception n = new Exception( |
| 2523 |
NLS |
| 2524 |
.bind( |
| 2525 |
"Exception during parse of default value for key ''{0}'' value was ''{1}''. Using 0 instead", //$NON-NLS-1$ |
| 2526 |
key, property), e1); |
| 2527 |
n.printStackTrace(); |
| 2528 |
} |
| 2529 |
|
| 2101 |
} |
2530 |
} |