org.grails.ide.eclipse.core.internal.GrailsResourceUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.grails.ide.eclipse.core.internal.GrailsResourceUtil.java

Source

/*******************************************************************************
 * Copyright (c) 2012 Pivotal Software, Inc.
 * 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
 * https://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Pivotal Software, Inc. - initial API and implementation
 *******************************************************************************/
package org.grails.ide.eclipse.core.internal;

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

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IAdaptable;
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.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.grails.ide.eclipse.commands.GrailsCommandUtils;
import org.grails.ide.eclipse.core.GrailsCoreActivator;
import org.grails.ide.eclipse.core.internal.classpath.GrailsClasspathContainer;
import org.grails.ide.eclipse.core.internal.classpath.GrailsClasspathUtils;
import org.grails.ide.eclipse.core.internal.plugins.GrailsProjectStructureManager;
import org.grails.ide.eclipse.core.internal.plugins.GrailsProjectStructureTypes;
import org.springsource.ide.eclipse.commons.core.JdtUtils;

/**
 * @author Nieraj Singh
 * @author Kris De Volder
 * @author Andrew Eisenberg
 */
public class GrailsResourceUtil {

    private GrailsResourceUtil() {
        // util
    }

    /**
     * Returns all accessible Grails projects in the workspace. If no accessible
     * Grails projects are found, empty list is returned. <br/>
     * Closed projects, or projects that cannot be read are not included in the
     * list.
     * 
     * @return All accessible Grails projects in the workspace, or empty list if
     *         nothing found
     */
    public static final List<IProject> getAllGrailsProjects() {
        IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
        List<IProject> grailsProjects = new ArrayList<IProject>();
        if (projects != null) {
            for (IProject project : projects) {
                if (GrailsNature.isGrailsProject(project)) {
                    grailsProjects.add(project);
                }
            }
        }
        return grailsProjects;
    }

    public static boolean hasClasspathContainer(IResource context) {
        if (JdtUtils.isJavaProject(context)) {
            return GrailsClasspathUtils.hasClasspathContainer(JdtUtils.getJavaProject(context));
        }
        return false;
    }

    public static IPackageFragmentRoot[] getGrailsDependencyPackageFragmentRoots(IProject project, IPath path) {
        if (project == null) {
            return null;
        }
        IJavaProject javaProject = JavaCore.create(project);
        try {

            IClasspathEntry[] entries = javaProject.getRawClasspath();
            for (IClasspathEntry entry : entries) {
                if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                    for (IClasspathAttribute attr : entry.getExtraAttributes()) {
                        if (attr.getName().equals(GrailsClasspathContainer.PLUGIN_SOURCEFOLDER_ATTRIBUTE_NAME)) {
                            IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(entry.getPath());
                            if (folder.getLocation().equals(path)) {
                                return javaProject.findPackageFragmentRoots(entry);
                            }
                        }
                    }
                }
            }

        } catch (JavaModelException e) {
            GrailsCoreActivator.log(e);
        }
        return null;

    }

    public static boolean isGrailsDependencyPackageFragmentRoot(IPackageFragmentRoot root) {
        if (root == null) {
            return false;
        }

        try {
            return isGrailsClasspathEntry(root.getRawClasspathEntry());
        } catch (JavaModelException e) {
            GrailsCoreActivator.log(e);
            return false;
        }

    }

    public static boolean isGrailsClasspathEntry(IClasspathEntry entry) {
        return hasClasspathAttribute(entry, GrailsClasspathContainer.PLUGIN_SOURCEFOLDER_ATTRIBUTE_NAME);
    }

    public static boolean hasClasspathAttribute(IClasspathEntry entry, String attributeName) {
        if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
            for (IClasspathAttribute attr : entry.getExtraAttributes()) {
                if (attr.getName().equals(attributeName)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Certain file folders containing source files are now filtered out as they
     * are represented by reimaged source package fragment roots.
     * <p>
     * This may include folders that are NOT reimaged but have corresponding
     * source class path entries
     * </p>
     * 
     * @param folder
     *            to check if it is a filtered file folder
     * @return true if it is a filtered file folder, false otherwise
     */
    public static boolean isFilteredGrailsFolder(IFolder folder) {
        if (isReimagedGrailsSourceFolder(folder)) {
            // Reimaged source folders are filtered, as
            // there are corresponding package fragment roots for them
            return true;
        } else if (isSourceFolder(folder)) {
            // if there is a source class path entry, it should be filtered out
            return true;
        }
        return false;
    }

    /**
     * A grails folder id is represented by the last two segments in a given
     * folder path.
     * 
     * @param folder
     *            to determine the last 2 folder path segments
     * @return the last two folder path segments
     */
    public static String getGrailsFolderID(IFolder folder) {
        if (folder != null) {
            IProject project = folder.getProject();
            IPath projectLocation = project.getLocation();
            if (projectLocation == null) {
                GrailsCoreActivator.log(new Status(IStatus.WARNING, GrailsCoreActivator.PLUGIN_ID,
                        "Couldn't compute project location for " + project
                                + " in GrailsResourceUtil.getGrailsFolderID"));
            } else {
                IPath folderLocation = folder.getLocation();
                if (folderLocation == null) {
                    GrailsCoreActivator.log(new Status(IStatus.WARNING, GrailsCoreActivator.PLUGIN_ID,
                            "Couldn't compute folder location for " + folder
                                    + " in GrailsResourceUtil.getGrailsFolderID"));
                } else {
                    folderLocation = folderLocation.makeRelativeTo(projectLocation);
                    int segNumber = folderLocation.segmentCount();

                    IPath comparison = (segNumber > 2) ? folderLocation.removeFirstSegments(segNumber - 2)
                            : folderLocation;

                    String segString = comparison.toPortableString();
                    int device = segString.indexOf(IPath.DEVICE_SEPARATOR);
                    if (device >= 0 && device + 1 < segString.length()) {
                        return segString.substring(device + 1);
                    }
                    return segString;
                }
            }
        }
        return null;
    }

    /**
     * Determines if the given folder is a grails project non-source file folder
     * that is reimaged with a new icon and display name.
     * 
     * @param folder
     *            to check if is a reimaged grails file folder
     * @return true if it is a grails file folder, false otherwise
     */
    public static boolean isReimagedGrailsProjectFileFolder(IFolder folder) {
        GrailsProjectStructureTypes type = getGrailsContainerType(folder);
        if (GrailsProjectStructureManager.getInstance().getGrailsFileFolders().contains(type)) {
            return true;
        }
        return false;
    }

    /**
     * Determines if the given source folder is a grails source folder that is
     * reimaged with a different name and icon.
     * 
     * @param folder
     *            to check if it is a reimaged grails source folder
     * @return true if it is a reimaged folder, false otherwise
     */
    public static boolean isReimagedGrailsSourceFolder(IFolder folder) {
        GrailsProjectStructureTypes type = getGrailsContainerType(folder);
        if (GrailsProjectStructureManager.getInstance().getGrailsSourceFolders().contains(type)) {
            return true;
        }
        return false;
    }

    /**
     * Determines if the given package fragment root is a grails source folder
     * that is reimaged with a different name and icon.
     * 
     * @param root
     *            to check if it is a reimaged grails package fragment root
     * @return true if it is a reimaged folder, false otherwise
     */
    public static boolean isReimagedGrailsSourceFolder(IPackageFragmentRoot root) {
        IFolder folder = getFolder(root);
        return isReimagedGrailsSourceFolder(folder);
    }

    /**
     * Converts a grails dependency plugin name containing at least one dash
     * into a path separator. Removes the plugin name and only returns the
     * source package name with separators. <br>
     * Example: <br>
     * input: hibernate-10-src-groovy <br>
     * output: src/groovy
     * 
     * 
     * @param name
     *            containing dashed plugin name to be converted to a OS path
     *            separator
     * @return converted name if it contains dashes, or the original name if it
     *         contains no dashes, or null if original name is null
     */
    public static String convertRootName(String name) {
        if (name == null) {
            return null;
        }

        int lastIndex = name.lastIndexOf('-');
        if (lastIndex < 0) {
            return name;
        }

        while (lastIndex > 0) {
            // find the second to last dash
            if (name.charAt(lastIndex - 1) == '-') {
                break;
            }
            lastIndex--;
        }

        String conversionPortion = name.substring(lastIndex);
        return conversionPortion.replace('-', IPath.SEPARATOR);
    }

    /**
     * Given a folder, which may represent either a file folder, or source
     * folder (package fragment or package fragment root), this will determine
     * if there is a Grails container type definition for it. If so, returns
     * true. False otherwise
     * <p>
     * Typically, a folder that is associated with a Grails container type is a
     * reimaged folder that is shown in the Project Explorer with its own icon
     * and label.
     * </p>
     * 
     * @param folder
     *            to check against a Grails container type
     * @return true if there is an associated type for the folder. False
     *         otherwise.
     */
    public static GrailsProjectStructureTypes getGrailsContainerType(IFolder folder) {
        if (folder == null) {
            return null;
        }
        String id = getGrailsFolderID(folder);
        if (id != null) {
            if (GrailsProjectStructureManager.getInstance().getAllGrailsFolderNames().contains(id)) {
                GrailsProjectStructureTypes[] types = GrailsProjectStructureTypes.values();
                for (GrailsProjectStructureTypes type : types) {
                    if (type.getFolderName().equals(id)) {
                        return type;
                    }
                }
            }
        }

        return null;
    }

    /**
     * Determines if the given folder corresponds to a Java source folder (i.e.
     * there is a source class path entry for it).
     * <p>
     * The folder could be either a package fragment or a package fragment root
     * </p>
     * 
     * @param folder
     *            to check if there is a corresponding source class path entry
     *            for it
     * @return true if there is a corresponding source class path entry for it.
     *         False otherwise.
     */
    public static boolean isSourceFolder(IFolder folder) {
        if (folder == null) {
            return false;
        }
        IJavaElement possiblePackageFragRoot = JavaCore.create(folder);
        if (possiblePackageFragRoot == null) {
            return false;
        }

        if (possiblePackageFragRoot instanceof IPackageFragment) {
            possiblePackageFragRoot = ((IPackageFragment) possiblePackageFragRoot).getParent();
        }

        if (possiblePackageFragRoot instanceof IPackageFragmentRoot) {
            IPackageFragmentRoot root = (IPackageFragmentRoot) possiblePackageFragRoot;
            try {
                if (root.getRawClasspathEntry().getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                    return true;
                }
            } catch (JavaModelException e) {
                GrailsCoreActivator.log(e);
            }
        }
        return false;
    }

    /**
     * Given a package fragment root, this will determine if it has a Grails
     * container type. If so, it most likely is a reimaged root.
     * 
     * @param root
     *            to check for grails container type
     * @return true if it has a type, false otherwise
     */
    public static GrailsProjectStructureTypes getGrailsContainerType(IPackageFragmentRoot root) {
        IFolder folder = getFolder(root);

        if (folder != null) {
            return getGrailsContainerType(folder);
        }

        return null;
    }

    /**
     * Retrieves the corresponding workspace folder for the given root, or null
     * if it cannot be resolved.
     * 
     * @param root
     *            to obtain workspace folder
     * @return workspace folder, or null if it cannot be resolved
     */
    protected static IFolder getFolder(IPackageFragmentRoot root) {
        if (root == null) {
            return null;
        }
        try {
            IResource resource = root.getCorrespondingResource();
            if (resource instanceof IFolder) {
                return (IFolder) resource;
            }
        } catch (JavaModelException e) {
            GrailsCoreActivator.log(e);
        }
        return null;

    }

    /**
     * @return true if the resource is either one of the Grails source folders
     *         containing unit/integration/functional tests.
     */
    public static boolean isTestFolder(IResource resource) {
        IPath path = resource.getProjectRelativePath();
        String[] segments = path.segments();
        if (segments.length == 2) {
            return typeOfTest(resource) != null;
        }
        return false;
    }

    /**
     * Checks whether a given resource is inside the "test" folder.
     * @param resource
     * @return The type of the test (unit/integration/functional) if the resource is inside
     *         the test folder. Return null if the resource is not in the test folder.
     */
    public static String typeOfTest(IResource resource) {
        IPath path = resource.getProjectRelativePath();
        String[] segments = path.segments();
        if (segments.length >= 2 && segments[0].equals("test")) {
            return segments[1];
        }
        return null;
    }

    public static boolean isSourceFile(IResource resource) {
        IJavaElement javaElement = (IJavaElement) resource.getAdapter(IJavaElement.class);
        return javaElement != null && isSourceFile(javaElement);
    }

    public static boolean isSourceFile(IJavaElement javaElement) {
        IPackageFragmentRoot root = (IPackageFragmentRoot) javaElement
                .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
        return root != null && isSourceFolder(root);
    }

    public static boolean isSourceFolder(IPackageFragmentRoot root) {
        IJavaProject jp = root.getJavaProject();
        try {
            IResource rootRsrc = root.getCorrespondingResource();
            if (rootRsrc == null) {
                return false;
            }
            IPath rootPath = rootRsrc.getFullPath();
            for (IClasspathEntry entry : jp.getRawClasspath()) {
                if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                    if (entry.getPath() != null && entry.getPath().equals(rootPath)) {
                        return true;
                    }
                }
            }
        } catch (JavaModelException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * If object is a {@link IResource} or adapatable to {@link IResource} then this returns the corresponding
     * IREsource otjerwise it returns null.
     */
    public static IResource asResource(Object object) {
        if (object instanceof IResource) {
            return (IResource) object;
        } else if (object instanceof IAdaptable) {
            return (IResource) ((IAdaptable) object).getAdapter(IResource.class);
        }
        return null;
    }

    public static boolean isDefaultOutputFolder(IFolder folder) {
        IPath filteredPath = new Path(GrailsCommandUtils.DEFAULT_GRAILS_OUTPUT_FOLDER);
        IPath folderPath = folder.getProjectRelativePath();
        return folderPath.isPrefixOf(filteredPath);
    }

}