X-Git-Url: http://git.phpeclipse.com 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 index 0000000..21b7dc1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java @@ -0,0 +1,449 @@ +/******************************************************************************* + * 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.JavaModelException; +import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil; +import net.sourceforge.phpeclipse.PHPCore; + +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. + *
+ * The following Java element hierarchy is surfaced by this content provider: + *
+ *
+Java model (+ * + *IJavaModel
) + Java project (IJavaProject
) + package fragment root (IPackageFragmentRoot
) + package fragment (IPackageFragment
) + compilation unit (ICompilationUnit
) + binary class file (IClassFile
) + *
+ * 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. + *
+ * 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 org.eclipse.jdt.ui.IWorkingCopyProvider + * @see JavaCore#getSharedWorkingCopies(org.eclipse.jdt.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 newStandardJavaElementContentProvider
.
+ *
+ * @param provideMembers if true
members below compilation units
+ * and class files are provided.
+ * @param provideWorkingCopy if true
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 true
if the content provider provides members;
+ * otherwise false
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 true
then members are provided.
+ * If false
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 true
if the content provider provides
+ * working copy members; otherwise false
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 true
members are provided from a
+ * working copy if one exists in JDT core. If false
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= PHPCore.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= PHPCore.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;
+ }
+
+
+}