org.ebayopensource.turmeric.eclipse.utils.plugin.JDTUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.ebayopensource.turmeric.eclipse.utils.plugin.JDTUtil.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *******************************************************************************/
package org.ebayopensource.turmeric.eclipse.utils.plugin;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.PropertyResourceBundle;
import java.util.Set;
import java.util.logging.Logger;

import org.apache.commons.lang.StringUtils;
import org.ebayopensource.turmeric.eclipse.utils.collections.ListUtil;
import org.ebayopensource.turmeric.eclipse.utils.collections.SetUtil;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jst.common.project.facet.JavaFacetUtils;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;

/**
 * The Class JDTUtil.
 *
 * @author smathew
 * 
 * Utility for JDT related functions
 */
public class JDTUtil {
    /**
     * @see org.eclipse.jdt.internal.compiler.impl.CompilerOptions.VERSION_1_4
     */
    @SuppressWarnings("restriction")
    private static final String COMPILER_OPTIONS_VERSION_1_4 = "1.4";

    /** The Constant DEFAULT_COMPILER_VERSION. */
    public static final String DEFAULT_COMPILER_VERSION = "1.6";

    /** The Constant DOT. */
    public static final String DOT = ".";

    /**
     * Pure Wrapper Call.
     *
     * @param name the name
     * @return the i status
     */
    public static IStatus validateIdentifier(String name) {
        return JavaConventions.validateIdentifier(name, COMPILER_OPTIONS_VERSION_1_4, COMPILER_OPTIONS_VERSION_1_4);

    }

    /**
     * Pure Wrapper Call to
     * This validates a type name ie Whatever compiler takes.
     * eg: a. is not valid.
     * a is valid
     *
     * @param typeName the type name
     * @return the i status
     */
    public static IStatus validateJavaTypeName(String typeName) {
        return JavaConventions.validateJavaTypeName(typeName, COMPILER_OPTIONS_VERSION_1_4,
                COMPILER_OPTIONS_VERSION_1_4);
    }

    /**
     * Validate method name.
     *
     * @param methodName the method name
     * @return True if the method name is valid
     */
    public static IStatus validateMethodName(String methodName) {
        return JavaConventions.validateMethodName(methodName, COMPILER_OPTIONS_VERSION_1_4,
                COMPILER_OPTIONS_VERSION_1_4);
    }

    /**
     * Validate pacakge name.
     *
     * @param packageName the package name
     * @return the i status
     */
    public static IStatus validatePacakgeName(String packageName) {
        return JavaConventions.validatePackageName(packageName, COMPILER_OPTIONS_VERSION_1_4,
                COMPILER_OPTIONS_VERSION_1_4);
    }

    /**
     * Adds the java support to eclipse project.
     * ie soa nature is added here.
     * Class Path container related linking etc..
     *
     * @param project the project
     * @param sourceDirectories the source directories
     * @param defaultCompilerLevel the default compiler level
     * @param outputLocation the output location
     * @param monitor the monitor
     * @throws CoreException the core exception
     */
    public static void addJavaSupport(IProject project, List<String> sourceDirectories, String defaultCompilerLevel,
            String outputLocation, IProgressMonitor monitor) throws CoreException {

        boolean changedClasspath = false;
        if (addJavaNature(project, monitor)) {
            changedClasspath = true;
        }
        // Configuring the Java Project
        final IJavaProject javaProject = JavaCore.create(project);
        final List<IClasspathEntry> classpath = JDTUtil.rawClasspath(javaProject, true);
        if (outputLocation.equals(javaProject.getOutputLocation()) == false) {
            final IFolder outputDirClasses = project.getFolder(outputLocation);
            javaProject.setOutputLocation(outputDirClasses.getFullPath(), monitor);
            changedClasspath = true;
        }

        // Dealing with the case where the root of the project is set to be the
        // src and bin destinations... bad... bad...
        for (final Iterator<IClasspathEntry> iterator = classpath.iterator(); iterator.hasNext();) {
            final IClasspathEntry entry = iterator.next();
            if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE
                    || !entry.getPath().equals(new Path("/" + project.getName())))
                continue;
            iterator.remove();
            changedClasspath |= true;
        }
        for (final String dir : sourceDirectories) {

            final IFolder source = project.getFolder(dir);
            // If the Java project existed previously, checking if directories
            // already exist in
            // its classpath.
            boolean found = false;
            for (final IClasspathEntry entry : classpath) {
                if (!entry.getPath().equals(source.getFullPath()))
                    continue;
                found = true;
                break;
            }
            if (found)
                continue;
            changedClasspath |= true;
            classpath.add(JavaCore.newSourceEntry(source.getFullPath()));
        }
        ProgressUtil.progressOneStep(monitor, 10);
        // Adding the runtime library
        boolean found = false;
        for (final IClasspathEntry entry : classpath) {
            // All JRE Containers should have a prefix of
            // org.eclipse.jdt.launching.JRE_CONTAINER
            if (JavaRuntime.newDefaultJREContainerPath().isPrefixOf(entry.getPath())
                    && JavaRuntime.newDefaultJREContainerPath().equals(entry.getPath())) {
                found = true;
                break;
            }
        }
        if (!found) {
            changedClasspath = true;
            classpath.add(JavaRuntime.getDefaultJREContainerEntry());
        }
        ProgressUtil.progressOneStep(monitor);
        // Configuring the classpath of the Java Project
        if (changedClasspath) {
            javaProject.setRawClasspath(classpath.toArray(new IClasspathEntry[0]), null);
        }

        IProjectFacetVersion projectFacetVersion = JavaFacetUtils.JAVA_60;
        if (StringUtils.isNotBlank(defaultCompilerLevel)) {
            try {
                projectFacetVersion = JavaFacetUtils.compilerLevelToFacet(defaultCompilerLevel);
            } catch (Exception e) {
                Logger.getLogger(JDTUtil.class.getName()).throwing(JDTUtil.class.getName(), "addJavaSupport", e);
            }
        }

        JavaFacetUtils.setCompilerLevel(project, projectFacetVersion);
    }

    /**
     * Resolve classpath to ur ls.
     *
     * @param bundle The plugin bundle to load jars
     * @param project The underlying SOA project
     * @return All jars in the runtime classpath of the provided bundle.
     * @throws Exception the exception
     */
    public static Set<URL> resolveClasspathToURLs(final Bundle bundle, final IProject project) throws Exception {
        final Map<String, URL> result = new LinkedHashMap<String, URL>();
        //      Object obj = bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
        //      for (final String path : StringUtils.split(String.valueOf(obj), ",")) {
        //         if (path.endsWith(".jar")) {
        //            URL url = bundle.getEntry(path);
        //            url = FileLocator.resolve(url);
        //            result.put(new Path(url.getFile()).lastSegment(), url);
        //         }
        //      }

        //load missing jars from the project's classpath
        for (final URL url : resolveClasspathToURLs(project)) {
            final Path path = new Path(url.getFile());
            final String fileName = path.lastSegment();

            if (StringUtils.equalsIgnoreCase(path.getFileExtension(), "jar")) {
                if (result.containsKey(fileName) == false)
                    result.put(fileName, url);
            } else if (result.containsKey(url.getFile()) == false) {
                result.put(url.getFile(), url);
            }
        }

        return SetUtil.linkedSet(result.values());
    }

    /**
     * Resolves the projects class path container entries
     * Explodes the container out and return a Set of URL Path.
     *
     * @param project the project
     * @return the sets the
     * @throws Exception the exception
     */
    public static Set<URL> resolveClasspathToURLs(final IProject project) throws Exception {
        return resolveClasspathToURLs(JavaCore.create(project));
    }

    private static Set<URL> resolveClasspathToURLs(final IJavaProject javaProject)
            throws JavaModelException, IOException {
        final Set<URL> classpath = SetUtil.linkedSet();
        resolveClasspathToURLs(javaProject, classpath, SetUtil.set(new String[0]));
        return classpath;
    }

    private static void resolveClasspathToURLs(final IJavaProject javaProject, final Set<URL> resolvedEntries,
            final Set<String> visited) throws JavaModelException, IOException {
        if (javaProject == null || !javaProject.exists())
            return;
        final String projectName = javaProject.getProject().getName();
        if (visited.contains(projectName))
            return;
        visited.add(projectName);
        for (final IClasspathEntry entry : javaProject.getResolvedClasspath(true)) {
            if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
                resolveClasspathToURLs(JavaCore.create(WorkspaceUtil.getProject(entry.getPath())), resolvedEntries,
                        visited);
            } else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
                resolvedEntries.add(WorkspaceUtil.getLocation(entry.getPath()).toFile().toURI().toURL());

            } else if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                IPath location = entry.getOutputLocation() != null ? entry.getOutputLocation()
                        : javaProject.getOutputLocation();
                if (location.toString().startsWith(WorkspaceUtil.PATH_SEPERATOR + projectName)) {
                    //it happens that the path is not absolute
                    location = javaProject.getProject().getFolder(location.removeFirstSegments(1)).getLocation();
                }

                resolvedEntries.add(location.toFile().toURI().toURL());
            }
        }
    }

    /**
     * Adds the natures.
     *
     * @param project the project
     * @param monitor the monitor
     * @param projectNatures the project natures
     * @return true, if successful
     * @throws CoreException the core exception
     */
    public static boolean addNatures(final IProject project, final IProgressMonitor monitor,
            String... projectNatures) throws CoreException {
        if (project == null || projectNatures == null || projectNatures.length == 0)
            return false;
        List<String> additionalNatureIds = new ArrayList<String>(projectNatures.length);
        for (String natureId : projectNatures) {
            if (project.hasNature(natureId) == false) {
                additionalNatureIds.add(natureId);
            }
        }

        if (additionalNatureIds.isEmpty() == false) {
            // Adding the natures to the project.
            final IProjectDescription description = project.getDescription();
            final List<String> natureIDs = ListUtil.array(description.getNatureIds());
            natureIDs.addAll(additionalNatureIds);
            description.setNatureIds(natureIDs.toArray(new String[0]));
            project.setDescription(description, monitor);
            return true;
        }
        return false;
    }

    /**
     * Adds the java nature.
     *
     * @param project the project
     * @param monitor the monitor
     * @return true, if successful
     * @throws CoreException the core exception
     */
    public static boolean addJavaNature(final IProject project, final IProgressMonitor monitor)
            throws CoreException {
        return addNatures(project, monitor, JavaCore.NATURE_ID);
    }

    /**
     * Raw classpath.
     *
     * @param project the project
     * @param readFromDisk the read from disk
     * @return the list
     * @throws JavaModelException the java model exception
     */
    public static List<IClasspathEntry> rawClasspath(final IProject project, final boolean readFromDisk)
            throws JavaModelException {
        return rawClasspath(JavaCore.create(project), readFromDisk);
    }

    /**
     * Raw classpath.
     *
     * @param project the project
     * @param readFromDisk the read from disk
     * @return the list
     * @throws JavaModelException the java model exception
     */
    public static List<IClasspathEntry> rawClasspath(final IJavaProject project, final boolean readFromDisk)
            throws JavaModelException {
        final List<IClasspathEntry> entries = ListUtil.list();
        if (project == null || !project.getProject().isAccessible())
            return entries;
        if (!readFromDisk && project.getProject().getFile(".classpath").isAccessible()
                && project.getProject().getFile(".classpath").isSynchronized(IResource.DEPTH_INFINITE))
            ListUtil.add(entries, project.getRawClasspath());
        else
            ListUtil.add(entries, project.readRawClasspath());
        return entries;
    }

    /**
     * Checks if is classpath container.
     *
     * @param entry the entry
     * @param path the path
     * @return true, if is classpath container
     */
    public static boolean isClasspathContainer(final IClasspathEntry entry, final String path) {
        return entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER && (path.equals(entry.getPath().segment(0)));
    }

    /**
     * Checks if is jRE classpath container.
     *
     * @param entry the entry
     * @return true, if is jRE classpath container
     */
    public static boolean isJREClasspathContainer(final IClasspathEntry entry) {
        return isClasspathContainer(entry, JavaRuntime.JRE_CONTAINER);
    }

    /**
     * Gets the bundle info.
     *
     * @param bundle the bundle
     * @param needDetail the need detail
     * @return the bundle info
     */
    public static String getBundleInfo(final Bundle bundle, final boolean needDetail) {
        final StringBuffer buf = new StringBuffer();
        if (bundle != null) {
            buf.append(bundle.getSymbolicName());
            Object versionID = bundle.getHeaders().get(Constants.BUNDLE_VERSION);
            if (versionID != null) {
                buf.append(" ");
                buf.append(versionID.toString());
            }
            if (needDetail) {
                buf.append("\nManifest Headers:");
                for (Enumeration<?> keys = bundle.getHeaders().keys(); keys.hasMoreElements();) {
                    Object key = keys.nextElement();
                    buf.append(key);
                    buf.append(" = ");
                    buf.append(bundle.getHeaders().get(key));
                    buf.append("\n");
                }
            }
        }
        return buf.toString();
    }

    /**
     * Generate qualified class name using path seperator.
     *
     * @param classNameForPkg the class name for pkg
     * @param pkgPrefix the pkg prefix
     * @param genClassName the gen class name
     * @return the string
     */
    public static String generateQualifiedClassNameUsingPathSeperator(String classNameForPkg, String pkgPrefix,
            String genClassName) {

        String genPkgName = null;

        int lastDotPos = classNameForPkg.lastIndexOf(DOT);
        if (lastDotPos > -1) {
            genPkgName = classNameForPkg.substring(0, lastDotPos) + WorkspaceUtil.PATH_SEPERATOR + pkgPrefix;
        } else {
            genPkgName = pkgPrefix;
        }
        genPkgName = StringUtils.replace(genPkgName, DOT, WorkspaceUtil.PATH_SEPERATOR);

        return genPkgName + WorkspaceUtil.PATH_SEPERATOR + genClassName;
    }

    /**
     * Gets the plugin properties.
     *
     * @param bundle the bundle
     * @param fileName the file name
     * @return the plugin properties
     * @throws IOException Signals that an I/O exception has occurred.
     */
    public static PropertyResourceBundle getPluginProperties(final Bundle bundle, String fileName)
            throws IOException {
        PropertyResourceBundle pluginProperties;

        if (StringUtils.isBlank(fileName)) {
            final Object object = bundle.getHeaders().get(Constants.BUNDLE_LOCALIZATION);
            fileName = object != null ? object.toString() + ".properties" : "plugin.properties";
        }

        pluginProperties = new PropertyResourceBundle(FileLocator.openStream(bundle, new Path(fileName), false));

        return pluginProperties;
    }

    /**
     * Gets the plugin properties.
     *
     * @param bundle the bundle
     * @return the plugin properties
     * @throws IOException Signals that an I/O exception has occurred.
     */
    public static PropertyResourceBundle getPluginProperties(final Bundle bundle) throws IOException {
        return getPluginProperties(bundle, null);
    }

    /**
     * Gets the source directories.
     *
     * @param project the project
     * @return the source directories
     */
    public static List<IPath> getSourceDirectories(final IProject project) {
        final IJavaProject jProject = JavaCore.create(project);
        final List<IPath> srcEntries = new ArrayList<IPath>();
        for (final IClasspathEntry entry : jProject.readRawClasspath()) {
            if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                srcEntries.add(entry.getPath());
            }
        }
        return srcEntries;
    }

    /**
     * Convert class name to file path.
     *
     * @param className the class name
     * @return the i path
     */
    public static IPath convertClassNameToFilePath(String className) {
        if (className == null)
            return null;
        final IPath path = new Path(StringUtils.replaceChars(className, ".", WorkspaceUtil.PATH_SEPERATOR));
        return path.addFileExtension("java");
    }

}