| /******************************************************************************* |
| * Copyright (c) 2016 ALL4TEC & CEA LIST. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * ALL4TEC & CEA LIST - initial API and implementation |
| ******************************************************************************/ |
| package org.polarsys.esf.core.common.metamodel.project; |
| |
| import java.io.File; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IProjectDescription; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.polarsys.esf.core.common.file.FileTools; |
| import org.polarsys.esf.core.common.metamodel.CommonMetamodelActivator; |
| |
| /** |
| * Utility class which centralise the methods to create a |
| * project and its content like the model and representation files. |
| * |
| * @author $Author: jdumont $ |
| * @version $Revision: 90 $ |
| */ |
| public final class ProjectCreator { |
| |
| /** |
| * Default constructor. |
| */ |
| private ProjectCreator() { |
| } |
| |
| /** |
| * Create a new project in the workspace. |
| * |
| * @param pProjectName Name of project to create |
| * @return {@link IProject} created |
| * @throws CoreException Exception thrown if problems occurs when creating project |
| */ |
| public static IProject createProject(final String pProjectName) throws CoreException { |
| // Create a new project in the workspace |
| return createProject(pProjectName, null, new NullProgressMonitor()); |
| } |
| |
| /** |
| * Create a new project, with the given name. |
| * |
| * The project is created as the specified location, or in the workspace if a null |
| * location is given. |
| * |
| * @param pProjectName Name of project to create |
| * @param pProjectLocationURI The location where the project must be created. |
| * If a null location is given, create the project in the workspace |
| * @param pMonitor Monitor to reporting creation |
| * @return {@link IProject} created |
| * @throws CoreException Exception thrown if problems occurs when creating project |
| */ |
| public static IProject createProject( |
| final String pProjectName, |
| final java.net.URI pProjectLocationURI, |
| final IProgressMonitor pMonitor) throws CoreException { |
| |
| // Get workspace |
| IWorkspaceRoot vWorkspace = ResourcesPlugin.getWorkspace().getRoot(); |
| |
| // Escape all the potential non alpha numeric characters and add |
| // a suffix if needed to use a unique name |
| String vProjectName = getValidProjectName(pProjectName, vWorkspace, pProjectLocationURI); |
| |
| // Warn the user if the project name has been changed |
| if (!pProjectName.equals(vProjectName)) { |
| CommonMetamodelActivator.logInfo( |
| "The project name has been modified to " + vProjectName //$NON-NLS-1$ |
| + " to ensure its uniquess and validity", //$NON-NLS-1$ |
| null); |
| } |
| |
| // Prepare the project handler |
| IProject vProject = vWorkspace.getProject(vProjectName); |
| |
| // Create the project description and set its location to specify where the project |
| // must be created on the file system |
| final IProjectDescription vProjectDescription = |
| ResourcesPlugin.getWorkspace().newProjectDescription(vProject.getName()); |
| vProjectDescription.setLocationURI(pProjectLocationURI); |
| |
| // Create the project |
| vProject.create(vProjectDescription, pMonitor); |
| |
| // Open project |
| vProject.open(pMonitor); |
| |
| // Associate ESF nature to created project |
| addESFProjectNature(pMonitor, vProject); |
| |
| return vProject; |
| } |
| |
| /** |
| * Associate ESF nature to a project conserving other project natures. |
| * |
| * @param pMonitor Monitor to display execution progress |
| * @param pProject Project to associate ESF nature |
| */ |
| public static void addESFProjectNature(final IProgressMonitor pMonitor, final IProject pProject) { |
| |
| try { |
| // Get existing descriptions from projects |
| IProjectDescription vDescription = pProject.getDescription(); |
| |
| // Get existing natures from project |
| String[] vNatures = vDescription.getNatureIds(); |
| String[] vNewNatures = new String[vNatures.length + 1]; |
| System.arraycopy(vNatures, 0, vNewNatures, 0, vNatures.length); |
| |
| // Add ESF nature to other and set theirs in project description |
| vNewNatures[vNatures.length] = "org.polarsys.esf.project.nature"; //$NON-NLS-1$ |
| vDescription.setNatureIds(vNewNatures); |
| |
| // Set modified description |
| pProject.setDescription(vDescription, pMonitor); |
| |
| } catch (final CoreException pException) { |
| CommonMetamodelActivator.logError( |
| CommonMetamodelActivator.getMessages().getString( |
| "ProjectCreator.project.nature.error", //$NON-NLS-1$ |
| new String[] {pProject.getName()}), |
| pException); |
| } |
| } |
| |
| /** |
| * Get a valid and unique project name from the candidate name given in parameter. |
| * All the non alpha numeric characters will be filtered, and a suffix may be added if needed. |
| * The project name must be unique in the workspace and must also not correspond to an existing file or |
| * folder at the same location. |
| * |
| * @param pProjectName Project name used as candidate |
| * @param pWorkspace Workspace where project is added |
| * @param pProjectLocation The location where the project will be created, or null to use the default location |
| * @return A valid project name which doesn't exist in workspace and which is not used |
| * by a file or folder at the same location |
| */ |
| private static String getValidProjectName( |
| final String pProjectName, |
| final IWorkspaceRoot pWorkspace, |
| final java.net.URI pProjectLocation) { |
| |
| // First escape any non alpha numeric characters to get the correct base name |
| final String vCorrectedName = FileTools.getCorrectName(pProjectName); |
| |
| // Get the location where the project will be created |
| // It can be a custom location, or the workspace root by default |
| IPath vProjectLocationPath = null; |
| if (pProjectLocation != null) { |
| vProjectLocationPath = new Path(pProjectLocation.getPath()); |
| } else { |
| vProjectLocationPath = pWorkspace.getLocation(); |
| } |
| |
| // Initialise the final valid project name |
| String vFinalName = vCorrectedName; |
| |
| // Initialise the flag specifying if the name is already used or not |
| boolean vNameAvailable = false; |
| |
| int vSuffix = 1; |
| |
| // As long as a free project name has not been found, index it. |
| // Risk of out of range exists but is really low, so set a limit to 1000 |
| while (!vNameAvailable && vSuffix < 1000) { |
| |
| // Build the path of the project, with the current candidate name |
| IPath vProjectPath = vProjectLocationPath.append(vFinalName); |
| |
| // Create a java File corresponding to this path and ensure that |
| // it doesn't correspond to an existing file or folder |
| File vProjectFolder = new File(vProjectPath.toOSString()); |
| |
| // Then check that the current name is not already used by a file or folder at this location, |
| // and that there is not another project in the workspace with the same name |
| vNameAvailable = !vProjectFolder.exists() && !pWorkspace.getProject(vFinalName).exists(); |
| |
| // Finally, prepare the next iteration if the name is not available |
| if (!vNameAvailable) { |
| // Add a suffix to the corrected base to try a new final name on next iteration |
| vFinalName = vCorrectedName + vSuffix; |
| vSuffix++; |
| } |
| } |
| |
| return vFinalName; |
| } |
| } |