blob: ca7d3bbcff8cacb826d471ecdb5dcb328f527995 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.cheatsheets.composite.model;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.ui.internal.cheatsheets.composite.parser.ITaskParseStrategy;
import org.eclipse.ui.internal.provisional.cheatsheets.ICompositeCheatSheet;
import org.eclipse.ui.internal.provisional.cheatsheets.ICompositeCheatSheetTask;
import org.eclipse.ui.internal.provisional.cheatsheets.ITaskGroup;
import org.osgi.framework.Bundle;
/**
* A single task within a composite cheatsheet. This class encapsulates the
* behavior common to editable tasks and taskGroups
*/
public abstract class AbstractTask implements ICompositeCheatSheetTask {
protected CompositeCheatSheetModel model;
protected int state = NOT_STARTED;
private String id;
private String name;
protected String kind;
private Dictionary parameters;
private String description;
private String completionMessage;
private ArrayList requiredTasks;
private ArrayList successorTasks;
private boolean skippable;
private TaskGroup parent;
protected static final ICompositeCheatSheetTask[] EMPTY = new ICompositeCheatSheetTask[0];
public AbstractTask(CompositeCheatSheetModel model, String id, String name, String kind) {
this.model = model;
this.id = id;
this.name = name;
this.kind = kind;
this.parameters = new Hashtable();
this.description = ""; //$NON-NLS-1$
requiredTasks = new ArrayList();
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getKind() {
return kind;
}
public Dictionary getParameters() {
return parameters;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void setCompletionMessage(String completionMessage) {
this.completionMessage = completionMessage;
}
public String getCompletionMessage() {
return completionMessage;
}
public ICompositeCheatSheetTask[] getRequiredTasks() {
if (requiredTasks==null) return EMPTY;
return (ICompositeCheatSheetTask[])requiredTasks.toArray(new ICompositeCheatSheetTask[requiredTasks.size()]);
}
public ICompositeCheatSheetTask[] getSuccessorTasks() {
if (successorTasks==null) return EMPTY;
return (ICompositeCheatSheetTask[])successorTasks.toArray(new ICompositeCheatSheetTask[successorTasks.size()]);
}
public void addRequiredTask(AbstractTask task) {
if (requiredTasks==null)
requiredTasks = new ArrayList();
requiredTasks.add(task);
if (task.successorTasks==null)
task.successorTasks = new ArrayList();
task.successorTasks.add(this);
}
public int getState() {
return state;
}
public void complete() {
setState(COMPLETED);
}
public boolean requiredTasksCompleted() {
boolean startable = true;
ICompositeCheatSheetTask[] requiredTasks = getRequiredTasks();
for (int i = 0; i < requiredTasks.length; i++) {
if (requiredTasks[i].getState() != COMPLETED &&
requiredTasks[i].getState() != SKIPPED ) {
startable = false;
}
}
return startable;
}
/**
* Determine whether the candidate task is a required task for this task.
* This function does not test for indirectly required tasks
* @param candidateTask a task which may be a required task
* @return true if candidateTask is in the list of required tasks.
*/
public boolean requiresTask(ICompositeCheatSheetTask candidateTask) {
return (requiredTasks.contains(candidateTask));
}
/**
* Interface used when restoring state from a file.
* Not intended to be called from task editors.
* @param state
*/
public void setState(int state) {
setStateNoNotify(state);
model.sendTaskChangeEvents();
}
/**
* Set the state of a task but don't send out any events yet,
* let them collect so we don't send out multiple events for
* one task
* @param state
*/
public void setStateNoNotify(int state) {
this.state = state;
if (parent != null) {
parent.checkState();
}
model.stateChanged(this);
}
/*
* Resolves the given path to a URL. The path can either be fully qualified with
* the plugin id, e.g. "/plugin_id/path/file.xml" or relative to the composite cheat
* sheet file, e.g. "tasks/task1.xml".
*/
public URL getInputUrl(String path) throws MalformedURLException {
int index = path.indexOf('/', 1);
if (index >= 1 && path.charAt(0) == '/') {
String bundleName = path.substring(1, index);
String relativePath = path.substring(index + 1);
Bundle bundle = Platform.getBundle(bundleName);
if (bundle != null) {
return FileLocator.find(bundle, new Path(relativePath), null);
}
}
return new URL(model.getContentUrl(), path);
}
public ICompositeCheatSheet getCompositeCheatSheet() {
return model;
}
public abstract ITaskParseStrategy getParserStrategy();
public abstract ICompositeCheatSheetTask[] getSubtasks();
public void setSkippable(boolean skippable) {
this.skippable = skippable;
}
public boolean isSkippable() {
return skippable;
}
protected void setParent(TaskGroup parent) {
this.parent = parent;
}
public ITaskGroup getParent() {
return parent;
}
public int hashCode() {
return getId().hashCode();
}
}