PathTools : Simple Yet Useful Eclipse Plug-in
- CopyPath - this action copies the fully qualified path of selected folders and files into the Clipboard.
- Explore - this action opens the selected folder or the folder containing the selected file in the OS file explorer. The user can configure the exact command that is used to launch the file explorer.
- Open in external editor... - this action opens the selected folder or file using the selected external editor. The user can configure the exact command that is used to launch the external editor.
The following screenshot shows the CopyPath, Explore and Open in external editor... actions on the second toolbar. The Activator.java file was selected in the Package Explorer. The Explore action was invoked to show it in the Finder (the Mac OS file explorer). The Open in external editor... action was invoked to show it in the TextEdit.

Implementing Actions
Extension Point
These extensions register the actions
. Both actions are enabled for any selected object of type org.eclipse.core.resources.IResource or adaptable as org.eclipse.core.resources.IResource
. The Explore path action is enabled when one object (enablesFor="1"
) is selected. The CopyPath action is enabled when one or more objects (enablesFor="+"
) are selected.
<extension
point="org.eclipse.ui.actionSets">
<actionSet
id="PathTools.actionSet"
label="Path Tools">
<actionclass="pathtools.EditAction"
enablesFor="1"
icon="icons/editpath.gif"
id="PathTools.Edit"
label="Open in external editor..."
menubarPath="File/additions"
style="push"
toolbarPath="PathTools/additions">
<enablement>
<or><objectClass
name="org.eclipse.core.resources.IResource"/>
<objectClass
name="org.eclipse.core.runtime.IAdaptable"/>
</or>
</enablement>
</action>
<actionclass="pathtools.ExploreAction"
enablesFor="1"
icon="icons/explore.gif"
id="PathTools.Explore"
label="Explore"
menubarPath="File/additions"
style="push"
toolbarPath="PathTools/additions">
<enablement>
<or><objectClass
name="org.eclipse.core.resources.IResource"/>
<objectClass
name="org.eclipse.core.runtime.IAdaptable"/>
</or>
</enablement>
</action>
<actionclass="pathtools.CopyPathAction"
enablesFor="+"
icon="icons/copypaths.gif"
id="PathTools.CopyPath"
label="Copy Path"
menubarPath="Edit/additions"
style="push"
toolbarPath="Edit/additions">
<enablement>
<or><objectClass
name="org.eclipse.core.resources.IResource"/>
<objectClass
name="org.eclipse.core.runtime.IAdaptable"/>
</or>
</enablement>
</action>
</actionSet>
</extension>
CopyPath Action
The following code implements the CopyPath action. The CopyPath action copies the full paths of selected folders or files (one per line) to the Clipboard.
CopyPath.java
package pathtools;Explore Action
import java.io.File;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PlatformUI;
/**
* This copies the absolute paths of selected folders and files (one per line)
* into the Clipboard.
*
* @author Sandip V. Chitale
*
*/
public class CopyPathAction implements IWorkbenchWindowActionDelegate {
private List<String> paths = new LinkedList<String>();
public void dispose() {
}
public void init(IWorkbenchWindow window) {
}
public void run(IAction action) {
// Are there any paths selected ?
if (paths.size() > 0) {
// Build a string with each path on separate line
StringBuilder stringBuilder = new StringBuilder();
for (String path : paths) {
stringBuilder.append(path + "\n");
}
// Get Clipboard
Clipboard clipboard = new Clipboard(PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getShell().getDisplay());
// Put the paths string into the Clipboard
clipboard.setContents(new Object[] { stringBuilder.toString() },
new Transfer[] { TextTransfer.getInstance() });
}
}
@SuppressWarnings("unchecked")
public void selectionChanged(IAction action, ISelection selection) {
// Start with a clear list
paths.clear();
if (selection instanceof IStructuredSelection) {
// Get structured selection
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
// Iterate through selected items
Iterator iterator = structuredSelection.iterator();
while (iterator.hasNext()) {
Object firstElement = iterator.next();
IPath location = null;
if (firstElement instanceof IResource) {
// Is it a IResource ?
IResource resource = (IResource) firstElement;
// Get the location
location = resource.getLocation();
} else if (firstElement instanceof IAdaptable) {
// Is it a IResource adaptable ?
IAdaptable adaptable = (IAdaptable) firstElement;
IResource resource = (IResource) adaptable
.getAdapter(IResource.class);
if (resource != null) {
// Get the location
location = resource.getLocation();
}
}
if (location != null) {
// Get the file for the location
File file = location.toFile();
if (file != null) {
// Add the absolute path to the list
paths.add(file.getAbsolutePath());
}
}
}
}
action.setEnabled(paths.size() > 0);
}
}
The following code implements the Explore action. The explore action launches the OS file explorer with the selected folder or file.
package pathtools;
import java.io.File;
import java.text.MessageFormat;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
/**
* This launches the OS file explorer showing the selected folder or the folder
* containing the selected file.
*
* @author Sandip V. Chitale
*
*/
public class ExploreAction implements IWorkbenchWindowActionDelegate {
private File fileObject;
private static String fileExploreComand = null;
private static String folderExploreComand = null;
public void dispose() {
}
public void init(IWorkbenchWindow window) {
}
public void run(IAction action) {
// Get the configured explorer commands for folder and file
folderExploreComand = Activator.getDefault().getPreferenceStore()
.getString(Activator.FOLDER_EXPLORE_COMMAND_KEY);
fileExploreComand = Activator.getDefault().getPreferenceStore()
.getString(Activator.FILE_EXPLORE_COMMAND_KEY);
if (fileExploreComand == null || folderExploreComand == null) {
return;
}
// Is this a physical file on the disk ?
if (fileObject != null) {
String commandFormat = fileObject.isDirectory() ? folderExploreComand
: fileExploreComand;
// Substitute parameter values ad format the explore command
String command = MessageFormat.format(Utilities
.convertParameters(commandFormat), new Object[] {
fileObject.getAbsolutePath().replace('/',
File.separatorChar).replace('\\',
File.separatorChar),
fileObject.getParentFile().getAbsolutePath().replace('/',
File.separatorChar).replace('\\',
File.separatorChar),
fileObject.getAbsolutePath().replace('\\', '/'),
fileObject.getParentFile().getAbsolutePath().replace('\\',
'/'),
fileObject.getAbsolutePath().replace('/', '\\'),
fileObject.getParentFile().getAbsolutePath().replace('/',
'\\'), });
// Launch the explore command
CommandLauncher.launch(command);
}
}
public void selectionChanged(IAction action, ISelection selection) {
fileObject = null;
action.setEnabled(false);
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
IPath location = null;
// Is only one item selected?
if (structuredSelection.size() == 1) {
Object firstElement = structuredSelection.getFirstElement();
if (firstElement instanceof IResource) {
// Is this an IResource ?
IResource resource = (IResource) firstElement;
location = resource.getLocation();
} else if (firstElement instanceof IAdaptable) {
IAdaptable adaptable = (IAdaptable) firstElement;
// Is this an IResource adaptable ?
IResource resource = (IResource) adaptable
.getAdapter(IResource.class);
if (resource != null) {
location = resource.getLocation();
}
}
}
if (location != null) {
fileObject = location.toFile();
}
}
action.setEnabled(fileObject != null);
}
}
Open in external editor... Action
The following code implements the Open in external editor... action. The Open in external editor... opens the selected folder or file in the user specified external editor.
EditAction.java
package pathtools;
import java.io.File;
import java.text.MessageFormat;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
/**
* This launches the external text editor for selected folder or file.
*
* @author Sandip V. Chitale
*
*/
public class EditAction implements IWorkbenchWindowActionDelegate {
private File fileObject;
private static String fileEditComand = null;
private static String folderEditComand = null;
public void dispose() {
}
public void init(IWorkbenchWindow window) {
}
public void run(IAction action) {
// Get the configured explorer commands for folder and file
folderEditComand = Activator.getDefault().getPreferenceStore()
.getString(Activator.FOLDER_EDIT_COMMAND_KEY);
fileEditComand = Activator.getDefault().getPreferenceStore().getString(
Activator.FILE_EDIT_COMMAND_KEY);
if (fileEditComand == null || folderEditComand == null) {
return;
}
// Is this a physical file on the disk ?
if (fileObject != null) {
String commandFormat = fileObject.isDirectory() ? folderEditComand
: fileEditComand;
// Substitute parameter values ad format the explore command
String command = MessageFormat.format(Utilities
.convertParameters(commandFormat), new Object[] {
fileObject.getAbsolutePath().replace('/',
File.separatorChar).replace('\\',
File.separatorChar),
fileObject.getParentFile().getAbsolutePath().replace('/',
File.separatorChar).replace('\\',
File.separatorChar),
fileObject.getAbsolutePath().replace('\\', '/'),
fileObject.getParentFile().getAbsolutePath().replace('\\',
'/'),
fileObject.getAbsolutePath().replace('/', '\\'),
fileObject.getParentFile().getAbsolutePath().replace('/',
'\\'), });
// Launch the explore command
CommandLauncher.launch(command);
}
}
public void selectionChanged(IAction action, ISelection selection) {
fileObject = null;
action.setEnabled(false);
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
IPath location = null;
// Is only one item selected?
if (structuredSelection.size() == 1) {
Object firstElement = structuredSelection.getFirstElement();
if (firstElement instanceof IResource) {
// Is this an IResource
IResource resource = (IResource) firstElement;
location = resource.getLocation();
} else if (firstElement instanceof IAdaptable) {
IAdaptable adaptable = (IAdaptable) firstElement;
// Is this an IResource adaptable
IResource resource = (IResource) adaptable
.getAdapter(IResource.class);
if (resource != null) {
location = resource.getLocation();
}
}
}
if (location != null) {
fileObject = location.toFile();
}
}
action.setEnabled(fileObject != null);
}
}
Required Plugin dependencies
MANIFEST.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Path Tools Plug-in
Bundle-SymbolicName: PathTools;singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: pathtools.Activator
Bundle-Vendor: Sandip V. ChitaleRequire-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.core.resources;bundle-version="3.4.0"
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
Implementing Preferences Page
The preferences page allows the user to commands for file explorer and external editor.
Extension Point for Preference Page
This extension registers the preferences page.
<extensionpoint="org.eclipse.ui.preferencePages">
<pageclass="pathtools.WorkbenchPreferencePage"
id="PathTools.page"
name="Path Tools">
</page>
</extension>
The following class (registred above
) implements the preferences page using the FieldEditors.WorkbenchPreferencePage.java
package pathtools;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
/**
*
* This implements the preferences page using the FieldEditor.
*
* @author Sandip V. Chitale
*
*/
public class WorkbenchPreferencePage extends FieldEditorPreferencePage
implements IWorkbenchPreferencePage {
public WorkbenchPreferencePage() {
super(FieldEditorPreferencePage.GRID);
}
public void init(IWorkbench workbench) {
// Initialize the preference store we wish to use
setPreferenceStore(Activator.getDefault().getPreferenceStore());
}
@Override
public String getDescription() {
return "Specify the commands for exploring folders and fies. You can\n"
+ "use \"\" (quotes) around command arguments with spaces in their value.\n"
+ "You can use the following parameters in the commands:\n\n"
+ Utilities.FILE_PATH
+ " - path of the selected object with default file separator.\n"
+ Utilities.FILE_PARENT_PATH
+ " - path of the parent of selected object with default file separator.\n"
+ Utilities.FILE_PATH_SLASHES
+ " - path of the selected object with / file separator.\n"
+ Utilities.FILE_PARENT_PATH_SLASHES
+ " - path of the parent of selected object with / file separator.\n"
+ Utilities.FILE_PATH_BACKSLASHES
+ " - path of the selected object with \\ File separator.\n"
+ Utilities.FILE_PARENT_PATH_BACKSLASHES
+ "{parent-path-backslashes} - path of the parent of selected object with \\ file separator.\n"
+ "\n";
}
@Override
protected void createFieldEditors() {
// Folder explore command field
StringFieldEditor folderExploreCommad = new StringFieldEditor(
Activator.FOLDER_EXPLORE_COMMAND_KEY, "Explore Folder:",
getFieldEditorParent());
addField(folderExploreCommad);
// File explore command field
StringFieldEditor fileExploreCommad = new StringFieldEditor(
Activator.FILE_EXPLORE_COMMAND_KEY, "Explore File:",
getFieldEditorParent());
addField(fileExploreCommad);
// Folder editor command field
StringFieldEditor folderEditCommad = new StringFieldEditor(
Activator.FOLDER_EDIT_COMMAND_KEY, "Edit Folder:",
getFieldEditorParent());
addField(folderEditCommad);
// File editor command field
StringFieldEditor fileEditCommad = new StringFieldEditor(
Activator.FILE_EDIT_COMMAND_KEY, "Edit File:",
getFieldEditorParent());
addField(fileEditCommad);
}
}
Bundle Activator
The following class implements the bundle activator. It initializes the default values of the explore commands for folders and files depending on the platform the Eclipse is running on.
Activator.java
package pathtools;
import java.io.File;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*
* @author Sandip V. Chitale
*
*/
public class Activator extends AbstractUIPlugin {
static final String FOLDER_EXPLORE_COMMAND_KEY = "folderExploreCommand";
static final String FILE_EXPLORE_COMMAND_KEY = "fileExploreCommand";
static String defaultFolderExploreCommand = "";
static String defaultFileExploreCommand = "";
static final String FOLDER_EDIT_COMMAND_KEY = "folderEditCommand";
static final String FILE_EDIT_COMMAND_KEY = "fileEditCommand";
static String defaultFolderEditCommand = "";
static String defaultFileEditCommand = "";
static {
if (Platform.OS_MACOSX.equals(Platform.getOS())) {
defaultFolderExploreCommand = "/usr/bin/open -a /System/Library/CoreServices/Finder.app \""
+ Utilities.FILE_PATH + "\"";
defaultFileExploreCommand = "/usr/bin/open -a /System/Library/CoreServices/Finder.app \""
+ Utilities.FILE_PARENT_PATH + "\"";
defaultFolderEditCommand = "/usr/bin/open -a /System/Library/CoreServices/Finder.app \""
+ Utilities.FILE_PATH + "\"";
defaultFileEditCommand = "/usr/bin/open -a /Applications/TextEdit.app \""
+ Utilities.FILE_PATH + "\"";
} else if (Platform.OS_WIN32.equals(Platform.getOS())) {
defaultFolderExploreCommand = "cmd /C start explorer /select,/e \""
+ Utilities.FILE_PATH + "\"";
defaultFileExploreCommand = "cmd /C start explorer /select,/e \""
+ Utilities.FILE_PARENT_PATH + "\"";
defaultFolderEditCommand = "cmd /C start explorer /select,/e \""
+ Utilities.FILE_PATH + "\"";
defaultFileEditCommand = "cmd /C start notepad \""
+ Utilities.FILE_PATH + "\"";
} else if (Platform.OS_LINUX.equals(Platform.getOS())) {
if (new File("/usr/bin/konqueror").exists()) {
defaultFolderExploreCommand = "/usr/bin/konqueror \""
+ Utilities.FILE_PATH + "\"";
defaultFileExploreCommand = "/usr/bin/konqueror \""
+ Utilities.FILE_PARENT_PATH + "\"";
defaultFolderEditCommand = "/usr/bin/konqueror \""
+ Utilities.FILE_PATH + "\"";
} else if (new File("/usr/bin/nautilus").exists()) {
defaultFolderExploreCommand = "/usr/bin/nautilus \""
+ Utilities.FILE_PATH + "\"";
defaultFileExploreCommand = "/usr/bin/nautilus \""
+ Utilities.FILE_PARENT_PATH + "\"";
defaultFolderEditCommand = "/usr/bin/nautilus \""
+ Utilities.FILE_PATH + "\"";
}
if (new File("/usr/bin/kedit").exists()) {
defaultFileEditCommand = "/usr/bin/kedit \""
+ Utilities.FILE_PATH + "\"";
} else if (new File("/usr/bin/gedit").exists()) {
defaultFileEditCommand = "/usr/bin/gedit \""
+ Utilities.FILE_PATH + "\"";
}
} else if (Platform.OS_SOLARIS.equals(Platform.getOS())) {
if (new File("/usr/bin/konqueror").exists()) {
defaultFolderExploreCommand = "/usr/bin/konqueror \""
+ Utilities.FILE_PATH + "\"";
defaultFileExploreCommand = "/usr/bin/konqueror \""
+ Utilities.FILE_PARENT_PATH + "\"";
defaultFolderEditCommand = "/usr/bin/konqueror \""
+ Utilities.FILE_PATH + "\"";
} else if (new File("/usr/bin/nautilus").exists()) {
defaultFolderExploreCommand = "/usr/bin/nautilus \""
+ Utilities.FILE_PATH + "\"";
defaultFileExploreCommand = "/usr/bin/nautilus \""
+ Utilities.FILE_PARENT_PATH + "\"";
defaultFolderEditCommand = "/usr/bin/nautilus \""
+ Utilities.FILE_PATH + "\"";
} else {
defaultFolderExploreCommand = "filemgr -c -d \""
+ Utilities.FILE_PATH + "\"";
defaultFolderExploreCommand = "filemgr -c -d \""
+ Utilities.FILE_PATH + "\"";
defaultFileEditCommand = "filemgr -c -d \""
+ Utilities.FILE_PARENT_PATH + "\"";
}
}
}
// The plug-in ID
public static final String PLUGIN_ID = "PathTools";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
* )
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
* )
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
@SuppressWarnings("deprecation")
@Override
protected void initializeDefaultPreferences(IPreferenceStore store) {
store.setDefault(FOLDER_EXPLORE_COMMAND_KEY,
defaultFolderExploreCommand);
store.setDefault(FILE_EXPLORE_COMMAND_KEY, defaultFileExploreCommand);
store.setDefault(FOLDER_EDIT_COMMAND_KEY, defaultFolderEditCommand);
store.setDefault(FILE_EDIT_COMMAND_KEY, defaultFileEditCommand);
super.initializeDefaultPreferences(store);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
}
Utilities
The following class implements the parameter substitution as well as parsing the quoted parameters and splitting the commands into String arrays.
Utilities.java
package pathtools;CommandLauncher.java
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
/**
* This implements some utility methods.
*
* @author Sandip V. Chitale
*
*/
public class Utilities {
static final String FILE_PATH = "{path}";
static final String FILE_PARENT_PATH = "{parent-path}";
static final String FILE_PATH_SLASHES = "{path-slashes}";
static final String FILE_PARENT_PATH_SLASHES = "{parent-path-slashes}";
static final String FILE_PATH_BACKSLASHES = "{path-backslashes}";
static final String FILE_PARENT_PATH_BACKSLASHES = "{parent-path-backslashes}";
static String convertParameters(String command) {
return command.replaceAll(Pattern.quote(FILE_PATH), "{0}").replaceAll(
Pattern.quote(FILE_PARENT_PATH), "{1}").replaceAll(
Pattern.quote(FILE_PATH_SLASHES), "{2}").replaceAll(
Pattern.quote(FILE_PARENT_PATH_SLASHES), "{3}").replaceAll(
Pattern.quote(FILE_PATH_BACKSLASHES), "{4}").replaceAll(
Pattern.quote(FILE_PARENT_PATH_BACKSLASHES), "{5}");
}
/**
* Parses parameters from a given string in shell-like manner. Users of the
* Bourne shell (e.g. on Unix) will already be familiar with the behavior.
* For example, when using <code>java.lang.ProcessBuilder</code> (Execution
* API) you should be able to:
* <ul>
* <li>Include command names with embedded spaces, such as
* <code>c:\Program Files\jdk\bin\javac</code>.
* <li>Include extra command arguments, such as <code>-Dname=value</code>.
* <li>Do anything else which might require unusual characters or
* processing. For example:
* <p>
* <code><pre>
* "c:\program files\jdk\bin\java" -Dmessage="Hello /\\/\\ there!" -Xmx128m
* </pre></code>
* <p>
* This example would create the following executable name and arguments:
* <ol>
* <li> <code>c:\program files\jdk\bin\java</code>
* <li> <code>-Dmessage=Hello /\/\ there!</code>
* <li> <code>-Xmx128m</code>
* </ol>
* Note that the command string does not escape its backslashes--under the
* assumption that Windows users will not think to do this, meaningless
* escapes are just left as backslashes plus following character.
* </ul>
* <em>Caveat</em>: even after parsing, Windows programs (such as the Java
* launcher) may not fully honor certain characters, such as quotes, in
* command names or arguments. This is because programs under Windows
* frequently perform their own parsing and unescaping (since the shell
* cannot be relied on to do this). On Unix, this problem should not occur.
*
* Copied from org.openide.util.Utilities.
*
* @param s
* a string to parse
* @return an array of parameters
*/
public static String[] parseParameters(String s) {
int NULL = 0x0; // STICK + whitespace or NULL + non_"
int INPARAM = 0x1; // NULL + " or STICK + " or INPARAMPENDING + "\ //
// NOI18N
int INPARAMPENDING = 0x2; // INPARAM + \
int STICK = 0x4; // INPARAM + " or STICK + non_" // NOI18N
int STICKPENDING = 0x8; // STICK + \
List<String> params = new LinkedList<String>();
char c;
int state = NULL;
StringBuffer buff = new StringBuffer(20);
int slength = s.length();
for (int i = 0; i < slength; i++) {
c = s.charAt(i);
if (Character.isWhitespace(c)) {
if (state == NULL) {
if (buff.length() > 0) {
params.add(buff.toString());
buff.setLength(0);
}
} else if (state == STICK) {
params.add(buff.toString());
buff.setLength(0);
state = NULL;
} else if (state == STICKPENDING) {
buff.append('\\');
params.add(buff.toString());
buff.setLength(0);
state = NULL;
} else if (state == INPARAMPENDING) {
state = INPARAM;
buff.append('\\');
buff.append(c);
} else { // INPARAM
buff.append(c);
}
continue;
}
if (c == '\\') {
if (state == NULL) {
++i;
if (i < slength) {
char cc = s.charAt(i);
if ((cc == '"') || (cc == '\\')) {
buff.append(cc);
} else if (Character.isWhitespace(cc)) {
buff.append(c);
--i;
} else {
buff.append(c);
buff.append(cc);
}
} else {
buff.append('\\');
break;
}
continue;
} else if (state == INPARAM) {
state = INPARAMPENDING;
} else if (state == INPARAMPENDING) {
buff.append('\\');
state = INPARAM;
} else if (state == STICK) {
state = STICKPENDING;
} else if (state == STICKPENDING) {
buff.append('\\');
state = STICK;
}
continue;
}
if (c == '"') {
if (state == NULL) {
state = INPARAM;
} else if (state == INPARAM) {
state = STICK;
} else if (state == STICK) {
state = INPARAM;
} else if (state == STICKPENDING) {
buff.append('"');
state = STICK;
} else { // INPARAMPENDING
buff.append('"');
state = INPARAM;
}
continue;
}
if (state == INPARAMPENDING) {
buff.append('\\');
state = INPARAM;
} else if (state == STICKPENDING) {
buff.append('\\');
state = STICK;
}
buff.append(c);
}
// collect
if (state == INPARAM) {
params.add(buff.toString());
} else if ((state & (INPARAMPENDING | STICKPENDING)) != 0) {
buff.append('\\');
params.add(buff.toString());
} else { // NULL or STICK
if (buff.length() != 0) {
params.add(buff.toString());
}
}
String[] ret = params.toArray(new String[0]);
return ret;
}
}
package pathtools;
import java.io.IOException;
import java.util.Arrays;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/**
* A simple external process launcher.
*
* @author Sandip V. Chitale
*
*/
public class CommandLauncher {
public static void launch(String command) {
Activator activator = Activator.getDefault();
String[] commandArray = Utilities.parseParameters(command);
try {
Process process = Runtime.getRuntime().exec(commandArray);
// TODO Should handle STDOUT and STDERR here.
int status = process.waitFor();
if (status == 0) {
// Good
} else {
activator.getLog().log(
new Status(IStatus.ERROR, activator.getBundle()
.getSymbolicName(), "Process '"
+ Arrays.asList(commandArray).toString()
+ "' exited with status: " + status));
}
} catch (InterruptedException ex) {
activator.getLog()
.log(
new Status(IStatus.ERROR, activator.getBundle()
.getSymbolicName(),
"Exception while executing '"
+ Arrays.asList(commandArray)
.toString() + "'", ex));
} catch (IOException ioe) {
activator.getLog()
.log(
new Status(IStatus.ERROR, activator.getBundle()
.getSymbolicName(),
"Exception while executing '"
+ Arrays.asList(commandArray)
.toString() + "'", ioe));
}
}
}
Installation
The resources section has the link to the plugin jar which can be dropped into your Eclipse installation's plugins directory. Once installed you will have to make the PathTools actions visible by going to the Window:Customize Perspectives:Commands tab and selecting the Path Tools action set.Source Code
The source code is bundled in the plug-in's jar file. In fact you can import the source plug-in project into PDE and hack it further.Conclusion
In this tutorial we built a simple yet useful Eclipse plug-in called - PathTools. It makes use of the actionSet and preference page extension points to add useful functionality to Eclipse. It also demonstrates how easy it is to build the preferences pages.Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.
Resources
Notes on the Eclipse Plug-in Architecture
PDE Does Plug-ins
Contributing Actions to the Eclipse Workbench
Preferences in the Eclipse Workbench UI
PathTools_1.0.0.jar
- Login or register to post comments
- 10265 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
Anuradha Gunasekara replied on Wed, 2008/08/20 - 8:48am
Hey Sandip,
Now you on Eclipse ;-) we miss you on Netbeans :-(
sandipchitale replied on Wed, 2008/08/20 - 1:36pm
I have created a Google Code project for PathTools.
You can download the latest plugin here.
sandipchitale replied on Thu, 2008/08/21 - 1:51pm
Hi Anuradha,
Yup... I will be working on Eclipse now. I use to work on Eclipse before I joined Sun also. However I will continue to support my NetBeans modules and also download and build NetBeans once in a while.
Regards,
Sandip
toyinf replied on Fri, 2008/08/22 - 8:34am
Hi your article was great.
I got a problem.
I've got elements A (ScrapItemEditPart), B, C (Folder) in my model on the workspace, I want to be able to replace element A with element C. This is my problem: When I select element A and hit the replace button, element C appears but element A becomes faded (not properly deleted) and the remaining elements B, C and D becomes unmovable (static) on the workspace. I cant even create any new elements. Do you have a code that can change a shape to another?
Here is my code:
public class CreateShape implements IObjectActionDelegate {
public final static String ID = "org.eclipse.scrapbook.custom.newAction";
private ScrapItemEditPart selectedElement;
public void run(IAction action) {
//CompoundCommand cc = new CompoundCommand("Create another shape");
// we will combine all of these commands together
CompoundCommand cc = new CompoundCommand("A compound command");
//add it to the compound command
// Create the new shape.
CreateViewRequest shapeRequest = CreateViewRequestFactory.getCreateShapeRequest(ScrapBuukElementTypes.Folder_1001, selectedElement.getDiagramPreferencesHint());
Point p = selectedElement.getFigure().getBounds().getTopRight().getCopy();
selectedElement.getFigure().translateToAbsolute(p);
int edgeCount = selectedElement.getNotationView().getSourceEdges().size();
// A quick hack to get element to layout to the right, from top to bottom
int offset = (edgeCount * 0);
shapeRequest.setLocation(p.translate(-45, offset));
ScrapBookDiagramEditPart scrapbookmodelEditPart = (ScrapBookDiagramEditPart) selectedElement.getParent();
Command createShapeCmd = scrapbookmodelEditPart.getCommand(shapeRequest);
cc.add(createShapeCmd);
// try this code to destroy the element to be replaced
DestroyElementRequest request2 = new DestroyElementRequest (selectedElement.resolveSemanticElement(), false);
Command destroy = selectedElement.getCommand(new EditCommandRequestWrapper(request2) );
cc.add(destroy);
// you can then execute the command
selectedElement.getDiagramEditDomain().getDiagramCommandStack().execute(cc);
}
public void selectionChanged(IAction action, ISelection selection) {
selectedElement = null;
if (selection instanceof IStructuredSelection) {
IStructuredSelection Selection = (IStructuredSelection) selection;
if (Selection.getFirstElement() instanceof ScrapItemEditPart) {
selectedElement = (ScrapItemEditPart) Selection.getFirstElement();
}
}
}
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
}
}
Thanks
sandipchitale replied on Fri, 2008/08/22 - 1:05pm
sandipchitale replied on Tue, 2008/08/26 - 10:47pm
PathTools 1.0.6 now supports custom commands. Get it.
Eric replied on Fri, 2008/09/05 - 10:05am
sandipchitale replied on Fri, 2008/09/05 - 6:45pm
in response to: etoelz
The commands appear in the Custom commands action's (fourth icon) dropdown:
sandipchitale replied on Sat, 2008/10/25 - 2:26pm
Added a lot more functionality to Path Tools plug-in. Check it out here.
musharrif replied on Tue, 2008/12/02 - 3:48am
in response to: sandipchitale
Hi Sandip
For my project I have my own 2 XML files. One file is responsible for formatting and other one is for checkstyle. Every time when i change the work space or view, the links to these files disappear and I get default configuration for checkstyle. I have tried to cope this situation by setting preferences but it I didn't succeed.
Please give me solution for this problem if there is any.
R/
Musharrif
sandipchitale replied on Wed, 2008/12/03 - 12:38am
Musharrif,
Get the latest version of the plug-in here:
http://code.google.com/p/pathtools/
I think this will solve your issue.
--
Sandip