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..2c9a3c5 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,17 +140,16 @@ 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 // */ -//protected void codeComplete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, org.eclipse.jdt.internal.compiler.env.ICompilationUnit unitToSkip, int position, ICompletionRequestor requestor) throws JavaModelException { +//protected void codeComplete(net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit cu, net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit unitToSkip, int position, ICompletionRequestor requestor) throws JavaModelException { // if (requestor == null) { -// throw new IllegalArgumentException(Util.bind("codeAssist.nullRequestor")); //$NON-NLS-1$ +// throw new IllegalArgumentException(ProjectPrefUtil.bind("codeAssist.nullRequestor")); //$NON-NLS-1$ // } // IBuffer buffer = getBuffer(); // if (buffer == null) { @@ -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) @@ -468,7 +567,7 @@ public PackageFragmentRoot getPackageFragmentRoot() { // * @see ICodeAssist // * @deprecated - use codeComplete(ICompilationUnit, ICompilationUnit, int, ICompletionRequestor) instead // */ -//protected void codeComplete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, org.eclipse.jdt.internal.compiler.env.ICompilationUnit unitToSkip, int position, final ICodeCompletionRequestor requestor) throws JavaModelException { +//protected void codeComplete(net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit cu, net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit unitToSkip, int position, final ICodeCompletionRequestor requestor) throws JavaModelException { // // if (requestor == null){ // codeComplete(cu, unitToSkip, position, (ICompletionRequestor)null);