org.granite.builder.util.ProjectUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.granite.builder.util.ProjectUtil.java

Source

/**
 *   GRANITE DATA SERVICES
 *   Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
 *
 *   This file is part of the Granite Data Services Platform.
 *
 *   Granite Data Services is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *
 *   Granite Data Services is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 *   General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 *   USA, or see <http://www.gnu.org/licenses/>.
 */

package org.granite.builder.util;

import static org.granite.builder.GraniteBuilder.FLEX_BUILDER_ID;
import static org.granite.builder.GraniteBuilder.GRANITE_BUILDER_ID;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.granite.builder.GraniteActivator;
import org.granite.util.ClassUtil;

/**
 * @author Franck WOLFF
 */
public class ProjectUtil {

    public static final Comparator<IPath> IPATH_COMPARATOR = new Comparator<IPath>() {
        @Override
        public int compare(IPath path1, IPath path2) {
            return path1.toString().compareTo(path2.toString());
        }
    };

    public static IProject[] getAllProjects(IProject project) {
        if (project == null)
            return new IProject[0];
        return project.getWorkspace().getRoot().getProjects();
    }

    public static IProject[] getAllOtherGraniteProjects(IProject project) throws CoreException {
        if (project == null)
            return new IProject[0];
        List<IProject> projects = new ArrayList<IProject>();
        for (IProject p : getAllProjects(project)) {
            if (!p.equals(project) && isGraniteProject(p))
                projects.add(p);
        }
        return projects.toArray(new IProject[projects.size()]);
    }

    public static IProject getProject(IProject project, String name) {
        if (project == null || name == null)
            return null;
        return project.getWorkspace().getRoot().getProject(name);
    }

    public static boolean isGraniteProject(IProject project) throws CoreException {
        if (project != null && project.exists() && project.isOpen()) {
            for (ICommand command : project.getDescription().getBuildSpec()) {
                if (GRANITE_BUILDER_ID.equals(command.getBuilderName()))
                    return true;
            }
        }
        return false;
    }

    public static boolean isFlexBuilderProject(IProject project) throws CoreException {
        if (project != null && project.exists() && project.isOpen()) {
            for (ICommand command : project.getDescription().getBuildSpec()) {
                if (FLEX_BUILDER_ID.equals(command.getBuilderName()))
                    return true;
            }
        }
        return false;
    }

    public static List<IPath> makeRelative(List<IPath> paths) {
        if (paths == null)
            return null;
        return Arrays.asList(makeRelative(paths.toArray(new IPath[paths.size()])));
    }

    public static IPath[] makeRelative(IPath[] paths) {
        if (paths != null) {
            for (int i = 0; i < paths.length; i++)
                paths[i] = paths[i].makeRelative();
        }
        return paths;
    }

    public static File getWorkspaceFile(IProject project) {
        IWorkspace workspace = project.getWorkspace();
        return workspace.getRoot().getLocation().toFile().getAbsoluteFile();
    }

    public static URI getWorkspaceURI(IProject project) {
        return getWorkspaceFile(project).toURI();
    }

    public static File getProjectFile(IProject project) {
        try {
            return FileUtil.getLocationFile(project).getAbsoluteFile();
        } catch (CoreException e) {
            throw new RuntimeException("Could not get " + project + " location file", e);
        }
    }

    public static URI getProjectURI(IProject project) {
        try {
            return FileUtil.getLocationURI(project);
        } catch (CoreException e) {
            throw new RuntimeException("Could not get " + project + " location URI", e);
        }
    }

    public static List<CpEntry> getFullResolvedClasspath(IJavaProject project) throws CoreException {
        return getFullClasspath(project, project.getResolvedClasspath(true));
    }

    public static List<CpEntry> getFullClasspath(IJavaProject project) throws CoreException {
        return getFullClasspath(project, project.getRawClasspath());
    }

    public static List<CpEntry> getFullClasspath(IJavaProject project, IClasspathEntry[] classpathEntries)
            throws CoreException {
        List<CpEntry> classpath = new ArrayList<CpEntry>();

        IWorkspaceRoot workspace = project.getProject().getWorkspace().getRoot();
        IPath path = null;
        try {

            // Output locations.
            if (project.getOutputLocation() != null) {
                path = project.getOutputLocation();
                File file = workspace.findMember(path).getLocation().toFile();
                classpath.add(new CpEntry(path.makeRelative().toString(), path, file,
                        CpEntry.CpeKind.PROJECT_OUTPUT_DIR));
            }
            for (IClasspathEntry cpe : classpathEntries) {
                if (cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE && cpe.getOutputLocation() != null) {
                    path = cpe.getOutputLocation();
                    File file = workspace.findMember(path).getLocation().toFile();
                    classpath.add(new CpEntry(path.makeRelative().toString(), path, file,
                            CpEntry.CpeKind.SOURCE_OUTPUT_DIR));
                }
            }

            // Project jars.
            for (IClasspathEntry cpe : classpathEntries) {
                if (cpe.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
                    path = cpe.getPath();
                    if (path != null) {
                        IResource member = workspace.findMember(path);
                        String description = path.lastSegment();
                        if (path.segmentCount() > 1)
                            description += " - " + path.removeLastSegments(1).makeRelative();
                        if (member != null)
                            classpath.add(new CpEntry(description, path, member.getLocation().toFile(),
                                    CpEntry.CpeKind.LIB_JAR));
                        else
                            classpath.add(new CpEntry(description, path, path.toFile(), CpEntry.CpeKind.LIB_JAR));
                    }
                }
            }

            // Containers jars/directories.
            for (IClasspathEntry cpe : classpathEntries) {
                if (cpe.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
                    path = cpe.getPath();
                    IClasspathContainer container = JavaCore.getClasspathContainer(path, project);
                    String description = container.getDescription();
                    CpEntry entry = new CpEntry(description, path, (path != null ? path.toFile() : null),
                            CpEntry.CpeKind.CONTAINER_JAR);

                    for (IClasspathEntry ccpe : container.getClasspathEntries()) {
                        path = ccpe.getPath();
                        String label = path.lastSegment();
                        if (path.segmentCount() > 1)
                            label += " - " + path.removeLastSegments(1).makeRelative();

                        File file = path.toFile();
                        IResource resource = workspace.findMember(path);
                        if (resource != null)
                            file = resource.getLocation().toFile();

                        entry.getChildren().add(new CpEntry(label, path, file, CpEntry.CpeKind.LIB_JAR));
                    }

                    classpath.add(entry);
                }
            }

        } catch (Exception e) {
            String msg = "Problem with classpath location: " + path;
            throw new CoreException(createErrorStatus(msg, e));
        }

        return classpath;
    }

    public static List<IPath> getSourceFolders(IJavaProject project) throws CoreException {
        List<IPath> paths = new ArrayList<IPath>();

        for (IClasspathEntry cpe : project.getRawClasspath()) {
            if (cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE)
                paths.add(cpe.getPath());
        }

        return paths;
    }

    public static IPath getOutputFolder(IJavaProject project, IClasspathEntry cpe) throws CoreException {
        if (cpe.getOutputLocation() != null)
            return cpe.getOutputLocation();
        return project.getOutputLocation();
    }

    public static List<IPath> getOutputFolders(IJavaProject project) throws CoreException {
        List<IPath> paths = new ArrayList<IPath>();

        for (IClasspathEntry cpe : project.getRawClasspath()) {
            if (cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                IPath output = cpe.getOutputLocation();
                if (output != null)
                    paths.add(output);
            }
        }
        IPath output = project.getOutputLocation();
        if (output != null)
            paths.add(output);

        return paths;
    }

    public static IPath getJavaPath(IJavaProject project, IFile classFile, boolean keepInner) throws CoreException {
        IPath classPath = classFile.getFullPath();

        List<IPath> outputFolders = getOutputFolders(project);
        IPath classOutputFolder = null;
        for (IPath outputFolder : outputFolders) {
            if (outputFolder.isPrefixOf(classPath)) {
                classOutputFolder = outputFolder;
                break;
            }
        }
        if (classOutputFolder == null)
            return null;

        classPath = classPath.removeFirstSegments(classOutputFolder.segmentCount());

        String sPath = classPath.toString();
        sPath = sPath.substring(0, sPath.length() - classPath.getFileExtension().length() - 1);
        if (!keepInner) {
            int iDollar = sPath.indexOf('$');
            if (iDollar != -1)
                sPath = sPath.substring(iDollar);
        }
        sPath += ".java";

        return new Path(sPath);
    }

    public static JavaClassInfo getJavaClassInfo(IJavaProject project, Class<?> clazz) {
        try {
            URI clazzUri = ClassUtil.findResource(clazz).toURI();
            URI projectUri = getProjectURI(project.getProject());
            URI relativeURI = projectUri.relativize(clazzUri);
            return getJavaClassInfo(project, project.getProject().getFile(relativeURI.toString()));
        } catch (Exception e) {
            return null;
        }
    }

    public static JavaClassInfo getJavaClassInfo(IJavaProject project, IFile resource) throws CoreException {
        // classPath = "<project name>/<output folder>/<package>/<file>.class"
        IPath classPath = resource.getFullPath().makeRelative();

        // Find output folder: "<project name>/<output folder>".
        IPath outputFolder = null;
        if (project.getOutputLocation() != null && project.getOutputLocation().isPrefixOf(classPath))
            outputFolder = project.getOutputLocation();
        else {
            for (IClasspathEntry cpe : project.getRawClasspath()) {
                if (cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                    IPath output = cpe.getOutputLocation();
                    if (output != null && output.isPrefixOf(classPath)) {
                        outputFolder = output;
                        break;
                    }
                }
            }
        }

        if (outputFolder == null)
            return null;

        // Compute class name.
        IPath relativeClassPath = classPath.removeFirstSegments(outputFolder.segmentCount());
        IPath relativeClassName = relativeClassPath.removeFileExtension();
        String className = relativeClassName.toPortableString().replace('/', '.');

        // Compute java source path: "<package>/<class name>[$<inner class>].java".
        String javaFullPath = relativeClassName.addFileExtension("java").toPortableString();
        String javaFilePath = javaFullPath;
        int iDollar = javaFilePath.indexOf('$');
        if (iDollar != -1)
            javaFilePath = javaFilePath.substring(0, iDollar) + ".java";

        IJavaElement javaElement = project.findElement(new Path(javaFilePath));
        if (javaElement == null)
            return null;

        IJavaElement sourceFolder = javaElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
        if (sourceFolder == null)
            return null;

        IPath folderPath = sourceFolder.getPath().makeRelative();
        if (folderPath.segmentCount() > 0)
            folderPath = folderPath.removeFirstSegments(1);

        // Fix issues with project not in the workspace directory.
        outputFolder = project.getProject().getWorkspace().getRoot().findMember(outputFolder).getLocation();

        return new JavaClassInfo(folderPath.toPortableString(), javaFullPath, className,
                new File(outputFolder.toPortableString(), relativeClassPath.toPortableString()));
    }

    public static IStatus createErrorStatus(String message) {
        return new Status(IStatus.ERROR, GraniteActivator.PLUGIN_ID, message);
    }

    public static IStatus createErrorStatus(String message, Throwable t) {
        return new Status(IStatus.ERROR, GraniteActivator.PLUGIN_ID, IStatus.OK, message, t);
    }

    public static class CpEntry {

        public enum CpeKind {
            PROJECT_OUTPUT_DIR, SOURCE_OUTPUT_DIR, CONTAINER_JAR, LIB_JAR
        }

        private final String description;
        private final IPath path;
        private final File file;
        private final CpeKind kind;
        private final List<CpEntry> children = new ArrayList<CpEntry>();

        public CpEntry(String description, IPath path, File file, CpeKind kind) {
            this.description = description;
            this.path = path;
            this.file = file;
            this.kind = kind;
        }

        public String getDescription() {
            return description;
        }

        public IPath getPath() {
            return path;
        }

        public File getFile() {
            return file;
        }

        public CpeKind getKind() {
            return kind;
        }

        public List<CpEntry> getChildren() {
            return children;
        }

        public boolean exists() {
            return (file != null && file.exists());
        }

        public URL toURL() throws IOException {
            if (file == null)
                return null;
            return file.getCanonicalFile().toURI().toURL();
        }

        @Override
        public String toString() {
            return "[" + kind + "] " + path + " -> " + file;
        }
    }
}