Статьи

PathTools: простой, но полезный плагин Eclipse


В этой статье мы разрабатываем простой, но полезный плагин Eclipse PathTools.
Плагин добавляет следующие три действия в Eclipse.



  • CopyPath — это действие копирует полный путь выбранных папок и файлов в буфер обмена.
  • Исследовать — это действие открывает выбранную папку или папку, содержащую выбранный файл в проводнике файлов ОС. Пользователь может настроить точную команду, которая используется для запуска проводника файлов.
  • Открыть во внешнем редакторе … — это действие открывает выбранную папку или файл с использованием выбранного внешнего редактора. Пользователь может настроить точную команду, которая используется для запуска внешнего редактора.


На следующем снимке
экрана показаны действия
CopyPath,
Explore и
Open во внешнем редакторе … на второй панели инструментов. Файл Activator.java был выбран в
проводнике пакетов . Действие
Explore было вызвано, чтобы показать его в Finder (проводнике файлов Mac OS). Было
открыто действие Открыть во внешнем редакторе …, чтобы показать его в TextEdit.


[Img_assist | NID = 4541 | название = | убывание = | ссылка = нет | ALIGN = не определено | ширина = 651 | Высота = 364]


Реализация действий

Точка расширения


Эти расширения регистрируют действия . Оба действия включены для любого выбранного объекта типа org.eclipse.core.resources.IResource или могут быть адаптированы как org.eclipse.core.resources.IResource . Действие «Исследовать путь» включается, когда выбран один объект ( enableFor = «1» ). Действие CopyPath включается, когда выбран один или несколько объектов ( enableFor = «+» ).


   <extension
point="org.eclipse.ui.actionSets">
<actionSet
id="PathTools.actionSet"
label="Path Tools">
<action
1 class="pathtools.EditAction"
2 enablesFor="1"
icon="icons/editpath.gif"
id="PathTools.Edit"
label="Open in external editor..."
menubarPath="File/additions"
style="push"
toolbarPath="PathTools/additions">
<enablement>
<or>
3 <objectClass
name="org.eclipse.core.resources.IResource"/>
<objectClass
name="org.eclipse.core.runtime.IAdaptable"/>
</or>
</enablement>
</action>
<action
1 class="pathtools.ExploreAction"
2 enablesFor="1"
icon="icons/explore.gif"
id="PathTools.Explore"
label="Explore"
menubarPath="File/additions"
style="push"
toolbarPath="PathTools/additions">
<enablement>
<or>
3 <objectClass
name="org.eclipse.core.resources.IResource"/>
<objectClass
name="org.eclipse.core.runtime.IAdaptable"/>
</or>
</enablement>
</action>
<action
1 class="pathtools.CopyPathAction"
4 enablesFor="+"
icon="icons/copypaths.gif"
id="PathTools.CopyPath"
label="Copy Path"
menubarPath="Edit/additions"
style="push"
toolbarPath="Edit/additions">
<enablement>
<or>
3 <objectClass
name="org.eclipse.core.resources.IResource"/>
<objectClass
name="org.eclipse.core.runtime.IAdaptable"/>
</or>
</enablement>
</action>
</actionSet>
</extension>

Действие CopyPath

Следующий код реализует действие CopyPath . Действие CopyPath копирует полные пути выбранных папок или файлов (по одному на строку) в буфер обмена.

CopyPath.java

package pathtools;

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);
}
}

Исследуй Действие

Следующий код реализует действие Explore . Действие исследования запускает проводник ОС с выбранной папкой или файлом.

ExploreAction.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 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);
}

}

Открыть во внешнем редакторе … Действие

Следующий код реализует действие « Открыть во внешнем редакторе …» . Открыть во внешнем редакторе … открывает выбранную папку или файл в указанном пользователе внешнего редактора.

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);
}

}

Требуемые зависимости плагина

Файл манифеста объявляет необходимые зависимости.

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. Chitale
1Require-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

Реализация страницы настроек

Страница настроек позволяет пользователю команды для файлового проводника и внешнего редактора.

 

Точка расширения для страницы предпочтений


Это расширение регистрирует страницу настроек.

   <extension
1 point="org.eclipse.ui.preferencePages">
<page
2 class="pathtools.WorkbenchPreferencePage"
id="PathTools.page"
name="Path Tools">
</page>
</extension>


Страница предпочтений

Следующий класс (зарегистрированный выше
) реализует страницу предпочтений с помощью 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);
}

}


Активатор комплекта

Следующий класс реализует активатор комплекта. Он инициализирует значения по умолчанию команд исследования для папок и файлов в зависимости от платформы, на которой работает Eclipse.

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;
}

}


Утилиты

Следующий класс реализует подстановку параметров, а также синтаксический анализ параметров в кавычках и разбиение команд на массивы String.


Utilities.java
package pathtools;

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;
}

}

CommandLauncher.java

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));
}
}

}

Установка

В разделе ресурсов есть ссылка на jar плагина, который можно поместить в каталог плагинов вашей инсталляции Eclipse. После установки вам нужно будет сделать действия PathTools видимыми, перейдя на вкладку Window: Customize Perspectives: Commands и выбрав набор действий Path Tools.

Исходный код

Исходный код находится в jar-файле плагина. Фактически вы можете импортировать исходный проект плагина в PDE и взломать его дальше.

Вывод

В этом уроке мы создали простой, но полезный плагин Eclipse под названием PathTools. Он использует actionSet и точки расширения страницы настроек для добавления полезных функций в Eclipse. Это также демонстрирует, как легко создавать страницы настроек.




Java и все товарные знаки и логотипы на основе Java являются товарными знаками или зарегистрированными товарными знаками Sun Microsystems, Inc. в США или других странах.
Примечания к


ресурсам

по архитектуре
подключаемых модулей Eclipse PDE выполняет ли подключаемые модули
действия для
предпочтений Eclipse Workbench в пользовательском интерфейсе Eclipse Workbench

PathTools_1.0.0.jar