/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.ui.actions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
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.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.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.core.builder.ModelBuildUtil;
import org.teiid.designer.core.container.Container;
import org.teiid.designer.core.notification.util.DefaultIgnorableNotificationSource;
import org.teiid.designer.core.refactor.ModelResourceCollectorVisitor;
import org.teiid.designer.core.refactor.RefactorResourceEvent;
import org.teiid.designer.core.workspace.ModelResource;
import org.teiid.designer.core.workspace.ModelUtil;
import org.teiid.designer.core.workspace.ModelWorkspaceException;
import org.teiid.designer.ui.UiConstants;
import org.teiid.designer.ui.UiPlugin;
import org.teiid.designer.ui.common.actions.AbstractAction;
import org.teiid.designer.ui.common.eventsupport.SelectionUtilities;
import org.teiid.designer.ui.common.util.UiUtil;
import org.teiid.designer.ui.common.widget.ListMessageDialog;
import org.teiid.designer.ui.editors.ModelEditorManager;
import org.teiid.designer.ui.event.ModelResourceEvent;
import org.teiid.designer.ui.refactor.delete.DeleteResourceActionDelegate;
import org.teiid.designer.ui.viewsupport.ModelUtilities;
/**
* The <code>DeleteResourceAction</code> is used to close models before deletion. If the model is open in an editor, the editor is
* closed. It delegates to Eclipse's delete resource action for the actual delete. Also it deletes EObjects by delegating to
* {@link org.teiid.designer.ui.actions.DeleteEObjectAction}.
*
* @since 8.0
*/
public class DeleteAction extends AbstractAction implements UiConstants {
/** Delegate action to delete resources. */
private DelegatableAction deleteResourceAction;
/** Delegate action to delete EObjects. */
private AbstractAction deleteEObjectAction;
/** Action to be executed */
private Action delegateAction;
/** Only initialised when delegates have been instantiated */
private boolean initialised = false;
/**
* Constructs a <code>DeleteResourceAction</code>.
*/
public DeleteAction() {
super(UiPlugin.getDefault());
final ISharedImages imgs = PlatformUI.getWorkbench().getSharedImages();
setImageDescriptor(imgs.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
setDisabledImageDescriptor(imgs.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE_DISABLED));
}
/*
* This method collects all model files either contained in the selected resources or
* contained in a selected folder.
*/
private List allSelectedAndContainedModelFiles( final List selectedResources ) {
List allSelectedAndContainedModelFiles = Collections.EMPTY_LIST;
// Iterator over the selected resources
for (int size = selectedResources.size(), i = 0; i < size; i++) {
final Object obj = selectedResources.get(i);
if (obj instanceof IResource) {
if (allSelectedAndContainedModelFiles.isEmpty()) allSelectedAndContainedModelFiles = new ArrayList();
final IResource iRes = (IResource)obj;
if (!(obj instanceof IFolder) && ModelUtilities.isModelFile(iRes)) {
// if the resource is not a folder and is a model file
// Add to the selected for deletion list
if (!allSelectedAndContainedModelFiles.contains(iRes)) allSelectedAndContainedModelFiles.add(iRes);
} else if (obj instanceof IFolder || obj instanceof IProject) {
// If the resource is a folder (and maybe a project) get all models
// contained under that folder
final Collection folderModels = getContainedModelFiles(obj);
final Iterator iter = folderModels.iterator();
IResource nextRes = null;
// Iterator over the contained models and check for duplicates.
while (iter.hasNext()) {
nextRes = (IResource)iter.next();
if (!allSelectedAndContainedModelFiles.contains(nextRes)) allSelectedAndContainedModelFiles.add(nextRes);
}
}
}
}
return allSelectedAndContainedModelFiles;
}
/*
* Filters modified resources to check for already existing in list, or in the list to be deleted.
*/
private void appendDependentModelFiles( final Collection affectedResources,
final Collection allAffectedResources,
final Collection targetedResources,
final Collection selectedObjects ) {
// Walk through affectedResources list and add to allAffectedResources only if it doesn't contain the model resourse
final Iterator iter = affectedResources.iterator();
IResource mr = null;
while (iter.hasNext()) {
mr = (IResource)iter.next();
if (!targetedResources.contains(mr) &&
!allAffectedResources.contains(mr) &&
!isUnderSelectedObjects(mr, selectedObjects)) {
allAffectedResources.add(mr);
}
}
}
/**
* If the specified <code>IFile</code> is a model resource it is closed. If the model is open in an editor, the editor is
* closed.
*
* @param theFile the <code>IFile</code> being closed
* @return <code>true</code> if the model closed successfully or if not a model file; <code>false</code> otherwise.
*/
private boolean closeFile( final IFile theFile ) {
boolean result = true;
ModelResource model = null;
if (ModelUtilities.isModelFile(theFile)) {
try {
model = ModelUtil.getModelResource(theFile, false);
if (model != null) if (model.isLoaded()) {
// see if the model is open, in an initialized ModelEditor
if (ModelEditorManager.isOpen(theFile)) {
if (!ModelEditorManager.isOpenAndInitialized(theFile)) // System.out.println("[DeleteResourceAction.closeFile] model is open; about to close: "
// +
// theFile.getName() );
ModelEditorManager.close(theFile, false);
} else {
// jh Defect 19139:
// if the model is not open it might be in an Editor Reference. If so, clean that up.
final IEditorReference editorRef = ModelEditorManager.getEditorReferenceForFile(theFile);
if (editorRef != null) // System.out.println("[DeleteResourceAction.closeFile] Found an EditorReference; about to remove: "
// + editorRef.getName() );
ModelEditorManager.removeEditorReference(editorRef);
}
// }
} else {
// jh Defect 19139:
// if the model is not loaded it might be in an Editor Reference. If so, clean that up.
final IEditorReference editorRef = ModelEditorManager.getEditorReferenceForFile(theFile);
if (editorRef != null) // System.out.println("[DeleteResourceAction.closeFile] Found an EditorReference; about to remove: "
// +
// editorRef.getName() );
ModelEditorManager.removeEditorReference(editorRef);
}
} catch (final ModelWorkspaceException theException) {
Util.log(theException);
result = false;
}
// don't close model if editor wasn't closed. user aborted close.
if (result) try {
if (model != null) // Need to close the model in the Explorer?
// System.out.println("[DeleteResourceAction.closeFile] result is true; about to call closeModel(model): "
// + model.getItemName() );
closeModel(model);
} catch (final ModelWorkspaceException theException) {
Util.log(theException);
result = false;
}
} else if (ModelUtil.isVdbArchiveFile(theFile)) {
// IResource vbdResource = (IResource)theFile;
final IEditorPart editor = UiUtil.getEditorForFile(theFile, false);
if (editor != null) {
if (editor.isDirty()) {
final String title = UiConstants.Util.getString("DeleteResourceAction.pendingChangesTitle"); //$NON-NLS-1$
final String message = UiConstants.Util.getString("DeleteResourceAction.pendingChangesMessage", theFile.getName()); //$NON-NLS-1$
result = MessageDialog.openQuestion(getShell(), title, message);
}
if (result) UiUtil.close(theFile, false);
}
}
return result;
}
/**
* Closes all models under the specified <code>IFolder</code>. If a model is open in an editor, the editor is closed.
*
* @param theFolder the <code>IFolder</code> whose models are being closed
* @return <code>true</code> if all models closed successfully; <code>false</code> otherwise.
*/
private boolean closeFolder( final IFolder theFolder ) {
boolean result = true;
try {
final IResource[] kids = theFolder.members();
if (kids.length > 0) for (int i = 0; i < kids.length; i++)
if (!closeResource(kids[i])) result = false;
} catch (final CoreException theException) {
Util.log(theException);
result = false;
}
return result;
}
private void closeModel( final ModelResource modelResource ) throws ModelWorkspaceException {
ModelResourceEvent event = new ModelResourceEvent(modelResource, ModelResourceEvent.CLOSING, this);
UiPlugin.getDefault().getEventBroker().processEvent(event);
if (modelResource.isOpen() && modelResource.isLoaded()) {
modelResource.getEmfResource().setModified(false);
modelResource.close();
event = new ModelResourceEvent(modelResource, ModelResourceEvent.CLOSED, this);
UiPlugin.getDefault().getEventBroker().processEvent(event);
}
}
/**
* Closes all models under the specified <code>IProject</code>. If a model is open in an editor, the editor is closed.
*
* @param theProject the <code>IProject</code> whose models are being closed
* @return <code>true</code> if all models closed successfully; <code>false</code> otherwise.
*/
private boolean closeProject( final IProject theProject ) {
boolean result = true;
try {
final IResource[] kids = theProject.members();
if (kids.length > 0) for (int i = 0; i < kids.length; i++)
if (!closeResource(kids[i])) result = false;
} catch (final CoreException theException) {
Util.log(theException);
result = false;
}
return result;
}
/**
* Closes all models under the specified <code>IResource</code>. If a model is open in an editor, the editor is closed.
*
* @param theResource the <code>IResource</code> whose models are being closed
* @return <code>true</code> if all models closed successfully; <code>false</code> otherwise.
*/
private boolean closeResource( final IResource theResource ) {
boolean result = true;
if (ModelerCore.hasModelNature(theResource.getProject())) if (theResource instanceof IProject) result = closeProject((IProject)theResource);
else if (theResource instanceof IFolder) result = closeFolder((IFolder)theResource);
else if (theResource instanceof IFile) result = closeFile((IFile)theResource);
return result;
}
private void closeResources( final List resources ) {
boolean userOK = true;
final List modifiedResources = ModelBuildUtil.getModifiedResources();
final boolean started = ModelerCore.startTxn(false, false, "Closing Resources for Delete", //$NON-NLS-1$
new DefaultIgnorableNotificationSource(DeleteAction.this));
boolean succeeded = false;
try {
for (int size = resources.size(), i = 0; i < size && userOK; i++) {
final Object obj = resources.get(i);
if (obj instanceof IResource) userOK = closeResource((IResource)obj);
}
succeeded = true;
} catch (final Exception err) {
final String msg = Util.getString("DeleteResourceAction.closeResources"); //$NON-NLS-1$
getPluginUtils().log(IStatus.ERROR, err, msg);
} finally {
if (started) if (succeeded) ModelerCore.commitTxn();
else ModelerCore.rollbackTxn();
}
ModelBuildUtil.setModifiedResources(modifiedResources);
}
protected Container doGetContainer() {
try {
return ModelerCore.getModelContainer();
} catch (final CoreException err) {
final String message = Util.getString("DeleteResourceAction.doGetContainerProblemMessage"); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err, message);
}
return null;
}
/**
* @see org.teiid.designer.ui.common.actions.AbstractAction#doRun()
*/
@Override
protected void doRun() {
initDelegateActions();
delegateAction.run();
// final Collection deletedModelPaths = new ArrayList();
// boolean deleteApproved = false;
//
// switch (delegateActionId) {
// case RESOURCE:
// // this should never be called when there is one or more selected objects that are NOT an IResource.
// // the delegate action enablement should assure this.
// final List resources = getSelectedObjects();
//
// /* Temp dependant model list */
// Collection depModelFiles = Collections.EMPTY_LIST;
// /*Cached list of all dependent models for all contained resources */
// final Collection allDependantModelFiles = new ArrayList();
// /* All models contained in select and under objects selected (i.e. projects and folders */
// final List allSelectedAndContainedModelFiles = allSelectedAndContainedModelFiles(resources);
//
// for (final Iterator iter2 = allSelectedAndContainedModelFiles.iterator(); iter2.hasNext();)
// deletedModelPaths.add(((IResource)iter2.next()).getFullPath());
//
// final Iterator iter = allSelectedAndContainedModelFiles.iterator();
// // Loop through all contained/objects targeted for deletion
// while (iter.hasNext()) {
// // Obtain all model file IResources for each model targeted for deletion
// depModelFiles = WorkspaceResourceFinderUtil.getResourcesThatUse((IResource)iter.next());
// // Append these to the big list using the private appendXXXX method below
// if (!depModelFiles.isEmpty()) appendDependentModelFiles(depModelFiles,
// allDependantModelFiles,
// allSelectedAndContainedModelFiles,
// resources);
// }
//
// if (!isOkToCloseResources(resources))
// return;
//
// boolean okToDelete = true;
// // If we find dependent models, we need to warn the user
// if (!allDependantModelFiles.isEmpty()) okToDelete = warnUserAboutDependants(allDependantModelFiles);
//
// if (okToDelete) {
// closeResources(resources);
//
// // Find all Deleting resources jobs and add listeners to count down the delete jobs, so this class
// // can perform both Undo manager cleanup and notifyDeleted() to listeners.
// Job[] jobs = Job.getJobManager().find(DeleteResourceAction_jobName);
//
// CountDownLatch latch = new CountDownLatch(jobs.length);
// IJobChangeListener deleteFinishedJobListener = new DeleteFinishedJobListener(latch, deletedModelPaths);
//
// if (jobs != null && jobs.length > 0) {
// deleteApproved = true;
//
// for (Job job : jobs) {
// job.addJobChangeListener(deleteFinishedJobListener);
// }
// }
//
// // if there are any dependent models AND the delete was approved (i.e. Delete jobs were started)
// // We assume we need to clean-up and revalidate dependent models.
// if (!allDependantModelFiles.isEmpty() && deleteApproved) {
//
// // Call the refactor model extension manager to update for Delete resource operations.
// // This is to clean up both SQL transformation inputs as well as Custom Diagram components that
// // may be been made "stale".
// // NOTE: This isn't a problem with delete "EObject" because of the inherent EMF framework.
// RefactorModelExtensionManager.helpUpdateModelContentsForDelete(deletedModelPaths,
// allDependantModelFiles,
// new NullProgressMonitor());
//
// // make a call to validate the dependent models so the appropriate problem markers are generated and
// // displayed to user.
//
// final WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
// @Override
// public void execute(final IProgressMonitor theMonitor) {
// validateDependentResources(allDependantModelFiles, theMonitor);
// theMonitor.done();
// }
// };
//
// try {
// new ProgressMonitorDialog(Display.getCurrent().getActiveShell()).run(true, true, op);
// } catch (final InterruptedException e) {
// } catch (final InvocationTargetException e) {
// UiConstants.Util.log(e.getTargetException());
// }
// }
// }
// break;
// case EOBJECTS:
// this.deleteEObjectAction.run();
// break;
// }
}
/*
* Private method used to obtain all Model file IResources contained in an IFolder
* or IProject IResource. This is required because if these containers are being deleted, we need to gather
* up all objects that will go along with it and check for dependencies so we can validate all affected
* resources.
*/
private Collection getContainedModelFiles( final Object folderOrProject ) {
Collection containedModelFiles = Collections.EMPTY_LIST;
final ModelResourceCollectorVisitor visitor = new ModelResourceCollectorVisitor();
if (folderOrProject instanceof IFolder) {
// get the folder's project
final IProject project = ((IFolder)folderOrProject).getProject();
if (project != null) {
// Insure that the project is open and is a Modeler Project
if (project.isOpen() && ModelerCore.hasModelNature(project)) try {
((IFolder)folderOrProject).accept(visitor);
} catch (final CoreException e) {
UiConstants.Util.log(e);
}
// Get the resources and weed out non-model files
final List pResources = visitor.getResources();
containedModelFiles = new ArrayList(pResources.size());
final Iterator iter = pResources.iterator();
IResource nextRes = null;
while (iter.hasNext()) {
nextRes = (IResource)iter.next();
if (ModelUtilities.isModelFile(nextRes)) containedModelFiles.add(nextRes);
}
}
} else if (folderOrProject instanceof IProject) {
// get the folder's project
final IProject project = (IProject)folderOrProject;
// Insure that the project is open and is a Modeler Project
if (project.isOpen() && ModelerCore.hasModelNature(project)) try {
project.accept(visitor);
} catch (final CoreException e) {
UiConstants.Util.log(e);
}
// Get the resources and weed out non-model files
final List pResources = visitor.getResources();
containedModelFiles = new ArrayList(pResources.size());
final Iterator iter = pResources.iterator();
IResource nextRes = null;
while (iter.hasNext()) {
nextRes = (IResource)iter.next();
if (ModelUtilities.isModelFile(nextRes)) containedModelFiles.add(nextRes);
}
}
// return on project model files.
return containedModelFiles;
}
protected Shell getShell() {
return UiPlugin.getDefault().getCurrentWorkbenchWindow().getShell();
}
protected void initDelegateActions() {
if (initialised)
return;
this.deleteResourceAction = new DelegatableAction(new DeleteResourceActionDelegate(), UiUtil.getWorkbenchWindow());
this.deleteEObjectAction = new DeleteEObjectAction();
this.delegateAction = deleteResourceAction;
initialised = true;
}
private boolean isOkToCloseFile( final IFile theFile ) {
boolean result = true;
ModelResource model = null;
if (ModelUtilities.isModelFile(theFile)) try {
model = ModelUtil.getModelResource(theFile, false);
if (model != null && model.isLoaded() && model.getEmfResource().isModified()) {
// first, see if the model has pending changes that need to be saved.
final String title = UiConstants.Util.getString("DeleteResourceAction.pendingChangesTitle"); //$NON-NLS-1$
final String message = UiConstants.Util.getString("DeleteResourceAction.pendingChangesMessage", theFile.getName()); //$NON-NLS-1$
result = MessageDialog.openQuestion(getShell(), title, message);
}
} catch (final ModelWorkspaceException theException) {
Util.log(theException);
result = false;
}
else if (ModelUtil.isVdbArchiveFile(theFile)) {
final IEditorPart editor = UiUtil.getEditorForFile(theFile, false);
if (editor != null) if (editor.isDirty()) {
final String title = UiConstants.Util.getString("DeleteResourceAction.pendingChangesTitle"); //$NON-NLS-1$
final String message = UiConstants.Util.getString("DeleteResourceAction.pendingChangesMessage", theFile.getName()); //$NON-NLS-1$
result = MessageDialog.openQuestion(getShell(), title, message);
}
}
return result;
}
private boolean isOkToCloseFolder( final IFolder theFolder ) {
boolean result = true;
try {
final IResource[] kids = theFolder.members();
if (kids.length > 0) for (int i = 0; i < kids.length; i++)
if (!isOkToCloseResource(kids[i])) result = false;
} catch (final CoreException theException) {
Util.log(theException);
result = false;
}
return result;
}
private boolean isOkToCloseProject( final IProject theProject ) {
boolean result = true;
try {
final IResource[] kids = theProject.members();
if (kids.length > 0) for (int i = 0; i < kids.length; i++)
if (!isOkToCloseResource(kids[i])) result = false;
} catch (final CoreException theException) {
Util.log(theException);
result = false;
}
return result;
}
private boolean isOkToCloseResource( final IResource theResource ) {
boolean result = true;
if (ModelerCore.hasModelNature(theResource.getProject())) if (theResource instanceof IProject) result = isOkToCloseProject((IProject)theResource);
else if (theResource instanceof IFolder) result = isOkToCloseFolder((IFolder)theResource);
else if (theResource instanceof IFile) result = isOkToCloseFile((IFile)theResource);
return result;
}
private boolean isOkToCloseResources( final List resources ) {
boolean userOK = true;
// We need to wrap this in a transaction
final boolean started = ModelerCore.startTxn(false, false, "Confirming Close Resources", //$NON-NLS-1$
new DefaultIgnorableNotificationSource(DeleteAction.this));
boolean succeeded = false;
try {
for (int size = resources.size(), i = 0; i < size && userOK; i++) {
final Object obj = resources.get(i);
if (obj instanceof IResource) userOK = isOkToCloseResource((IResource)obj);
}
succeeded = true;
} catch (final Exception err) {
final String msg = UiConstants.Util.getString("DeleteResourceAction.confirmingCloseResources"); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err, msg);
} finally {
if (started) if (succeeded) ModelerCore.commitTxn();
else ModelerCore.rollbackTxn();
}
return userOK;
}
private boolean isUnderSelectedObjects( final IResource dependentResource,
final Collection selectedObjects ) {
final Iterator iter = selectedObjects.iterator();
while (iter.hasNext())
if (dependentResource.getProject().equals(iter.next())) return true;
return false;
}
private boolean isValidSelection() {
// Check for mixed Selection
// Can't delete EObjects & IResources together
if (SelectionUtilities.isMixedObjectTypes(getSelection())) return false;
final boolean isValid = true;
// 1) Can't delete a .project file
// 2) Can't delete the "Configuration" project
// 3) Can't delete the "FunctionDefinitions" model
final List selectedObjects = getSelectedObjects();
for (final Iterator iter = selectedObjects.iterator(); iter.hasNext();) {
final Object nextObj = iter.next();
if (nextObj instanceof IProject) {
final String projName = ((IProject)nextObj).getName();
if (ModelerCore.isReservedProjectName(projName)) return false;
} else if (nextObj instanceof IFile) {
final IFile file = (IFile)nextObj;
if (file.getFileExtension() != null && file.getFileExtension().equalsIgnoreCase(ModelerCore.DOT_PROJECT_EXTENSION)) return false;
else if (file.getName().equalsIgnoreCase(ModelerCore.UDF_MODEL_NAME)) return false;
}
}
return isValid;
}
/*
* Notify with RefactorRenameEvent.TYPE_DELETE
*/
private void notifyDeleted( final IPath deletedResourcePath ) {
((ModelerCore)ModelerCore.getPlugin()).notifyRefactored(new RefactorResourceEvent(null, RefactorResourceEvent.TYPE_DELETE,
this, deletedResourcePath));
}
private void setEnablement() {
if (! isValidSelection()) {
setEnabled(false);
return;
}
if (deleteResourceAction.isEnabled()) {
delegateAction = deleteResourceAction;
setEnabled(true);
} else if ((this.deleteEObjectAction != null) && this.deleteEObjectAction.isEnabled()) {
delegateAction = deleteEObjectAction;
setEnabled(true);
} else {
setEnabled(false);
}
}
/* (non-Javadoc)
* see org.teiid.designer.ui.common.actions.AbstractAction#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
*/
@Override
public void selectionChanged( final IWorkbenchPart thePart, final ISelection theSelection ) {
initDelegateActions();
super.selectionChanged(thePart, theSelection);
if (this.deleteEObjectAction != null)
this.deleteEObjectAction.selectionChanged(thePart, theSelection);
this.deleteResourceAction.selectionChanged(thePart, theSelection);
setEnablement();
}
/* (non-Javadoc)
* see org.teiid.designer.ui.common.actions.AbstractAction#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
*/
@Override
public void selectionChanged( final SelectionChangedEvent theEvent ) {
initDelegateActions();
super.selectionChanged(theEvent);
if (this.deleteEObjectAction != null)
this.deleteEObjectAction.selectionChanged(theEvent);
this.deleteResourceAction.selectionChanged(theEvent.getSelection());
setEnablement();
}
/*
* This method calls the appropriate validate method to create the "Missing" import problem markers (and others) for the
* resources just deleted.
*/
void validateDependentResources( final Collection modelIResources,
final IProgressMonitor theMontitor ) {
if (!modelIResources.isEmpty()) {
// In order for the notifications caused by "opening models" for validation, to be swallowed, the validation
// call needs to be wrapped in a transaction. This was discovered and relayed by Goutam on 2/14/05.
final boolean started = ModelerCore.startTxn(false, false, "Validate Dependent Resources", //$NON-NLS-1$
new DefaultIgnorableNotificationSource(DeleteAction.this));
boolean succeeded = false;
try {
ModelBuildUtil.validateResources(theMontitor, modelIResources, doGetContainer(), false);
succeeded = true;
} catch (final Exception err) {
final String msg = Util.getString("DeleteResourceAction.validateDependentResources"); //$NON-NLS-1$
getPluginUtils().log(IStatus.ERROR, err, msg);
} finally {
if (started) if (succeeded) ModelerCore.commitTxn();
else ModelerCore.rollbackTxn();
}
}
}
private boolean warnUserAboutDependants( final Collection dependentResources ) {
final String title = Util.getString("DeleteResourceAction.confirmDependenciesTitle"); //$NON-NLS-1$
final String msg = Util.getString("DeleteResourceAction.confirmDependenciesMessage"); //$NON-NLS-1$
final List resourceList = new ArrayList(dependentResources.size());
for (final Iterator iter = dependentResources.iterator(); iter.hasNext();) {
final IPath shortPath = ((IResource)iter.next()).getFullPath().makeRelative();
resourceList.add(shortPath);
}
return ListMessageDialog.openWarningQuestion(getShell(), title, null, msg, resourceList, null);
}
// Inner class designed to count down each Deleting resources
private class DeleteFinishedJobListener extends JobChangeAdapter {
private final CountDownLatch latch;
Collection deletedModelPaths;
public DeleteFinishedJobListener( CountDownLatch latch, Collection deletedModelPaths) {
this.latch = latch;
this.deletedModelPaths = new ArrayList(deletedModelPaths);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse.core.runtime.jobs.IJobChangeEvent)
*/
@Override
public void done( IJobChangeEvent event ) {
this.latch.countDown();
if( latch.getCount() == 0 ) {
for (final Object path : deletedModelPaths)
notifyDeleted((IPath)path);
}
}
}
}