new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / Openable.java
index a8ed665..79481b1 100644 (file)
  *******************************************************************************/
 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 <code>null</code> 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 <code>Openable</code> that is known to be closed (no check for <code>isOpen()</code>).
-// */
-//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 <code>Openable</code> that is known to be closed (no check for <code>isOpen()</code>).
+ */
+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
  */