[297881] [editor] StructuredRegionProcessor issues with shared structured model
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java index b97de6d..7861f66 100644 --- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java
@@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2001, 2009 IBM Corporation and others. + * Copyright (c) 2001, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -62,17 +62,32 @@ * @see org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener#processPreModelEvent(org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent) */ public void processPreModelEvent(ModelLifecycleEvent event) { - if (event.getType() == ModelLifecycleEvent.MODEL_DOCUMENT_CHANGED && event.getModel() == fCurrentModel) { - changing = event.getModel(); - flushDirtyRegionQueue(); - // note: old annotations are removed via the strategies on - // AbstractStructuredTextReconcilingStrategy#setDocument(...) + if(fCurrentDoc != null) { + IStructuredModel model = null; + try { + model = getStructuredModelForRead(fCurrentDoc); + if (event.getType() == ModelLifecycleEvent.MODEL_DOCUMENT_CHANGED && event.getModel() == model) { + changing = event.getModel(); + flushDirtyRegionQueue(); + // note: old annotations are removed via the strategies on + // AbstractStructuredTextReconcilingStrategy#setDocument(...) + } + } finally { + if(model != null) { + model.releaseFromRead(); + } + } } } } + /** + * The life cycle listener used to listen to the current documents model even though + * this class does not hold onto a reference to the model. + */ private IModelLifecycleListener fLifeCycleListener = new ModelLifecycleListener(); - IStructuredModel fCurrentModel = null; + /** Used to get the current model on demand so a model does not need to be held by permanently */ + private IDocument fCurrentDoc = null; /* * (non-Javadoc) @@ -83,26 +98,33 @@ protected DirtyRegion getOuterRegion(DirtyRegion root, DirtyRegion possible) { // first try simple region check if one region contains the other DirtyRegion outer = super.getOuterRegion(root, possible); - if (outer == null) { - // now compare nodes - IStructuredModel sModel = fCurrentModel; - - if (sModel != null) { - IndexedRegion rootRegion = sModel.getIndexedRegion(root.getOffset()); - IndexedRegion possRegion = sModel.getIndexedRegion(possible.getOffset()); - if (rootRegion != null && possRegion != null) { - int rootStart = rootRegion.getStartOffset(); - int possStart = possRegion.getStartOffset(); - // first just check if rootregion starts before - // possregion - if (rootStart <= possStart) { - // check if possregion is inside rootregion - outer = _getOuterRegion(root, possible, sModel, rootStart, possStart); + if (outer == null && fCurrentDoc != null) { + IStructuredModel sModel = null; + try { + sModel = getStructuredModelForRead(fCurrentDoc); + if (sModel != null) { + // now compare nodes + IndexedRegion rootRegion = sModel.getIndexedRegion(root.getOffset()); + IndexedRegion possRegion = sModel.getIndexedRegion(possible.getOffset()); + if (rootRegion != null && possRegion != null) { + int rootStart = rootRegion.getStartOffset(); + int possStart = possRegion.getStartOffset(); + // first just check if rootregion starts before + // possregion + if (rootStart <= possStart) { + // check if possregion is inside rootregion + outer = _getOuterRegion(root, possible, sModel, rootStart, possStart); + } + else { + // otherwise if rootregion is inside possregion + outer = _getOuterRegion(possible, root, sModel, possStart, rootStart); + } } - else { - // otherwise if rootregion is inside possregion - outer = _getOuterRegion(possible, root, sModel, possStart, rootStart); - } + } + + } finally { + if(sModel != null) { + sModel.releaseFromRead(); } } } @@ -175,7 +197,7 @@ String contentTypeId = null; IStructuredModel sModel = null; try { - sModel = StructuredModelManager.getModelManager().getExistingModelForRead(doc); + sModel = getStructuredModelForRead(doc); if (sModel != null) { contentTypeId = sModel.getContentTypeIdentifier(); } @@ -204,23 +226,35 @@ if (!isInstalled() || isInRewriteSession() || dirtyRegion == null || getDocument() == null) return; - // use structured model to determine area to process - IStructuredModel sModel = fCurrentModel; - if (sModel != null) { - int start = dirtyRegion.getOffset(); - int end = start + dirtyRegion.getLength(); - IndexedRegion irStart = sModel.getIndexedRegion(start); - IndexedRegion irEnd = sModel.getIndexedRegion(end); + // unhook old lifecycle listener + if(fCurrentDoc != null) { + IStructuredModel sModel = null; + try { + sModel = getStructuredModelForRead(fCurrentDoc); + + // use structured model to determine area to process + if (sModel != null) { + int start = dirtyRegion.getOffset(); + int end = start + dirtyRegion.getLength(); + IndexedRegion irStart = sModel.getIndexedRegion(start); + IndexedRegion irEnd = sModel.getIndexedRegion(end); - if (irStart != null) { - start = Math.min(start, irStart.getStartOffset()); + if (irStart != null) { + start = Math.min(start, irStart.getStartOffset()); + } + if (irEnd != null) { + end = Math.max(end, irEnd.getEndOffset()); + } + super.process(createDirtyRegion(start, end - start, DirtyRegion.INSERT)); + } else { + super.process(dirtyRegion); + } + } finally { + if(sModel != null) { + sModel.releaseFromRead(); + } } - if (irEnd != null) { - end = Math.max(end, irEnd.getEndOffset()); - } - super.process(createDirtyRegion(start, end - start, DirtyRegion.INSERT)); - } - else { + } else { super.process(dirtyRegion); } } @@ -236,20 +270,37 @@ public void setDocument(IDocument newDocument) { // unhook old lifecycle listener - if (fCurrentModel != null) - fCurrentModel.removeModelLifecycleListener(fLifeCycleListener); - - if (fCurrentModel != null) { - fCurrentModel.releaseFromRead(); - fCurrentModel = null; - } - super.setDocument(newDocument); - if (newDocument != null) { - fCurrentModel = getStructuredModelForRead(newDocument); + if(fCurrentDoc != null) { + IStructuredModel oldModel = null; + try { + oldModel = getStructuredModelForRead(fCurrentDoc); + if(oldModel != null) { + oldModel.removeModelLifecycleListener(fLifeCycleListener); + } + } finally { + if(oldModel != null) { + oldModel.releaseFromRead(); + } + } } + //set the new document + super.setDocument(newDocument); + fCurrentDoc = newDocument; + // add new lifecycle listener - if (fCurrentModel != null) - fCurrentModel.addModelLifecycleListener(fLifeCycleListener); + if (newDocument != null) { + IStructuredModel newModel = null; + try { + newModel = getStructuredModelForRead(newDocument); + if(newModel != null) { + newModel.addModelLifecycleListener(fLifeCycleListener); + } + } finally { + if(newModel != null) { + newModel.releaseFromRead(); + } + } + } } }