001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 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.internal.cheatsheets.composite.model;
011:
012: import java.net.MalformedURLException;
013: import java.net.URL;
014: import java.util.ArrayList;
015: import java.util.Dictionary;
016: import java.util.Hashtable;
017:
018: import org.eclipse.core.runtime.Platform;
019: import org.eclipse.ui.internal.cheatsheets.composite.parser.ITaskParseStrategy;
020: import org.eclipse.ui.internal.provisional.cheatsheets.ICompositeCheatSheet;
021: import org.eclipse.ui.internal.provisional.cheatsheets.ICompositeCheatSheetTask;
022: import org.eclipse.ui.internal.provisional.cheatsheets.ITaskGroup;
023: import org.osgi.framework.Bundle;
024:
025: /**
026: * A single task within a composite cheatsheet. This class encapsulates the
027: * behavior common to editable tasks and taskGroups
028: */
029:
030: public abstract class AbstractTask implements ICompositeCheatSheetTask {
031: protected CompositeCheatSheetModel model;
032: protected int state = NOT_STARTED;
033: private String id;
034:
035: private String name;
036:
037: protected String kind;
038:
039: private Dictionary parameters;
040:
041: private String description;
042:
043: private String completionMessage;
044:
045: private ArrayList requiredTasks;
046:
047: private ArrayList successorTasks;
048:
049: private boolean skippable;
050:
051: private TaskGroup parent;
052:
053: protected static final ICompositeCheatSheetTask[] EMPTY = new ICompositeCheatSheetTask[0];
054:
055: public AbstractTask(CompositeCheatSheetModel model, String id,
056: String name, String kind) {
057: this .model = model;
058: this .id = id;
059: this .name = name;
060: this .kind = kind;
061: this .parameters = new Hashtable();
062: this .description = ""; //$NON-NLS-1$
063: requiredTasks = new ArrayList();
064: }
065:
066: public String getId() {
067: return id;
068: }
069:
070: public String getName() {
071: return name;
072: }
073:
074: public String getKind() {
075: return kind;
076: }
077:
078: public Dictionary getParameters() {
079: return parameters;
080: }
081:
082: public String getDescription() {
083: return description;
084: }
085:
086: public void setDescription(String description) {
087: this .description = description;
088: }
089:
090: public void setCompletionMessage(String completionMessage) {
091: this .completionMessage = completionMessage;
092: }
093:
094: public String getCompletionMessage() {
095: return completionMessage;
096: }
097:
098: public ICompositeCheatSheetTask[] getRequiredTasks() {
099: if (requiredTasks == null)
100: return EMPTY;
101: return (ICompositeCheatSheetTask[]) requiredTasks
102: .toArray(new ICompositeCheatSheetTask[requiredTasks
103: .size()]);
104: }
105:
106: public ICompositeCheatSheetTask[] getSuccessorTasks() {
107: if (successorTasks == null)
108: return EMPTY;
109: return (ICompositeCheatSheetTask[]) successorTasks
110: .toArray(new ICompositeCheatSheetTask[successorTasks
111: .size()]);
112: }
113:
114: public void addRequiredTask(AbstractTask task) {
115: if (requiredTasks == null)
116: requiredTasks = new ArrayList();
117: requiredTasks.add(task);
118: if (task.successorTasks == null)
119: task.successorTasks = new ArrayList();
120: task.successorTasks.add(this );
121: }
122:
123: public int getState() {
124: return state;
125: }
126:
127: public void complete() {
128: setState(COMPLETED);
129: }
130:
131: public boolean requiredTasksCompleted() {
132: boolean startable = true;
133: ICompositeCheatSheetTask[] requiredTasks = getRequiredTasks();
134: for (int i = 0; i < requiredTasks.length; i++) {
135: if (requiredTasks[i].getState() != COMPLETED
136: && requiredTasks[i].getState() != SKIPPED) {
137: startable = false;
138: }
139: }
140: return startable;
141: }
142:
143: /**
144: * Determine whether the candidate task is a required task for this task.
145: * This function does not test for indirectly required tasks
146: * @param candidateTask a task which may be a required task
147: * @return true if candidateTask is in the list of required tasks.
148: */
149: public boolean requiresTask(ICompositeCheatSheetTask candidateTask) {
150: return (requiredTasks.contains(candidateTask));
151: }
152:
153: /**
154: * Interface used when restoring state from a file.
155: * Not intended to be called from task editors.
156: * @param state
157: */
158: public void setState(int state) {
159: setStateNoNotify(state);
160: model.sendTaskChangeEvents();
161: }
162:
163: /**
164: * Set the state of a task but don't send out any events yet,
165: * let them collect so we don't send out multiple events for
166: * one task
167: * @param state
168: */
169: public void setStateNoNotify(int state) {
170: this .state = state;
171: if (parent != null) {
172: parent.checkState();
173: }
174: model.stateChanged(this );
175: }
176:
177: /*
178: * Resolves the given path to a URL. The path can either be fully qualified with
179: * the plugin id, e.g. "/plugin_id/path/file.xml" or relative to the composite cheat
180: * sheet file, e.g. "tasks/task1.xml".
181: */
182: public URL getInputUrl(String path) throws MalformedURLException {
183: int index = path.indexOf('/', 1);
184: if (index >= 1) {
185: String bundleName = path.substring(1, index);
186: String relativePath = path.substring(index + 1);
187: Bundle bundle = Platform.getBundle(bundleName);
188: if (bundle != null) {
189: return bundle.getEntry(relativePath);
190: }
191: }
192: return new URL(model.getContentUrl(), path);
193:
194: }
195:
196: public ICompositeCheatSheet getCompositeCheatSheet() {
197: return model;
198: }
199:
200: public abstract ITaskParseStrategy getParserStrategy();
201:
202: public abstract ICompositeCheatSheetTask[] getSubtasks();
203:
204: public void setSkippable(boolean skippable) {
205: this .skippable = skippable;
206: }
207:
208: public boolean isSkippable() {
209: return skippable;
210: }
211:
212: protected void setParent(TaskGroup parent) {
213: this .parent = parent;
214: }
215:
216: public ITaskGroup getParent() {
217: return parent;
218: }
219:
220: public int hashCode() {
221: return getId().hashCode();
222: }
223:
224: }
|