01: /*******************************************************************************
02: * Copyright (c) 2006 IBM Corporation and others.
03: * All rights reserved. This program and the accompanying materials
04: * are made available under the terms of the Eclipse Public License v1.0
05: * which accompanies this distribution, and is available at
06: * http://www.eclipse.org/legal/epl-v10.html
07: *
08: * Contributors:
09: * IBM Corporation - initial API and implementation
10: *******************************************************************************/package org.eclipse.ui.internal.cheatsheets.composite.model;
11:
12: import java.util.HashSet;
13: import java.util.Iterator;
14: import java.util.Set;
15:
16: import org.eclipse.ui.internal.provisional.cheatsheets.ICompositeCheatSheetTask;
17:
18: public class BlockedTaskFinder {
19:
20: private Set stateChangedTasks;
21: private Set impactedTasks;
22:
23: /**
24: * Find which tasks have either become blocked or unblocked so that they
25: * can be added to the list of change events.
26: * @param stateChangedTasks The set of tasks which has changed
27: * @return The set of tasks which have become blocked or unblocked by the
28: * change of state and were not in the original set. The algorithm will sometimes add tasks to
29: * the result set which were not actually impacted but this is not a major problem
30: * since it only means that extra events get sent to the explorer. For updates other
31: * than resets the number of extra events is very low.
32: *
33: * This takes several steps.
34: * <li> If a group is completed, skipped or reset add any non-started children.
35: * <li> Determine all successors of tasks whose state has changed that are not in the change set
36: * <li> Add the successor and its children to the list if not started
37: */
38:
39: public Set findBlockedTaskChanges(Set stateChangedTasks) {
40: this .stateChangedTasks = stateChangedTasks;
41: impactedTasks = new HashSet();
42: visitChangedTasks();
43: findSuccesors();
44: return impactedTasks;
45: }
46:
47: private void visitChangedTasks() {
48: for (Iterator iter = stateChangedTasks.iterator(); iter
49: .hasNext();) {
50: final ICompositeCheatSheetTask nextTask = (ICompositeCheatSheetTask) iter
51: .next();
52: if (nextTask.getState() != ICompositeCheatSheetTask.IN_PROGRESS) {
53: findUnstartedChildren(nextTask);
54: }
55: }
56: }
57:
58: /*
59: * Look for children which we have not seen elsewhere and if they are not started
60: * add them to the list of impacted tasks.
61: */
62: private void findUnstartedChildren(ICompositeCheatSheetTask task) {
63: ICompositeCheatSheetTask[] children = task.getSubtasks();
64: for (int i = 0; i < children.length; i++) {
65: ICompositeCheatSheetTask nextChild = children[i];
66: // Ignore if this task has been seen before
67: if ((!stateChangedTasks.contains(nextChild))
68: && !impactedTasks.contains(nextChild)) {
69: if (nextChild.getState() == ICompositeCheatSheetTask.NOT_STARTED) {
70: impactedTasks.add(nextChild);
71: }
72: findUnstartedChildren(nextChild);
73: }
74: }
75: }
76:
77: private void findSuccesors() {
78: for (Iterator iter = stateChangedTasks.iterator(); iter
79: .hasNext();) {
80: final AbstractTask nextTask = (AbstractTask) iter.next();
81: ICompositeCheatSheetTask[] successors = nextTask
82: .getSuccessorTasks();
83: for (int i = 0; i < successors.length; i++) {
84: ICompositeCheatSheetTask nextSuccessor = successors[i];
85: if (nextSuccessor.getState() == ICompositeCheatSheetTask.NOT_STARTED) {
86: impactedTasks.add(nextSuccessor);
87: }
88: findUnstartedChildren(nextSuccessor);
89: }
90: }
91: }
92:
93: }
|