blob: 352b129885f5bd43d43c5fce0db7134c3d458a2f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.ui.internal.ide.handlers;
import java.io.File;
import java.io.IOException;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.e4.core.services.statusreporter.StatusReporter;
import org.eclipse.jface.util.Util;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.internal.ide.IDEInternalPreferences;
import org.eclipse.ui.internal.ide.IDEPreferenceInitializer;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
/**
* @since 3.106
*/
public class ShowInSystemExplorerHandler extends AbstractHandler {
/**
* Command id
*/
public static final String ID = "org.eclipse.ui.showIn.systemExplorer"; //$NON-NLS-1$
private static final String VARIABLE_RESOURCE = "${selected_resource_loc}"; //$NON-NLS-1$
private static final String VARIABLE_RESOURCE_URI = "${selected_resource_uri}"; //$NON-NLS-1$
private static final String VARIABLE_FOLDER = "${selected_resource_parent_loc}"; //$NON-NLS-1$
@Override
public Object execute(final ExecutionEvent event) {
final IResource item = getResource(event);
if (item == null) {
return null;
}
final StatusReporter statusReporter = HandlerUtil.getActiveWorkbenchWindow(event).getService(
StatusReporter.class);
Job job = new Job(IDEWorkbenchMessages.ShowInSystemExplorerHandler_jobTitle) {
@Override
protected IStatus run(IProgressMonitor monitor) {
String logMsgPrefix;
try {
logMsgPrefix = event.getCommand().getName() + ": "; //$NON-NLS-1$
} catch (NotDefinedException e) {
// will used id instead...
logMsgPrefix = event.getCommand().getId() + ": "; //$NON-NLS-1$
}
try {
File canonicalPath = getSystemExplorerPath(item);
if (canonicalPath == null) {
return statusReporter.newStatus(IStatus.ERROR, logMsgPrefix
+ IDEWorkbenchMessages.ShowInSystemExplorerHandler_notDetermineLocation, null);
}
String launchCmd = formShowInSytemExplorerCommand(canonicalPath);
if ("".equals(launchCmd)) { //$NON-NLS-1$
return statusReporter.newStatus(IStatus.ERROR, logMsgPrefix
+ IDEWorkbenchMessages.ShowInSystemExplorerHandler_commandUnavailable, null);
}
File dir = item.getWorkspace().getRoot().getLocation().toFile();
Process p;
if (Util.isLinux() || Util.isMac()) {
p = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", launchCmd }, null, dir); //$NON-NLS-1$ //$NON-NLS-2$
} else {
p = Runtime.getRuntime().exec(launchCmd, null, dir);
}
int retCode = p.waitFor();
if (retCode != 0 && !Util.isWindows()) {
return statusReporter.newStatus(IStatus.ERROR, "Execution of '" + launchCmd //$NON-NLS-1$
+ "' failed with return code: " + retCode, null); //$NON-NLS-1$
}
} catch (Exception e) {
return statusReporter.newStatus(IStatus.ERROR, logMsgPrefix + "Unhandled failure.", e); //$NON-NLS-1$
}
return Status.OK_STATUS;
}
};
job.schedule();
return null;
}
private IResource getResource(ExecutionEvent event) {
IResource resource = getSelectionResource(event);
if (resource==null) {
resource = getEditorInputResource(event);
}
return resource;
}
private IResource getSelectionResource(ExecutionEvent event) {
ISelection selection = HandlerUtil.getCurrentSelection(event);
if ((selection == null) || (selection.isEmpty())
|| (!(selection instanceof IStructuredSelection))) {
return null;
}
Object selectedObject = ((IStructuredSelection) selection)
.getFirstElement();
IResource item = (IResource) org.eclipse.ui.internal.util.Util
.getAdapter(selectedObject, IResource.class);
return item;
}
private IResource getEditorInputResource(ExecutionEvent event) {
IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
if (!(activePart instanceof IEditorPart)) {
return null;
}
IEditorInput input = ((IEditorPart)activePart).getEditorInput();
if (input instanceof IFileEditorInput) {
return ((IFileEditorInput)input).getFile();
}
return (IResource) input.getAdapter(IResource.class);
}
/**
* Prepare command for launching system explorer to show a path
*
* @param path
* the path to show
* @return the command that shows the path
*/
private String formShowInSytemExplorerCommand(File path) throws IOException {
String command = IDEWorkbenchPlugin.getDefault().getPreferenceStore()
.getString(IDEInternalPreferences.WORKBENCH_SYSTEM_EXPLORER);
command = Util.replaceAll(command, VARIABLE_RESOURCE, quotePath(path.getCanonicalPath()));
command = Util.replaceAll(command, VARIABLE_RESOURCE_URI, path.getCanonicalFile().toURI().toString());
File parent = path.getParentFile();
if (parent != null) {
command = Util.replaceAll(command, VARIABLE_FOLDER, quotePath(parent.getCanonicalPath()));
}
return command;
}
private String quotePath(String path) {
if (Util.isLinux() || Util.isMac()) {
// Quote for usage inside "", man sh, topic QUOTING:
path = path.replaceAll("[\"$`]", "\\\\$0"); //$NON-NLS-1$ //$NON-NLS-2$
}
// Windows: Can't quote, since explorer.exe has a very special command line parsing strategy.
return path;
}
/**
* Returns the path used for a resource when showing it in the system
* explorer
*
* @see File#getCanonicalPath()
* @param resource
* the {@link IResource} object to be used
* @return the canonical path to show in the system explorer for this
* resource, or null if it cannot be determined
* @throws IOException
* if an I/O error occurs while trying to determine the path
*/
private File getSystemExplorerPath(IResource resource) throws IOException {
IPath location = resource.getLocation();
if (location == null)
return null;
return location.toFile();
}
/**
* The default command for launching the system explorer on this platform.
*
* @return The default command which launches the system explorer on this system, or an empty
* string if no default exists
*/
public static String getDefaultCommand() {
// See https://bugs.eclipse.org/419940 why it is implemented in IDEPreferenceInitializer
return IDEPreferenceInitializer.getShowInSystemExplorerCommand();
}
}