X-Git-Url: http://secure.phpeclipse.com
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java
index 79481b1..4fbafee 100644
--- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package net.sourceforge.phpdt.internal.core;
+import java.text.NumberFormat;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
@@ -23,8 +24,8 @@ import net.sourceforge.phpdt.core.IJavaElement;
import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
import net.sourceforge.phpdt.core.IOpenable;
import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.IParent;
import net.sourceforge.phpdt.core.JavaModelException;
-import net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
@@ -40,8 +41,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
*/
public abstract class Openable extends JavaElement implements IOpenable, IBufferChangedListener {
-protected Openable(int type, IJavaElement parent, String name) {
- super(type, parent, name);
+protected Openable(JavaElement parent, String name) {
+ super(parent, name);
}
/**
* The buffer associated with this element has changed. Registers
@@ -59,30 +60,70 @@ protected Openable(int type, IJavaElement parent, String name) {
JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().put(this, this);
}
}
+
+ /**
+ * Builds this element's structure and properties in the given
+ * info object, based on this element's current contents (reuse buffer
+ * contents if this element has an open buffer, or resource contents
+ * if this element does not have an open buffer). Children
+ * are placed in the given newElements table (note, this element
+ * has already been placed in the newElements table). Returns true
+ * if successful, or false if an error is encountered while determining
+ * the structure of this element.
+ */
+ protected abstract boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException;
+
+///**
+// * Updates the info objects for this element and all of its children by
+// * removing the current infos, generating new infos, and then placing
+// * the new infos into the Java Model cache tables.
+// */
+//protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException {
+//
+// if (monitor != null && monitor.isCanceled()) return;
+//
+// // remove existing (old) infos
+// removeInfo();
+// HashMap newElements = new HashMap(11);
+// info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
+// JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
+// for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
+// IJavaElement key = (IJavaElement) iter.next();
+// Object value = newElements.get(key);
+// JavaModelManager.getJavaModelManager().putInfo(key, value);
+// }
+//
+// // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
+// // to be flushed. Might lead to performance issues.
+// // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type
+// JavaModelManager.getJavaModelManager().putInfo(this, info);
+//}
+/*
+ * Returns whether this element can be removed from the Java model cache to make space.
+ */
+public boolean canBeRemovedFromCache() {
+ try {
+ return !hasUnsavedChanges();
+ } catch (JavaModelException e) {
+ return false;
+ }
+}
+/*
+ * Returns whether the buffer of this element can be removed from the Java model cache to make space.
+ */
+public boolean canBufferBeRemovedFromCache(IBuffer buffer) {
+ return !buffer.hasUnsavedChanges();
+}
/**
- * Updates the info objects for this element and all of its children by
- * removing the current infos, generating new infos, and then placing
- * the new infos into the Java Model cache tables.
+ * Close the buffer associated with this element, if any.
*/
-protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException {
-
- if (monitor != null && monitor.isCanceled()) return;
-
- // remove existing (old) infos
- removeInfo();
- HashMap newElements = new HashMap(11);
- info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
- JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
- for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
- IJavaElement key = (IJavaElement) iter.next();
- Object value = newElements.get(key);
- JavaModelManager.getJavaModelManager().putInfo(key, value);
+protected void closeBuffer() {
+ if (!hasBuffer()) return; // nothing to do
+ IBuffer buffer = getBufferManager().getBuffer(this);
+ if (buffer != null) {
+ buffer.close();
+ buffer.removeBufferChangedListener(this);
}
-
- // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
- // to be flushed. Might lead to performance issues.
- // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type
- JavaModelManager.getJavaModelManager().putInfo(this, info);
}
/**
* Close the buffer associated with this element, if any.
@@ -99,11 +140,10 @@ protected void closeBuffer(OpenableElementInfo info) {
/**
* This element is being closed. Do any necessary cleanup.
*/
-protected void closing(Object info) throws JavaModelException {
- OpenableElementInfo openableInfo = (OpenableElementInfo) info;
- closeBuffer(openableInfo);
- super.closing(info);
+protected void closing(Object info) {
+ closeBuffer();
}
+
///**
// * @see ICodeAssist
// */
@@ -156,24 +196,56 @@ protected void closing(Object info) throws JavaModelException {
// SelectionEngine engine = new SelectionEngine(environment, requestor, project.getOptions(true));
// engine.select(cu, offset, offset + length - 1);
//}
-/**
+/*
* Returns a new element info for this element.
*/
-protected OpenableElementInfo createElementInfo() {
+protected Object createElementInfo() {
return new OpenableElementInfo();
}
+///**
+// * Builds this element's structure and properties in the given
+// * info object, based on this element's current contents (reuse buffer
+// * contents if this element has an open buffer, or resource contents
+// * if this element does not have an open buffer). Children
+// * are placed in the given newElements table (note, this element
+// * has already been placed in the newElements table). Returns true
+// * if successful, or false if an error is encountered while determining
+// * the structure of this element.
+// */
+//protected abstract boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException;
-/**
- * Builds this element's structure and properties in the given
- * info object, based on this element's current contents (reuse buffer
- * contents if this element has an open buffer, or resource contents
- * if this element does not have an open buffer). Children
- * are placed in the given newElements table (note, this element
- * has already been placed in the newElements table). Returns true
- * if successful, or false if an error is encountered while determining
- * the structure of this element.
- */
-protected abstract boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException;
+protected void generateInfos(Object info, HashMap newElements, IProgressMonitor monitor) throws JavaModelException {
+
+ if (JavaModelManager.VERBOSE){
+ System.out.println("OPENING Element ("+ Thread.currentThread()+"): " + this.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ // open the parent if necessary
+ openParent(info, newElements, monitor);
+ if (monitor != null && monitor.isCanceled()) return;
+
+ // puts the info before building the structure so that questions to the handle behave as if the element existed
+ // (case of compilation units becoming working copies)
+ newElements.put(this, info);
+
+ // build the structure of the openable (this will open the buffer if needed)
+ try {
+ OpenableElementInfo openableElementInfo = (OpenableElementInfo)info;
+ boolean isStructureKnown = buildStructure(openableElementInfo, monitor, newElements, getResource());
+ openableElementInfo.setIsStructureKnown(isStructureKnown);
+ } catch (JavaModelException e) {
+ newElements.remove(this);
+ throw e;
+ }
+
+ // remove out of sync buffer for this element
+ JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
+
+ if (JavaModelManager.VERBOSE) {
+ System.out.println("-> Package cache size = " + JavaModelManager.getJavaModelManager().cache.pkgSize()); //$NON-NLS-1$
+ System.out.println("-> Openable cache filling ratio = " + NumberFormat.getInstance().format(JavaModelManager.getJavaModelManager().cache.openableFillingRatio()) + "%"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+}
/**
* Note: a buffer with no unsaved changes can be closed by the Java Model
* since it has a finite number of buffers allowed open at one time. If this
@@ -235,14 +307,14 @@ public IOpenable getOpenable() {
* @see IJavaElement
*/
public IResource getUnderlyingResource() throws JavaModelException {
- IResource parentResource = fParent.getUnderlyingResource();
+ IResource parentResource = parent.getUnderlyingResource();
if (parentResource == null) {
return null;
}
int type = parentResource.getType();
if (type == IResource.FOLDER || type == IResource.PROJECT) {
IContainer folder = (IContainer) parentResource;
- IResource resource = folder.findMember(fName);
+ IResource resource = folder.findMember(name);
if (resource == null) {
throw newNotPresentException();
} else {
@@ -288,12 +360,13 @@ public boolean hasUnsavedChanges() throws JavaModelException{
if (buf != null && buf.hasUnsavedChanges()) {
return true;
}
- // for package fragments, package fragment roots, and projects must check open buffers
+// for package fragments, package fragment roots, and projects must check open buffers
// to see if they have an child with unsaved changes
- if (fLEType == PACKAGE_FRAGMENT ||
- fLEType == PACKAGE_FRAGMENT_ROOT ||
- fLEType == JAVA_PROJECT ||
- fLEType == JAVA_MODEL) { // fix for 1FWNMHH
+ int elementType = getElementType();
+ if (elementType == PACKAGE_FRAGMENT ||
+ elementType == PACKAGE_FRAGMENT_ROOT ||
+ elementType == JAVA_PROJECT ||
+ elementType == JAVA_MODEL) { // fix for 1FWNMHH
Enumeration openBuffers= getBufferManager().getOpenBuffers();
while (openBuffers.hasMoreElements()) {
IBuffer buffer= (IBuffer)openBuffers.nextElement();
@@ -333,25 +406,54 @@ public boolean isOpen() {
protected boolean isSourceElement() {
return false;
}
+///**
+// * @see IOpenable
+// */
+//public void makeConsistent(IProgressMonitor pm) throws JavaModelException {
+// if (!isConsistent()) {
+// buildStructure((OpenableElementInfo)getElementInfo(), pm);
+// }
+//}
/**
* @see IOpenable
- */
-public void makeConsistent(IProgressMonitor pm) throws JavaModelException {
- if (!isConsistent()) {
- buildStructure((OpenableElementInfo)getElementInfo(), pm);
+ */
+public void makeConsistent(IProgressMonitor monitor) throws JavaModelException {
+ if (isConsistent()) return;
+
+ // create a new info and make it the current info
+ // (this will remove the info and its children just before storing the new infos)
+ JavaModelManager manager = JavaModelManager.getJavaModelManager();
+ boolean hadTemporaryCache = manager.hasTemporaryCache();
+ try {
+ HashMap newElements = manager.getTemporaryCache();
+ openWhenClosed(newElements, monitor);
+ if (newElements.get(this) == null) {
+ // close any buffer that was opened for the new elements
+ Iterator iterator = newElements.keySet().iterator();
+ while (iterator.hasNext()) {
+ IJavaElement element = (IJavaElement)iterator.next();
+ if (element instanceof Openable) {
+ ((Openable)element).closeBuffer();
+ }
+ }
+ throw newNotPresentException();
+ }
+ if (!hadTemporaryCache) {
+ manager.putInfos(this, newElements);
+ }
+ } finally {
+ if (!hadTemporaryCache) {
+ manager.resetTemporaryCache();
+ }
}
}
+
/**
* @see IOpenable
*/
public void open(IProgressMonitor pm) throws JavaModelException {
- if (!isOpen()) {
- // TODO: need to synchronize (IOpenable.open(IProgressMonitor) is API
- // TODO: could use getElementInfo instead
- this.openWhenClosed(pm);
- }
+ getElementInfo(pm);
}
-
/**
* Opens a buffer on the contents of this element, and returns
* the buffer, or returns null
if opening fails.
@@ -363,57 +465,54 @@ protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException {
}
/**
- * Open the parent element if necessary
- *
+ * Open the parent element if necessary.
*/
-protected void openParent(IProgressMonitor pm) throws JavaModelException {
+protected void openParent(Object childInfo, HashMap newElements, IProgressMonitor pm) throws JavaModelException {
Openable openableParent = (Openable)getOpenableParent();
- if (openableParent != null) {
- if (!openableParent.isOpen()){
- openableParent.openWhenClosed(pm);
- }
+ if (openableParent != null && !openableParent.isOpen()){
+ openableParent.generateInfos(openableParent.createElementInfo(), newElements, pm);
}
}
-/**
- * Open an Openable
that is known to be closed (no check for isOpen()
).
- */
-protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException {
- try {
-
- if (JavaModelManager.VERBOSE){
- System.out.println("OPENING Element ("+ Thread.currentThread()+"): " + this.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$
- }
-
- // 1) Parent must be open - open the parent if necessary
- openParent(pm);
-
- // 2) create the new element info and open a buffer if needed
- OpenableElementInfo info = createElementInfo();
- if (isSourceElement()) {
- this.openBuffer(pm);
- }
-
- // 3) build the structure of the openable
- buildStructure(info, pm);
-
- // 4) anything special
- opening(info);
-
-// if (JavaModelManager.VERBOSE) {
-// System.out.println("-> Package cache size = " + JavaModelManager.getJavaModelManager().cache.pkgSize()); //$NON-NLS-1$
-// System.out.println("-> Openable cache filling ratio = " + JavaModelManager.getJavaModelManager().cache.openableFillingRatio() + "%"); //$NON-NLS-1$//$NON-NLS-2$
+///**
+// * Open an Openable
that is known to be closed (no check for isOpen()
).
+// */
+//protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException {
+// try {
+//
+// if (JavaModelManager.VERBOSE){
+// System.out.println("OPENING Element ("+ Thread.currentThread()+"): " + this.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$
// }
-
- // if any problems occuring openning the element, ensure that it's info
- // does not remain in the cache (some elements, pre-cache their info
- // as they are being opened).
- } catch (JavaModelException e) {
- JavaModelManager.getJavaModelManager().removeInfo(this);
- throw e;
- }
-}
+//
+// // 1) Parent must be open - open the parent if necessary
+// openParent(pm);
+//
+// // 2) create the new element info and open a buffer if needed
+// OpenableElementInfo info = createElementInfo();
+// if (isSourceElement()) {
+// this.openBuffer(pm);
+// }
+//
+// // 3) build the structure of the openable
+// buildStructure(info, pm);
+//
+// // 4) anything special
+// opening(info);
+//
+//// if (JavaModelManager.VERBOSE) {
+//// System.out.println("-> Package cache size = " + JavaModelManager.getJavaModelManager().cache.pkgSize()); //$NON-NLS-1$
+//// System.out.println("-> Openable cache filling ratio = " + JavaModelManager.getJavaModelManager().cache.openableFillingRatio() + "%"); //$NON-NLS-1$//$NON-NLS-2$
+//// }
+//
+// // if any problems occuring openning the element, ensure that it's info
+// // does not remain in the cache (some elements, pre-cache their info
+// // as they are being opened).
+// } catch (JavaModelException e) {
+// JavaModelManager.getJavaModelManager().removeInfo(this);
+// throw e;
+// }
+//}
/**
* Answers true if the parent exists (null parent is answering true)