1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
13 import java.io.InputStream;
14 import java.util.ArrayList;
15 import java.util.HashMap;
17 import net.sourceforge.phpdt.core.ICompilationUnit;
18 import net.sourceforge.phpdt.core.IJavaElement;
19 import net.sourceforge.phpdt.core.IJavaElementDelta;
20 import net.sourceforge.phpdt.core.IJavaModel;
21 import net.sourceforge.phpdt.core.IJavaModelStatus;
22 import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
23 import net.sourceforge.phpdt.core.IPackageFragment;
24 import net.sourceforge.phpdt.core.IWorkingCopy;
25 import net.sourceforge.phpdt.core.JavaModelException;
26 import net.sourceforge.phpdt.internal.core.util.PerThreadObject;
27 import net.sourceforge.phpdt.internal.core.util.Util;
29 import org.eclipse.core.resources.IContainer;
30 import org.eclipse.core.resources.IFile;
31 import org.eclipse.core.resources.IFolder;
32 import org.eclipse.core.resources.IResource;
33 import org.eclipse.core.resources.IResourceStatus;
34 import org.eclipse.core.resources.IWorkspace;
35 import org.eclipse.core.resources.IWorkspaceRunnable;
36 import org.eclipse.core.resources.ResourcesPlugin;
37 import org.eclipse.core.runtime.CoreException;
38 import org.eclipse.core.runtime.IPath;
39 import org.eclipse.core.runtime.IProgressMonitor;
40 import org.eclipse.core.runtime.OperationCanceledException;
41 import org.eclipse.core.runtime.Path;
42 import org.eclipse.core.runtime.SubProgressMonitor;
43 import org.eclipse.core.runtime.jobs.ISchedulingRule;
46 * Defines behavior common to all Java Model operations
48 public abstract class JavaModelOperation implements IWorkspaceRunnable,
50 protected interface IPostAction {
52 * Returns the id of this action.
54 * @see JavaModelOperation#postAction
61 void run() throws JavaModelException;
65 * Constants controlling the insertion mode of an action.
67 * @see JavaModelOperation#postAction
69 protected static final int APPEND = 1; // insert at the end
71 protected static final int REMOVEALL_APPEND = 2; // remove all existing
76 protected static final int KEEP_EXISTING = 3; // do not insert if already
77 // existing with same ID
80 * Whether tracing post actions is enabled.
82 protected static boolean POST_ACTION_VERBOSE;
85 * A list of IPostActions.
87 protected IPostAction[] actions;
89 protected int actionsStart = 0;
91 protected int actionsEnd = -1;
94 * A HashMap of attributes that can be used by operations
96 protected HashMap attributes;
98 public static final String HAS_MODIFIED_RESOURCE_ATTR = "hasModifiedResource"; //$NON-NLS-1$
100 public static final String TRUE = "true"; //$NON-NLS-1$
102 // public static final String FALSE = "false"; //$NON-NLS-1$
105 * The elements this operation operates on, or <code>null</code> if this
106 * operation does not operate on specific elements.
108 protected IJavaElement[] fElementsToProcess;
111 * The parent elements this operation operates with or <code>null</code>
112 * if this operation does not operate with specific parent elements.
114 protected IJavaElement[] fParentElements;
117 * An empty collection of <code>IJavaElement</code> s - the common empty
118 * result if no elements are created, or if this operation is not actually
121 protected static IJavaElement[] NO_ELEMENTS = new IJavaElement[] {};
124 * The elements created by this operation - empty until the operation
125 * actually creates elements.
127 protected IJavaElement[] resultElements = NO_ELEMENTS;
130 * The progress monitor passed into this operation
132 protected IProgressMonitor progressMonitor = null;
135 * A flag indicating whether this operation is nested.
137 protected boolean isNested = false;
140 * Conflict resolution policy - by default do not force (fail on a
143 protected boolean force = false;
146 * A per thread stack of java model operations (PerThreadObject of
149 protected static PerThreadObject operationStacks = new PerThreadObject();
151 protected JavaModelOperation() {
155 * A common constructor for all Java Model operations.
157 protected JavaModelOperation(IJavaElement[] elements) {
158 fElementsToProcess = elements;
162 * Common constructor for all Java Model operations.
164 protected JavaModelOperation(IJavaElement[] elementsToProcess,
165 IJavaElement[] parentElements) {
166 fElementsToProcess = elementsToProcess;
167 fParentElements = parentElements;
171 * A common constructor for all Java Model operations.
173 protected JavaModelOperation(IJavaElement[] elementsToProcess,
174 IJavaElement[] parentElements, boolean force) {
175 fElementsToProcess = elementsToProcess;
176 fParentElements = parentElements;
181 * A common constructor for all Java Model operations.
183 protected JavaModelOperation(IJavaElement[] elements, boolean force) {
184 fElementsToProcess = elements;
189 * Common constructor for all Java Model operations.
191 protected JavaModelOperation(IJavaElement element) {
192 fElementsToProcess = new IJavaElement[] { element };
196 * A common constructor for all Java Model operations.
198 protected JavaModelOperation(IJavaElement element, boolean force) {
199 fElementsToProcess = new IJavaElement[] { element };
204 * Registers the given action at the end of the list of actions to run.
206 protected void addAction(IPostAction action) {
207 int length = this.actions.length;
208 if (length == ++this.actionsEnd) {
209 System.arraycopy(this.actions, 0,
210 this.actions = new IPostAction[length * 2], 0, length);
212 this.actions[this.actionsEnd] = action;
216 * Registers the given delta with the Java Model Manager.
218 protected void addDelta(IJavaElementDelta delta) {
219 JavaModelManager.getJavaModelManager().registerJavaModelDelta(delta);
223 * Registers the given reconcile delta with the Java Model Manager.
225 protected void addReconcileDelta(IWorkingCopy workingCopy,
226 IJavaElementDelta delta) {
227 HashMap reconcileDeltas = JavaModelManager.getJavaModelManager().reconcileDeltas;
228 JavaElementDelta previousDelta = (JavaElementDelta) reconcileDeltas
230 if (previousDelta != null) {
231 IJavaElementDelta[] children = delta.getAffectedChildren();
232 for (int i = 0, length = children.length; i < length; i++) {
233 JavaElementDelta child = (JavaElementDelta) children[i];
234 previousDelta.insertDeltaTree(child.getElement(), child);
237 reconcileDeltas.put(workingCopy, delta);
242 * Deregister the reconcile delta for the given working copy
244 protected void removeReconcileDelta(IWorkingCopy workingCopy) {
245 JavaModelManager.getJavaModelManager().reconcileDeltas
246 .remove(workingCopy);
250 * @see IProgressMonitor
252 public void beginTask(String name, int totalWork) {
253 if (progressMonitor != null) {
254 progressMonitor.beginTask(name, totalWork);
259 * Checks with the progress monitor to see whether this operation should be
260 * canceled. An operation should regularly call this method during its
261 * operation so that the user can cancel it.
263 * @exception OperationCanceledException
264 * if cancelling the operation has been requested
265 * @see IProgressMonitor#isCanceled
267 protected void checkCanceled() {
269 throw new OperationCanceledException(Util
270 .bind("operation.cancelled")); //$NON-NLS-1$
275 * Common code used to verify the elements this operation is processing.
277 * @see JavaModelOperation#verify()
279 protected IJavaModelStatus commonVerify() {
280 if (fElementsToProcess == null || fElementsToProcess.length == 0) {
281 return new JavaModelStatus(
282 IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
284 for (int i = 0; i < fElementsToProcess.length; i++) {
285 if (fElementsToProcess[i] == null) {
286 return new JavaModelStatus(
287 IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
290 return JavaModelStatus.VERIFIED_OK;
294 * Convenience method to copy resources
296 protected void copyResources(IResource[] resources, IPath destinationPath)
297 throws JavaModelException {
298 IProgressMonitor subProgressMonitor = getSubProgressMonitor(resources.length);
299 IWorkspace workspace = resources[0].getWorkspace();
301 workspace.copy(resources, destinationPath, false,
303 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
304 } catch (CoreException e) {
305 throw new JavaModelException(e);
310 * Convenience method to create a file
312 protected void createFile(IContainer folder, String name,
313 InputStream contents, boolean force) throws JavaModelException {
314 IFile file = folder.getFile(new Path(name));
316 file.create(contents, force ? IResource.FORCE
317 | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
318 getSubProgressMonitor(1));
319 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
320 } catch (CoreException e) {
321 throw new JavaModelException(e);
326 * Convenience method to create a folder
328 protected void createFolder(IContainer parentFolder, String name,
329 boolean force) throws JavaModelException {
330 IFolder folder = parentFolder.getFolder(new Path(name));
332 // we should use true to create the file locally. Only VCM should
334 folder.create(force ? IResource.FORCE | IResource.KEEP_HISTORY
335 : IResource.KEEP_HISTORY, true, // local
336 getSubProgressMonitor(1));
337 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
338 } catch (CoreException e) {
339 throw new JavaModelException(e);
344 * Convenience method to delete an empty package fragment
346 protected void deleteEmptyPackageFragment(IPackageFragment fragment,
347 boolean force, IResource rootResource) throws JavaModelException {
349 IContainer resource = (IContainer) fragment.getResource();
352 resource.delete(force ? IResource.FORCE | IResource.KEEP_HISTORY
353 : IResource.KEEP_HISTORY, getSubProgressMonitor(1));
354 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
355 while (resource instanceof IFolder) {
356 // deleting a package: delete the parent if it is empty (eg.
357 // deleting x.y where folder x doesn't have resources but y)
358 // without deleting the package fragment root
359 resource = resource.getParent();
360 if (!resource.equals(rootResource)
361 && resource.members().length == 0) {
362 resource.delete(force ? IResource.FORCE
363 | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
364 getSubProgressMonitor(1));
365 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
368 } catch (CoreException e) {
369 throw new JavaModelException(e);
374 * Convenience method to delete a resource
376 protected void deleteResource(IResource resource, int flags)
377 throws JavaModelException {
379 resource.delete(flags, getSubProgressMonitor(1));
380 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
381 } catch (CoreException e) {
382 throw new JavaModelException(e);
387 * Convenience method to delete resources
389 protected void deleteResources(IResource[] resources, boolean force)
390 throws JavaModelException {
391 if (resources == null || resources.length == 0)
393 IProgressMonitor subProgressMonitor = getSubProgressMonitor(resources.length);
394 IWorkspace workspace = resources[0].getWorkspace();
396 workspace.delete(resources, force ? IResource.FORCE
397 | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
399 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
400 } catch (CoreException e) {
401 throw new JavaModelException(e);
406 * @see IProgressMonitor
409 if (progressMonitor != null) {
410 progressMonitor.done();
415 * Returns whether the given path is equals to one of the given other paths.
417 protected boolean equalsOneOf(IPath path, IPath[] otherPaths) {
418 for (int i = 0, length = otherPaths.length; i < length; i++) {
419 if (path.equals(otherPaths[i])) {
427 * Verifies the operation can proceed and executes the operation. Subclasses
428 * should override <code>#verify</code> and <code>executeOperation</code>
429 * to implement the specific operation behavior.
431 * @exception JavaModelException
432 * The operation has failed.
434 // protected void execute() throws JavaModelException {
435 // IJavaModelStatus status= verify();
436 // if (status.isOK()) {
437 // // if first time here, computes the root infos before executing the
439 // DeltaProcessor deltaProcessor =
440 // JavaModelManager.getJavaModelManager().deltaProcessor;
441 // if (deltaProcessor.roots == null) {
442 // deltaProcessor.initializeRoots();
444 // executeOperation();
446 // throw new JavaModelException(status);
450 * Convenience method to run an operation within this operation
452 public void executeNestedOperation(JavaModelOperation operation,
453 int subWorkAmount) throws JavaModelException {
454 IProgressMonitor subProgressMonitor = getSubProgressMonitor(subWorkAmount);
455 // fix for 1FW7IKC, part (1)
457 operation.setNested(true);
458 operation.run(subProgressMonitor);
459 } catch (CoreException ce) {
460 if (ce instanceof JavaModelException) {
461 throw (JavaModelException) ce;
463 // translate the core exception to a java model exception
464 if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) {
465 Throwable e = ce.getStatus().getException();
466 if (e instanceof JavaModelException) {
467 throw (JavaModelException) e;
470 throw new JavaModelException(ce);
476 * Performs the operation specific behavior. Subclasses must override.
478 protected abstract void executeOperation() throws JavaModelException;
481 * Returns the attribute registered at the given key with the top level
482 * operation. Returns null if no such attribute is found.
484 protected Object getAttribute(Object key) {
485 ArrayList stack = this.getCurrentOperationStack();
486 if (stack.size() == 0)
488 JavaModelOperation topLevelOp = (JavaModelOperation) stack.get(0);
489 if (topLevelOp.attributes == null) {
492 return topLevelOp.attributes.get(key);
497 * Returns the compilation unit the given element is contained in, or the
498 * element itself (if it is a compilation unit), otherwise <code>null</code>.
500 protected ICompilationUnit getCompilationUnitFor(IJavaElement element) {
502 return ((JavaElement) element).getCompilationUnit();
506 * Returns the stack of operations running in the current thread. Returns an
507 * empty stack if no operations are currently running in this thread.
509 protected ArrayList getCurrentOperationStack() {
510 ArrayList stack = (ArrayList) operationStacks.getCurrent();
512 stack = new ArrayList();
513 operationStacks.setCurrent(stack);
519 * Returns the elements to which this operation applies, or
520 * <code>null</code> if not applicable.
522 protected IJavaElement[] getElementsToProcess() {
523 return fElementsToProcess;
527 * Returns the element to which this operation applies, or <code>null</code>
530 protected IJavaElement getElementToProcess() {
531 if (fElementsToProcess == null || fElementsToProcess.length == 0) {
534 return fElementsToProcess[0];
538 * Returns the Java Model this operation is operating in.
540 public IJavaModel getJavaModel() {
541 if (fElementsToProcess == null || fElementsToProcess.length == 0) {
542 return getParentElement().getJavaModel();
544 return fElementsToProcess[0].getJavaModel();
548 // protected IPath[] getNestedFolders(IPackageFragmentRoot root) throws
549 // JavaModelException {
550 // IPath rootPath = root.getPath();
551 // IClasspathEntry[] classpath = root.getJavaProject().getRawClasspath();
552 // int length = classpath.length;
553 // IPath[] result = new IPath[length];
555 // for (int i = 0; i < length; i++) {
556 // IPath path = classpath[i].getPath();
557 // if (rootPath.isPrefixOf(path) && !rootPath.equals(path)) {
558 // result[index++] = path;
561 // if (index < length) {
562 // System.arraycopy(result, 0, result = new IPath[index], 0, index);
567 * Returns the parent element to which this operation applies, or
568 * <code>null</code> if not applicable.
570 protected IJavaElement getParentElement() {
571 if (fParentElements == null || fParentElements.length == 0) {
574 return fParentElements[0];
578 * Returns the parent elements to which this operation applies, or
579 * <code>null</code> if not applicable.
581 protected IJavaElement[] getParentElements() {
582 return fParentElements;
586 * Returns the elements created by this operation.
588 public IJavaElement[] getResultElements() {
589 return resultElements;
593 * Returns the scheduling rule for this operation (i.e. the resource that
594 * needs to be locked while this operation is running. Subclasses can
597 protected ISchedulingRule getSchedulingRule() {
598 return ResourcesPlugin.getWorkspace().getRoot();
602 * Creates and returns a subprogress monitor if appropriate.
604 protected IProgressMonitor getSubProgressMonitor(int workAmount) {
605 IProgressMonitor sub = null;
606 if (progressMonitor != null) {
607 sub = new SubProgressMonitor(progressMonitor, workAmount,
608 SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
614 * Returns whether this operation has performed any resource modifications.
615 * Returns false if this operation has not been executed yet.
617 public boolean hasModifiedResource() {
618 return !this.isReadOnly()
619 && this.getAttribute(HAS_MODIFIED_RESOURCE_ATTR) == TRUE;
622 public void internalWorked(double work) {
623 if (progressMonitor != null) {
624 progressMonitor.internalWorked(work);
629 * @see IProgressMonitor
631 public boolean isCanceled() {
632 if (progressMonitor != null) {
633 return progressMonitor.isCanceled();
639 * Returns <code>true</code> if this operation performs no resource
640 * modifications, otherwise <code>false</code>. Subclasses must override.
642 public boolean isReadOnly() {
647 * Returns whether this operation is the first operation to run in the
650 protected boolean isTopLevelOperation() {
652 return (stack = this.getCurrentOperationStack()).size() > 0
653 && stack.get(0) == this;
657 * Returns the index of the first registered action with the given id,
658 * starting from a given position. Returns -1 if not found.
660 protected int firstActionWithID(String id, int start) {
661 for (int i = start; i <= this.actionsEnd; i++) {
662 if (this.actions[i].getID().equals(id)) {
670 * Convenience method to move resources
672 protected void moveResources(IResource[] resources, IPath destinationPath)
673 throws JavaModelException {
674 IProgressMonitor subProgressMonitor = null;
675 if (progressMonitor != null) {
676 subProgressMonitor = new SubProgressMonitor(progressMonitor,
678 SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
680 IWorkspace workspace = resources[0].getWorkspace();
682 workspace.move(resources, destinationPath, false,
684 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
685 } catch (CoreException e) {
686 throw new JavaModelException(e);
691 * Creates and returns a new <code>IJavaElementDelta</code> on the Java
694 public JavaElementDelta newJavaElementDelta() {
695 return new JavaElementDelta(getJavaModel());
699 * Removes the last pushed operation from the stack of running operations.
700 * Returns the poped operation or null if the stack was empty.
702 protected JavaModelOperation popOperation() {
703 ArrayList stack = getCurrentOperationStack();
704 int size = stack.size();
706 if (size == 1) { // top level operation
707 operationStacks.setCurrent(null); // release reference (see
708 // http://bugs.eclipse.org/bugs/show_bug.cgi?id=33927)
710 return (JavaModelOperation) stack.remove(size - 1);
717 * Registers the given action to be run when the outer most java model
718 * operation has finished. The insertion mode controls whether: - the action
719 * should discard all existing actions with the same id, and be queued at
720 * the end (REMOVEALL_APPEND), - the action should be ignored if there is
721 * already an action with the same id (KEEP_EXISTING), - the action should
722 * be queued at the end without looking at existing actions (APPEND)
724 protected void postAction(IPostAction action, int insertionMode) {
725 if (POST_ACTION_VERBOSE) {
727 .print("(" + Thread.currentThread() + ") [JavaModelOperation.postAction(IPostAction, int)] Posting action " + action.getID()); //$NON-NLS-1$ //$NON-NLS-2$
728 switch (insertionMode) {
729 case REMOVEALL_APPEND:
730 System.out.println(" (REMOVEALL_APPEND)"); //$NON-NLS-1$
733 System.out.println(" (KEEP_EXISTING)"); //$NON-NLS-1$
736 System.out.println(" (APPEND)"); //$NON-NLS-1$
741 JavaModelOperation topLevelOp = (JavaModelOperation) getCurrentOperationStack()
743 IPostAction[] postActions = topLevelOp.actions;
744 if (postActions == null) {
745 topLevelOp.actions = postActions = new IPostAction[1];
746 postActions[0] = action;
747 topLevelOp.actionsEnd = 0;
749 String id = action.getID();
750 switch (insertionMode) {
751 case REMOVEALL_APPEND:
752 int index = this.actionsStart - 1;
753 while ((index = topLevelOp.firstActionWithID(id, index + 1)) >= 0) {
754 // remove action[index]
755 System.arraycopy(postActions, index + 1, postActions,
756 index, topLevelOp.actionsEnd - index);
757 postActions[topLevelOp.actionsEnd--] = null;
759 topLevelOp.addAction(action);
762 if (topLevelOp.firstActionWithID(id, 0) < 0) {
763 topLevelOp.addAction(action);
767 topLevelOp.addAction(action);
774 * Returns whether the given path is the prefix of one of the given other
777 protected boolean prefixesOneOf(IPath path, IPath[] otherPaths) {
778 for (int i = 0, length = otherPaths.length; i < length; i++) {
779 if (path.isPrefixOf(otherPaths[i])) {
787 * Pushes the given operation on the stack of operations currently running
790 protected void pushOperation(JavaModelOperation operation) {
791 getCurrentOperationStack().add(operation);
795 * Main entry point for Java Model operations. Executes this operation and
796 * registers any deltas created.
798 * @see IWorkspaceRunnable
799 * @exception CoreException
800 * if the operation fails
802 public void run(IProgressMonitor monitor) throws CoreException {
803 JavaModelManager manager = JavaModelManager.getJavaModelManager();
804 DeltaProcessor deltaProcessor = manager.getDeltaProcessor();
805 int previousDeltaCount = deltaProcessor.javaModelDeltas.size();
807 progressMonitor = monitor;
810 // computes the root infos before executing the operation
811 // noop if aready initialized
812 JavaModelManager.getJavaModelManager().deltaState
817 if (this.isTopLevelOperation()) {
818 this.runPostActions();
824 // update JavaModel using deltas that were recorded during this
826 for (int i = previousDeltaCount, size = manager.javaModelDeltas
827 .size(); i < size; i++) {
829 .updateJavaModel((IJavaElementDelta) manager.javaModelDeltas
834 // - the operation is a top level operation
835 // - the operation did produce some delta(s)
836 // - but the operation has not modified any resource
837 if (this.isTopLevelOperation()) {
838 if ((manager.javaModelDeltas.size() > previousDeltaCount || !manager.reconcileDeltas
840 && !this.hasModifiedResource()) {
842 JavaModelManager.DEFAULT_CHANGE_EVENT);
843 } // else deltas are fired while processing the resource
853 * Main entry point for Java Model operations. Runs a Java Model Operation
854 * as an IWorkspaceRunnable if not read-only.
856 public void runOperation(IProgressMonitor monitor)
857 throws JavaModelException {
858 IJavaModelStatus status = verify();
859 if (!status.isOK()) {
860 throw new JavaModelException(status);
866 // Use IWorkspace.run(...) to ensure that a build will be done
867 // in autobuild mode.
868 // Note that if the tree is locked, this will throw a
869 // CoreException, but this is ok
870 // as this operation is modifying the tree (not read-only) and a
871 // CoreException will be thrown anyway.
872 ResourcesPlugin.getWorkspace().run(this, getSchedulingRule(),
873 IWorkspace.AVOID_UPDATE, monitor);
875 } catch (CoreException ce) {
876 if (ce instanceof JavaModelException) {
877 throw (JavaModelException) ce;
879 if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) {
880 Throwable e = ce.getStatus().getException();
881 if (e instanceof JavaModelException) {
882 throw (JavaModelException) e;
885 throw new JavaModelException(ce);
890 protected void runPostActions() throws JavaModelException {
891 while (this.actionsStart <= this.actionsEnd) {
892 IPostAction postAction = this.actions[this.actionsStart++];
893 if (POST_ACTION_VERBOSE) {
895 .println("(" + Thread.currentThread() + ") [JavaModelOperation.runPostActions()] Running action " + postAction.getID()); //$NON-NLS-1$ //$NON-NLS-2$
902 * Registers the given attribute at the given key with the top level
905 protected void setAttribute(Object key, Object attribute) {
906 JavaModelOperation topLevelOp = (JavaModelOperation) this
907 .getCurrentOperationStack().get(0);
908 if (topLevelOp.attributes == null) {
909 topLevelOp.attributes = new HashMap();
911 topLevelOp.attributes.put(key, attribute);
915 * @see IProgressMonitor
917 public void setCanceled(boolean b) {
918 if (progressMonitor != null) {
919 progressMonitor.setCanceled(b);
924 * Sets whether this operation is nested or not.
926 * @see CreateElementInCUOperation#checkCanceled
928 protected void setNested(boolean nested) {
933 * @see IProgressMonitor
935 public void setTaskName(String name) {
936 if (progressMonitor != null) {
937 progressMonitor.setTaskName(name);
942 * @see IProgressMonitor
944 public void subTask(String name) {
945 if (progressMonitor != null) {
946 progressMonitor.subTask(name);
951 * Returns a status indicating if there is any known reason this operation
952 * will fail. Operations are verified before they are run.
954 * Subclasses must override if they have any conditions to verify before
955 * this operation executes.
957 * @see IJavaModelStatus
959 protected IJavaModelStatus verify() {
960 return commonVerify();
964 * @see IProgressMonitor
966 public void worked(int work) {
967 if (progressMonitor != null) {
968 progressMonitor.worked(work);