blob: 886d69a2278f8723faa9e04a79f67b391c6c3f4e [file] [log] [blame]
/*******************************************************************************
* 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;
}
}