diff options
Diffstat (limited to 'org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model')
9 files changed, 1588 insertions, 0 deletions
diff --git a/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/ExternalTool.java b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/ExternalTool.java new file mode 100644 index 000000000..9ad2ca6aa --- /dev/null +++ b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/ExternalTool.java @@ -0,0 +1,543 @@ +package org.eclipse.ui.externaltools.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: +**********************************************************************/ + +import java.text.MessageFormat; +import java.util.ArrayList; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IActionFilter; +import org.eclipse.ui.externaltools.internal.model.ExternalToolsPlugin; +import org.eclipse.ui.model.IWorkbenchAdapter; + +/** + * This class represents an external tool that can be run. The tool + * can be inside or outside the workspace. + * <p> + * An external tool consist of a user defined name, the location + * of the tool, optional arguments for the tool, and the working + * directory. + * </p><p> + * After the tool has run, part or all of the workspace can be + * refreshed to pickup changes made by the tool. This is optional + * and does nothing by default + * </p><p> + * This class is not intended to be extended by clients + * </p> + */ +public final class ExternalTool implements IAdaptable { + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + private static final int[] DEFAULT_BUILD_KINDS = + {IncrementalProjectBuilder.INCREMENTAL_BUILD, + IncrementalProjectBuilder.FULL_BUILD, + IncrementalProjectBuilder.AUTO_BUILD}; + + private static final ToolWorkbenchAdapter workbenchAdapter = new ToolWorkbenchAdapter(); + private static final ToolFilterAdapter filterAdapter = new ToolFilterAdapter(); + + private String type = EMPTY_STRING; + private String name = EMPTY_STRING; + private String location = EMPTY_STRING; + private String arguments = EMPTY_STRING; + private String workDirectory = EMPTY_STRING; + private String description = EMPTY_STRING; + private String openPerspective = null; + private String refreshScope = null; + private boolean refreshRecursive = true; + private boolean captureOutput = true; + private boolean showConsole = true; + private boolean runInBackground = true; + private boolean promptForArguments = false; + private boolean showInMenu = false; + private boolean saveDirtyEditors = false; + private int[] runForBuildKinds = DEFAULT_BUILD_KINDS; + private ArrayList extraAttributes = null; + + /** + * Creates a fully initialized external tool. + * + * @param type the type of external tool. + * @param name the name given to the external tool. Must only + * contain letters, numbers, hyphens, and spaces. + */ + public ExternalTool(String type, String name) throws CoreException { + super(); + + if (type != null) + this.type = type; + + String errorText = validateToolName(name); + if (errorText == null) + this.name = name.trim(); + else + throw ExternalToolsPlugin.newError(errorText, null); + } + + /** + * Validates the specified tool name only includes letters, + * numbers, hyphens, and spaces. Must contain at least one + * letter or number. + * + * @param name the proposed name for the external tool + * @return a string indicating the invalid format or <code>null</code> if valid. + */ + public static String validateToolName(String name) { + IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE); + if (status.getCode() != IStatus.OK) { + return status.getMessage(); + } + return null; + } + + /* (non-Javadoc) + * Method declared on IAdaptable. + */ + public Object getAdapter(Class adapter) { + if (adapter == IWorkbenchAdapter.class) + return workbenchAdapter; + + if (adapter == IActionFilter.class) + return filterAdapter; + + return null; + } + + /** + * Returns the extra attribute value + * + * @param key the unique attribute name + * @return the value of the attribute, or <code>null</code> + * if not such attribute name. + */ + public String getExtraAttribute(String key) { + if (key == null || key.length() == 0) + return null; + if (extraAttributes == null) + return null; + + for (int i = 0; i < extraAttributes.size(); i++) { + Attribute attr = (Attribute)extraAttributes.get(i); + if (attr.key.equals(key)) + return attr.value; + } + + return null; + } + + /** + * Returns all the extra attribute keys + */ + public String[] getExtraAttributeKeys() { + if (extraAttributes == null) + return new String[0]; + + String[] results = new String[extraAttributes.size()]; + for (int i = 0; i < extraAttributes.size(); i++) { + Attribute attr = (Attribute)extraAttributes.get(i); + results[i] = attr.key; + } + + return results; + } + + /** + * Returns all the extra attribute values + */ + public String[] getExtraAttributeValues() { + if (extraAttributes == null) + return new String[0]; + + String[] results = new String[extraAttributes.size()]; + for (int i = 0; i < extraAttributes.size(); i++) { + Attribute attr = (Attribute)extraAttributes.get(i); + results[i] = attr.value; + } + + return results; + } + + /** + * Sets an extra attribute to the tool. + * + * @param key the unique attribute name + * @param value the value for the attribute. If <code>null</code>, + * then the existing attribute is removed. + */ + public void setExtraAttribute(String key, String value) { + // Exit on invalid key + if (key == null || key.length() == 0) + return; + + // Init the list but only if not attempting to remove + // an extra attribute + if (extraAttributes == null) { + if (value == null) + return; + else + extraAttributes = new ArrayList(4); + } + + // If the extra attribute exist, update it with the + // new value, or remove it if the value is null + for (int i = 0; i < extraAttributes.size(); i++) { + Attribute attr = (Attribute)extraAttributes.get(i); + if (attr.key.equals(key)) { + if (value == null) + extraAttributes.remove(i); + else + attr.value = value.trim(); + return; + } + } + + // Otherwise add the new extra attribute + if (value != null) + extraAttributes.add(new Attribute(key, value.trim())); + } + + /** + * Returns the type of external tool. + */ + public String getType() { + return type; + } + + /** + * Returns the name of the external tool. + */ + public String getName() { + return name; + } + + /** + * Returns the location of the external tool. + */ + public String getLocation() { + return location; + } + + /** + * Returns the arguments for the external tool. + */ + public String getArguments() { + return arguments; + } + + /** + * Returns the working directory to run the external tool in. + */ + public String getWorkingDirectory() { + return workDirectory; + } + + /** + * Returns whether the refresh will be recursive. + */ + public boolean getRefreshRecursive() { + return refreshRecursive; + } + + /** + * Returns the scope of resources to refresh after + * the external tool is run, or <code>null</code> if + * not specified. The value is in an variable + * format. + */ + public String getRefreshScope() { + return refreshScope; + } + + /** + * Returns whether to capture output messages from the + * running tool. + */ + public boolean getCaptureOutput() { + return captureOutput; + } + + /** + * Returns whether to show the log console when + * the tool is run. + */ + public boolean getShowConsole() { + return showConsole; + } + + /** + * Returns whether to run the external tool in the + * background so as not to block the UI. + */ + public boolean getRunInBackground() { + return runInBackground; + } + + /** + * Returns whether to prompt for arguments before + * the tool is run. + */ + public boolean getPromptForArguments() { + return promptForArguments; + } + + /** + * Returns whether to show this tool in the + * Run > External Tools menu. + */ + public boolean getShowInMenu() { + return showInMenu; + } + + /** + * Returns whether to save all dirty editors before + * running this tool. + */ + public boolean getSaveDirtyEditors() { + return saveDirtyEditors; + } + + /** + * Returns the perspective ID to open when this + * tool is run, or <code>null</code> if not specified. + */ + public String getOpenPerspective() { + return openPerspective; + } + + /** + * Returns a description of this external tool + */ + public String getDescription() { + return description; + } + + /** + * Returns the list of build kinds that this + * tool wants to run when used as a builder. + * The list of valid build kinds is defined + * on <code>IncrementalProjectBuilder</code>. + */ + public int[] getRunForBuildKinds() { + return runForBuildKinds; + } + + /** + * Sets the name of the external tool. + */ + public void rename(String name) throws CoreException { + IStatus status= ExternalToolsPlugin.getDefault().getToolRegistry(null).renameTool(this, name); + if (!status.isOK()) { + // Throw an exception + ExternalToolsPlugin.newError(MessageFormat.format("An exception occurred attempting to rename the tool: ", new Object[] {this.getName()}), null); + } + if (name == null) { + this.name = EMPTY_STRING; + } else { + this.name = name; + } + } + + /** + * Sets the location of the external tool. + */ + public void setLocation(String location) { + if (location == null) + this.location = EMPTY_STRING; + else + this.location = location.trim(); + } + + /** + * Sets the arguments for the external tool. + */ + public void setArguments(String arguments) { + if (arguments == null) + this.arguments = EMPTY_STRING; + else + this.arguments = arguments.trim(); + } + + /** + * Sets the working directory to run the external tool in. + */ + public void setWorkingDirectory(String workDirectory) { + if (workDirectory == null) + this.workDirectory = EMPTY_STRING; + else + this.workDirectory = workDirectory.trim(); + } + + /** + * Sets whether the refresh will be recursive. + */ + public void setRefreshRecursive(boolean refreshRecursive) { + this.refreshRecursive = refreshRecursive; + } + + /** + * Sets the scope of resources to refresh after + * the external tool is run, or <code>null</code> + * if none. The value is in a variable format. + */ + public void setRefreshScope(String refreshScope) { + if (refreshScope == null) + this.refreshScope = null; + else { + this.refreshScope = refreshScope.trim(); + if (this.refreshScope.length() == 0) + this.refreshScope = null; + } + } + + /** + * Sets whether to capture output messages from the + * running tool. + */ + public void setCaptureOutput(boolean captureOutput) { + this.captureOutput = captureOutput; + } + + /** + * Sets whether to show the log console when + * the tool is run. + */ + public void setShowConsole(boolean showConsole) { + this.showConsole = showConsole; + } + + /** + * Sets whether to run the external tool in the + * background so as not to block the UI. + */ + public void setRunInBackground(boolean runInBackground) { + this.runInBackground = runInBackground; + } + + /** + * Sets whether to prompt for arguments before + * the tool is run. + */ + public void setPromptForArguments(boolean promptForArguments) { + this.promptForArguments = promptForArguments; + } + + /** + * Sets whether to show this tool in the + * Run > External Tools menu. + */ + public void setShowInMenu(boolean showInMenu) { + this.showInMenu = showInMenu; + } + + /** + * Sets whether all dirty editors will be saved + * before running this tool. + */ + public void setSaveDirtyEditors(boolean saveDirtyEditors) { + this.saveDirtyEditors = saveDirtyEditors; + } + + /** + * Sets the perspective ID to open when this + * tool is run, or <code>null</code> if not specified. + */ + public void setOpenPerspective(String openPerspective) { + if (openPerspective == null) + this.openPerspective = null; + else { + this.openPerspective = openPerspective.trim(); + if (this.openPerspective.length() == 0) + this.openPerspective = null; + } + } + + /** + * Sets a description of this external tool + */ + public void setDescription(String description) { + if (description == null) + this.description = EMPTY_STRING; + else + this.description = description.trim(); + } + + /** + * Sets the list of build kinds that this + * tool wants to run when used as a builder. + * The list of valid build kinds is defined + * on <code>IncrementalProjectBuilder</code>. + */ + public void setRunForBuildKinds(int[] kinds) { + if (kinds == null) + this.runForBuildKinds = DEFAULT_BUILD_KINDS; + else + this.runForBuildKinds = kinds; + } + + /** + * Internal representation of extra attributes. + */ + private static class Attribute { + public String key; + public String value; + + public Attribute(String key, String value) { + super(); + this.key = key; + this.value = value; + } + } + + /** + * Internal workbench adapter implementation. + */ + private static class ToolWorkbenchAdapter implements IWorkbenchAdapter { + public Object[] getChildren(Object o) { + return new Object[0]; + } + + public ImageDescriptor getImageDescriptor(Object o) { + String type = ((ExternalTool)o).getType(); + return ExternalToolsPlugin.getDefault().getTypeRegistry().getToolTypeImageDescriptor(type); + } + + public String getLabel(Object o) { + return ((ExternalTool)o).getName(); + } + + public Object getParent(Object o) { + String type = ((ExternalTool)o).getType(); + return ExternalToolsPlugin.getDefault().getTypeRegistry().getToolType(type); + } + } + + /** + * Internal action filter adapter implementation. + */ + private static class ToolFilterAdapter implements IExternalToolFilter { + public boolean testAttribute(Object target, String name, String value) { + ExternalTool tool = (ExternalTool) target; + + if (IExternalToolFilter.TYPE.equals(name)) + return tool.getType().equals(value); + + String attrValue = tool.getExtraAttribute(name); + if (attrValue != null) + return attrValue.equals(value); + + return false; + } + } +}
\ No newline at end of file diff --git a/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/ExternalToolStorage.java b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/ExternalToolStorage.java new file mode 100644 index 000000000..a22e2278c --- /dev/null +++ b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/ExternalToolStorage.java @@ -0,0 +1,153 @@ +package org.eclipse.ui.externaltools.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: +**********************************************************************/ + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.util.ListenerList; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.externaltools.internal.model.ExternalToolsPlugin; +import org.eclipse.ui.externaltools.internal.model.ToolMessages; +import org.eclipse.ui.externaltools.internal.registry.ExternalToolRegistry; + +/** + * Provides utility methods to manager the storage + * of external tools. + */ +public final class ExternalToolStorage { + private static ListenerList listeners = new ListenerList(); + + /** + * Allows no instance to be created + */ + private ExternalToolStorage() { + super(); + } + + /** + * Adds a tool storage listener. + * + * @param listener the tool storage listener to add + */ + public static void addStorageListener(IStorageListener listener) { + listeners.add(listener); + } + + /** + * Deletes the external tool from storage and from + * the tools registry. + * + * @param tool the external tool to be deleted + * @param shell the shell to parent any error dialogs, + * of <code>null</code> to operate quietly. + */ + public static void deleteTool(ExternalTool tool, Shell shell) { + if (tool == null) + return; + + ExternalToolRegistry registry = ExternalToolsPlugin.getDefault().getToolRegistry(shell); + IStatus results = registry.deleteTool(tool); + + if (handleResults(results, shell, "ExternalToolStorage.deleteErrorTitle", "ExternalToolStorage.deleteErrorMessage")) //$NON-NLS-2$//$NON-NLS-1$ + return; + + Object list[] = listeners.getListeners(); + for (int i = 0; i < list.length; i++) { + ((IStorageListener)list[i]).toolDeleted(tool); + } + } + + /** + * Handles the display of any error message if the + * results were not ok. + * + * @return <code>true</code> if an error was displayed, <code>false</code> otherwise + */ + private static boolean handleResults(final IStatus results, final Shell shell, final String titleKey, final String msgKey) { + if (!results.isOK() && shell != null && !shell.isDisposed()) { + shell.getDisplay().syncExec(new Runnable() { + public void run() { + String title = ToolMessages.getString(titleKey); + String msg = ToolMessages.getString(msgKey); + ErrorDialog.openError(shell, title, msg, results); + } + }); + + return true; + } + + return false; + } + + /** + * Reloads the tools from storage into the registry. + * + * @param shell the shell to parent any error dialogs, + * of <code>null</code> to operate quietly. + */ + public static void refreshTools(final Shell shell) { + final IStatus[] results = new IStatus[1]; + + BusyIndicator.showWhile(shell.getDisplay(), new Runnable() { + public void run() { + results[0] = ExternalToolsPlugin.getDefault().getToolRegistry(shell).reloadTools(); + } + }); + + if (handleResults(results[0], shell, "ExternalToolStorage.reloadErrorTitle", "ExternalToolStorage.reloadErrorMessage")) //$NON-NLS-2$//$NON-NLS-1$ + return; + + Object list[] = listeners.getListeners(); + for (int i = 0; i < list.length; i++) { + ((IStorageListener)list[i]).toolsRefreshed(); + } + } + + /** + * Removes a tool storage listener. + * + * @param listener the tool storage listener to remove + */ + public static void removeStorageListener(IStorageListener listener) { + listeners.remove(listener); + } + + /** + * Saves the external tool to storage and to + * the tools registry. + * + * @param tool the external tool to be saved + * @param shell the shell to parent any error dialogs, + * of <code>null</code> to operate quietly. + * @return <code>true</code> if save successful, <code>false</code> otherwise. + */ + public static boolean saveTool(ExternalTool tool, Shell shell) { + if (tool == null) + return false; + + ExternalToolRegistry registry = ExternalToolsPlugin.getDefault().getToolRegistry(shell); + boolean exists = registry.hasToolNamed(tool.getName()); + + IStatus results = registry.saveTool(tool); + if (handleResults(results, shell, "ExternalToolStorage.saveErrorTitle", "ExternalToolStorage.saveErrorMessage")) //$NON-NLS-2$//$NON-NLS-1$ + return false; + + Object list[] = listeners.getListeners(); + for (int i = 0; i < list.length; i++) { + if (exists) + ((IStorageListener)list[i]).toolModified(tool); + else + ((IStorageListener)list[i]).toolCreated(tool); + } + + return true; + } +} diff --git a/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IExternalToolConstants.java b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IExternalToolConstants.java new file mode 100644 index 000000000..8469d3a80 --- /dev/null +++ b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IExternalToolConstants.java @@ -0,0 +1,210 @@ +package org.eclipse.ui.externaltools.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: +**********************************************************************/ + +/** + * Defines the constants available for client use. + * <p> + * This interface is not intended to be extended or implemented by clients. + * </p> + */ +public interface IExternalToolConstants { + // ------- Extensions ------- + /** + * Plugin identifier for external tools (value <code>org.eclipse.ui.externaltools</code>). + */ + public static final String PLUGIN_ID = "org.eclipse.ui.externaltools"; //$NON-NLS-1$; + + /** + * Extension point to declare types of external tools + * (value <code>toolTypes</code>). + */ + public static final String PL_TOOL_TYPES = "toolTypes"; //$NON-NLS-1$ + + /** + * Extension point to declare argument variables + * (value <code>argumentVariables</code>). + */ + public static final String PL_ARGUMENT_VARIABLES = "argumentVariables"; //$NON-NLS-1$ + + /** + * Extension point to declare file variables + * (value <code>fileVariables</code>). + */ + public static final String PL_FILE_VARIABLES = "fileVariables"; //$NON-NLS-1$ + + /** + * Extension point to declare directory variables + * (value <code>directoryVariables</code>). + */ + public static final String PL_DIRECTORY_VARIABLES = "directoryVariables"; //$NON-NLS-1$ + + /** + * Extension point to declare refresh scope variables + * (value <code>refreshVariables</code>). + */ + public static final String PL_REFRESH_VARIABLES = "refreshVariables"; //$NON-NLS-1$ + + + // ------- Views ------- + /** + * External tool view identifier (value <code>org.eclipse.ui.externaltools.ExternalToolView</code>). + */ + public static final String VIEW_ID = PLUGIN_ID + ".ExternalToolView"; //$NON-NLS-1$ + + /** + * Log Console view identifier (value <code>org.eclipse.ui.externaltools.LogConsoleView</code>). + */ + public static final String LOG_CONSOLE_VIEW_ID = PLUGIN_ID + ".LogConsoleView"; //$NON-NLS-1$ + + + // ------- Tool Types ------- + /** + * External tool type for programs such as executables, batch files, + * shell scripts, etc (value <code>programType</code>). + */ + public static final String TOOL_TYPE_PROGRAM = "programType"; //$NON-NLS-1$; + + /** + * External tool type for Ant build files (value <code>antBuildType</code>). + */ + public static final String TOOL_TYPE_ANT_BUILD = "antBuildType"; //$NON-NLS-1$; + + + // ------- Variables ------- + /** + * Variable that expands to the workspace root object (value <code>workspace</code>). + */ + public static final String VAR_WORKSPACE = "workspace"; //$NON-NLS-1$ + + /** + * Variable that expands to the absolute path on the system's hard drive + * to the workspace directory (value <code>workspace_loc</code>). + */ + public static final String VAR_WORKSPACE_LOC = "workspace_loc"; //$NON-NLS-1$ + + /** + * Variable that expands to the project resource (value <code>project</code>). + */ + public static final String VAR_PROJECT = "project"; //$NON-NLS-1$ + + /** + * Variable that expands to the absolute path on the system's hard drive + * to a project's directory (value <code>project_loc</code>). + */ + public static final String VAR_PROJECT_LOC = "project_loc"; //$NON-NLS-1$ + + /** + * Variable that expands to the full path, relative to the workspace root, + * of a project (value <code>project_path</code>). + */ + public static final String VAR_PROJECT_PATH = "project_path"; //$NON-NLS-1$ + + /** + * Variable that expands to the name of a project (value <code>project_name</code>). + */ + public static final String VAR_PROJECT_NAME = "project_name"; //$NON-NLS-1$ + + /** + * Variable that expands to a resource (value <code>resource</code>). + */ + public static final String VAR_RESOURCE = "resource"; //$NON-NLS-1$ + + /** + * Variable that expands to the absolute path on the system's hard drive + * to a resource's location (value <code>resource_loc</code>). + */ + public static final String VAR_RESOURCE_LOC = "resource_loc"; //$NON-NLS-1$ + + /** + * Variable that expands to the full path, relative to the workspace root, + * of a resource (value <code>resource_path</code>). + */ + public static final String VAR_RESOURCE_PATH = "resource_path"; //$NON-NLS-1$ + + /** + * Variable that expands to the name of a resource (value <code>resource_name</code>). + */ + public static final String VAR_RESOURCE_NAME = "resource_name"; //$NON-NLS-1$ + + /** + * Variable that expands to the container resource (value <code>container</code>). + */ + public static final String VAR_CONTAINER = "container"; //$NON-NLS-1$ + + /** + * Variable that expands to the absolute path on the system's hard drive + * to a resource's containing directory (value <code>container_loc</code>). + */ + public static final String VAR_CONTAINER_LOC = "container_loc"; //$NON-NLS-1$ + + /** + * Variable that expands to the full path, relative to the workspace root, + * of a resource's parent (value <code>container_path</code>). + */ + public static final String VAR_CONTAINER_PATH = "container_path"; //$NON-NLS-1$ + + /** + * Variable that expands to the name of a resource's parent (value <code>container_name</code>). + */ + public static final String VAR_CONTAINER_NAME = "container_name"; //$NON-NLS-1$ + + /** + * Variable that expands to the type of build (value <code>build_type</code>). See + * <code>BUILD_TYPE_*</code> constants for possible values. + */ + public static final String VAR_BUILD_TYPE = "build_type"; //$NON-NLS-1$ + + /** + * Variable that expands to the working set object (value <code>working_set</code>). + */ + public static final String VAR_WORKING_SET = "working_set"; //$NON-NLS-1$ + + /** + * Variable that expands to the current editor cursor column (value <code>editor_cur_col</code>). + */ + public static final String VAR_EDITOR_CUR_COL = "editor_cur_col"; //$NON-NLS-1$ + + /** + * Variable that expands to the current editor cursor line (value <code>editor_cur_line</code>). + */ + public static final String VAR_EDITOR_CUR_LINE = "editor_cur_line"; //$NON-NLS-1$ + + /** + * Variable that expands to the current editor selected text (value <code>editor_sel_text</code>). + */ + public static final String VAR_EDITOR_SEL_TEXT = "editor_sel_text"; //$NON-NLS-1$ + + + // ------- Build Types ------- + /** + * Build type indicating an incremental project build request for + * the external tool running as a builder (value <code>incremental</code>). + */ + public static final String BUILD_TYPE_INCREMENTAL = "incremental"; //$NON-NLS-1$ + + /** + * Build type indicating a full project build request for + * the external tool running as a builder (value <code>full</code>). + */ + public static final String BUILD_TYPE_FULL = "full"; //$NON-NLS-1$ + + /** + * Build type indicating an automatic project build request for + * the external tool running as a builder (value <code>incremental</code>). + */ + public static final String BUILD_TYPE_AUTO = "auto"; //$NON-NLS-1$ + + /** + * Build type indicating an no project build request for + * the external tool running as a builder (value <code>none</code>). + */ + public static final String BUILD_TYPE_NONE = "none"; //$NON-NLS-1$ +} diff --git a/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IExternalToolFilter.java b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IExternalToolFilter.java new file mode 100644 index 000000000..5ec00651f --- /dev/null +++ b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IExternalToolFilter.java @@ -0,0 +1,34 @@ +package org.eclipse.ui.externaltools.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: +**********************************************************************/ + +import org.eclipse.ui.IActionFilter; + +/** + * Describes the public attributes for an external tool and the acceptables values + * each may have. + * <p> + * Beside the attributes defined below, all of the extra attribute keys are + * also available. Only use extra attribute keys which have been made public + * by clients. + * </p><p> + * This interface is not to be extended or implemented by clients + * </p> + * + * @see IActionFilter + */ +public interface IExternalToolFilter extends IActionFilter { + /** + * An attribute indicating the external tool type (value <code>"type"</code>). + * The attribute value should match one of the external tool types defined in + * the external tool's type extension point. + */ + public static final String TYPE = "type"; //$NON-NLS-1$ +} diff --git a/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IExternalToolRunner.java b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IExternalToolRunner.java new file mode 100644 index 000000000..5014e0f4d --- /dev/null +++ b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IExternalToolRunner.java @@ -0,0 +1,38 @@ +package org.eclipse.ui.externaltools.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: +**********************************************************************/ + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.MultiStatus; + +/** + * The implementation of this interface is responsible for running + * an external tool within the specified context. + * <p> + * Clients using the extension point to define a new external + * tool type must provide an implementation of this interface. + * </p><p> + * The implementation of this interface will be treated like + * a singleton. That is, only one instance will be created + * per tool type. + * </p><p> + * This interface is not intended to be extended by clients. + * </p> + */ +public interface IExternalToolRunner { + /** + * Runs an external tool using the specified context. + * + * @param monitor the monitor to report progress or cancellation to + * @param runnerContext the context representing the tool to run + * @param status a multi status to report any problems while running tool + */ + public void run(IProgressMonitor monitor, IRunnerContext runnerContext, MultiStatus status); +} diff --git a/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IRunnerContext.java b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IRunnerContext.java new file mode 100644 index 000000000..1b12e298c --- /dev/null +++ b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IRunnerContext.java @@ -0,0 +1,67 @@ +package org.eclipse.ui.externaltools.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: +**********************************************************************/ + +/** + * Represents the context of the external tool to run. An implementation + * of this interface is provided to the <code>IExternalToolRunner</code>. + * <p> + * This interface is not be extended nor implemented by clients. + * </p> + */ +public interface IRunnerContext { + /** + * Returns whether the external tool runner should capture + * output messages from the running tool and log these + * messages. + */ + public boolean getCaptureOutput(); + + /** + * Returns the arguments for the external tool. All + * variables embedded in the arguments have been fully + * expanded. + */ + public String[] getExpandedArguments(); + + /** + * Returns the path where the external tool is located. All + * variables embedded in the path have been fully + * expanded. + */ + public String getExpandedLocation(); + + /** + * Returns the working directory to run the external tool in. + * All variables embedded in the path have been fully + * expanded. + */ + public String getExpandedWorkingDirectory(); + + /** + * Returns the extra attribute value of the external tool. + * + * @param key the unique attribute name + * @return the value of the attribute, or <code>null</code> + * if not such attribute name. + */ + public String getExtraAttribute(String key); + + /** + * Returns the log the runner can used to log + * messages captured from the running tool's output. + */ + public IRunnerLog getLog(); + + /** + * Returns the name of the external tool. + */ + public String getName(); +} diff --git a/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IRunnerLog.java b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IRunnerLog.java new file mode 100644 index 000000000..4245d2d66 --- /dev/null +++ b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IRunnerLog.java @@ -0,0 +1,43 @@ +package org.eclipse.ui.externaltools.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: +**********************************************************************/ + +/** + * Provides an API for <code>IExternalToolRunner</code> implementors + * to log messages captured from the running tool's output. + * <p> + * This interface is not be extended nor implemented by clients. + * </p> + */ +public interface IRunnerLog { + public static final int LEVEL_ERROR = 0; + public static final int LEVEL_WARNING = 10; + public static final int LEVEL_INFO = 20; + public static final int LEVEL_VERBOSE = 30; + public static final int LEVEL_DEBUG = 40; + + /** + * Places the specified message text into the log. Ignored + * if the specified message level is higher than the + * current filter level. + * + * @param message the text to add to the log + * @param level the message priority + */ + public void append(String message, int level); + + /** + * Returns the current level used for filtering + * messages. Any calls to <code>append</code> with + * a level greater than this filter value will be + * ignored. + */ + public int getFilterLevel(); +} diff --git a/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IStorageListener.java b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IStorageListener.java new file mode 100644 index 000000000..84c502b76 --- /dev/null +++ b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/IStorageListener.java @@ -0,0 +1,50 @@ +package org.eclipse.ui.externaltools.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: +**********************************************************************/ + +/** + * Defines the changes within the external tool storage that + * a listeners can be notified of. + * <p> + * This interface is not to be extended by clients, but can be + * implemented by clients. + * </p> + */ +public interface IStorageListener { + /** + * Notifies this listener that an external tool has + * been removed from the registry and storage. + * + * @param tool the external tool that was removed + */ + public void toolDeleted(ExternalTool tool); + + /** + * Notifies this listener that a new external tool has + * been added to the registry and storage. + * + * @param tool the external tool that was created + */ + public void toolCreated(ExternalTool tool); + + /** + * Notifies this listener that an existing external tool + * in the registry has been modified and saved to storage. + * + * @param tool the external tool that was modified + */ + public void toolModified(ExternalTool tool); + + /** + * Notifies this listener that the entire external tool + * registry was refreshed from storage. + */ + public void toolsRefreshed(); +} diff --git a/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/ToolUtil.java b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/ToolUtil.java new file mode 100644 index 000000000..fbb883868 --- /dev/null +++ b/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/model/ToolUtil.java @@ -0,0 +1,450 @@ +package org.eclipse.ui.externaltools.model; + +/********************************************************************** +Copyright (c) 2002 IBM Corp. and others. All rights reserved. +This file is made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: +**********************************************************************/ + +import java.util.ArrayList; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.ui.externaltools.internal.model.ExternalToolsPlugin; +import org.eclipse.ui.externaltools.internal.model.ToolMessages; +import org.eclipse.ui.externaltools.internal.registry.ArgumentVariable; +import org.eclipse.ui.externaltools.internal.registry.ArgumentVariableRegistry; +import org.eclipse.ui.externaltools.internal.registry.PathLocationVariable; +import org.eclipse.ui.externaltools.internal.registry.PathLocationVariableRegistry; +import org.eclipse.ui.externaltools.variable.ExpandVariableContext; + +/** + * General utility class dealing with external tools + */ +public final class ToolUtil { + /** + * Argument parsing constants + */ + private static final char ARG_DELIMITER = ' '; //$NON-NLS-1$ + private static final char ARG_DBL_QUOTE = '"'; //$NON-NLS-1$ + + /** + * Variable tag indentifiers + */ + private static final char VAR_TAG_START_CHAR1 = '$'; //$NON-NLS-1$ + private static final char VAR_TAG_START_CHAR2 = '{'; //$NON-NLS-1$ + private static final char VAR_TAG_END_CHAR1 = '}'; //$NON-NLS-1$ + private static final String VAR_TAG_START = "${"; //$NON-NLS-1$ + private static final String VAR_TAG_END = "}"; //$NON-NLS-1$ + private static final String VAR_TAG_SEP = ":"; //$NON-NLS-1$ + + /** + * No instances allowed + */ + private ToolUtil() { + super(); + } + + /** + * Builds a variable tag that will be auto-expanded before + * the tool is run. + * + * @param varName the name of a known variable (one of the VAR_* constants for instance) + * @param varArgument an optional argument for the variable, <code>null</code> if none + */ + public static String buildVariableTag(String varName, String varArgument) { + StringBuffer buf = new StringBuffer(); + buildVariableTag(varName,varArgument, buf); + return buf.toString(); + } + + /** + * Builds a variable tag that will be auto-expanded before + * the tool is run. + * + * @param varName the name of a known variable (one of the VAR_* constants for instance) + * @param varArgument an optional argument for the variable, <code>null</code> if none + * @param buffer the buffer to write the constructed variable tag + */ + public static void buildVariableTag(String varName, String varArgument, StringBuffer buffer) { + buffer.append(VAR_TAG_START); + buffer.append(varName); + if (varArgument != null && varArgument.length() > 0) { + buffer.append(VAR_TAG_SEP); + buffer.append(varArgument); + } + buffer.append(VAR_TAG_END); + } + + /** + * Expands all the variables found in an individual + * argument text. + * + * @param argument one of the argument text in the list of arguments + * @param context the context to use for expanding variables + * @param status multi status to report any problems expanding variables + * @return the argument text with all variables expanded, or <code>null</code> if not possible + */ + public static String expandArgument(String argument, ExpandVariableContext context, MultiStatus status) { + StringBuffer buffer = new StringBuffer(); + + int start = 0; + while (true) { + VariableDefinition varDef = extractVariableTag(argument, start); + + // No more variables found... + if (varDef.start == -1) { + if (start == 0) + buffer.append(argument); + else + buffer.append(argument.substring(start)); + break; + } + + // Invalid variable format + if (varDef.end == -1 || varDef.name == null || varDef.name.length() == 0) { + String msg = ToolMessages.getString("ToolUtil.argumentVarFormatWrong"); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + // Copy text between start and variable. + if (varDef.start > start) + buffer.append(argument.substring(start, varDef.start)); + start = varDef.end; + + // Lookup the variable if it exist + ArgumentVariableRegistry registry; + registry = ExternalToolsPlugin.getDefault().getArgumentVariableRegistry(); + ArgumentVariable variable = registry.getArgumentVariable(varDef.name); + if (variable == null) { + String msg = ToolMessages.format("ToolUtil.argumentVarMissing", new Object[] {varDef.name}); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + // Expand the variable as text if possible + String text = variable.getExpander().getText(varDef.name, varDef.argument, context); + if (text == null) { + String msg = ToolMessages.format("ToolUtil.argumentVarExpandFailed", new Object[] {varDef.name}); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + buffer.append(text); + } + + return buffer.toString(); + } + + /** + * Returns a list of individual arguments where all + * variables have been expanded. + * + * @param arguments the arguments with leading and trailing + * spaces already removed. + * @param context the context used to expand the variable(s) + * @param status multi status to report any problems expanding variables + * @return the list of individual arguments where some elements in the + * list maybe <code>null</code> if problems expanding variable(s). + */ + public static String[] expandArguments(String arguments, ExpandVariableContext context, MultiStatus status) { + if (arguments == null || arguments.length() == 0) + return new String[0]; + + String[] argList = parseArgumentsIntoList(arguments); + for (int i = 0; i < argList.length; i++) + argList[i] = expandArgument(argList[i], context, status); + + return argList; + } + + /** + * Returns the expanded directory location if represented by a + * directory variable. Otherwise, the directory location given is + * return unless an unknown variable was detected. + * + * @param dirLocation a directory location either as a path or a variable + * with leading and trailing spaces already removed. + * @param context the context used to expand the variable + * @param status multi status to report any problems expanding variables + * @return the directory location as a string or <code>null</code> if not possible + */ + public static String expandDirectoryLocation(String dirLocation, ExpandVariableContext context, MultiStatus status) { + if (dirLocation == null || dirLocation.length() == 0) + return ""; //$NON-NLS-1$ + + VariableDefinition varDef = extractVariableTag(dirLocation, 0); + // Return if no variable found + if (varDef.start < 0) + return dirLocation; + + // Disallow text before/after variable + if (varDef.start != 0 || (varDef.end < dirLocation.length() && varDef.end != -1)) { + String msg = ToolMessages.getString("ToolUtil.dirLocVarBetweenText"); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + // Invalid variable format + if (varDef.name == null || varDef.name.length() == 0 || varDef.end == -1) { + String msg = ToolMessages.getString("ToolUtil.dirLocVarFormatWrong"); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + // Lookup the variable if it exist + PathLocationVariableRegistry registry; + registry = ExternalToolsPlugin.getDefault().getDirectoryLocationVariableRegistry(); + PathLocationVariable variable = registry.getPathLocationVariable(varDef.name); + if (variable == null) { + String msg = ToolMessages.format("ToolUtil.dirLocVarMissing", new Object[] {varDef.name}); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + // Expand the variable into a IPath if possible + IPath path = variable.getExpander().getPath(varDef.name, varDef.argument, context); + if (path == null) { + String msg = ToolMessages.format("ToolUtil.dirLocVarExpandFailed", new Object[] {varDef.name}); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + return path.toOSString(); + } + + /** + * Returns the expanded file location if represented by a + * file variable. Otherwise, the file location given is + * return unless an unknown variable was detected. + * + * @param fileLocation a file location either as a path or a variable + * with leading and trailing spaces already removed. + * @param context the context used to expand the variable + * @param status multi status to report any problems expanding variables + * @return the file location as a string or <code>null</code> if not possible + */ + public static String expandFileLocation(String fileLocation, ExpandVariableContext context, MultiStatus status) { + if (fileLocation == null || fileLocation.length() == 0) + return ""; //$NON-NLS-1$ + + VariableDefinition varDef = extractVariableTag(fileLocation, 0); + // Return if no variable found + if (varDef.start < 0) + return fileLocation; + + // Disallow text before/after variable + if (varDef.start != 0 || (varDef.end < fileLocation.length() && varDef.end != -1)) { + String msg = ToolMessages.getString("ToolUtil.fileLocVarBetweenText"); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + // Invalid variable format + if (varDef.name == null || varDef.name.length() == 0 || varDef.end == -1) { + String msg = ToolMessages.getString("ToolUtil.fileLocVarFormatWrong"); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + // Lookup the variable if it exist + PathLocationVariableRegistry registry; + registry = ExternalToolsPlugin.getDefault().getFileLocationVariableRegistry(); + PathLocationVariable variable = registry.getPathLocationVariable(varDef.name); + if (variable == null) { + String msg = ToolMessages.format("ToolUtil.fileLocVarMissing", new Object[] {varDef.name}); //$NON-NLS-1$ + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + // Expand the variable into a IPath if possible + IPath path = variable.getExpander().getPath(varDef.name, varDef.argument, context); + if (path == null) { + String msg = ToolMessages.format("The variable {0} with argument {1} could not be expanded to a valid path.", new Object[] {varDef.name, varDef.argument}); + status.merge(ExternalToolsPlugin.newErrorStatus(msg, null)); + return null; + } + + return path.toString(); + } + + /** + * Extracts from the source text the variable tag's name + * and argument. + * + * @param text the source text to parse for a variable tag + * @param start the index in the string to start the search + * @return the variable definition + */ + public static VariableDefinition extractVariableTag(String text, int start) { + VariableDefinition varDef = new VariableDefinition(); + + varDef.start = text.indexOf(VAR_TAG_START, start); + if (varDef.start < 0) + return varDef; + start = varDef.start + VAR_TAG_START.length(); + + int end = text.indexOf(VAR_TAG_END, start); + if (end < 0) + return varDef; + varDef.end = end + VAR_TAG_END.length(); + if (end == start) + return varDef; + + int mid = text.indexOf(VAR_TAG_SEP, start); + if (mid < 0 || mid > end) { + varDef.name = text.substring(start, end); + } else { + if (mid > start) + varDef.name = text.substring(start, mid); + mid = mid + VAR_TAG_SEP.length(); + if (mid < end) + varDef.argument = text.substring(mid, end); + } + + return varDef; + } + + /** + * Parses the argument text into an array of individual + * arguments using the space character as the delimiter. + * An individual argument containing spaces must have a + * double quote (") at the start and end. Two double + * quotes together is taken to mean an embedded double + * quote in the argument text. Variables are treated as + * a single unit and therefore spaces and double quotes + * inside a variable are copied as is and not parsed. + * + * @param arguments the arguments as one string + * @return the array of arguments + */ + public static String[] parseArgumentsIntoList(String arguments) { + if (arguments == null || arguments.length() == 0) + return new String[0]; + + ArrayList list = new ArrayList(10); + boolean inQuotes = false; + boolean inVar = false; + int start = 0; + int end = arguments.length(); + StringBuffer buffer = new StringBuffer(end); + + while (start < end) { + char ch = arguments.charAt(start); + start++; + + switch (ch) { + case ARG_DELIMITER : + if (inQuotes || inVar) { + buffer.append(ch); + } else { + if (buffer.length() > 0) { + list.add(buffer.toString()); + buffer.setLength(0); + } + } + break; + + case ARG_DBL_QUOTE : + if (inVar) { + buffer.append(ch); + } else { + if (start < end) { + if (arguments.charAt(start) == ARG_DBL_QUOTE) { + // Two quotes together represents one quote + buffer.append(ch); + start++; + } else { + inQuotes = !inQuotes; + } + } else { + // A lone quote at the end, just drop it. + inQuotes = false; + } + } + break; + + case VAR_TAG_START_CHAR1 : + buffer.append(ch); + if (!inVar && start < end) { + if (arguments.charAt(start) == VAR_TAG_START_CHAR2) { + buffer.append(VAR_TAG_START_CHAR2); + inVar = true; + start++; + } + } + break; + + case VAR_TAG_END_CHAR1 : + buffer.append(ch); + inVar = false; + break; + + default : + buffer.append(ch); + break; + } + + } + + if (buffer.length() > 0) + list.add(buffer.toString()); + + String[] results = new String[list.size()]; + list.toArray(results); + return results; + } + + + /** + * Structure to represent a variable definition within a + * source string. + */ + public static final class VariableDefinition { + /** + * Index in the source text where the variable started + * or <code>-1</code> if no valid variable start tag + * identifier found. + */ + public int start = -1; + + /** + * Index in the source text of the character following + * the end of the variable or <code>-1</code> if no + * valid variable end tag found. + */ + public int end = -1; + + /** + * The variable's name found in the source text, or + * <code>null</code> if no valid variable found. + */ + public String name = null; + + /** + * The variable's argument found in the source text, or + * <code>null</code> if no valid variable found or if + * the variable did not specify an argument + */ + public String argument = null; + + /** + * Create an initialized variable definition. + */ + private VariableDefinition() { + super(); + } + + /** + * Create an initialized variable definition. + */ + private VariableDefinition(int start, int end) { + super(); + this.start = start; + this.end = end; + } + } +} |