org.springframework.ide.eclipse.beans.ui.properties.NonJavaResourceContentProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.beans.ui.properties.NonJavaResourceContentProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2006, 2010 Spring IDE Developers
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Spring IDE Developers - initial API and implementation
 *******************************************************************************/
package org.springframework.ide.eclipse.beans.ui.properties;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IContainer;
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.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IParent;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.JarEntryDirectory;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.springframework.ide.eclipse.core.io.ZipEntryStorage;
import org.springframework.ide.eclipse.core.java.JdtUtils;

/**
 * This content provider is used to display a tree of non-java resources.
 * @author Torsten Juergeleit
 * @author Christian Dupuis
 */
@SuppressWarnings("restriction")
public class NonJavaResourceContentProvider implements ITreeContentProvider {

    public static final Object[] NO_CHILDREN = new Object[0];

    private static final Path JVM_CLASSPATH_CONTAINER = new Path("org.eclipse.jdt.launching.JRE_CONTAINER");

    public void dispose() {
    }

    public Object[] getChildren(Object element) {
        if (!exists(element)) {
            return NO_CHILDREN;
        }
        try {
            if (element instanceof IProject) {
                IProject project = (IProject) element;
                if (JdtUtils.isJavaProject(project)) {
                    element = JavaCore.create(project);
                }
            }
            if (element instanceof IJavaProject) {
                return getPackageFragmentRoots((IJavaProject) element);
            }
            if (element instanceof IProject) {
                return getResources((IProject) 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 (element instanceof JarEntryDirectory) {
                return getResources((JarEntryDirectory) element);
            }
        } catch (JavaModelException e) {
            return NO_CHILDREN;
        }
        return NO_CHILDREN;
    }

    public Object[] getElements(Object parent) {
        return getChildren(parent);
    }

    public Object getParent(Object element) {
        if (!exists(element)) {
            return null;
        }
        return internalGetParent(element);
    }

    public boolean hasChildren(Object element) {
        if (element instanceof IProject) {
            IProject project = (IProject) element;
            if (!project.isOpen()) {
                return false;
            }
        }
        if (element instanceof IJavaProject) {
            IJavaProject javaProject = (IJavaProject) element;
            if (!javaProject.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;
    }

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    }

    private Object[] getNonJavaResources(IPackageFragment fragment) throws JavaModelException {
        Object[] nonJavaResources = fragment.getNonJavaResources();
        IPackageFragmentRoot root = (IPackageFragmentRoot) fragment.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
        if (root != null && root.getKind() == IPackageFragmentRoot.K_BINARY) {
            for (int i = 0; i < nonJavaResources.length; i++) {
                Object resource = nonJavaResources[i];
                if (resource instanceof IFile) {
                    nonJavaResources[i] = resource;
                } else if (resource instanceof IStorage && root.getResource() instanceof IFile) {
                    IStorage storage = (IStorage) resource;
                    nonJavaResources[i] = new ZipEntryStorage((IFile) root.getResource(),
                            storage.getFullPath().toString());
                }
            }
        }
        return nonJavaResources;
    }

    private Object[] getNonJavaResources(IPackageFragmentRoot root) throws JavaModelException {
        Object[] nonJavaResources = root.getNonJavaResources();

        // Replace JAR entries with our own wrapper
        if (root.getKind() == IPackageFragmentRoot.K_BINARY && root.getResource() instanceof IFile) {
            for (int i = 0; i < nonJavaResources.length; i++) {
                Object resource = nonJavaResources[i];
                if (resource instanceof IStorage) {
                    IStorage storage = (IStorage) resource;
                    nonJavaResources[i] = new ZipEntryStorage((IFile) root.getResource(),
                            storage.getFullPath().toString());
                }
            }
        }
        return nonJavaResources;
    }

    private Object[] getPackageContents(IPackageFragment fragment) throws JavaModelException {
        return getNonJavaResources(fragment);
    }

    private Object[] getPackageFragments(IPackageFragmentRoot root) throws JavaModelException {
        Object[] fragments = root.getChildren();
        Object[] nonJavaResources = getNonJavaResources(root);
        if (nonJavaResources == null) {
            return fragments;
        }
        return concatenate(fragments, nonJavaResources);
    }

    private Object[] getResources(IContainer container) {
        try {
            IResource[] members = container.members();
            IJavaProject javaProject = JavaCore.create(container.getProject());
            if (javaProject == null || !javaProject.exists()) {
                return members;
            }
            boolean isFolderOnClasspath = javaProject.isOnClasspath(container);
            List<Object> nonJavaResources = new ArrayList<Object>();

            // Can be on classpath but as a member of non-java resource folder
            for (IResource member : members) {

                // A resource can also be a java element in the case of
                // exclusion and inclusion filters. We therefore exclude Java
                // elements from the list of non-Java resources.
                if (isFolderOnClasspath) {
                    if (javaProject.findPackageFragmentRoot(member.getFullPath()) == null) {
                        nonJavaResources.add(member);
                    }
                } else if (!javaProject.isOnClasspath(member)) {
                    nonJavaResources.add(member);
                }
            }
            return nonJavaResources.toArray();
        } catch (CoreException e) {
            return NO_CHILDREN;
        }
    }

    private Object[] getResources(JarEntryDirectory element) {
        return element.getChildren();
    }

    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;
    }

    protected Object[] getJavaProjects(IJavaModel model) throws JavaModelException {
        return model.getJavaProjects();
    }

    protected Object[] getPackageFragmentRoots(IJavaProject project) throws JavaModelException {
        if (!project.getProject().isOpen()) {
            return NO_CHILDREN;
        }

        List<IJavaElement> list = new ArrayList<IJavaElement>();
        for (IPackageFragmentRoot root : project.getPackageFragmentRoots()) {
            if (!JVM_CLASSPATH_CONTAINER.isPrefixOf(root.getRawClasspathEntry().getPath())) {
                if (isProjectPackageFragmentRoot(root)) {
                    for (IJavaElement element : root.getChildren()) {
                        list.add(element);
                    }
                } else if (hasChildren(root)) {
                    list.add(root);
                }
            }
        }
        return concatenate(list.toArray(), project.getNonJavaResources());
    }

    protected Object internalGetParent(Object element) {

        // 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;
        } else if (element instanceof IJavaElement) {
            IJavaElement parent = ((IJavaElement) element).getParent();

            // 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) {
                return skipProjectPackageFragmentRoot((IPackageFragmentRoot) parent);
            }
            return parent;
        }
        return null;
    }

    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));
    }

    protected boolean isInternalLibrary(IJavaProject project, IPackageFragmentRoot root) {
        if (root.isArchive()) {
            IResource resource = root.getResource();
            if (resource != null) {
                IProject jarProject = resource.getProject();
                IProject container = root.getJavaProject().getProject();
                return container.equals(jarProject);
            }
            return false;
        }
        return true;
    }

    protected boolean isPackageFragmentEmpty(IJavaElement element) throws JavaModelException {
        if (element instanceof IPackageFragment) {
            IPackageFragment fragment = (IPackageFragment) element;
            if (fragment.exists() && !(fragment.hasChildren() || fragment.getNonJavaResources().length > 0)
                    && fragment.hasSubpackages()) {
                return true;
            }
        }
        return false;
    }

    protected boolean isProjectPackageFragmentRoot(IPackageFragmentRoot root) {
        IResource resource = root.getResource();
        return (resource instanceof IProject);
    }

    protected Object skipProjectPackageFragmentRoot(IPackageFragmentRoot root) {
        if (isProjectPackageFragmentRoot(root)) {
            return root.getParent();
        }
        return root;
    }

    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;
    }
}