/***************************************************************************** * Copyright (c) 2008 g-Eclipse Consortium * 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 * * Initial development of the original code was made for the * g-Eclipse project founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributors: * Mathias Stuempert - initial API and implementation *****************************************************************************/ package eu.geclipse.core.project; import java.util.Hashtable; 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.IWorkspaceRoot; import org.eclipse.core.resources.ProjectScope; 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.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.preferences.IScopeContext; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; import eu.geclipse.core.internal.Activator; import eu.geclipse.core.model.IVirtualOrganization; import eu.geclipse.core.reporting.ProblemException; /** * An operation that is used to create a grid project in the workspace. */ public class GridProjectCreationOperation { /** * The properties from which to create the project. */ private GridProjectProperties properties; /** * The resulting {@link IProject}. */ private IProject gridProject; /** * Create a new {@link GridProjectCreationOperation} that will create a * project from the specified properties. * * @param properties The properties of the newly created grid project. */ public GridProjectCreationOperation( final GridProjectProperties properties ) { this.properties = properties; this.gridProject = null; } /** * Create the grid project according to the {@link GridProjectProperties} of * this operation. * * @param monitor A progress monitor used to monitor the progress of this * operation. * @throws ProblemException If the creation of the project fails. */ public void run( final IProgressMonitor monitor ) throws ProblemException { monitor.beginTask( Messages.getString("GridProjectCreationOperation.create_progress"), 300 ); //$NON-NLS-1$ try { IProject proj = createProject( this.properties, monitor ); addProjectNature( proj, monitor ); this.gridProject = proj; } catch ( CoreException cExc ) { throw new ProblemException( cExc.getStatus() ); } finally { monitor.done(); } } /** * Get the resulting {@link IProject}. In case the operation's * {@link #run(IProgressMonitor)}-metod was not yet called or failed this * will return <code>null</code>. * * @return The {@link IProject} corresponding to the created grid project. */ public IProject getProject() { return this.gridProject; } /** * Create the project in the workspace and apply the specified project * properties. * * @param props The properties of the newly created project. * @param monitor A monitor used to monitor the progress of the creation * operation. * @return The resulting {@link IProject}. * @throws CoreException If the project creation fails. */ private IProject createProject( final GridProjectProperties props, final IProgressMonitor monitor ) throws CoreException { monitor.subTask( Messages.getString("GridProjectCreationOperation.init_progress") ); //$NON-NLS-1$ String projectName = props.getProjectName(); IPath projectPath = props.getProjectLocation(); IProject[] referencesProjects = props.getReferencesProjects(); IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); IProject project = workspaceRoot.getProject( projectName ); IStatus status = ResourcesPlugin.getWorkspace().validateProjectLocation( project, projectPath ); if ( status.getSeverity() != IStatus.OK ) { throw new CoreException( status ); } IProjectDescription desc = project.getWorkspace().newProjectDescription( projectName ); desc.setLocation( projectPath ); if ( referencesProjects != null ) { desc.setReferencedProjects( referencesProjects ); } project.create( desc, new SubProgressMonitor( monitor, 50 ) ); project.open( new SubProgressMonitor( monitor, 50 ) ); createProjectStructure( project, props ); setProjectProperties( project, props ); if ( monitor.isCanceled() ) { throw new OperationCanceledException(); } return project; } /** * Add the grid project nature to the specified project. * * @param proj The project to which the nature should be added. * @param monitor A monitor used to monitor the progress. * @throws CoreException If an error occurs. */ private void addProjectNature( final IProject proj, final IProgressMonitor monitor ) throws CoreException { monitor.subTask( Messages.getString("GridProjectCreationOperation.add_nature_progress") ); //$NON-NLS-1$ IProjectDescription desc = proj.getDescription(); String[] natureIDs = desc.getNatureIds(); String gridNatureID = GridProjectNature.getID(); boolean found = false; for ( int i = 0 ; ( i < natureIDs.length ) && ( !found ) ; i++ ) { if ( natureIDs[i].equals( gridNatureID ) ) { found = true; } } if ( !found ) { String[] newNatureIDs = new String[ natureIDs.length +1 ]; System.arraycopy( natureIDs, 0, newNatureIDs, 1, natureIDs.length ); newNatureIDs[0] = gridNatureID; desc.setNatureIds( newNatureIDs ); proj.setDescription( desc, new SubProgressMonitor( monitor, 100 ) ); } if ( monitor.isCanceled() ) { throw new OperationCanceledException(); } } /** * Create a project folder with the specified name in the specified project. * * @param project The project for which to create a project folder. * @param name The name of the newly created project folder. * @throws CoreException If the creation of the project folder fails. */ private void createProjectFolder( final IProject project, final String name ) throws CoreException { if ( ( name != null ) && ( name.length() != 0 ) ) { IFolder folder = project.getFolder( new Path( name ) ); if ( !folder.exists() ) { folder.create( IResource.FORCE, true, null ); } } } /** * Create the project structure, i.e. the project folders according to the * specified project properties. * * @param project The project for which to create the structure. * @param props The project properties containing the folder specifications. * @throws CoreException If the creation of the project structure fails. */ private void createProjectStructure( final IProject project, final GridProjectProperties props ) throws CoreException { Hashtable< String, String > projectFolders = props.getProjectFolders(); for ( String label : projectFolders.values() ) { createProjectFolder( project, label ); } } /** * Sets the projects properties, i.e. the VO and the project folders. * * @param project The project for which to set the properties. * @param props The project properties containing the VO name and the project * folder specifications. * @throws CoreException If the project properties setting fails. */ private void setProjectProperties( final IProject project, final GridProjectProperties props ) throws CoreException { IVirtualOrganization projectVo = props.getProjectVo(); String voName = projectVo.getName(); Hashtable< String, String > folders = props.getProjectFolders(); IScopeContext projectScope = new ProjectScope( project ); try { Preferences projectNode = projectScope.getNode( "eu.geclipse.core" ); //$NON-NLS-1$ projectNode.put( "vo", voName ); //$NON-NLS-1$ projectNode.flush(); Preferences folderNode = projectScope.getNode( "eu.geclipse.core.folders" ); //$NON-NLS-1$ for ( String id : folders.keySet() ) { String label = folders.get( id ); folderNode.put( id, label ); } folderNode.flush(); } catch( BackingStoreException bsExc ) { IStatus status = new Status( IStatus.ERROR, Activator.PLUGIN_ID, IStatus.CANCEL, Messages.getString("GridProjectCreationOperation.preference_failure"), //$NON-NLS-1$ bsExc ); throw new CoreException( status ); } } }