/****************************************************************************** * Copyright (c) 2006-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 * project g-Eclipse founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributor(s): * Pawel Wolniewicz - PSNC * Harald Kornmayer - NEC * David Johnson - ACET *****************************************************************************/ package eu.geclipse.ui.wizards.jobsubmission; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExecutableExtension; 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.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.wizard.Wizard; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; import eu.geclipse.core.model.GridModel; import eu.geclipse.core.model.IGridContainer; import eu.geclipse.core.model.IGridJob; import eu.geclipse.core.model.IGridJobCreator; import eu.geclipse.core.model.IGridJobDescription; import eu.geclipse.core.model.IGridJobID; import eu.geclipse.core.model.IGridJobService; import eu.geclipse.core.model.IGridProject; import eu.geclipse.core.reporting.IProblem; import eu.geclipse.core.reporting.ISolution; import eu.geclipse.core.reporting.ProblemException; import eu.geclipse.ui.dialogs.ProblemDialog; import eu.geclipse.ui.internal.Activator; import eu.geclipse.ui.wizards.wizardselection.IInitializableWizard; /** * Base class for submission wizard */ public abstract class JobSubmissionWizardBase extends Wizard implements IInitializableWizard, IExecutableExtension { protected IGridJobCreator creator; protected List<IGridJobDescription> jobDescriptions; ArrayList<String> jobNames; WrapperInitObject initObject; protected JobSubmissionWizardBase() { setNeedsProgressMonitor( true ); } /* * This it the routine were the sub-submission is started. (non-Javadoc) * * @see org.eclipse.jface.wizard.Wizard#performFinish() */ @Override public boolean performFinish() { { Job job = new JobSubmissionJob(); job.setUser( true ); Shell shell = getWizardShell(); if( shell != null ) { shell.setVisible( false ); } job.schedule(); // start as soon as possible return false; } } /** * Method called when wizard is finished, and job should be submitted * Submission service is then asked to submit job using submitJob method * * @return */ protected abstract IGridJobService getSubmissionService(); IGridContainer buildPath( final IGridJobDescription description ) throws CoreException { IGridContainer result = null; IGridProject project = description.getProject(); IPath projectPath = project.getPath(); IGridContainer jobFolder = project.getProjectFolder( IGridJob.class ); IPath jobFolderPath = jobFolder.getPath(); if( jobFolderPath.equals( projectPath ) ) { result = project; } else { IPath descriptionPath = description.getPath().removeLastSegments( 1 ); IGridContainer descriptionFolder = project.getProjectFolder( IGridJobDescription.class ); IPath descriptionFolderPath = descriptionFolder.getPath(); if( descriptionFolderPath.isPrefixOf( descriptionPath ) ) { int matchingFirstSegments = descriptionPath.matchingFirstSegments( descriptionFolderPath ); IPath appendedPath = descriptionPath.removeFirstSegments( matchingFirstSegments ); jobFolderPath = jobFolderPath.append( appendedPath ); IWorkspaceRoot workspaceRoot = ( IWorkspaceRoot ) GridModel.getRoot().getResource(); IFolder folder = workspaceRoot.getFolder( jobFolderPath ); createFolder( folder ); result = ( IGridContainer )GridModel.getRoot().findElement( folder ); } else { result = jobFolder; } } return result; } void createFolder( final IContainer folder ) throws CoreException { IContainer parent = folder.getParent(); if( ( parent != null ) && ( parent instanceof IFolder ) ) { createFolder( parent ); } if( !( folder.exists() ) && ( folder instanceof IFolder ) ) { ( ( IFolder )folder ).create( true, true, null ); } } /* * (non-Javadoc) * * @see eu.geclipse.ui.wizards.wizardselection.IInitializableWizard#init(java.lang.Object) */ @SuppressWarnings("unchecked") public boolean init( final Object data ) { boolean result = false; if( data instanceof WrapperInitObject ) { this.initObject = ( WrapperInitObject )data; this.jobDescriptions = new ArrayList<IGridJobDescription>( this.initObject.getJobDescriptions() ); this.jobNames = new ArrayList<String>( this.initObject.getJobNames() ); result = true; } return result; } public void setInitializationData( final IConfigurationElement config, final String propertyName, final Object data ) throws CoreException { IConfigurationElement[] elements = config.getDeclaringExtension() .getConfigurationElements(); for( IConfigurationElement element : elements ) { if( "job_creator".equals( element.getName() ) ) { //$NON-NLS-1$ Object obj = element.createExecutableExtension( "class" ); //$NON-NLS-1$ if( !( obj instanceof IGridJobCreator ) ) { String errorMessage = "Job Creator configured in class atribute for job_creator " //$NON-NLS-1$ + "element in eu.geclipse.ou.jobSubmissionWizzard " //$NON-NLS-1$ + "is not implementing IGridJobCreator interface"; //$NON-NLS-1$ Status status = new Status( IStatus.ERROR, Activator.PLUGIN_ID, IStatus.OK, errorMessage, null ); throw new CoreException( status ); } this.creator = ( IGridJobCreator )obj; } } } private class JobSubmissionJob extends Job { // create the service for the job submission final IGridJobService service = getSubmissionService(); JobSubmissionJob() { super( Messages.getString( "JobSubmissionWizardBase.jobName" ) ); //$NON-NLS-1$ } /** * the run method for the Background job create the JobSubmissionWizard and * call the service */ @Override protected IStatus run( final IProgressMonitor monitor ) { boolean closeWizard = true; SubMonitor betterMonitor = SubMonitor.convert( monitor, JobSubmissionWizardBase.this.jobDescriptions.size() ); try { /* * we loop over all selected jobs in the workspace yes, we can submit * more than one job at a time */ Iterator<IGridJobDescription> iterator = JobSubmissionWizardBase.this.jobDescriptions.iterator(); Iterator<String> namesIterator = JobSubmissionWizardBase.this.jobNames.iterator(); while( iterator.hasNext() ) { testCancelled( betterMonitor ); IGridJobDescription description = iterator.next(); betterMonitor.setTaskName( String.format( Messages.getString( "JobSubmissionWizardBase.taskNameSubmitting" ), description.getName() ) ); //$NON-NLS-1$ if( JobSubmissionWizardBase.this.creator.canCreate( description ) ) { IGridContainer parent = buildTargetFolder( description, JobSubmissionWizardBase.this.initObject.getDestinationFolder() ); IGridJobID jobId = null; if( this.service != null ) { jobId = this.service.submitJob( description, betterMonitor.newChild( 1 ) ); } testCancelled( betterMonitor ); JobSubmissionWizardBase.this.creator.create( parent, jobId, service, namesIterator.next() ); // don't submit this job again during again submission after error iterator.remove(); namesIterator.remove(); } } } catch( ProblemException pExc ) { showProblem( pExc ); closeWizard = false; } catch( CoreException cExc ) { showProblem( cExc ); closeWizard = false; } finally { betterMonitor.done(); } if( closeWizard ) { closeWizard(); } return Status.OK_STATUS; } private IGridContainer buildTargetFolder( final IGridJobDescription description, final IResource folder ) throws CoreException { IResource targetFolder = folder; IContainer targetBuildFolder = null; IGridProject project = description.getProject(); IPath descriptionPath = description.getPath().removeLastSegments( 1 ); IPath descriptionFolderPath = project.getProjectFolder( IGridJobDescription.class ) .getPath(); // if jsdl is in subfolder of JsdlContainer, then build that subfolder // structure also in JobContainer if( descriptionFolderPath.isPrefixOf( descriptionPath ) && folder.getFullPath() .equals( project.getProjectFolder( IGridJob.class ).getPath() ) ) { int matchingFirstSegments = descriptionPath.matchingFirstSegments( descriptionFolderPath ); IPath appendedPath = descriptionPath.removeFirstSegments( matchingFirstSegments ); IWorkspaceRoot workspaceRoot = ( IWorkspaceRoot )GridModel.getRoot() .getResource(); // if (workspaceRoot.findContainersForLocation( // targetFolder.getFullPath().append( appendedPath ) )); if( targetFolder instanceof IProject && appendedPath.toString().equals( "" ) ) { targetBuildFolder = ( IContainer )targetFolder; } else { targetBuildFolder = workspaceRoot.getFolder( targetFolder.getFullPath() .append( appendedPath ) ); } createFolder( targetBuildFolder ); } if( targetBuildFolder == null ) { targetBuildFolder = ( IContainer )targetFolder; } return ( IGridContainer )GridModel.getRoot() .findElement( targetBuildFolder ); } private void testCancelled( final IProgressMonitor monitor ) { if( monitor.isCanceled() ) { throw new OperationCanceledException(); } } void closeWizard() { IWorkbench workbench = PlatformUI.getWorkbench(); Display display = workbench.getDisplay(); display.asyncExec( new Runnable() { public void run() { WizardDialog dialog = ( WizardDialog )getContainer(); dialog.close(); } } ); } private void showProblem( final Throwable exc ) { IWorkbench workbench = PlatformUI.getWorkbench(); Display display = workbench.getDisplay(); display.asyncExec( new Runnable() { public void run() { addShowWizardSolution( exc ); ProblemDialog.openProblem( getShell(), Messages.getString( "JobSubmissionWizardBase.errSubmissionFailed" ), //$NON-NLS-1$ null, exc ); // if "show wizard" action wasn't called, we can definitely close the // wizard if( !JobSubmissionWizardBase.this.getContainer() .getShell() .isVisible() ) { JobSubmissionWizardBase.this.getContainer().getShell().close(); } } } ); } } private Shell getWizardShell() { Shell shell = null; if( getContainer() != null ) { shell = getContainer().getShell(); } return shell; } protected void addShowWizardSolution( final Throwable exc ) { if( exc instanceof ProblemException ) { ProblemException problemExc = ( ProblemException )exc; IProblem problem = problemExc.getProblem(); problem.addSolution( new ISolution() { public String getDescription() { return Messages.getString( "JobSubmissionWizardBase.solutionOpenWizard" ); //$NON-NLS-1$ } public String getID() { return null; } public boolean isActive() { return true; } public void solve() throws InvocationTargetException { JobSubmissionWizardBase.this.getContainer() .getShell() .setVisible( true ); } } ); } } }