1) Moved net.sourceforge.phpeclipse.ui\src\net\sourceforge\phpdt back to net.sourcefo...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / ui / StandardJavaElementContentProvider.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java
new file mode 100644 (file)
index 0000000..5c10738
--- /dev/null
@@ -0,0 +1,511 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+//import net.sourceforge.phpdt.core.IJavaElementDelta;
+import net.sourceforge.phpdt.core.IJavaModel;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.IParent;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * A base content provider for Java elements. It provides access to the Java
+ * element hierarchy without listening to changes in the Java model. If updating
+ * the presentation on Java model change is required than clients have to
+ * subclass, listen to Java model changes and have to update the UI using
+ * corresponding methods provided by the JFace viewers or their own UI
+ * presentation.
+ * <p>
+ * The following Java element hierarchy is surfaced by this content provider:
+ * <p>
+ * 
+ * <pre>
+ *  Java model (
+ * <code>
+ * IJavaModel
+ * </code>
+ * )
+ *  Java project (
+ * <code>
+ * IJavaProject
+ * </code>
+ * )
+ *  package fragment root (
+ * <code>
+ * IPackageFragmentRoot
+ * </code>
+ * )
+ *  package fragment (
+ * <code>
+ * IPackageFragment
+ * </code>
+ * )
+ *  compilation unit (
+ * <code>
+ * ICompilationUnit
+ * </code>
+ * )
+ *  binary class file (
+ * <code>
+ * IClassFile
+ * </code>
+ * )
+ * </pre>
+ * 
+ * </p>
+ * <p>
+ * Note that when the entire Java project is declared to be package fragment
+ * root, the corresponding package fragment root element that normally appears
+ * between the Java project and the package fragments is automatically filtered
+ * out.
+ * </p>
+ * This content provider can optionally return working copy elements for members
+ * below compilation units. If enabled, working copy members are returned for
+ * those compilation units in the Java element hierarchy for which a shared
+ * working copy exists in JDT core.
+ * 
+ * @see net.sourceforge.phpdt.ui.IWorkingCopyProvider
+ * @see JavaCore#getSharedWorkingCopies(net.sourceforge.phpdt.core.IBufferFactory)
+ * 
+ * @since 2.0
+ */
+public class StandardJavaElementContentProvider implements
+               ITreeContentProvider, IWorkingCopyProvider {
+
+       protected static final Object[] NO_CHILDREN = new Object[0];
+
+       protected boolean fProvideMembers = false;
+
+       protected boolean fProvideWorkingCopy = false;
+
+       /**
+        * Creates a new content provider. The content provider does not provide
+        * members of compilation units or class files and it does not provide
+        * working copy elements.
+        */
+//     public StandardJavaElementContentProvider() {
+//     }
+
+       /**
+        * Creates a new <code>StandardJavaElementContentProvider</code>.
+        * 
+        * @param provideMembers
+        *            if <code>true</code> members below compilation units and
+        *            class files are provided.
+        * @param provideWorkingCopy
+        *            if <code>true</code> the element provider provides working
+        *            copies members of compilation units which have an associated
+        *            working copy in JDT core. Otherwise only original elements are
+        *            provided.
+        */
+       public StandardJavaElementContentProvider(boolean provideMembers,
+                       boolean provideWorkingCopy) {
+               fProvideMembers = provideMembers;
+               fProvideWorkingCopy = provideWorkingCopy;
+       }
+
+       /**
+        * Returns whether members are provided when asking for a compilation units
+        * or class file for its children.
+        * 
+        * @return <code>true</code> if the content provider provides members;
+        *         otherwise <code>false</code> is returned
+        */
+//     public boolean getProvideMembers() {
+//             return fProvideMembers;
+//     }
+
+       /**
+        * Sets whether the content provider is supposed to return members when
+        * asking a compilation unit or class file for its children.
+        * 
+        * @param b
+        *            if <code>true</code> then members are provided. If
+        *            <code>false</code> compilation units and class files are the
+        *            leaves provided by this content provider.
+        */
+//     public void setProvideMembers(boolean b) {
+//             fProvideMembers = b;
+//     }
+
+       /**
+        * Returns whether the provided members are from a working copy or the
+        * original compilation unit.
+        * 
+        * @return <code>true</code> if the content provider provides working copy
+        *         members; otherwise <code>false</code> is returned
+        * 
+        * @see #setProvideWorkingCopy(boolean)
+        */
+//     public boolean getProvideWorkingCopy() {
+//             return fProvideWorkingCopy;
+//     }
+
+       /**
+        * Sets whether the members are provided from a shared working copy that
+        * exists for a original compilation unit in the Java element hierarchy.
+        * 
+        * @param b
+        *            if <code>true</code> members are provided from a working
+        *            copy if one exists in JDT core. If <code>false</code> the
+        *            provider always returns original elements.
+        */
+//     public void setProvideWorkingCopy(boolean b) {
+//             fProvideWorkingCopy = b;
+//     }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IWorkingCopyProvider#providesWorkingCopies()
+        */
+       public boolean providesWorkingCopies() {
+               return fProvideWorkingCopy;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IStructuredContentProvider.
+        */
+       public Object[] getElements(Object parent) {
+               return getChildren(parent);
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentProvider.
+        */
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentProvider.
+        */
+       public void dispose() {
+       }
+
+       /*
+        * (non-Javadoc) Method declared on ITreeContentProvider.
+        */
+       public Object[] getChildren(Object element) {
+               if (!exists(element))
+                       return NO_CHILDREN;
+
+               try {
+                       if (element instanceof IJavaModel)
+                               return getJavaProjects((IJavaModel) element);
+
+                       // if (element instanceof IJavaProject)
+                       // return getPackageFragmentRoots((IJavaProject)element);
+                       //                      
+                       if (element instanceof IPackageFragmentRoot)
+                               return getPackageFragments((IPackageFragmentRoot) element);
+
+                       // if (element instanceof IPackageFragment)
+                       // return getPackageContents((IPackageFragment)element);
+
+                       if (element instanceof IFolder)
+                               return getResources((IFolder) element);
+
+                       if (fProvideMembers && element instanceof ISourceReference
+                                       && element instanceof IParent) {
+                               if (fProvideWorkingCopy && element instanceof ICompilationUnit) {
+                                       element = JavaModelUtil
+                                                       .toWorkingCopy((ICompilationUnit) element);
+                               }
+                               return ((IParent) element).getChildren();
+                       }
+               } catch (JavaModelException e) {
+                       return NO_CHILDREN;
+               }
+               return NO_CHILDREN;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see ITreeContentProvider
+        */
+       public boolean hasChildren(Object element) {
+               if (fProvideMembers) {
+                       // assume CUs and class files are never empty
+                       if (element instanceof ICompilationUnit) {
+                               // ||
+                               // element instanceof IClassFile) {
+                               return true;
+                       }
+               } else {
+                       // don't allow to drill down into a compilation unit or class file
+                       if (element instanceof ICompilationUnit ||
+                       // element instanceof IClassFile ||
+                                       element instanceof IFile)
+                               return false;
+               }
+
+               if (element instanceof IJavaProject) {
+                       IJavaProject jp = (IJavaProject) element;
+                       if (!jp.getProject().isOpen()) {
+                               return false;
+                       }
+               }
+
+               if (element instanceof IParent) {
+                       try {
+                               // when we have Java children return true, else we fetch all the
+                               // children
+                               if (((IParent) element).hasChildren())
+                                       return true;
+                       } catch (JavaModelException e) {
+                               return true;
+                       }
+               }
+               Object[] children = getChildren(element);
+               return (children != null) && children.length > 0;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on ITreeContentProvider.
+        */
+       public Object getParent(Object element) {
+               if (!exists(element))
+                       return null;
+               return internalGetParent(element);
+       }
+
+       private Object[] getPackageFragments(IPackageFragmentRoot root)
+                       throws JavaModelException {
+               IJavaElement[] fragments = root.getChildren();
+               // Object[] nonJavaResources= root.getNonJavaResources();
+               // if (nonJavaResources == null)
+               return fragments;
+               // return concatenate(fragments, nonJavaResources);
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       // protected Object[] getPackageFragmentRoots(IJavaProject project) throws
+       // JavaModelException {
+       // if (!project.getProject().isOpen())
+       // return NO_CHILDREN;
+       //                      
+       // IPackageFragmentRoot[] roots= project.getPackageFragmentRoots();
+       // List list= new ArrayList(roots.length);
+       // // filter out package fragments that correspond to projects and
+       // // replace them with the package fragments directly
+       // for (int i= 0; i < roots.length; i++) {
+       // IPackageFragmentRoot root= (IPackageFragmentRoot)roots[i];
+       // if (isProjectPackageFragmentRoot(root)) {
+       // Object[] children= root.getChildren();
+       // for (int k= 0; k < children.length; k++)
+       // list.add(children[k]);
+       // }
+       // else if (hasChildren(root)) {
+       // list.add(root);
+       // }
+       // }
+       // return concatenate(list.toArray(), project.getNonJavaResources());
+       // }
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected Object[] getJavaProjects(IJavaModel jm) throws JavaModelException {
+               return jm.getJavaProjects();
+       }
+
+       // private Object[] getPackageContents(IPackageFragment fragment) throws
+       // JavaModelException {
+       // if (fragment.getKind() == IPackageFragmentRoot.K_SOURCE) {
+       // return concatenate(fragment.getCompilationUnits(),
+       // fragment.getNonJavaResources());
+       // }
+       // return concatenate(fragment.getClassFiles(),
+       // fragment.getNonJavaResources());
+       // }
+
+       private Object[] getResources(IFolder folder) {
+               try {
+                       // filter out folders that are package fragment roots
+                       Object[] members = folder.members();
+                       List nonJavaResources = new ArrayList();
+                       for (int i = 0; i < members.length; i++) {
+                               Object o = members[i];
+                               // A folder can also be a package fragement root in the
+                               // following case
+                               // Project
+                               // + src <- source folder
+                               // + excluded <- excluded from class path
+                               // + included <- a new source folder.
+                               // Included is a member of excluded, but since it is rendered as
+                               // a source
+                               // folder we have to exclude it as a normal child.
+                               if (o instanceof IFolder) {
+                                       IJavaElement element = JavaCore.create((IFolder) o);
+                                       if (element instanceof IPackageFragmentRoot
+                                                       && element.exists()) {
+                                               continue;
+                                       }
+                               }
+                               nonJavaResources.add(o);
+                       }
+                       return nonJavaResources.toArray();
+               } catch (CoreException e) {
+                       return NO_CHILDREN;
+               }
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+//     protected boolean isClassPathChange(IJavaElementDelta delta) {
+//
+//             // need to test the flags only for package fragment roots
+//             if (delta.getElement().getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT)
+//                     return false;
+//
+//             int flags = delta.getFlags();
+//             return (delta.getKind() == IJavaElementDelta.CHANGED
+//                             && ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0)
+//                             || ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) || ((flags & IJavaElementDelta.F_REORDER) != 0));
+//     }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected Object skipProjectPackageFragmentRoot(IPackageFragmentRoot root) {
+               try {
+                       if (isProjectPackageFragmentRoot(root))
+                               return root.getParent();
+                       return root;
+               } catch (JavaModelException e) {
+                       return root;
+               }
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+//     protected boolean isPackageFragmentEmpty(IJavaElement element)
+//                     throws JavaModelException {
+//             if (element instanceof IPackageFragment) {
+//                     IPackageFragment fragment = (IPackageFragment) element;
+//                     if (!(fragment.hasChildren()))
+//                             // ||
+//                             // fragment.getNonJavaResources().length > 0) &&
+//                             // fragment.hasSubpackages())
+//                             return true;
+//             }
+//             return false;
+//     }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected boolean isProjectPackageFragmentRoot(IPackageFragmentRoot root)
+                       throws JavaModelException {
+               IResource resource = root.getResource();
+               return (resource instanceof IProject);
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected boolean exists(Object element) {
+               if (element == null) {
+                       return false;
+               }
+               if (element instanceof IResource) {
+                       return ((IResource) element).exists();
+               }
+               if (element instanceof IJavaElement) {
+                       return ((IJavaElement) element).exists();
+               }
+               return true;
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected Object internalGetParent(Object element) {
+               if (element instanceof IJavaProject) {
+                       return ((IJavaProject) element).getJavaModel();
+               }
+               // try to map resources to the containing package fragment
+               if (element instanceof IResource) {
+                       IResource parent = ((IResource) element).getParent();
+                       IJavaElement jParent = JavaCore.create(parent);
+                       // http://bugs.eclipse.org/bugs/show_bug.cgi?id=31374
+                       if (jParent != null && jParent.exists())
+                               return jParent;
+                       return parent;
+               }
+
+               // for package fragments that are contained in a project package
+               // fragment
+               // we have to skip the package fragment root as the parent.
+               if (element instanceof IPackageFragment) {
+                       IPackageFragmentRoot parent = (IPackageFragmentRoot) ((IPackageFragment) element)
+                                       .getParent();
+                       return skipProjectPackageFragmentRoot(parent);
+               }
+               if (element instanceof IJavaElement) {
+                       IJavaElement candidate = ((IJavaElement) element).getParent();
+                       // If the parent is a CU we might have shown working copy elements
+                       // below CU level. If so
+                       // return the original element instead of the working copy.
+                       if (candidate != null
+                                       && candidate.getElementType() == IJavaElement.COMPILATION_UNIT) {
+                               candidate = JavaModelUtil
+                                               .toOriginal((ICompilationUnit) candidate);
+                       }
+                       return candidate;
+               }
+               return null;
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+//     protected static Object[] concatenate(Object[] a1, Object[] a2) {
+//             int a1Len = a1.length;
+//             int a2Len = a2.length;
+//             Object[] res = new Object[a1Len + a2Len];
+//             System.arraycopy(a1, 0, res, 0, a1Len);
+//             System.arraycopy(a2, 0, res, a1Len, a2Len);
+//             return res;
+//     }
+
+}