/******************************************************************************* * Copyright (c) 2005, 2010 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 *******************************************************************************/ /* * $$RCSfile: ProjectUtilities.java,v $$ * $$Revision: 1.4 $$ $$Date: 2005/05/11 19:01:24 $$ */ package net.enilink.komma.workbench; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.core.resources.ICommand; 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.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceDescription; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ResourceAttributes; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; 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.core.runtime.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.enilink.komma.model.IModel; import net.enilink.komma.model.IModelSet; import net.enilink.komma.model.IObject; import net.enilink.komma.workbench.internal.KommaWorkbenchPlugin; /** * KOMMA Workbench Project Utilities. * * @since 1.0.0 */ public class ProjectUtilities { private static final Logger log = LoggerFactory .getLogger(ProjectUtilities.class); private ProjectUtilities() { } /** * Add the nature id to the project ahead of all other nature ids. * * @param proj * @param natureId * @throws CoreException * * @since 1.0.0 */ public static void addNatureToProject(IProject proj, String natureId) throws CoreException { IProjectDescription description = proj.getDescription(); String[] prevNatures = description.getNatureIds(); String[] newNatures = new String[prevNatures.length + 1]; System.arraycopy(prevNatures, 0, newNatures, 1, prevNatures.length); newNatures[0] = natureId; description.setNatureIds(newNatures); proj.setDescription(description, null); } /** * Add the nature id after all of the other nature ids for the project. * * @param proj * @param natureId * @throws CoreException * * @since 1.0.0 */ public static void addNatureToProjectLast(IProject proj, String natureId) throws CoreException { IProjectDescription description = proj.getDescription(); String[] prevNatures = description.getNatureIds(); String[] newNatures = new String[prevNatures.length + 1]; System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length); newNatures[prevNatures.length] = natureId; description.setNatureIds(newNatures); proj.setDescription(description, null); } /** * Remove the nature id from the project. * * @param project * @param natureId * @throws CoreException * * @since 1.0.0 */ public static void removeNatureFromProject(IProject project, String natureId) throws CoreException { IProjectDescription description = project.getDescription(); String[] prevNatures = description.getNatureIds(); int size = prevNatures.length; int newsize = 0; String[] newNatures = new String[size]; boolean matchfound = false; for (int i = 0; i < size; i++) { if (prevNatures[i].equals(natureId)) { matchfound = true; continue; } else newNatures[newsize++] = prevNatures[i]; } if (!matchfound) throw new CoreException( new Status( IStatus.ERROR, KommaWorkbenchPlugin.PLUGIN_ID, 0, "The nature id " + natureId + " does not exist on the project " + project.getName(), null)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ else { String[] temp = newNatures; newNatures = new String[newsize]; System.arraycopy(temp, 0, newNatures, 0, newsize); description.setNatureIds(newNatures); project.setDescription(description, null); } } /** * Add the list of projects to end of the "referenced projects" list from * the project's description. * * @param project * @param toBeAddedProjectsList * @throws CoreException * * @since 1.0.0 */ public static void addReferenceProjects(IProject project, List<IProject> toBeAddedProjectsList) throws CoreException { IProjectDescription description = project.getDescription(); IProject[] projects = description.getReferencedProjects(); List<IProject> projectsList = new ArrayList<IProject>( Arrays.asList(projects)); projectsList.addAll(toBeAddedProjectsList); description.setReferencedProjects(projectsList .toArray(new IProject[projectsList.size()])); project.setDescription(description, null); } /** * Add the single project to the end of the "referenced projects" list from * the project's description. * * @param project * @param projectToBeAdded * @throws CoreException * * @since 1.0.0 */ public static void addReferenceProjects(IProject project, IProject projectToBeAdded) throws CoreException { IProjectDescription description = project.getDescription(); IProject[] projects = description.getReferencedProjects(); List<IProject> projectsList = new ArrayList<IProject>( Arrays.asList(projects)); projectsList.add(projectToBeAdded); description.setReferencedProjects(projectsList .toArray(new IProject[projectsList.size()])); project.setDescription(description, null); } /** * Force a an immediate build of the project. * * @param project * @param progressMonitor * * @since 1.0.0 */ public static void forceAutoBuild(IProject project, IProgressMonitor progressMonitor) { try { project.build(IncrementalProjectBuilder.FULL_BUILD, progressMonitor); } catch (CoreException ce) { log.error("Building project failed", ce); } } /** * Return if auto build is turned on. * * @return <code>true</code> if auto build is turned on. * * @since 1.0.0 */ public static boolean getCurrentAutoBuildSetting() { IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceDescription wd = workspace.getDescription(); return wd.isAutoBuilding(); } /** * Get the project associated with the given object. * * @param object * may be an * * <code>IProject, IResource, IAdaptable (to an IProject), EObject (gets IProject if object is in a ProjectResourceSet</code> * . * @param natureId * if <code>null</code> then returns project. If not * <code>null</code> then returns project only if project has * this nature id. * @return project associated with the object or <code>null</code> if not * found. * * @since 1.0.0 */ public static IProject getProject(Object object, String natureId) { IProject result = getProject(object); if (natureId == null) return result; if (result != null && result.isAccessible() && natureId != null) try { if (result.hasNature(natureId)) { return result; } } catch (CoreException e) { log.error("Determining project nature failed", e); } return null; } /** * Get the project associated with the given object. * * @param object * may be an * * <code>IProject, IResource, IAdaptable (to an IProject), EObject (gets IProject if object is in a ProjectResourceSet</code> * . * @return project associated with the object or <code>null</code> if not * found. * * @since 1.0.0 */ public static IProject getProject(Object object) { IProject result = null; if (object instanceof IProject) result = (IProject) object; else if (object instanceof IResource) result = ((IResource) object).getProject(); else if (object instanceof IAdaptable) result = (IProject) ((IAdaptable) object) .getAdapter(IProject.class); else if (object instanceof IObject) result = getProject((IObject) object); return result; } /** * Get the project associated with the given EObject. (If in a * ProjectResourceSet, then the project from that resource set). * * @param aRefObject * @return project if associated or <code>null</code> if not found. * * @since 1.0.0 */ public static IProject getProject(IObject aRefObject) { if (aRefObject != null) { IModel model = aRefObject.getModel(); return getProject(model); } return null; } /** * Get the project associated with the given Resource. (If in a * ProjectResourceSet, then the project from that resource set). * * @param resource * @return project if associated or <code>null</code> if not found. * * @since 1.0.0 */ public static IProject getProject(IModel model) { IModelSet set = model == null ? null : model.getModelSet(); if (set instanceof IProjectModelSet) { return ((IProjectModelSet) set).getProject(); } return null; } /** * Remove the list of projects from the list of "referenced projects" in the * project's description. * * @param project * @param toBeRemovedProjectList * @throws org.eclipse.core.runtime.CoreException * * @since 1.0.0 */ public static void removeReferenceProjects(IProject project, List<IProject> toBeRemovedProjectList) throws org.eclipse.core.runtime.CoreException { IProjectDescription description = project.getDescription(); IProject[] projects = description.getReferencedProjects(); List<IProject> projectsList = new ArrayList<IProject>( Arrays.asList(projects)); projectsList.removeAll(toBeRemovedProjectList); description.setReferencedProjects(projectsList .toArray(new IProject[projectsList.size()])); project.setDescription(description, null); } /** * Remove the project from the list of "referenced projects" in the * description for the given project. * * @param project * @param toBeRemovedProject * @throws org.eclipse.core.runtime.CoreException * * @since 1.0.0 */ public static void removeReferenceProjects(IProject project, IProject toBeRemovedProject) throws org.eclipse.core.runtime.CoreException { IProjectDescription description = project.getDescription(); IProject[] projects = description.getReferencedProjects(); List<IProject> projectsList = new ArrayList<IProject>( Arrays.asList(projects)); projectsList.remove(toBeRemovedProject); description.setReferencedProjects(projectsList .toArray(new IProject[projectsList.size()])); project.setDescription(description, null); } /** * Set the auto-building state. * * @param aBoolean * <code>true</code> to turn auto-building on. * * @since 1.0.0 */ public static void turnAutoBuildOn(boolean aBoolean) { try { IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceDescription wd = workspace.getDescription(); wd.setAutoBuilding(aBoolean); workspace.setDescription(wd); } catch (CoreException ce) { log.error("Failed to change auto build state", ce); } } /** * Adds a builder to the build spec for the given project. * * @param builderID * The id of the builder. * @param project * Project to add to. * @return whether the builder id was actually added (it may have already * existed) * @throws CoreException * @since 1.0.0 */ public static boolean addToBuildSpec(String builderID, IProject project) throws CoreException { return addToBuildSpecBefore(builderID, null, project); } /** * Adds a builder to the build spec for the given project, immediately * before the specified successor builder. * * @param builderID * The id of the builder. * @param successorID * The id to put the builder before. * @return whether the builder id was actually added (it may have already * existed) * @throws CoreException * @since 1.0.0 */ public static boolean addToBuildSpecBefore(String builderID, String successorID, IProject project) throws CoreException { IProjectDescription description = project.getDescription(); ICommand[] commands = description.getBuildSpec(); boolean found = false; for (int i = 0; i < commands.length; ++i) { if (commands[i].getBuilderName().equals(builderID)) { found = true; break; } } if (!found) { boolean successorFound = false; ICommand command = description.newCommand(); command.setBuilderName(builderID); ICommand[] newCommands = new ICommand[commands.length + 1]; for (int j = 0, index = 0; j < commands.length; j++, index++) { if (successorID != null && commands[j].getBuilderName().equals(successorID)) { successorFound = true; newCommands[index++] = command; } newCommands[index] = commands[j]; } if (!successorFound) newCommands[newCommands.length - 1] = command; description.setBuildSpec(newCommands); project.setDescription(description, null); } return !found; } /** * Remove the builder from the build spec. * * @param builderID * The id of the builder. * @param project * Project to remove from. * @return boolean if the builder id was found and removed * @throws CoreException * @since 1.0.0 */ public static boolean removeFromBuildSpec(String builderID, IProject project) throws CoreException { IProjectDescription description = project.getDescription(); ICommand[] commands = description.getBuildSpec(); boolean found = false; for (int i = 0; i < commands.length; ++i) { if (commands[i].getBuilderName().equals(builderID)) { found = true; break; } } if (found) { ICommand[] newCommands = new ICommand[commands.length - 1]; int newCount = 0; for (int i = 0; i < commands.length; ++i) { if (!(commands[i].getBuilderName().equals(builderID))) { // Add the existng to the new array newCommands[newCount] = commands[i]; newCount++; } } description.setBuildSpec(newCommands); project.setDescription(description, null); } return found; } /** * Ensure the container is not read-only. * <p> * For Linux, a Resource cannot be created in a ReadOnly folder. This is * only necessary for new files. * * @param resource * workspace resource to make read/write * @since 1.0.0 */ public static void ensureContainerNotReadOnly(IResource resource) { if (resource != null && !resource.exists()) { // it must be new IContainer container = resource.getParent(); ResourceAttributes attr = container.getResourceAttributes(); while (attr != null && !attr.isReadOnly()) { container = container.getParent(); if (container == null) break; attr = container.getResourceAttributes(); } if (container != null && attr != null) attr.setReadOnly(false); } } /** * Get projects from primary nature. * * @param natureID * @return All projects that have the given nature id as the first nature * id. * * @since 1.0.0 */ public static IProject[] getProjectsForPrimaryNature(String natureID) { IProject[] projectsWithNature = new IProject[] {}; List<IProject> result = new ArrayList<IProject>(); IProject[] projects = getAllProjects(); for (int i = 0; i < projects.length; i++) { if (isProjectPrimaryNature(projects[i], natureID)) result.add(projects[i]); } return result.toArray(projectsWithNature); } /** * Get all projects in the workspace * * @return all workspace projects * * @since 1.0.0 */ public static IProject[] getAllProjects() { return ResourcesPlugin.getWorkspace().getRoot().getProjects(); } /** * Is this nature id the primary nature id for the project * * @param project * @param natureID * @return <code>true</code> if first nature id for the project. * * @since 1.0.0 */ public static boolean isProjectPrimaryNature(IProject project, String natureID) { String[] natures = null; try { natures = project.getDescription().getNatureIds(); } catch (Exception e1) { } return (natures != null && natures.length > 0 && natures[0] .equals(natureID)); } protected static IPath createPath(IProject p, String defaultSourceName) { IPath path = new Path(p.getName()); path = path.append(defaultSourceName); path = path.makeAbsolute(); return path; } /** * Strip off a leading "/" from each project name in the array, if it has * one. * * @param projecNames * @return array of project names with all leading '/' removed. * * @since 1.0.0 */ public static String[] getProjectNamesWithoutForwardSlash( String[] projecNames) { String[] projNames = new String[projecNames.length]; List<String> temp = java.util.Arrays.asList(projecNames); for (int i = 0; i < temp.size(); i++) { String name = (temp.get(i)); if (name.startsWith("/")) { //$NON-NLS-1$ projNames[i] = name.substring(1, name.length()); } else { projNames[i] = name; } } return projNames; } /** * List of all files in the project. * <p> * Note: A more efficient way to do this is to use * {@link IResource#accept(org.eclipse.core.resources.IResourceProxyVisitor, int)} * * @param 1.0.0 * @return list of files in the project * * @see IResource#accept(org.eclipse.core.resources.IResourceProxyVisitor, * int) * @since 1.0.0 */ public static List<IResource> getAllProjectFiles(IProject project) { List<IResource> result = new ArrayList<IResource>(); if (project == null) return result; try { result = collectFiles(project.members(), result); } catch (CoreException e) { } return result; } private static List<IResource> collectFiles(IResource[] members, List<IResource> result) throws CoreException { // recursively collect files for the given members for (int i = 0; i < members.length; i++) { IResource res = members[i]; if (res instanceof IFolder) { collectFiles(((IFolder) res).members(), result); } else if (res instanceof IFile) { result.add(res); } } return result; } /** * Get the project. * * @param projectName * @return a IProject given the projectName * @since 1.0.0 */ public static IProject getProject(String projectName) { return ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); } /** * Return whether the given builder name is attached to the project. * * @param project * @param builderName * @return <code>true</code> if builder name is attached to the project. * * @since 1.0.0 */ public static boolean hasBuilder(IProject project, String builderName) { try { ICommand[] builders = project.getDescription().getBuildSpec(); for (int i = 0; i < builders.length; i++) { ICommand builder = builders[i]; if (builder != null) { if (builder.getBuilderName().equals(builderName)) return true; } } } catch (Exception e) { } return false; } }