X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java new file mode 100644 index 0000000..87d461c --- /dev/null +++ b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java @@ -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. + *
+ * 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 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 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 = 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;
+ }
+
+}