X-Git-Url: http://git.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 a8ed665..79481b1 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,15 +10,26 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.core; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import net.sourceforge.phpdt.core.BufferChangedEvent; import net.sourceforge.phpdt.core.IBuffer; import net.sourceforge.phpdt.core.IBufferChangedListener; +import net.sourceforge.phpdt.core.IBufferFactory; 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.JavaModelException; +import net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; /** @@ -42,57 +53,57 @@ protected Openable(int type, IJavaElement parent, String name) { */ public void bufferChanged(BufferChangedEvent event) { if (event.getBuffer().isClosed()) { -// JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this); -// getBufferManager().removeBuffer(event.getBuffer()); + JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this); + getBufferManager().removeBuffer(event.getBuffer()); } else { -// JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().put(this, this); + JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().put(this, this); } } -///** -// * 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); -//} -///** -// * Close the buffer associated with this element, if any. -// */ -//protected void closeBuffer(OpenableElementInfo info) { -// if (!hasBuffer()) return; // nothing to do -// IBuffer buffer = null; -// buffer = getBufferManager().getBuffer(this); -// if (buffer != null) { -// buffer.close(); -// buffer.removeBufferChangedListener(this); -// } -//} -///** -// * 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); -//} +/** + * 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); +} +/** + * Close the buffer associated with this element, if any. + */ +protected void closeBuffer(OpenableElementInfo info) { + if (!hasBuffer()) return; // nothing to do + IBuffer buffer = null; + buffer = getBufferManager().getBuffer(this); + if (buffer != null) { + buffer.close(); + buffer.removeBufferChangedListener(this); + } +} +/** + * 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); +} ///** // * @see ICodeAssist // */ @@ -116,18 +127,18 @@ protected Openable(int type, IJavaElement parent, String name) { // engine.complete(cu, position, 0); // environment.unitToSkip = null; //} -///** -// * @see ICodeAssist -// */ -//protected IJavaElement[] codeSelect(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, int offset, int length) throws JavaModelException { +/** + * @see ICodeAssist + */ +//protected IJavaElement[] codeSelect(net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit cu, int offset, int length) throws JavaModelException { // SelectionRequestor requestor= new SelectionRequestor(((JavaProject)getJavaProject()).getNameLookup(), this); // this.codeSelect(cu, offset, length, requestor); // return requestor.getElements(); //} -///** -// * @see ICodeAssist -// */ -//protected void codeSelect(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, int offset, int length, ISelectionRequestor requestor) throws JavaModelException { +/** + * @see ICodeAssist + */ +//protected void codeSelect(net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit cu, int offset, int length, ISelectionRequestor requestor) throws JavaModelException { // IBuffer buffer = getBuffer(); // if (buffer == null) { // return; @@ -145,24 +156,24 @@ protected Openable(int type, IJavaElement parent, String name) { // 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() { -// 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; +/** + * Returns a new element info for this element. + */ +protected OpenableElementInfo 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; /** * 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 @@ -188,14 +199,14 @@ public IBuffer getBuffer() throws JavaModelException { return null; } } -// -///** -// * Answers the buffer factory to use for creating new buffers -// */ -//public IBufferFactory getBufferFactory(){ -// return getBufferManager().getDefaultBufferFactory(); -//} -// + +/** + * Answers the buffer factory to use for creating new buffers + */ +public IBufferFactory getBufferFactory(){ + return getBufferManager().getDefaultBufferFactory(); +} + /** * Returns the buffer manager for this element. */ @@ -211,15 +222,15 @@ protected BufferManager getBufferManager() { public IResource getCorrespondingResource() throws JavaModelException { return getUnderlyingResource(); } -///* -// * @see IJavaElement -// */ -//public IOpenable getOpenable() { -// return this; -//} -// -// -// +/* + * @see IJavaElement + */ +public IOpenable getOpenable() { + return this; +} + + + /** * @see IJavaElement */ @@ -242,15 +253,15 @@ public IResource getUnderlyingResource() throws JavaModelException { } } -//public boolean exists() { -// -// IPackageFragmentRoot root = this.getPackageFragmentRoot(); -// if (root == null || root == this || !root.isArchive()) { -// return parentExists() && resourceExists(); -// } else { -// return super.exists(); -// } -//} +public boolean exists() { + + IPackageFragmentRoot root = this.getPackageFragmentRoot(); + if (root == null || root == this || !root.isArchive()) { + return parentExists() && resourceExists(); + } else { + return super.exists(); + } +} /** * Returns true if this element may have an associated source buffer, @@ -259,44 +270,44 @@ public IResource getUnderlyingResource() throws JavaModelException { protected boolean hasBuffer() { return false; } -///** -// * @see IParent -// */ -//public boolean hasChildren() throws JavaModelException { -// return getChildren().length > 0; -//} -///** -// * @see IOpenable -// */ -//public boolean hasUnsavedChanges() throws JavaModelException{ -// -// if (isReadOnly() || !isOpen()) { -// return false; -// } -// IBuffer buf = this.getBuffer(); -// if (buf != null && buf.hasUnsavedChanges()) { -// return true; -// } -// // 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 -// Enumeration openBuffers= getBufferManager().getOpenBuffers(); -// while (openBuffers.hasMoreElements()) { -// IBuffer buffer= (IBuffer)openBuffers.nextElement(); -// if (buffer.hasUnsavedChanges()) { -// IJavaElement owner= (IJavaElement)buffer.getOwner(); -// if (isAncestorOf(owner)) { -// return true; -// } -// } -// } -// } -// -// return false; -//} +/** + * @see IParent + */ +public boolean hasChildren() throws JavaModelException { + return getChildren().length > 0; +} +/** + * @see IOpenable + */ +public boolean hasUnsavedChanges() throws JavaModelException{ + + if (isReadOnly() || !isOpen()) { + return false; + } + IBuffer buf = this.getBuffer(); + if (buf != null && buf.hasUnsavedChanges()) { + return true; + } + // 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 + Enumeration openBuffers= getBufferManager().getOpenBuffers(); + while (openBuffers.hasMoreElements()) { + IBuffer buffer= (IBuffer)openBuffers.nextElement(); + if (buffer.hasUnsavedChanges()) { + IJavaElement owner= (IJavaElement)buffer.getOwner(); + if (isAncestorOf(owner)) { + return true; + } + } + } + } + + return false; +} /** * Subclasses must override as required. * @@ -310,39 +321,37 @@ public boolean isConsistent() throws JavaModelException { * @see IOpenable */ public boolean isOpen() { - // TODO isOpen - Openable needs JavaModelManager -// synchronized(JavaModelManager.getJavaModelManager()){ -// return JavaModelManager.getJavaModelManager().getInfo(this) != null; -// } - return false; + synchronized(JavaModelManager.getJavaModelManager()){ + return JavaModelManager.getJavaModelManager().getInfo(this) != null; + } +} +/** + * Returns true if this represents a source element. + * Openable source elements have an associated buffer created + * when they are opened. + */ +protected boolean isSourceElement() { + return false; } -///** -// * Returns true if this represents a source element. -// * Openable source elements have an associated buffer created -// * when they are opened. -// */ -//protected boolean isSourceElement() { -// return false; -//} -///** -// * @see IOpenable -// */ -//public void makeConsistent(IProgressMonitor pm) throws JavaModelException { -// if (!isConsistent()) { -// buildStructure((OpenableElementInfo)getElementInfo(), pm); -// } -//} -///** -// * @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); -// } -//} -// +/** + * @see IOpenable + */ +public void makeConsistent(IProgressMonitor pm) throws JavaModelException { + if (!isConsistent()) { + buildStructure((OpenableElementInfo)getElementInfo(), pm); + } +} +/** + * @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); + } +} + /** * Opens a buffer on the contents of this element, and returns * the buffer, or returns null if opening fails. @@ -352,98 +361,98 @@ public boolean isOpen() { protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException { return null; } -// -///** -// * Open the parent element if necessary -// * -// */ -//protected void openParent(IProgressMonitor pm) throws JavaModelException { -// -// Openable openableParent = (Openable)getOpenableParent(); -// if (openableParent != null) { -// if (!openableParent.isOpen()){ -// openableParent.openWhenClosed(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); -// + +/** + * Open the parent element if necessary + * + */ +protected void openParent(IProgressMonitor pm) throws JavaModelException { + + Openable openableParent = (Openable)getOpenableParent(); + if (openableParent != null) { + if (!openableParent.isOpen()){ + openableParent.openWhenClosed(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$ // } -// -// // 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) -// * -// */ -//protected boolean parentExists(){ -// -// IJavaElement parent = this.getParent(); -// if (parent == null) return true; -// return parent.exists(); -//} -// -///** -// * Returns whether the corresponding resource or associated file exists -// */ -//protected boolean resourceExists() { -// IWorkspace workspace = ResourcesPlugin.getWorkspace(); -// if (workspace == null) return false; // workaround for http://bugs.eclipse.org/bugs/show_bug.cgi?id=34069 -// return -// JavaModel.getTarget( -// workspace.getRoot(), -// this.getPath().makeRelative(), // ensure path is relative (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517) -// true) != null; -//} -// -///** -// * @see IOpenable -// */ -//public void save(IProgressMonitor pm, boolean force) throws JavaModelException { -// if (isReadOnly() || this.getResource().isReadOnly()) { -// throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this)); -// } -// IBuffer buf = getBuffer(); -// if (buf != null) { // some Openables (like a JavaProject) don't have a buffer -// buf.save(pm, force); -// this.makeConsistent(pm); // update the element info of this element -// } -//} -// + + // 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) + * + */ +protected boolean parentExists(){ + + IJavaElement parent = this.getParent(); + if (parent == null) return true; + return parent.exists(); +} + +/** + * Returns whether the corresponding resource or associated file exists + */ +protected boolean resourceExists() { + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + if (workspace == null) return false; // workaround for http://bugs.eclipse.org/bugs/show_bug.cgi?id=34069 + return + JavaModel.getTarget( + workspace.getRoot(), + this.getPath().makeRelative(), // ensure path is relative (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517) + true) != null; +} + +/** + * @see IOpenable + */ +public void save(IProgressMonitor pm, boolean force) throws JavaModelException { + if (isReadOnly() || this.getResource().isReadOnly()) { + throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this)); + } + IBuffer buf = getBuffer(); + if (buf != null) { // some Openables (like a JavaProject) don't have a buffer + buf.save(pm, force); + this.makeConsistent(pm); // update the element info of this element + } +} + /** * Find enclosing package fragment root if any */