Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 106360 Details for
Bug 4922
[EditorMgmt] Need ability to open a file in eclipse from the command line
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Simple socket solution (reformatted)
patch.txt (text/plain), 18.54 KB, created by
John Arthorne
on 2008-07-02 17:05:33 EDT
(
hide
)
Description:
Simple socket solution (reformatted)
Filename:
MIME Type:
Creator:
John Arthorne
Created:
2008-07-02 17:05:33 EDT
Size:
18.54 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.ui.ide.application >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide.application/META-INF/MANIFEST.MF,v >retrieving revision 1.8 >diff -u -r1.8 MANIFEST.MF >--- META-INF/MANIFEST.MF 1 May 2008 14:01:17 -0000 1.8 >+++ META-INF/MANIFEST.MF 2 Jul 2008 21:03:53 -0000 >@@ -13,7 +13,8 @@ > org.eclipse.ui.navigator.resources;bundle-version="[3.2.100,4.0.0)", > org.eclipse.core.net;bundle-version="[1.0.0,2.0.0)", > org.eclipse.update.core;bundle-version="[3.1.100,4.0.0)", >- com.ibm.icu;bundle-version="3.8.1" >+ com.ibm.icu;bundle-version="3.8.1", >+ org.eclipse.core.filesystem;bundle-version="1.2.0" > Export-Package: org.eclipse.ui.internal.ide.application;x-internal:=true, > org.eclipse.ui.internal.ide.application.dialogs;x-internal:=true > Bundle-RequiredExecutionEnvironment: J2SE-1.4 >Index: src/org/eclipse/ui/internal/ide/application/IDEWorkbenchAdvisor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEWorkbenchAdvisor.java,v >retrieving revision 1.13 >diff -u -r1.13 IDEWorkbenchAdvisor.java >--- src/org/eclipse/ui/internal/ide/application/IDEWorkbenchAdvisor.java 1 May 2008 14:01:17 -0000 1.13 >+++ src/org/eclipse/ui/internal/ide/application/IDEWorkbenchAdvisor.java 2 Jul 2008 21:03:53 -0000 >@@ -16,7 +16,7 @@ > import java.util.Iterator; > import java.util.Map; > import java.util.TreeMap; >- >+import org.eclipse.core.filesystem.EFS; > import org.eclipse.core.net.proxy.IProxyService; > import org.eclipse.core.resources.IContainer; > import org.eclipse.core.resources.IResource; >@@ -27,6 +27,7 @@ > import org.eclipse.core.runtime.IAdaptable; > import org.eclipse.core.runtime.IBundleGroup; > import org.eclipse.core.runtime.IBundleGroupProvider; >+import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.IStatus; > import org.eclipse.core.runtime.MultiStatus; >@@ -46,6 +47,9 @@ > import org.eclipse.swt.SWT; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Listener; >+import org.eclipse.ui.IWorkbenchPage; >+import org.eclipse.ui.IWorkbenchWindow; >+import org.eclipse.ui.PartInitException; > import org.eclipse.ui.PlatformUI; > import org.eclipse.ui.application.IWorkbenchConfigurer; > import org.eclipse.ui.application.IWorkbenchWindowConfigurer; >@@ -128,7 +132,7 @@ > private IDEIdleHelper idleHelper; > > private Listener settingsChangeListener; >- >+ > /** > * Support class for monitoring workspace changes and periodically > * validating the undo history >@@ -140,6 +144,10 @@ > */ > private AbstractStatusHandler ideWorkbenchErrorHandler; > >+ static IDEWorkbenchAdvisor getInstance() { >+ return workbenchAdvisor; >+ } >+ > /** > * Creates a new workbench advisor instance. > */ >@@ -159,7 +167,7 @@ > public void initialize(IWorkbenchConfigurer configurer) { > > PluginActionBuilder.setAllowIdeLogging(true); >- >+ > // make sure we always save and restore workspace state > configurer.setSaveAndRestore(true); > >@@ -194,7 +202,7 @@ > > // initialize idle handler > idleHelper = new IDEIdleHelper(configurer); >- >+ > // initialize the workspace undo monitor > workspaceUndoMonitor = WorkspaceUndoMonitor.getInstance(); > >@@ -242,12 +250,51 @@ > initializeSettingsChangeListener(); > Display.getCurrent().addListener(SWT.Settings, > settingsChangeListener); >+ runStartupCommand(Platform.getCommandLineArgs()); > } finally {// Resume background jobs after we startup > Job.getJobManager().resume(); > } > } > > /** >+ * Runs a command specified on the command line, if any >+ */ >+ boolean runStartupCommand(String[] arguments) { >+ if (arguments.length == 0) >+ return false; >+ // if the last command line argument is a file, open that file in an >+ // editor >+ final IPath path = new Path(arguments[arguments.length - 1]); >+ if (!path.toFile().exists()) >+ return false; >+ IWorkbenchWindow window = PlatformUI.getWorkbench() >+ .getActiveWorkbenchWindow(); >+ if (window == null) { >+ IWorkbenchWindow[] windows = PlatformUI.getWorkbench() >+ .getWorkbenchWindows(); >+ if (windows.length > 0) >+ window = windows[0]; >+ } >+ if (window == null) >+ return false; >+ final IWorkbenchPage page = window.getActivePage(); >+ if (page == null) >+ return false; >+ window.getShell().getDisplay().syncExec(new Runnable() { >+ public void run() { >+ try { >+ IDE.openEditorOnFileStore(page, EFS.getLocalFileSystem() >+ .getStore(path)); >+ } catch (PartInitException e) { >+ IDEWorkbenchPlugin.log( >+ "Error opening editor on path: " + path, e); //$NON-NLS-1$ >+ } >+ } >+ }); >+ return true; >+ } >+ >+ /** > * Activate the proxy service by obtaining it. > */ > private void activateProxyService() { >@@ -260,7 +307,7 @@ > } > if (proxyService == null) { > IDEWorkbenchPlugin.log("Proxy service could not be found."); //$NON-NLS-1$ >- } >+ } > } > > /** >@@ -697,7 +744,7 @@ > declareWorkbenchImage(ideBundle, > IDEInternalWorkbenchImages.IMG_ETOOL_PROBLEM_CATEGORY, > PATH_ETOOL + "problem_category.gif", true); //$NON-NLS-1$ >- >+ > // synchronization indicator objects > // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_WBET_STAT, > // PATH_OVERLAY+"wbet_stat.gif"); >Index: src/org/eclipse/ui/internal/ide/application/IDEApplication.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEApplication.java,v >retrieving revision 1.7 >diff -u -r1.7 IDEApplication.java >--- src/org/eclipse/ui/internal/ide/application/IDEApplication.java 3 Jun 2008 17:56:02 -0000 1.7 >+++ src/org/eclipse/ui/internal/ide/application/IDEApplication.java 2 Jul 2008 21:03:53 -0000 >@@ -105,7 +105,7 @@ > Platform.endSplash(); > return EXIT_OK; > } >- >+ > // create the workbench with this advisor and run it until it exits > // N.B. createWorkbench remembers the advisor, and also registers > // the workbench globally so that all UI plug-ins can find it using >@@ -217,6 +217,15 @@ > // -data @noDefault or -data not specified, prompt and set > ChooseWorkspaceData launchData = new ChooseWorkspaceData(instanceLoc > .getDefault()); >+ >+ //check if someone is listening that we can pass our command line to >+ if (launchData.getPort() != 0) { >+ if (new IDECommunication().writeToPort(launchData.getPort(), launchData.getIPCAuthorization())) { >+ //we successfully punted this application's command line to another instance, >+ //so we can just shutdown this instance. >+ return false; >+ } >+ } > > boolean force = false; > while (true) { >@@ -233,6 +242,11 @@ > // the operation will fail if the url is not a valid > // instance data area, so other checking is unneeded > if (instanceLoc.setURL(workspaceUrl, true)) { >+ int[] ipcData = new IDECommunication().listen(); >+ if (ipcData != null) { >+ launchData.setPort(ipcData[0]); >+ launchData.setIPCAuthorization(ipcData[1]); >+ } > launchData.writePersistedData(); > writeWorkspaceVersion(); > return true; >Index: src/org/eclipse/ui/internal/ide/application/IDECommunication.java >=================================================================== >RCS file: src/org/eclipse/ui/internal/ide/application/IDECommunication.java >diff -N src/org/eclipse/ui/internal/ide/application/IDECommunication.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/internal/ide/application/IDECommunication.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,208 @@ >+/******************************************************************************* >+ * Copyright (c) 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.ui.internal.ide.application; >+ >+import java.security.SecureRandom; >+ >+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; >+ >+import java.io.*; >+import java.net.*; >+import org.eclipse.core.runtime.*; >+import org.eclipse.core.runtime.jobs.Job; >+ >+/** >+ * A helper class that deals with interprocess communication between applications. >+ * <p> >+ * This class uses a socket connection on a random available port to establish >+ * communication between applications. The client must provide an authorization >+ * code to protect against communication from arbitrary port sniffing applications. >+ * >+ * @since 3.5 >+ */ >+class IDECommunication { >+ /** >+ * A job that listens on a socket for a command, and then invokes the >+ * workbench advisor to handle the command. >+ */ >+ class ListenJob extends Job { >+ private ServerSocket server; >+ private int auth; >+ >+ public ListenJob(ServerSocket server, int auth) { >+ super("Listen"); //$NON-NLS-1$ >+ this.server = server; >+ this.auth = auth; >+ setSystem(true); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.core.runtime.jobs.Job#canceling() >+ */ >+ protected void canceling() { >+ try { >+ server.close(); >+ } catch (IOException e) { >+ //ignore >+ } >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) >+ */ >+ protected IStatus run(IProgressMonitor monitor) { >+ if (server.isClosed()) >+ return Status.OK_STATUS; >+ Socket client = null; >+ DataInputStream in = null; >+ DataOutputStream out = null; >+ try { >+ client = server.accept(); >+ in = new DataInputStream(client.getInputStream()); >+ out = new DataOutputStream(client.getOutputStream()); >+ //read the protocol version >+ int version = in.readInt(); >+ String[] args = null; >+ if (version == PROTOCOL_VERSION_ONE) { >+ //read the authorization checksum >+ int receivedAuth = in.readInt(); >+ //abort immediately if we failed to read the authorization integer >+ if (receivedAuth != auth) { >+ schedule(SCHEDULE_DELAY); >+ return new Status(IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, "Connection from unauthorized client on port " + server.getLocalPort()); //$NON-NLS-1$ >+ } >+ args = new String[in.readInt()]; >+ for (int i = 0; i < args.length; i++) { >+ args[i] = in.readUTF(); >+ } >+ } >+ //pass the read arguments to the workbench advisor >+ IDEWorkbenchAdvisor advisor = IDEWorkbenchAdvisor.getInstance(); >+ if (advisor != null && args != null) { >+ if (advisor.runStartupCommand(args)) >+ out.writeUTF(OK); >+ else >+ out.writeUTF(FAIL); >+ } >+ } catch (IOException e) { >+ IDEWorkbenchPlugin.log("Error communicating with client", e); //$NON-NLS-1$ >+ } finally { >+ safeClose(in); >+ safeClose(out); >+ safeClose(client); >+ } >+ //reschedule >+ schedule(SCHEDULE_DELAY); >+ return Status.OK_STATUS; >+ } >+ } >+ >+ /** >+ * The first communication protocol version. This version contains an authorization >+ * integer followed by a list of command line arguments. The format is: int authorizationId, int N, String[N]. >+ */ >+ private static final int PROTOCOL_VERSION_ONE = 1; >+ >+ private static final long SCHEDULE_DELAY = 1000; >+ >+ static final String OK = "OK"; //$NON-NLS-1$ >+ static final String FAIL = "FAIL"; //$NON-NLS-1$ >+ >+ /** >+ * Start listening for commands. >+ * @return An integer array of size two. The first integer is the port >+ * number we are listening on, and the second integer is an authorization >+ * integer used to validate connections. Returns <code>null</code> if >+ * there was a failure to establish communication >+ */ >+ public int[] listen() { >+ try { >+ ServerSocket server = new ServerSocket(0); >+ int auth = new SecureRandom().nextInt(); >+ new ListenJob(server, auth).schedule(SCHEDULE_DELAY); >+ return new int[] {server.getLocalPort(), auth}; >+ } catch (IOException e) { >+ return null; >+ } >+ } >+ >+ /** >+ * Close the given stream and ignore secondary failures. >+ */ >+ void safeClose(DataInputStream in) { >+ try { >+ if (in != null) >+ in.close(); >+ } catch (IOException e) { >+ //ignore secondary failure while closing >+ } >+ } >+ >+ /** >+ * Close the given stream and ignore secondary failures. >+ */ >+ void safeClose(DataOutputStream out) { >+ try { >+ if (out != null) >+ out.close(); >+ } catch (IOException e) { >+ //ignore secondary failure while closing >+ } >+ } >+ >+ /** >+ * Close the given socket and ignore secondary failures. >+ */ >+ void safeClose(Socket socket) { >+ try { >+ if (socket != null) >+ socket.close(); >+ } catch (IOException e) { >+ //ignore secondary failure while closing >+ } >+ } >+ >+ /** >+ * Writes this application's command line arguments to the given port. >+ * >+ * @param port The port to write data to >+ * @param auth The authorization integer >+ * @return <code>true</code> if written successfully, and <code>false</code> otherwise. >+ */ >+ public boolean writeToPort(int port, int auth) { >+ Socket socket = null; >+ DataOutputStream out = null; >+ DataInputStream in = null; >+ try { >+ socket = new Socket("localhost", port);//$NON-NLS-1$ >+ out = new DataOutputStream(socket.getOutputStream()); >+ in = new DataInputStream(socket.getInputStream()); >+ out.writeInt(PROTOCOL_VERSION_ONE); >+ out.writeInt(auth); >+ String[] args = Platform.getCommandLineArgs(); >+ out.writeInt(args.length); >+ for (int i = 0; i < args.length; i++) >+ out.writeUTF(args[i]); >+ //server will return OK or FAIL >+ return in.readUTF().equals(OK); >+ } catch (UnknownHostException e) { >+ return false; >+ } catch (IOException e) { >+ return false; >+ } finally { >+ safeClose(socket); >+ safeClose(out); >+ safeClose(in); >+ } >+ } >+ >+} >#P org.eclipse.ui.ide >Index: src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java,v >retrieving revision 1.21 >diff -u -r1.21 ChooseWorkspaceData.java >--- src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java 24 Mar 2008 19:13:35 -0000 1.21 >+++ src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java 2 Jul 2008 21:03:54 -0000 >@@ -69,7 +69,7 @@ > /** > * This is the second version of the encode/decode protocol that uses the > * confi area preferences store for persistence. This version is the same as >- * the previous version except it uses a \n character to seperate the path >+ * the previous version except it uses a \n character to separate the path > * entries instead of commas. (see bug 98467) > * > * @since 3.3.1 >@@ -83,6 +83,18 @@ > private String selection; > > private String[] recentWorkspaces; >+ >+ /** >+ * The port on which an instance of this configuration is already listening for remote communication. >+ * This value is 0 if nobody is already listening. >+ */ >+ private int port = 0; >+ /** >+ * An authorization integer that a client must provide when communication with >+ * this application. This is a simple security measure to prevent a port scanner >+ * from executing commands in this application. >+ */ >+ private int ipcAuth = 0; > > // xml tags > private static interface XML { >@@ -101,7 +113,11 @@ > public static final String MAX_LENGTH = "maxLength"; //$NON-NLS-1$ > > public static final String PATH = "path"; //$NON-NLS-1$ >- } >+ >+ public static final String PORT= "port"; //$NON-NLS-1$ >+ >+ public static final String IPC_AUTH= "ipcAuth"; //$NON-NLS-1$ >+} > > /** > * Creates a new instance, loading persistent data if its found. >@@ -151,6 +167,23 @@ > } > initialDefault = dir; > } >+ >+ /** >+ * Sets the port on which an instance is listening for remote communication. >+ * @param port The port, or 0 to indicate not listening. >+ */ >+ public void setPort(int port) { >+ this.port = port; >+ } >+ >+ /** >+ * Sets an authorization integer that a client must provide to establish >+ * remote communication. This is used to prevent a port sniffer from >+ * executing commands. >+ */ >+ public void setIPCAuthorization(int auth) { >+ this.ipcAuth = auth; >+ } > > /** > * Return the currently selected workspace or null if nothing is selected. >@@ -173,6 +206,23 @@ > public String[] getRecentWorkspaces() { > return recentWorkspaces; > } >+ >+ /** >+ * Returns the port on which an instance of this same configuration is >+ * already listening for remote communication, or 0 if nobody is listening. >+ * @return The port number, or 0. >+ */ >+ public int getPort() { >+ return port; >+ } >+ >+ /** >+ * Returns the authorization integer for establishing interprocess communication. >+ * @return The authorization integer >+ */ >+ public int getIPCAuthorization() { >+ return ipcAuth; >+ } > > /** > * The argument workspace has been selected, update the receiver. Does not >@@ -230,8 +280,14 @@ > // 5. store the protocol version used to encode the list > node.putInt(IDE.Preferences.RECENT_WORKSPACES_PROTOCOL, > PERS_ENCODING_VERSION_CONFIG_PREFS_NO_COMMAS); >+ >+ // 6. store the interprocess communication data, if any >+ if (port != 0) { >+ node.putInt(XML.PORT, port); >+ node.putInt(XML.IPC_AUTH, ipcAuth); >+ } > >- // 6. store the node >+ // 7. store the node > try { > node.flush(); > } catch (BackingStoreException e) { >@@ -405,6 +461,10 @@ > .getString(IDE.Preferences.RECENT_WORKSPACES); > recentWorkspaces = decodeStoredWorkspacePaths(protocol, max, workspacePathPref); > >+ // 5. load the interprocess communication data >+ port = store.getInt(XML.PORT); >+ ipcAuth = store.getInt(XML.IPC_AUTH); >+ > return true; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 4922
:
83454
|
104405
|
104406
|
106356
| 106360 |
156681
|
156974
|
156991