Java tutorial
/****************************************************************************** * 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): * Mariusz Wojtysiak - initial API and implementation * David Johnson (UoR) - added support for deleting JSDLs linked to * workflows *****************************************************************************/ package eu.geclipse.ui.internal.actions; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; 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.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.IShellProvider; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.DeleteResourceAction; import org.eclipse.ui.actions.SelectionListenerAction; import eu.geclipse.core.filesystem.GEclipseFileSystem; import eu.geclipse.core.model.GridModel; import eu.geclipse.core.model.IGridConnectionElement; import eu.geclipse.core.model.IGridContainer; import eu.geclipse.core.model.IGridElement; import eu.geclipse.core.model.IGridJob; import eu.geclipse.core.model.IGridJobDescription; 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.workflow.IGridWorkflowDescription; import eu.geclipse.workflow.IGridWorkflowJobDescription; /** * */ public class DeleteGridElementAction extends SelectionListenerAction { Shell shell; private DeleteResourceAction eclipseAction; protected DeleteGridElementAction(final Shell shell) { super(Messages.getString("DeleteGridElementAction.actionNameDelete")); //$NON-NLS-1$ this.shell = shell; this.eclipseAction = new DeleteResourceAction(new IShellProvider() { public Shell getShell() { return shell; } }); ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages(); ImageDescriptor deleteImage = sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE); setImageDescriptor(deleteImage); } /* * (non-Javadoc) * * @see org.eclipse.jface.action.Action#run() */ @Override public void run() { List<IGridJob> selectedJobs = new ArrayList<IGridJob>(getSelectedResources().size()); List<IGridJobDescription> selectedWorkflowJobDescriptions = new ArrayList<IGridJobDescription>( getSelectedResources().size()); List<IResource> selectedResources = new ArrayList<IResource>(getSelectedResources().size()); dispatchSelectedElements(selectedJobs, selectedWorkflowJobDescriptions, selectedResources); deactivateConnections(selectedResources.toArray(new IResource[selectedResources.size()])); if (!selectedJobs.isEmpty()) { deleteJobs(selectedJobs); } if (!selectedResources.isEmpty()) { deleteOtherResources(selectedResources); } if (!selectedWorkflowJobDescriptions.isEmpty()) { deleteWorkflowJobDescriptions(selectedWorkflowJobDescriptions); } } @Override protected boolean updateSelection(final IStructuredSelection selection) { return !getSelectedResources().isEmpty(); } private void deactivateConnections(final IResource[] resources) { if (resources != null) { for (IResource resource : resources) { IGridElement element = GridModel.getRoot().findElement(resource); if (element instanceof IGridConnectionElement) { try { IGridConnectionElement connection = (IGridConnectionElement) element; IFileStore fileStore = connection.getConnectionFileStore(); // Deactivate the connection before deleting it in order to avoid // info or child fetching GEclipseFileSystem.setFileStoreActive(fileStore, false, false, false); // Refresh the resource tree in order to remove all cached child // resources that would also cause info fetching resource.refreshLocal(IResource.DEPTH_INFINITE, null); } catch (CoreException cExc) { Activator.logException(cExc); } } if (resource instanceof IContainer) { try { IResource[] members = ((IContainer) resource).members(); deactivateConnections(members); } catch (CoreException cExc) { Activator.logException(cExc); } } } } } private void dispatchSelectedElements(final List<IGridJob> selectedJobs, final List<IGridJobDescription> selectedWorkflowJobDescriptions, final List<IResource> otherSelectedResources) { for (Object obj : getSelectedResources()) { if (obj instanceof IResource) { IResource resource = (IResource) obj; IGridElement element = GridModel.getRoot().findElement(resource); if (element instanceof IGridJob) { selectedJobs.add((IGridJob) element); } else if (element instanceof IGridJobDescription) { // find out if the parent resource is a workflow IGridContainer parent = element.getParent(); if (parent instanceof IGridWorkflowDescription) { boolean inWorkflow = false; List<IGridWorkflowJobDescription> childrenJobs = ((IGridWorkflowDescription) parent) .getChildrenJobs(); for (Iterator<IGridWorkflowJobDescription> i = childrenJobs.iterator(); i.hasNext();) { IGridWorkflowJobDescription child = i.next(); String childUri = child.getDescriptionPath().toString(); String fullPath = element.getResource().getLocation().toString(); if (childUri.equals(fullPath)) { inWorkflow = true; } } if (inWorkflow) { selectedWorkflowJobDescriptions.add((IGridJobDescription) element); } else { otherSelectedResources.add(resource); } } else { otherSelectedResources.add(resource); } } else { otherSelectedResources.add(resource); } } } } private void deleteOtherResources(final List<IResource> selectedResources) { this.eclipseAction.selectionChanged(new StructuredSelection(selectedResources)); this.eclipseAction.run(); } /* * At the moment it only works if workflow is not dirty (i.e. workflow must be saved for * it to behave correctly). There is not yet any Problem reporting or Progress monitoring. */ private void deleteWorkflowJobDescriptions(final List<IGridJobDescription> selectedJobDescriptions) { MessageDialog dialog = null; String dialogMessage = ""; //$NON-NLS-1$ if (selectedJobDescriptions.size() == 1) { IGridJobDescription selectedJobDesc = selectedJobDescriptions.get(0); String jsdl = selectedJobDesc.getResource().getName(); dialogMessage = String.format(Messages.getString("DeleteGridElementAction.confirmJobDescDeleteOne"), //$NON-NLS-1$ jsdl); } else { String jsdlList = ""; //$NON-NLS-1$ for (Iterator<IGridJobDescription> i = selectedJobDescriptions.iterator(); i.hasNext();) { jsdlList = jsdlList + " " + i.next().getResource().getName(); //$NON-NLS-1$ } dialogMessage = String.format(Messages.getString("DeleteGridElementAction.confirmJobDescDeleteMany"), //$NON-NLS-1$ jsdlList); } dialog = new MessageDialog(DeleteGridElementAction.this.shell, Messages.getString("DeleteGridElementAction.confirmationTitle"), //$NON-NLS-1$ null, dialogMessage, MessageDialog.WARNING, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0); if (dialog.open() == Window.OK) { try { for (Iterator<IGridJobDescription> i1 = selectedJobDescriptions.iterator(); i1.hasNext();) { IResource r = i1.next().getResource(); r.delete(true, new NullProgressMonitor()); // TODO add a proper progress monitor to use } } catch (CoreException e) { // TODO Auto-generated catch block, add proper problem reporting e.printStackTrace(); } } } private enum ConfirmChoice { /** * */ deleteFromGrid, /** * */ deleteOnlyFromWorkspace, /** * */ cancel } private void deleteJobs(final List<IGridJob> selectedJobs) { ConfirmChoice choice = confirmDeleteJobs(selectedJobs); if (choice != ConfirmChoice.cancel) { DeleteJobsJob job = new DeleteJobsJob(selectedJobs, choice); job.setUser(true); job.schedule(); } } private ConfirmChoice confirmDeleteJobs(final List<IGridJob> selectedJobs) { ConfirmChoice choice = ConfirmChoice.cancel; String question = null, warning = null; if (selectedJobs.size() == 1) { IGridJob job = selectedJobs.iterator().next(); question = String.format(Messages.getString("DeleteGridElementAction.confirmationOne"), //$NON-NLS-1$ job.getJobName()); if (job.getJobStatus().canChange()) { warning = String.format(Messages.getString("DeleteGridElementAction.warningOne"), job.getJobName()); //$NON-NLS-1$ } } else { question = String.format(Messages.getString("DeleteGridElementAction.confirmationMany"), //$NON-NLS-1$ Integer.valueOf(selectedJobs.size())); for (IGridJob job : selectedJobs) { if (job.getJobStatus().canChange()) { warning = Messages.getString("DeleteGridElementAction.warningMany"); //$NON-NLS-1$ break; } } } String msg = question; if (warning != null) { msg += "\n\n" + warning; //$NON-NLS-1$ } ConfirmDeleteJobsDialog dialog = new ConfirmDeleteJobsDialog(msg, warning == null ? MessageDialog.QUESTION : MessageDialog.WARNING); if (dialog.open() == 0) { if (dialog.isDeleteFromGrid()) { choice = ConfirmChoice.deleteFromGrid; } else { choice = ConfirmChoice.deleteOnlyFromWorkspace; } } return choice; } private class ConfirmDeleteJobsDialog extends MessageDialog { private Button deleteFromGridCheckbox; private boolean deleteFromGrid; ConfirmDeleteJobsDialog(final String dialogMessage, final int dialogImageType) { super(DeleteGridElementAction.this.shell, Messages.getString("DeleteGridElementAction.confirmationTitle"), //$NON-NLS-1$ null, dialogMessage, dialogImageType, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0); } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.MessageDialog#createCustomArea(org.eclipse.swt.widgets.Composite) */ @Override protected Control createCustomArea(final Composite parent) { this.deleteFromGridCheckbox = new Button(parent, SWT.CHECK); this.deleteFromGridCheckbox.setText(Messages.getString("DeleteGridElementAction.alsoDeleteFromGrid")); //$NON-NLS-1$ this.deleteFromGridCheckbox.setSelection(true); return super.createCustomArea(parent); } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#close() */ @Override public boolean close() { this.deleteFromGrid = this.deleteFromGridCheckbox.getSelection(); return super.close(); } boolean isDeleteFromGrid() { return this.deleteFromGrid; } } private class DeleteJobsJob extends Job { boolean forceDeleteLocal = false; private List<IGridJob> selectedJobs; private ConfirmChoice userChoice; /** * @param selectedJobs * @param userChoice */ public DeleteJobsJob(final List<IGridJob> selectedJobs, final ConfirmChoice userChoice) { super(Messages.getString("DeleteGridElementAction.deleteJobName")); //$NON-NLS-1$ this.selectedJobs = selectedJobs; this.userChoice = userChoice; } @Override protected IStatus run(final IProgressMonitor monitor) { IStatus status = Status.OK_STATUS; SubMonitor submonitor = SubMonitor.convert(monitor); submonitor.setWorkRemaining(this.selectedJobs.size()); try { Iterator<IGridJob> iterator = this.selectedJobs.iterator(); IGridJob job = null; while (iterator.hasNext()) { try { testCancel(submonitor); job = iterator.next(); deleteJob(submonitor.newChild(1), job); iterator.remove(); // if succesful deleted, then don't delete it again during eventually next try } catch (ProblemException exception) { addSolutionOnlyLocalDel(exception); ProblemDialog.openProblem(DeleteGridElementAction.this.shell, Messages.getString("DeleteGridElementAction.deleteProblemTitle"), //$NON-NLS-1$ String.format(Messages.getString("DeleteGridElementAction.problemDescription"), //$NON-NLS-1$ job != null ? job.getJobName() : "unknown"), //$NON-NLS-1$ exception); break; } } } finally { submonitor.done(); } return status; } private void deleteJob(final SubMonitor monitor, final IGridJob job) throws ProblemException { monitor.setTaskName(String.format(Messages.getString("DeleteGridElementAction.taskNameDeleting"), //$NON-NLS-1$ job.getJobName())); monitor.setWorkRemaining(this.userChoice == ConfirmChoice.deleteFromGrid ? 3 : 2); stopJobStatusUpdater(job, monitor.newChild(1)); if (this.userChoice == ConfirmChoice.deleteFromGrid) { try { job.deleteJob(monitor.newChild(1)); } catch (ProblemException exception) { if (this.forceDeleteLocal) { Activator.logException(exception); } else { throw exception; } } } try { testCancel(monitor); job.getResource().delete(true, monitor.newChild(1)); } catch (CoreException exception) { throw new ProblemException("eu.geclipse.problem.deleteGridElementAction.cannotDeleteResource", //$NON-NLS-1$ exception, Activator.PLUGIN_ID); } } private void stopJobStatusUpdater(final IGridJob job, final SubMonitor monitor) { monitor.subTask(Messages.getString("DeleteGridElementAction.taskStoppingUpdater")); //$NON-NLS-1$ GridModel.getJobManager().removeJobStatusUpdater(job, true, monitor); } private void testCancel(final IProgressMonitor monitor) { if (monitor.isCanceled()) { throw new OperationCanceledException(); } } void addSolutionOnlyLocalDel(final ProblemException exception) { if (this.userChoice == ConfirmChoice.deleteFromGrid && !this.forceDeleteLocal) { IProblem problem = exception.getProblem(); problem.addSolution(new ISolution() { public String getDescription() { return Messages.getString("DeleteGridElementAction.forceDeleteLocal"); //$NON-NLS-1$ } public String getID() { return null; } public boolean isActive() { return true; } public void solve() throws InvocationTargetException { DeleteJobsJob.this.forceDeleteLocal = true; DeleteJobsJob.this.schedule(); } }); } } } }