001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.ide.undo;
011:
012: import java.util.ArrayList;
013:
014: import org.eclipse.core.resources.IResource;
015: import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
016: import org.eclipse.core.runtime.CoreException;
017: import org.eclipse.core.runtime.IAdaptable;
018: import org.eclipse.core.runtime.IProgressMonitor;
019: import org.eclipse.core.runtime.IStatus;
020: import org.eclipse.core.runtime.Status;
021: import org.eclipse.core.runtime.jobs.ISchedulingRule;
022:
023: /**
024: * A DeleteResourcesOperation represents an undoable operation for deleting one
025: * or more resources in the workspace. Clients may call the public API from a
026: * background thread.
027: *
028: * This class is intended to be instantiated and used by clients. It is not
029: * intended to be subclassed by clients.
030: *
031: * @since 3.3
032: *
033: */
034: public class DeleteResourcesOperation extends
035: AbstractResourcesOperation {
036:
037: // Whether to delete project content
038: private boolean deleteContent = false;
039:
040: /**
041: * Create a DeleteResourcesOperation
042: *
043: * @param resources
044: * the resources to be deleted
045: * @param label
046: * the label of the operation
047: * @param deleteContent
048: * whether or not we are deleting content for projects
049: */
050: public DeleteResourcesOperation(IResource[] resources,
051: String label, boolean deleteContent) {
052: super (resources, label);
053: this .deleteContent = deleteContent;
054: }
055:
056: /*
057: * (non-Javadoc)
058: *
059: * Map execution to resource deletion.
060: *
061: * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#doExecute(org.eclipse.core.runtime.IProgressMonitor,
062: * org.eclipse.core.runtime.IAdaptable)
063: */
064: protected void doExecute(IProgressMonitor monitor, IAdaptable uiInfo)
065: throws CoreException {
066: delete(monitor, uiInfo, deleteContent);
067: }
068:
069: /*
070: * (non-Javadoc)
071: *
072: * Map undo to resource recreation.
073: *
074: * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#doUndo(org.eclipse.core.runtime.IProgressMonitor,
075: * org.eclipse.core.runtime.IAdaptable)
076: */
077: protected void doUndo(IProgressMonitor monitor, IAdaptable uiInfo)
078: throws CoreException {
079: recreate(monitor, uiInfo);
080: }
081:
082: /*
083: * (non-Javadoc)
084: *
085: * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#updateResourceChangeDescriptionFactory(org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory,
086: * int)
087: */
088: protected boolean updateResourceChangeDescriptionFactory(
089: IResourceChangeDescriptionFactory factory, int operation) {
090: boolean modified = false;
091: if (operation == UNDO) {
092: for (int i = 0; i < resourceDescriptions.length; i++) {
093: IResource resource = resourceDescriptions[i]
094: .createResourceHandle();
095: factory.create(resource);
096: modified = true;
097: }
098: } else {
099: for (int i = 0; i < resources.length; i++) {
100: IResource resource = resources[i];
101: factory.delete(resource);
102: modified = true;
103: }
104: }
105: return modified;
106: }
107:
108: /*
109: * (non-Javadoc)
110: *
111: * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#getExecuteSchedulingRule()
112: */
113: protected ISchedulingRule getExecuteSchedulingRule() {
114: return super .computeDeleteSchedulingRule();
115: }
116:
117: /*
118: * (non-Javadoc)
119: *
120: * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#getUndoSchedulingRule()
121: */
122: protected ISchedulingRule getUndoSchedulingRule() {
123: return super .computeCreateSchedulingRule();
124: }
125:
126: /*
127: * (non-Javadoc)
128: *
129: * Map execution status to deletion status. Provide an extra warning if
130: * project content is to be deleted.
131: *
132: * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#computeExecutionStatus(org.eclipse.core.runtime.IProgressMonitor)
133: */
134: public IStatus computeExecutionStatus(IProgressMonitor monitor) {
135: IStatus status = super .computeExecutionStatus(monitor);
136: if (status.isOK()) {
137: status = computeDeleteStatus();
138: }
139: return status;
140: }
141:
142: /*
143: * (non-Javadoc)
144: *
145: * Map undo status to resource creation status.
146: *
147: * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#computeUndoableStatus(org.eclipse.core.runtime.IProgressMonitor)
148: */
149: public IStatus computeUndoableStatus(IProgressMonitor monitor) {
150: IStatus status = super .computeUndoableStatus(monitor);
151: if (status.isOK()) {
152: // Recreating should not allow overwriting anything that is there,
153: // because we have no way to restore it.
154: // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=162655
155: status = computeCreateStatus(false);
156: }
157: return status;
158: }
159:
160: /*
161: * (non-Javadoc)
162: *
163: * Map redo status to resource deletion status.
164: *
165: * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#computeRedoableStatus(org.eclipse.core.runtime.IProgressMonitor)
166: */
167: public IStatus computeRedoableStatus(IProgressMonitor monitor) {
168: IStatus status = super .computeRedoableStatus(monitor);
169: if (status.isOK()) {
170: status = computeDeleteStatus();
171: }
172: return status;
173: }
174:
175: /*
176: * (non-Javadoc)
177: *
178: * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#appendDescriptiveText(java.lang.StringBuffer)
179: */
180: protected void appendDescriptiveText(StringBuffer text) {
181: super .appendDescriptiveText(text);
182: text.append(" deleteContent: "); //$NON-NLS-1$
183: text.append(deleteContent);
184: text.append('\'');
185: }
186:
187: /*
188: * Overridden so that projects whose contents are not to be deleted
189: * will not be checked. A better solution would be to add API to
190: * ReadOnlyStateChecker to specify whether project children should
191: * be checked, but it is too late to do that now.
192: * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=180758
193: */
194: IStatus checkReadOnlyResources(IResource[] resourcesToCheck) {
195: // If we aren't deleting content of projects, don't bother
196: // checking the read only status of projects or their children.
197: // Clients currently do not mix and match projects and non-projects
198: // in a DeleteResourcesOperation. However, this is not specified
199: // in the API, so assume that there could be mixes.
200: if (!deleteContent) {
201: ArrayList nonProjectResourcesToCheck = new ArrayList();
202: for (int i = 0; i < resourcesToCheck.length; i++) {
203: if (resourcesToCheck[i].getType() != IResource.PROJECT) {
204: nonProjectResourcesToCheck.add(resourcesToCheck[i]);
205: }
206: }
207: if (nonProjectResourcesToCheck.isEmpty()) {
208: return Status.OK_STATUS;
209: }
210: return super
211: .checkReadOnlyResources((IResource[]) nonProjectResourcesToCheck
212: .toArray(new IResource[nonProjectResourcesToCheck
213: .size()]));
214: }
215: // We are deleting project content, so do it the normal way
216: return super.checkReadOnlyResources(resourcesToCheck);
217: }
218: }
|