KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > cheatsheets > composite > model > SuccesorTaskFinder


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.ui.internal.cheatsheets.composite.model;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.ui.internal.provisional.cheatsheets.ICompositeCheatSheetTask;
18 import org.eclipse.ui.internal.provisional.cheatsheets.ITaskGroup;
19
20 public class SuccesorTaskFinder {
21     
22     private AbstractTask currentTask;
23     ICompositeCheatSheetTask bestLaterTask;
24     ICompositeCheatSheetTask bestEarlierTask;
25     private boolean seenThisTask;
26
27     public SuccesorTaskFinder(ICompositeCheatSheetTask task) {
28         currentTask = (AbstractTask)task;
29     }
30     
31     /**
32      * Find the next recommended task or tasks to be completed.
33      * Algorithm - visualize the tree as having its root at the top,
34      * children below and to the left of their parents and then
35      * search the tree from left to right. Look for
36      * the best predecessor which is the first task to the
37      * left of this task that is runnable and the best successor
38      * which is the first task to the
39      * right of this task which is runnable.
40      * @param task The task which was just completed
41      * @return An array of tasks which can be started
42      */

43     public ICompositeCheatSheetTask[] getRecommendedSuccessors()
44     {
45         // TODO this code could be moved to TaskGroup
46
if (ITaskGroup.CHOICE.equals(currentTask.getKind())) {
47             // For a choice if more than one child is runnable return it
48
List JavaDoc runnableChoices = findRunnableChoices();
49             if (runnableChoices.size() != 0) {
50                 return (ICompositeCheatSheetTask[])runnableChoices.toArray
51                 ( new ICompositeCheatSheetTask[runnableChoices.size()]);
52             }
53         }
54         return getBestSuccessor();
55     }
56
57     private List JavaDoc findRunnableChoices() {
58         List JavaDoc result;
59         result = new ArrayList JavaDoc();
60         if (isStartable(currentTask)) {
61             ICompositeCheatSheetTask[] subtasks = currentTask.getSubtasks();
62             for (int i = 0; i < subtasks.length; i++) {
63                 if (isStartable(subtasks[i])) {
64                     result.add(subtasks[i]);
65                 }
66             }
67         }
68         return result;
69     }
70
71     private boolean isStartable(ICompositeCheatSheetTask task) {
72         int state = task.getState();
73         return (state != ICompositeCheatSheetTask.COMPLETED &&
74                 state != ICompositeCheatSheetTask.SKIPPED &&
75                 task.requiredTasksCompleted());
76     }
77
78     private ICompositeCheatSheetTask[] getBestSuccessor() {
79         bestLaterTask = null;
80         bestEarlierTask = null;
81         seenThisTask = false;
82         searchRunnableChildren(currentTask.getCompositeCheatSheet().getRootTask());
83         // If there is a task which is found later in the tree return
84
// that, otherwise an earlier task.
85
if (bestLaterTask != null) {
86             return new ICompositeCheatSheetTask[] {bestLaterTask};
87         }
88         if (bestEarlierTask != null) {
89             return new ICompositeCheatSheetTask[] {bestEarlierTask};
90         }
91         return new ICompositeCheatSheetTask[0];
92     }
93
94     private void searchRunnableChildren(ICompositeCheatSheetTask task) {
95         // Don't search completed tasks or their children
96
// and stop searching if we've already found the best successor
97
if (bestLaterTask != null) {
98             return;
99         }
100         if (task == currentTask) {
101             seenThisTask = true;
102         }
103         if (task.getState() == ICompositeCheatSheetTask.COMPLETED ||
104             task.getState() == ICompositeCheatSheetTask.SKIPPED ) {
105             if (isTaskAncestor(task, currentTask)) {
106                 seenThisTask = true;
107             }
108             return;
109         }
110         
111         if ( isStartable(task) && task != currentTask) {
112             if (seenThisTask) {
113                 if (bestLaterTask == null) {
114                     bestLaterTask = task;
115                 }
116             } else {
117                 if (bestEarlierTask == null) {
118                     bestEarlierTask = task;
119                 }
120             }
121         }
122
123         ICompositeCheatSheetTask[] subtasks = task.getSubtasks();
124         for (int i = 0; i < subtasks.length; i++) {
125             searchRunnableChildren(subtasks[i]);
126         }
127
128     }
129
130     private boolean isTaskAncestor(ICompositeCheatSheetTask ancestorCandididate, ICompositeCheatSheetTask task) {
131         ICompositeCheatSheetTask nextTask = task;
132         while (nextTask != null) {
133             if (nextTask == ancestorCandididate) {
134                 return true;
135             }
136             nextTask = nextTask.getParent();
137         }
138         return false;
139     }
140 }
141
Popular Tags