org.eclipse.ajdt.core.CoreUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ajdt.core.CoreUtils.java

Source

/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *     Matt Chapman - initial version
 *     Matt Chapman - moved getAspectjrtClasspath here from ui plugin (84967)
 *******************************************************************************/
package org.eclipse.ajdt.core;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.jdt.internal.core.JavaProject;
import org.osgi.framework.Bundle;

/**
 * 
 * @author mchapman
 */
public class CoreUtils {

    public static final String PLUGIN_ID = "org.eclipse.ajdt.ui"; //$NON-NLS-1$
    public static final String ID_NATURE = PLUGIN_ID + ".ajnature"; //$NON-NLS-1$

    private static final String CLASSES = "classes";
    private static final String SOURCE = "source";
    /**
    * Computed classpath to aspectjrt.jar
    */
    private static String aspectjrtPath = null;

    private static String aspectjrtSourcePath = null;

    private static boolean sourceCheckDone = false;
    private static boolean rtCheckDone = false;

    /**
     * Return the fully-qualified name of the root directory for a project.
     */
    public static String getProjectRootDirectory(IProject project) {
        return project.getLocation().toOSString();
    }

    public static interface FilenameFilter {
        public boolean accept(String name);
    }

    public static final FilenameFilter ASPECTJ_SOURCE_ONLY_FILTER = new FilenameFilter() {
        public boolean accept(String name) {
            return (name.endsWith(".aj")); //$NON-NLS-1$
        }
    };

    public static final FilenameFilter ASPECTJ_SOURCE_FILTER = new FilenameFilter() {
        public boolean accept(String name) {
            return (name.endsWith(".java") || name.endsWith(".aj")); //$NON-NLS-1$ //$NON-NLS-2$
        }
    };

    public static final FilenameFilter RESOURCE_FILTER = new FilenameFilter() {
        public boolean accept(String name) {
            return !(name.endsWith(".java") || name.endsWith(".aj") || name //$NON-NLS-1$ //$NON-NLS-2$
                    .endsWith(".class")); //$NON-NLS-1$
        }
    };

    /**
     * Get the aspectjrt.jar classpath entry. This is usually in
     * plugins/org.aspectj.ajde_ <VERSION>/aspectjrt.jar
     */
    public synchronized static String getAspectjrtClasspath() {
        if (aspectjrtPath == null && !rtCheckDone) {
            rtCheckDone = true;
            aspectjrtPath = internalGetPath(AspectJPlugin.RUNTIME_PLUGIN_ID, false);
            if (aspectjrtPath == null) {
                AspectJPlugin.getDefault().getLog()
                        .log(new Status(IStatus.ERROR, AspectJPlugin.PLUGIN_ID, "Could not find AspectJ runtime."));
            }
        }
        return aspectjrtPath;
    }

    private static String internalGetPath(String bundleId, boolean useSource) {
        Bundle bundle = Platform.getBundle(bundleId);

        if (bundle != null) {
            URL installLoc = bundle.getEntry("/"); //$NON-NLS-1$
            URL resolved = null;
            try {
                resolved = FileLocator.resolve(installLoc);
                String fullPath = resolved.getFile();
                // !/ indicates a location inside of a jar
                if (fullPath.endsWith("!/")) {
                    fullPath = fullPath.substring(0, fullPath.length() - 2);
                }
                if (fullPath.startsWith("file:")) {
                    fullPath = new URL(fullPath).getFile();
                }
                File ajrt = new File(fullPath);
                if (ajrt.exists()) {
                    if (ajrt.isDirectory()) {
                        // in a runtime workbench
                        ajrt = new File(ajrt, useSource ? SOURCE : CLASSES);
                    }
                    return ajrt.getCanonicalPath();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    public synchronized static String getAspectjrtSourcePath() throws IOException {
        if (aspectjrtSourcePath == null && !sourceCheckDone) {
            sourceCheckDone = true;
            String aspectjrtClasspath = getAspectjrtClasspath();
            if (aspectjrtClasspath != null) {
                if (aspectjrtClasspath.endsWith(".jar")) {
                    int ajrtIndex = aspectjrtClasspath.lastIndexOf(AspectJPlugin.RUNTIME_PLUGIN_ID)
                            + AspectJPlugin.RUNTIME_PLUGIN_ID.length();
                    aspectjrtSourcePath = aspectjrtClasspath.substring(0, ajrtIndex) + "." + SOURCE
                            + aspectjrtClasspath.substring(ajrtIndex);
                } else if (aspectjrtClasspath.endsWith(CLASSES)) {
                    // runtime workbench
                    aspectjrtSourcePath = aspectjrtClasspath.substring(0,
                            aspectjrtClasspath.length() - CLASSES.length()) + SOURCE;
                }
            }
        }
        return aspectjrtSourcePath;
    }

    /**
     * Get all projects within the workspace who have a dependency on the given
     * project - this can either be a class folder dependency or on a library
     * which the project exports.
     * 
     * @param IProject
     *            project
     * @return List of two IProject[] where the first is all the class folder
     *         depending projects, and the second is all the exported library
     *         dependent projects
     */
    public static List<IProject[]> getDependingProjects(IProject project) {
        List<IProject[]> projects = new ArrayList<IProject[]>();

        IProject[] projectsInWorkspace = AspectJPlugin.getWorkspace().getRoot().getProjects();
        List<IPath> outputLocationPaths = getOutputLocationPaths(project);
        IClasspathEntry[] exportedEntries = getExportedEntries(project);
        List<IProject> classFolderDependingProjects = new ArrayList<IProject>();
        List<IProject> exportedLibraryDependingProjects = new ArrayList<IProject>();

        workThroughProjects: for (int i = 0; i < projectsInWorkspace.length; i++) {
            if (projectsInWorkspace[i].equals(project) || !(projectsInWorkspace[i].isOpen()))
                continue workThroughProjects;
            try {
                if (projectsInWorkspace[i].hasNature(JavaCore.NATURE_ID)) {
                    JavaProject javaProject = (JavaProject) JavaCore.create(projectsInWorkspace[i]);
                    if (javaProject == null)
                        continue workThroughProjects;

                    try {
                        IClasspathEntry[] cpEntry = javaProject.getRawClasspath();
                        for (int j = 0; j < cpEntry.length; j++) {
                            IClasspathEntry entry = cpEntry[j];
                            if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
                                for (Iterator<IPath> iter = outputLocationPaths.iterator(); iter.hasNext();) {
                                    IPath path = iter.next();
                                    if (entry.getPath().equals(path)) {
                                        classFolderDependingProjects.add(projectsInWorkspace[i]);
                                        continue workThroughProjects;
                                    }
                                }
                                for (int k = 0; k < exportedEntries.length; k++) {
                                    if (entry.getPath().equals(exportedEntries[k].getPath())) {
                                        exportedLibraryDependingProjects.add(projectsInWorkspace[i]);
                                    }
                                }
                            }
                        }
                    } catch (JavaModelException e) {
                        continue workThroughProjects;
                    }
                }
            } catch (CoreException e) {
            }
        }
        projects.add(0, classFolderDependingProjects.toArray(new IProject[] {}));
        projects.add(1, exportedLibraryDependingProjects.toArray(new IProject[] {}));
        return projects;
    }

    private static IClasspathEntry[] getExportedEntries(IProject project) {
        List<IClasspathEntry> exportedEntries = new ArrayList<IClasspathEntry>();

        IJavaProject javaProject = JavaCore.create(project);
        if (javaProject == null) {
            return new IClasspathEntry[0];
        }

        try {
            IClasspathEntry[] cpEntry = javaProject.getRawClasspath();
            for (int j = 0; j < cpEntry.length; j++) {
                IClasspathEntry entry = cpEntry[j];
                if (entry.isExported()) {
                    // we don't want to export it in the new classpath.
                    if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
                        IClasspathEntry nonExportedEntry = JavaCore.newLibraryEntry(entry.getPath(), null, null);
                        exportedEntries.add(nonExportedEntry);
                    }
                }
            }
        } catch (JavaModelException e) {
        }
        return (IClasspathEntry[]) exportedEntries.toArray(new IClasspathEntry[exportedEntries.size()]);
    }

    /**
     * Get the output locations for the project
     * 
     * @param project
     * @return list of IPath objects
     */
    public static List<IPath> getOutputLocationPaths(IProject project) {
        List<IPath> outputLocations = new ArrayList<IPath>();
        IJavaProject javaProject = JavaCore.create(project);
        if (javaProject == null)
            return outputLocations;

        try {
            // Have been unable to create a user scenario where the following
            // for
            // loop adds something to outputLocations, therefore always
            // fall through to the following if loop. However, if a project has
            // more than one output folder, then this for loop should pick them
            // up.
            // Needs testing.......
            IClasspathEntry[] cpEntry = javaProject.getRawClasspath();
            for (int j = 0; j < cpEntry.length; j++) {
                IClasspathEntry entry = cpEntry[j];
                int contentKind = entry.getContentKind();
                if (contentKind == ClasspathEntry.K_OUTPUT) {
                    if (entry.getOutputLocation() != null) {
                        outputLocations.add(entry.getOutputLocation());
                    }
                }
            }
            // If we haven't added anything from reading the .classpath
            // file, then use the default output location
            if (outputLocations.size() == 0) {
                outputLocations.add(javaProject.getOutputLocation());
            }
        } catch (JavaModelException e) {
        }
        return outputLocations;
    }

    public static IPath[] getOutputFolders(IJavaProject project) throws CoreException {
        List<IPath> paths = new ArrayList<IPath>();
        paths.add(project.getOutputLocation());
        IClasspathEntry[] cpe = project.getRawClasspath();
        for (int i = 0; i < cpe.length; i++) {
            if (cpe[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                IPath output = cpe[i].getOutputLocation();
                if (output != null) {
                    paths.add(output);
                }
            }
        }
        return (IPath[]) paths.toArray(new IPath[paths.size()]);
    }

    public static boolean isAJProject(IProject project) {
        if ((project != null) && project.isOpen()) {
            try {
                if (project.hasNature(ID_NATURE)) {
                    return true;
                }
            } catch (CoreException e) {
            }
        }
        return false;
    }

    /**
     * Converts an AspectJ style signature in chars to 
     * a Java style signature as an array of String
     * 
     * Replace the 'P' for parameterized to 'L' for resolved
     */
    public static String[] listAJSigToJavaSig(List<char[]> chars) {
        if (chars != null) {
            String[] result = new String[chars.size()];
            int index = 0;
            for (Iterator<char[]> charsIter = chars.iterator(); charsIter.hasNext(); index++) {
                char[] c = charsIter.next();
                if (c == null) {
                    result[index] = "";
                    continue;
                }
                boolean wasLessThan = true;
                for (int i = 0; i < c.length; i++) {
                    if (wasLessThan) {
                        if (c[i] == 'P') { // Java spec does not use 'P' for parameterized types, AspectJ does
                            c[i] = 'L';
                        }
                        wasLessThan = false;
                    } else {
                        switch (c[i]) {
                        case '<':
                            wasLessThan = true;
                            break;

                        case '/':
                            c[i] = '.';
                            wasLessThan = false;
                            break;
                        }
                    }
                }

                result[index] = new String(c);
            }
            return result;
        }
        return new String[0];
    }

    public static char[][] listStringsToCharArrays(List<String> strings) {
        if (strings != null) {
            char[][] result = new char[strings.size()][];
            int index = 0;
            for (Iterator<String> stringIter = strings.iterator(); stringIter.hasNext(); index++) {
                String string = stringIter.next();
                result[index] = string != null ? string.toCharArray() : "".toCharArray();
            }
            return result;
        }
        return new char[0][];
    }

    public static char[][] listCharsToCharArrays(List<char[]> strings) {
        if (strings != null) {
            char[][] result = new char[strings.size()][];
            int index = 0;
            for (Iterator<char[]> stringIter = strings.iterator(); stringIter.hasNext(); index++) {
                char[] string = stringIter.next();
                result[index] = string != null ? string : "".toCharArray();
            }
            return result;
        }
        return new char[0][];
    }
}