/******************************************************************************
* 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
* project g-Eclipse founded by European Union
* project number: FP6-IST-034327 http://www.geclipse.eu/
*
* Contributor(s):
* PSNC:
* - Katarzyna Bylec (katis@man.poznan.pl)
* - Pawel Wolniewicz
*
*****************************************************************************/
package eu.geclipse.ui.wizards.jobsubmission;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
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.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.resource.ImageDescriptor;
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.IEditorDescriptor;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import eu.geclipse.core.jobs.GridJob;
import eu.geclipse.core.jobs.GridJobCreator;
import eu.geclipse.core.jobs.ParametricJobService;
import eu.geclipse.core.model.GridModel;
import eu.geclipse.core.model.IGridContainer;
import eu.geclipse.core.model.IGridJob;
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.jsdl.JSDLJobDescription;
import eu.geclipse.ui.dialogs.ProblemDialog;
import eu.geclipse.ui.internal.Activator;
public class JobCreatorSelectionWizard extends Wizard {
protected List<IGridJobDescription> jobDescriptions;
private List<IGridJobService> jobServices;
private JobServiceSelectionWizardPage selectionPage;
private FolderSelectionWizardPage folderSelection;
public JobCreatorSelectionWizard( final List<IGridJobDescription> jobDescriptions )
{
this.jobDescriptions = new ArrayList<IGridJobDescription>( jobDescriptions );
setNeedsProgressMonitor( true );
setForcePreviousAndNextButtons( true );
setWindowTitle( Messages.getString( "JobCreatorSelectionWizard.title" ) ); //$NON-NLS-1$
URL imgUrl = Activator.getDefault()
.getBundle()
.getEntry( "icons/wizban/jobsubmit_wiz.gif" ); //$NON-NLS-1$
setDefaultPageImageDescriptor( ImageDescriptor.createFromURL( imgUrl ) );
}
public IResource getDestinationFolder() {
return this.folderSelection.getDestinationFolder();
}
public IGridJobService getSubmissionService() {
return this.selectionPage.getSubmissionService();
}
@Override
public void addPages() {
this.folderSelection = new FolderSelectionWizardPage( "name",
this.jobDescriptions.get( 0 )
.getProject(),
this.jobDescriptions );
addPage( this.folderSelection );
this.selectionPage = new JobServiceSelectionWizardPage( "Job Service Selection",
this.jobDescriptions );
// start job for retrieving list of services
this.jobServices = new ArrayList<IGridJobService>();
Job job = new Job( "Retrieving list of job services" ) {
@Override
protected IStatus run( final IProgressMonitor monitor ) {
assert JobCreatorSelectionWizard.this.jobDescriptions != null;
assert JobCreatorSelectionWizard.this.jobDescriptions.get( 0 ) != null;
IGridJobService[] allServices = null;
IGridProject project = JobCreatorSelectionWizard.this.jobDescriptions.get( 0 )
.getProject();
assert project != null;
assert project.getVO() != null;
try {
allServices = project.getVO().getJobSubmissionServices( null );
boolean valid;
for( IGridJobService service : allServices ) {
Iterator<IGridJobDescription> iter = JobCreatorSelectionWizard.this.jobDescriptions.iterator();
valid = true;
while( iter.hasNext() ) {
IGridJobDescription jobDescription = iter.next();
if( !service.canSubmit( jobDescription ) )
valid = false;
}
if( valid == true ) {
JobCreatorSelectionWizard.this.jobServices.add( service );
}
}
IWorkbench workbench = PlatformUI.getWorkbench();
Display display = workbench.getDisplay();
display.syncExec( new Runnable() {
public void run() {
// List<IGridJobService> synchronizedList =
// Collections.synchronizedList( jobServices );
JobCreatorSelectionWizard.this.selectionPage.setServices( JobCreatorSelectionWizard.this.jobServices );
}
} );
} catch( ProblemException e ) {
// TODO pawelw - handle error
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
};
job.setUser( true );
job.schedule();
addPage( this.selectionPage );
}
@Override
public boolean canFinish() {
return super.canFinish() && this.getSubmissionService() != null;
}
/*
* This it the routine were the sub-submission is started. (non-Javadoc)
* @see org.eclipse.jface.wizard.Wizard#performFinish()
*/
@Override
public boolean performFinish() {
{
JobSubmissionJob job = new JobSubmissionJob();
// needs to be stored, because JobSubmissionJob cannot access GUI fields
// from folderSelectionWizardPage
job.setJobNames( this.folderSelection.getJobNames() );
job.setDestinationFolder( this.folderSelection.getDestinationFolder() );
job.setUser( true );
Shell shell = getWizardShell();
if( shell != null ) {
shell.setVisible( false );
}
job.schedule(); // start as soon as possible
return false;
}
}
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;
}
}
/*
* IPath descPath = description.getPath().removeLastSegments( 1 ); IPath
* projPath = description.getProject().getPath(); descPath =
* descPath.removeFirstSegments( projPath.segmentCount() ); IPath jobPath =
* projPath.append( IGridProject.DIR_JOBS ); if (
* IGridProject.DIR_JOBDESCRIPTIONS.equals( descPath.segment( 0 ) ) ) {
* jobPath = jobPath.append( descPath.removeFirstSegments( 1 ) ); }
* IWorkspaceRoot workspaceRoot = ( IWorkspaceRoot )GridModel.getRoot()
* .getResource(); IFolder folder = workspaceRoot.getFolder( jobPath );
* createFolder( folder ); result = ( IGridContainer
* )GridModel.getRoot().findElement( folder );
*/
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 );
}
}
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 {
JobCreatorSelectionWizard.this.getContainer()
.getShell()
.setVisible( true );
}
} );
}
}
protected void addOpenEditorSolution( 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.solutionOpenEditor" ); //$NON-NLS-1$
}
public String getID() {
return null;
}
public boolean isActive() {
return true;
}
public void solve() throws InvocationTargetException {
for( IGridJobDescription descr : JobCreatorSelectionWizard.this.jobDescriptions )
{
IResource res = descr.getResource();
if( res instanceof IFile ) {
IFile desFile = ( IFile )res;
IWorkbenchPage page = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow()
.getActivePage();
IEditorDescriptor desc = PlatformUI.getWorkbench()
.getEditorRegistry()
.getDefaultEditor( desFile.getName() );
try {
page.openEditor( new FileEditorInput( desFile ), desc.getId() );
} catch( PartInitException e ) {
// just ignore
}
}
}
}
} );
problem.addReason( Messages.getString( "JobSubmissionWizardBase.submissionFailedReasonNotEnoughInput" ) );
}
}
private class JobSubmissionJob extends Job {
// create the service for the job submission
final IGridJobService service = JobCreatorSelectionWizard.this.getSubmissionService();
private List<String> jobNames;
private IResource destinationFolder;
JobSubmissionJob() {
super( Messages.getString( "JobSubmissionWizardBase.jobName" ) ); //$NON-NLS-1$
}
void setJobNames( final List<String> _jobNames ) {
this.jobNames = _jobNames;
}
void setDestinationFolder( final IResource folder ) {
this.destinationFolder = folder;
}
/**
* the run method for the Background job create the JobSubmissionWizard and
* call the service
*/
@Override
protected IStatus run( final IProgressMonitor monitor ) {
boolean closeWizard = true;
GridJobCreator creator = new GridJobCreator();
SubMonitor betterMonitor = SubMonitor.convert( monitor,
JobCreatorSelectionWizard.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 = JobCreatorSelectionWizard.this.jobDescriptions.iterator();
Iterator<String> namesIterator = 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$
IGridContainer parent = buildTargetFolder( description,
this.destinationFolder );
IGridJobID jobId = null;
if( isParametric( description ) ) {
ParametricJobService paramService = new ParametricJobService( this.service );
paramService.submitJob( description,
betterMonitor.newChild( 1 ),
parent,
namesIterator.next() );
} else {
jobId = this.service.submitJob( description,
betterMonitor.newChild( 1 ) );
// needed to pass jobDescription to creator
// maybe will change some day...
creator.canCreate( description );
creator.create( parent, jobId, this.service, namesIterator.next() );
}
testCancelled( betterMonitor );
// 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 boolean isParametric( final IGridJobDescription description ) {
boolean parametric = false;
if( description instanceof JSDLJobDescription ) {
JSDLJobDescription jsdl = ( JSDLJobDescription )description;
if( jsdl.isParametric() ) {
parametric = true;
} else {
// check if parent is parametric job
IGridContainer parent = jsdl.getParent();
while( parent != null ) {
if( parent instanceof GridJob ) {
GridJob parentJob = ( GridJob )parent;
IGridJobDescription parentDescription = parentJob.getJobDescription();
if( parentDescription instanceof JSDLJobDescription ) {
parametric = ( ( JSDLJobDescription )parentDescription ).isParametric();
}
break;
}
parent = parent.getParent();
}
}
}
return parametric;
}
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 );
addOpenEditorSolution( 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( !JobCreatorSelectionWizard.this.getContainer()
.getShell()
.isVisible() )
{
JobCreatorSelectionWizard.this.getContainer().getShell().close();
}
}
} );
}
}
}