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;
44 import net.sourceforge.phpdt.internal.core.DeltaProcessor;
45 import net.sourceforge.phpdt.internal.core.JavaModelManager;
49 * Defines behavior common to all Java Model operations
51 public abstract class JavaModelOperation implements IWorkspaceRunnable, IProgressMonitor {
52 protected interface IPostAction {
54 * Returns the id of this action.
55 * @see JavaModelOperation#postAction
61 void run() throws JavaModelException;
64 * Constants controlling the insertion mode of an action.
65 * @see JavaModelOperation#postAction
67 protected static final int APPEND = 1; // insert at the end
68 protected static final int REMOVEALL_APPEND = 2; // remove all existing ones with same ID, and add new one at the end
69 protected static final int KEEP_EXISTING = 3; // do not insert if already existing with same ID
72 * Whether tracing post actions is enabled.
74 protected static boolean POST_ACTION_VERBOSE;
77 * A list of IPostActions.
79 protected IPostAction[] actions;
80 protected int actionsStart = 0;
81 protected int actionsEnd = -1;
83 * A HashMap of attributes that can be used by operations
85 protected HashMap attributes;
87 public static final String HAS_MODIFIED_RESOURCE_ATTR = "hasModifiedResource"; //$NON-NLS-1$
88 public static final String TRUE = "true"; //$NON-NLS-1$
89 //public static final String FALSE = "false"; //$NON-NLS-1$
92 * The elements this operation operates on,
93 * or <code>null</code> if this operation
94 * does not operate on specific elements.
96 protected IJavaElement[] fElementsToProcess;
98 * The parent elements this operation operates with
99 * or <code>null</code> if this operation
100 * does not operate with specific parent elements.
102 protected IJavaElement[] fParentElements;
104 * An empty collection of <code>IJavaElement</code>s - the common
105 * empty result if no elements are created, or if this
106 * operation is not actually executed.
108 protected static IJavaElement[] NO_ELEMENTS= new IJavaElement[] {};
112 * The elements created by this operation - empty
113 * until the operation actually creates elements.
115 protected IJavaElement[] resultElements= NO_ELEMENTS;
118 * The progress monitor passed into this operation
120 protected IProgressMonitor progressMonitor= null;
122 * A flag indicating whether this operation is nested.
124 protected boolean isNested = false;
126 * Conflict resolution policy - by default do not force (fail on a conflict).
128 protected boolean force= false;
131 * A per thread stack of java model operations (PerThreadObject of ArrayList).
133 protected static PerThreadObject operationStacks = new PerThreadObject();
134 protected JavaModelOperation() {
137 * A common constructor for all Java Model operations.
139 protected JavaModelOperation(IJavaElement[] elements) {
140 fElementsToProcess = elements;
143 * Common constructor for all Java Model operations.
145 protected JavaModelOperation(IJavaElement[] elementsToProcess, IJavaElement[] parentElements) {
146 fElementsToProcess = elementsToProcess;
147 fParentElements= parentElements;
150 * A common constructor for all Java Model operations.
152 protected JavaModelOperation(IJavaElement[] elementsToProcess, IJavaElement[] parentElements, boolean force) {
153 fElementsToProcess = elementsToProcess;
154 fParentElements= parentElements;
158 * A common constructor for all Java Model operations.
160 protected JavaModelOperation(IJavaElement[] elements, boolean force) {
161 fElementsToProcess = elements;
166 * Common constructor for all Java Model operations.
168 protected JavaModelOperation(IJavaElement element) {
169 fElementsToProcess = new IJavaElement[]{element};
172 * A common constructor for all Java Model operations.
174 protected JavaModelOperation(IJavaElement element, boolean force) {
175 fElementsToProcess = new IJavaElement[]{element};
180 * Registers the given action at the end of the list of actions to run.
182 protected void addAction(IPostAction action) {
183 int length = this.actions.length;
184 if (length == ++this.actionsEnd) {
185 System.arraycopy(this.actions, 0, this.actions = new IPostAction[length*2], 0, length);
187 this.actions[this.actionsEnd] = action;
190 * Registers the given delta with the Java Model Manager.
192 protected void addDelta(IJavaElementDelta delta) {
193 JavaModelManager.getJavaModelManager().registerJavaModelDelta(delta);
196 * Registers the given reconcile delta with the Java Model Manager.
198 protected void addReconcileDelta(IWorkingCopy workingCopy, IJavaElementDelta delta) {
199 HashMap reconcileDeltas = JavaModelManager.getJavaModelManager().reconcileDeltas;
200 JavaElementDelta previousDelta = (JavaElementDelta)reconcileDeltas.get(workingCopy);
201 if (previousDelta != null) {
202 IJavaElementDelta[] children = delta.getAffectedChildren();
203 for (int i = 0, length = children.length; i < length; i++) {
204 JavaElementDelta child = (JavaElementDelta)children[i];
205 previousDelta.insertDeltaTree(child.getElement(), child);
208 reconcileDeltas.put(workingCopy, delta);
212 * Deregister the reconcile delta for the given working copy
214 protected void removeReconcileDelta(IWorkingCopy workingCopy) {
215 JavaModelManager.getJavaModelManager().reconcileDeltas.remove(workingCopy);
218 * @see IProgressMonitor
220 public void beginTask(String name, int totalWork) {
221 if (progressMonitor != null) {
222 progressMonitor.beginTask(name, totalWork);
226 * Checks with the progress monitor to see whether this operation
227 * should be canceled. An operation should regularly call this method
228 * during its operation so that the user can cancel it.
230 * @exception OperationCanceledException if cancelling the operation has been requested
231 * @see IProgressMonitor#isCanceled
233 protected void checkCanceled() {
235 throw new OperationCanceledException(Util.bind("operation.cancelled")); //$NON-NLS-1$
239 * Common code used to verify the elements this operation is processing.
240 * @see JavaModelOperation#verify()
242 protected IJavaModelStatus commonVerify() {
243 if (fElementsToProcess == null || fElementsToProcess.length == 0) {
244 return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
246 for (int i = 0; i < fElementsToProcess.length; i++) {
247 if (fElementsToProcess[i] == null) {
248 return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
251 return JavaModelStatus.VERIFIED_OK;
254 * Convenience method to copy resources
256 protected void copyResources(IResource[] resources, IPath destinationPath) throws JavaModelException {
257 IProgressMonitor subProgressMonitor = getSubProgressMonitor(resources.length);
258 IWorkspace workspace = resources[0].getWorkspace();
260 workspace.copy(resources, destinationPath, false, subProgressMonitor);
261 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
262 } catch (CoreException e) {
263 throw new JavaModelException(e);
267 * Convenience method to create a file
269 protected void createFile(IContainer folder, String name, InputStream contents, boolean force) throws JavaModelException {
270 IFile file= folder.getFile(new Path(name));
274 force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
275 getSubProgressMonitor(1));
276 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
277 } catch (CoreException e) {
278 throw new JavaModelException(e);
282 * Convenience method to create a folder
284 protected void createFolder(IContainer parentFolder, String name, boolean force) throws JavaModelException {
285 IFolder folder= parentFolder.getFolder(new Path(name));
287 // we should use true to create the file locally. Only VCM should use tru/false
289 force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
291 getSubProgressMonitor(1));
292 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
293 } catch (CoreException e) {
294 throw new JavaModelException(e);
298 * Convenience method to delete an empty package fragment
300 protected void deleteEmptyPackageFragment(
301 IPackageFragment fragment,
303 IResource rootResource)
304 throws JavaModelException {
306 IContainer resource = (IContainer) fragment.getResource();
310 force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
311 getSubProgressMonitor(1));
312 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
313 while (resource instanceof IFolder) {
314 // deleting a package: delete the parent if it is empty (eg. deleting x.y where folder x doesn't have resources but y)
315 // without deleting the package fragment root
316 resource = resource.getParent();
317 if (!resource.equals(rootResource) && resource.members().length == 0) {
319 force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
320 getSubProgressMonitor(1));
321 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
324 } catch (CoreException e) {
325 throw new JavaModelException(e);
329 * Convenience method to delete a resource
331 protected void deleteResource(IResource resource,int flags) throws JavaModelException {
333 resource.delete(flags, getSubProgressMonitor(1));
334 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
335 } catch (CoreException e) {
336 throw new JavaModelException(e);
340 * Convenience method to delete resources
342 protected void deleteResources(IResource[] resources, boolean force) throws JavaModelException {
343 if (resources == null || resources.length == 0) return;
344 IProgressMonitor subProgressMonitor = getSubProgressMonitor(resources.length);
345 IWorkspace workspace = resources[0].getWorkspace();
349 force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
351 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
352 } catch (CoreException e) {
353 throw new JavaModelException(e);
357 * @see IProgressMonitor
360 if (progressMonitor != null) {
361 progressMonitor.done();
365 * Returns whether the given path is equals to one of the given other paths.
367 protected boolean equalsOneOf(IPath path, IPath[] otherPaths) {
368 for (int i = 0, length = otherPaths.length; i < length; i++) {
369 if (path.equals(otherPaths[i])) {
376 * Verifies the operation can proceed and executes the operation.
377 * Subclasses should override <code>#verify</code> and
378 * <code>executeOperation</code> to implement the specific operation behavior.
380 * @exception JavaModelException The operation has failed.
382 // protected void execute() throws JavaModelException {
383 // IJavaModelStatus status= verify();
384 // if (status.isOK()) {
385 // // if first time here, computes the root infos before executing the operation
386 // DeltaProcessor deltaProcessor = JavaModelManager.getJavaModelManager().deltaProcessor;
387 // if (deltaProcessor.roots == null) {
388 //// TODO khartlage temp-del
389 // deltaProcessor.initializeRoots();
391 // executeOperation();
393 // throw new JavaModelException(status);
398 * Convenience method to run an operation within this operation
400 public void executeNestedOperation(JavaModelOperation operation, int subWorkAmount) throws JavaModelException {
401 IProgressMonitor subProgressMonitor = getSubProgressMonitor(subWorkAmount);
402 // fix for 1FW7IKC, part (1)
404 operation.setNested(true);
405 operation.run(subProgressMonitor);
406 } catch (CoreException ce) {
407 if (ce instanceof JavaModelException) {
408 throw (JavaModelException)ce;
410 // translate the core exception to a java model exception
411 if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) {
412 Throwable e = ce.getStatus().getException();
413 if (e instanceof JavaModelException) {
414 throw (JavaModelException) e;
417 throw new JavaModelException(ce);
422 * Performs the operation specific behavior. Subclasses must override.
424 protected abstract void executeOperation() throws JavaModelException;
426 * Returns the attribute registered at the given key with the top level operation.
427 * Returns null if no such attribute is found.
429 protected Object getAttribute(Object key) {
430 ArrayList stack = this.getCurrentOperationStack();
431 if (stack.size() == 0) return null;
432 JavaModelOperation topLevelOp = (JavaModelOperation)stack.get(0);
433 if (topLevelOp.attributes == null) {
436 return topLevelOp.attributes.get(key);
440 * Returns the compilation unit the given element is contained in,
441 * or the element itself (if it is a compilation unit),
442 * otherwise <code>null</code>.
444 protected ICompilationUnit getCompilationUnitFor(IJavaElement element) {
446 return ((JavaElement)element).getCompilationUnit();
449 * Returns the stack of operations running in the current thread.
450 * Returns an empty stack if no operations are currently running in this thread.
452 protected ArrayList getCurrentOperationStack() {
453 ArrayList stack = (ArrayList)operationStacks.getCurrent();
455 stack = new ArrayList();
456 operationStacks.setCurrent(stack);
461 * Returns the elements to which this operation applies,
462 * or <code>null</code> if not applicable.
464 protected IJavaElement[] getElementsToProcess() {
465 return fElementsToProcess;
468 * Returns the element to which this operation applies,
469 * or <code>null</code> if not applicable.
471 protected IJavaElement getElementToProcess() {
472 if (fElementsToProcess == null || fElementsToProcess.length == 0) {
475 return fElementsToProcess[0];
478 * Returns the Java Model this operation is operating in.
480 public IJavaModel getJavaModel() {
481 if (fElementsToProcess == null || fElementsToProcess.length == 0) {
482 return getParentElement().getJavaModel();
484 return fElementsToProcess[0].getJavaModel();
487 // protected IPath[] getNestedFolders(IPackageFragmentRoot root) throws JavaModelException {
488 // IPath rootPath = root.getPath();
489 // IClasspathEntry[] classpath = root.getJavaProject().getRawClasspath();
490 // int length = classpath.length;
491 // IPath[] result = new IPath[length];
493 // for (int i = 0; i < length; i++) {
494 // IPath path = classpath[i].getPath();
495 // if (rootPath.isPrefixOf(path) && !rootPath.equals(path)) {
496 // result[index++] = path;
499 // if (index < length) {
500 // System.arraycopy(result, 0, result = new IPath[index], 0, index);
505 * Returns the parent element to which this operation applies,
506 * or <code>null</code> if not applicable.
508 protected IJavaElement getParentElement() {
509 if (fParentElements == null || fParentElements.length == 0) {
512 return fParentElements[0];
515 * Returns the parent elements to which this operation applies,
516 * or <code>null</code> if not applicable.
518 protected IJavaElement[] getParentElements() {
519 return fParentElements;
522 * Returns the elements created by this operation.
524 public IJavaElement[] getResultElements() {
525 return resultElements;
528 * Returns the scheduling rule for this operation (i.e. the resource that needs to be locked
529 * while this operation is running.
530 * Subclasses can override.
532 protected ISchedulingRule getSchedulingRule() {
533 return ResourcesPlugin.getWorkspace().getRoot();
536 * Creates and returns a subprogress monitor if appropriate.
538 protected IProgressMonitor getSubProgressMonitor(int workAmount) {
539 IProgressMonitor sub = null;
540 if (progressMonitor != null) {
541 sub = new SubProgressMonitor(progressMonitor, workAmount, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
547 * Returns whether this operation has performed any resource modifications.
548 * Returns false if this operation has not been executed yet.
550 public boolean hasModifiedResource() {
551 return !this.isReadOnly() && this.getAttribute(HAS_MODIFIED_RESOURCE_ATTR) == TRUE;
553 public void internalWorked(double work) {
554 if (progressMonitor != null) {
555 progressMonitor.internalWorked(work);
559 * @see IProgressMonitor
561 public boolean isCanceled() {
562 if (progressMonitor != null) {
563 return progressMonitor.isCanceled();
568 * Returns <code>true</code> if this operation performs no resource modifications,
569 * otherwise <code>false</code>. Subclasses must override.
571 public boolean isReadOnly() {
575 * Returns whether this operation is the first operation to run in the current thread.
577 protected boolean isTopLevelOperation() {
580 (stack = this.getCurrentOperationStack()).size() > 0
581 && stack.get(0) == this;
584 * Returns the index of the first registered action with the given id, starting from a given position.
585 * Returns -1 if not found.
587 protected int firstActionWithID(String id, int start) {
588 for (int i = start; i <= this.actionsEnd; i++) {
589 if (this.actions[i].getID().equals(id)) {
597 * Convenience method to move resources
599 protected void moveResources(IResource[] resources, IPath destinationPath) throws JavaModelException {
600 IProgressMonitor subProgressMonitor = null;
601 if (progressMonitor != null) {
602 subProgressMonitor = new SubProgressMonitor(progressMonitor, resources.length, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
604 IWorkspace workspace = resources[0].getWorkspace();
606 workspace.move(resources, destinationPath, false, subProgressMonitor);
607 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
608 } catch (CoreException e) {
609 throw new JavaModelException(e);
613 * Creates and returns a new <code>IJavaElementDelta</code>
616 public JavaElementDelta newJavaElementDelta() {
617 return new JavaElementDelta(getJavaModel());
620 * Removes the last pushed operation from the stack of running operations.
621 * Returns the poped operation or null if the stack was empty.
623 protected JavaModelOperation popOperation() {
624 ArrayList stack = getCurrentOperationStack();
625 int size = stack.size();
627 if (size == 1) { // top level operation
628 operationStacks.setCurrent(null); // release reference (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=33927)
630 return (JavaModelOperation)stack.remove(size-1);
636 * Registers the given action to be run when the outer most java model operation has finished.
637 * The insertion mode controls whether:
638 * - the action should discard all existing actions with the same id, and be queued at the end (REMOVEALL_APPEND),
639 * - the action should be ignored if there is already an action with the same id (KEEP_EXISTING),
640 * - the action should be queued at the end without looking at existing actions (APPEND)
642 protected void postAction(IPostAction action, int insertionMode) {
643 if (POST_ACTION_VERBOSE) {
644 System.out.print("(" + Thread.currentThread() + ") [JavaModelOperation.postAction(IPostAction, int)] Posting action " + action.getID()); //$NON-NLS-1$ //$NON-NLS-2$
645 switch(insertionMode) {
646 case REMOVEALL_APPEND:
647 System.out.println(" (REMOVEALL_APPEND)"); //$NON-NLS-1$
650 System.out.println(" (KEEP_EXISTING)"); //$NON-NLS-1$
653 System.out.println(" (APPEND)"); //$NON-NLS-1$
658 JavaModelOperation topLevelOp = (JavaModelOperation)getCurrentOperationStack().get(0);
659 IPostAction[] postActions = topLevelOp.actions;
660 if (postActions == null) {
661 topLevelOp.actions = postActions = new IPostAction[1];
662 postActions[0] = action;
663 topLevelOp.actionsEnd = 0;
665 String id = action.getID();
666 switch (insertionMode) {
667 case REMOVEALL_APPEND :
668 int index = this.actionsStart-1;
669 while ((index = topLevelOp.firstActionWithID(id, index+1)) >= 0) {
670 // remove action[index]
671 System.arraycopy(postActions, index+1, postActions, index, topLevelOp.actionsEnd - index);
672 postActions[topLevelOp.actionsEnd--] = null;
674 topLevelOp.addAction(action);
677 if (topLevelOp.firstActionWithID(id, 0) < 0) {
678 topLevelOp.addAction(action);
682 topLevelOp.addAction(action);
688 * Returns whether the given path is the prefix of one of the given other paths.
690 protected boolean prefixesOneOf(IPath path, IPath[] otherPaths) {
691 for (int i = 0, length = otherPaths.length; i < length; i++) {
692 if (path.isPrefixOf(otherPaths[i])) {
699 * Pushes the given operation on the stack of operations currently running in this thread.
701 protected void pushOperation(JavaModelOperation operation) {
702 getCurrentOperationStack().add(operation);
706 * Main entry point for Java Model operations. Executes this operation
707 * and registers any deltas created.
709 * @see IWorkspaceRunnable
710 * @exception CoreException if the operation fails
712 public void run(IProgressMonitor monitor) throws CoreException {
713 JavaModelManager manager = JavaModelManager.getJavaModelManager();
714 DeltaProcessor deltaProcessor = manager.getDeltaProcessor();
715 int previousDeltaCount = deltaProcessor.javaModelDeltas.size();
717 progressMonitor = monitor;
720 // computes the root infos before executing the operation
721 // noop if aready initialized
722 JavaModelManager.getJavaModelManager().deltaState.initializeRoots();
726 if (this.isTopLevelOperation()) {
727 this.runPostActions();
733 // TODO jsurfer temp-del
734 // update JavaModel using deltas that were recorded during this operation
735 // for (int i = previousDeltaCount, size = manager.javaModelDeltas.size(); i < size; i++) {
736 // manager.updateJavaModel((IJavaElementDelta)manager.javaModelDeltas.get(i));
740 // - the operation is a top level operation
741 // - the operation did produce some delta(s)
742 // - but the operation has not modified any resource
743 if (this.isTopLevelOperation()) {
744 if ((manager.javaModelDeltas.size() > previousDeltaCount || !manager.reconcileDeltas.isEmpty())
745 && !this.hasModifiedResource()) {
746 manager.fire(null, JavaModelManager.DEFAULT_CHANGE_EVENT);
747 } // else deltas are fired while processing the resource delta
755 * Main entry point for Java Model operations. Runs a Java Model Operation as an IWorkspaceRunnable
758 public void runOperation(IProgressMonitor monitor) throws JavaModelException {
759 IJavaModelStatus status= verify();
760 if (!status.isOK()) {
761 throw new JavaModelException(status);
767 // Use IWorkspace.run(...) to ensure that a build will be done in autobuild mode.
768 // Note that if the tree is locked, this will throw a CoreException, but this is ok
769 // as this operation is modifying the tree (not read-only) and a CoreException will be thrown anyway.
770 ResourcesPlugin.getWorkspace().run(this, getSchedulingRule(), IWorkspace.AVOID_UPDATE, monitor);
772 } catch (CoreException ce) {
773 if (ce instanceof JavaModelException) {
774 throw (JavaModelException)ce;
776 if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) {
777 Throwable e= ce.getStatus().getException();
778 if (e instanceof JavaModelException) {
779 throw (JavaModelException) e;
782 throw new JavaModelException(ce);
786 protected void runPostActions() throws JavaModelException {
787 while (this.actionsStart <= this.actionsEnd) {
788 IPostAction postAction = this.actions[this.actionsStart++];
789 if (POST_ACTION_VERBOSE) {
790 System.out.println("(" + Thread.currentThread() + ") [JavaModelOperation.runPostActions()] Running action " + postAction.getID()); //$NON-NLS-1$ //$NON-NLS-2$
796 * Registers the given attribute at the given key with the top level operation.
798 protected void setAttribute(Object key, Object attribute) {
799 JavaModelOperation topLevelOp = (JavaModelOperation)this.getCurrentOperationStack().get(0);
800 if (topLevelOp.attributes == null) {
801 topLevelOp.attributes = new HashMap();
803 topLevelOp.attributes.put(key, attribute);
806 * @see IProgressMonitor
808 public void setCanceled(boolean b) {
809 if (progressMonitor != null) {
810 progressMonitor.setCanceled(b);
814 * Sets whether this operation is nested or not.
815 * @see CreateElementInCUOperation#checkCanceled
817 protected void setNested(boolean nested) {
821 * @see IProgressMonitor
823 public void setTaskName(String name) {
824 if (progressMonitor != null) {
825 progressMonitor.setTaskName(name);
829 * @see IProgressMonitor
831 public void subTask(String name) {
832 if (progressMonitor != null) {
833 progressMonitor.subTask(name);
837 * Returns a status indicating if there is any known reason
838 * this operation will fail. Operations are verified before they
841 * Subclasses must override if they have any conditions to verify
842 * before this operation executes.
844 * @see IJavaModelStatus
846 protected IJavaModelStatus verify() {
847 return commonVerify();
851 * @see IProgressMonitor
853 public void worked(int work) {
854 if (progressMonitor != null) {
855 progressMonitor.worked(work);