|
From: Mike G. <mi...@us...> - 2006-05-05 05:34:21
|
Update of /cvsroot/jcommander/plugins/org.jcommander.ui.app/src/org/jcommander/ui/app In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3834/src/org/jcommander/ui/app Modified Files: PlatformRunnable.java Added Files: ApplicationEntryPoint.java SingletonAppLauncher.java Log Message: An implementation of the [ 1366374 ] 'Enforce singleton JCommander instance feature'. Needs some finishing works regarding port configuration. Index: PlatformRunnable.java =================================================================== RCS file: /cvsroot/jcommander/plugins/org.jcommander.ui.app/src/org/jcommander/ui/app/PlatformRunnable.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** PlatformRunnable.java 29 Dec 2005 14:38:51 -0000 1.7 --- PlatformRunnable.java 5 May 2006 05:34:15 -0000 1.8 *************** *** 25,56 **** * those running stand-alone. */ ! public Object run(Object args) throws Exception { ! int returnCode = 0; ! ! Location userLocation = Platform.getUserLocation(); ! if(userLocation != null) { ! LoggerPlugin.rootLogger.info("User data location: "+userLocation.getURL()); } ! ! WorkbenchAdvisor workbenchAdvisor = null; ! ! if(args instanceof String[]) { ! String[] actualArgs = (String[])args; ! ! for(int i=0;i<actualArgs.length;i++) { ! if(actualArgs[i].equalsIgnoreCase("-devel")) { ! LoggerPlugin.rootLogger.warn("JCmd running in development mode."); ! ! workbenchAdvisor = new JCmdWorkbenchAdvisor("*DEVEL* "); ! } ! } ! } ! ! if(workbenchAdvisor == null) { ! workbenchAdvisor = new JCmdWorkbenchAdvisor(); } ! Display display = PlatformUI.createDisplay(); ! ! returnCode = PlatformUI.createAndRunWorkbench(display, workbenchAdvisor); if(returnCode == PlatformUI.RETURN_RESTART){ --- 25,40 ---- * those running stand-alone. */ ! public Object run(Object args) throws Exception { ! String[] strArgs = null; ! if(args instanceof String[]){ ! strArgs = (String[])args; } ! JCMDApplicationEntryPoint entryPoint = new JCMDApplicationEntryPoint(); ! boolean first = new SingletonAppLauncher(entryPoint, 63500, 64500).startingFirstInstance(strArgs); ! if(!first){ ! LoggerPlugin.rootLogger.info("Exitting from duplicate instance"); ! return IPlatformRunnable.EXIT_OK; } ! int returnCode = entryPoint.getReturnCode(); if(returnCode == PlatformUI.RETURN_RESTART){ *************** *** 61,63 **** --- 45,92 ---- } + private static class JCMDApplicationEntryPoint implements ApplicationEntryPoint{ + private int returnCode = 0; + private boolean started = false; + + public int getReturnCode(){ + return returnCode; + } + + public String getIdentification(){ + return "JCommander@" + System.getProperty("user.name"); + } + + public void startup(String[] params){ + if(started){ + LoggerPlugin.rootLogger.info("Already started up. Place for secondary startups"); + return; + } + started = true; + Location userLocation = Platform.getUserLocation(); + if(userLocation != null) { + LoggerPlugin.rootLogger.info("User data location: "+userLocation.getURL()); + } + + WorkbenchAdvisor workbenchAdvisor = null; + + if(params != null) { + String[] actualArgs = params; + + for(int i=0;i<actualArgs.length;i++) { + if(actualArgs[i].equalsIgnoreCase("-devel")) { + LoggerPlugin.rootLogger.warn("JCmd running in development mode."); + + workbenchAdvisor = new JCmdWorkbenchAdvisor("*DEVEL* "); + } + } + } + + if(workbenchAdvisor == null) { + workbenchAdvisor = new JCmdWorkbenchAdvisor(); + } + Display display = PlatformUI.createDisplay(); + returnCode = PlatformUI.createAndRunWorkbench(display, workbenchAdvisor); + } + } + } --- NEW FILE: ApplicationEntryPoint.java --- package org.jcommander.ui.app; /** * <p></p> * @author Mike Grigorov * @version 1.0 * Created on 2006-3-10 */ public interface ApplicationEntryPoint { public String getIdentification(); public void startup(String[] params); } --- NEW FILE: SingletonAppLauncher.java --- package org.jcommander.ui.app; import java.io.*; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; /** * <p></p> * @author Mike Grigorov * @version 1.0 * Created on 26.04.2006 */ public class SingletonAppLauncher { private final ApplicationEntryPoint entryPoint; private final int fromPort; private final int toPort; public SingletonAppLauncher(ApplicationEntryPoint entryPoint, int fromPort, int toPort){ if(null == entryPoint){ throw new NullPointerException("entryPoint"); } if(fromPort < 0){ throw new IllegalArgumentException("fromPort:" + fromPort); } if(toPort < 0){ throw new IllegalArgumentException("toPort:" + toPort); } if(fromPort > toPort){ throw new IllegalArgumentException(fromPort + ">" + toPort); } this.entryPoint = entryPoint; this.fromPort = fromPort; this.toPort = toPort; } public boolean startingFirstInstance(String[] params){ ServerSocket server = null; Socket sameApplication = null; for(int i = fromPort; i <= toPort; i++){ ServerSocket loopSocket = tryToOccupy(i); if(null != loopSocket){ if(null == server){ server = loopSocket; } else{ try{ loopSocket.close(); }catch(Exception ex){} } } else{ Socket same = contactSameApplication(i); if(null != same){ sameApplication = same; break; } } } try{ if ((null != sameApplication) && (startSameApp(sameApplication, params))) { return false; } else { final ServerSocket serverSocket = server; new Thread(new Runnable(){ public void run(){ new HandshakeServer(serverSocket, entryPoint); } }, "Handshake server").start(); entryPoint.startup(params); return true; } } finally{ if(null != sameApplication){ try { sameApplication.close(); } catch (Exception e) {} } } } private boolean startSameApp(Socket sameApplication, String[] parameters){ try{ StringBuffer params = new StringBuffer(); if(null != parameters){ for(int i = 0; i < parameters.length; i++){ if(null == parameters[i]){ continue; } if(params.length() > 0){ params.append(','); } params.append(parameters[i]); } } PrintWriter writer = new PrintWriter(sameApplication.getOutputStream()); BufferedReader reader = new BufferedReader(new InputStreamReader(sameApplication.getInputStream())); writer.println(Requests.STARTUP_REQUEST + params.toString()); writer.flush(); reader.readLine(); writer.println(Requests.DISCONNECT_REQUEST); writer.flush(); return true; } catch(IOException ex){ return false; } } private ServerSocket tryToOccupy(int port){ try { return new ServerSocket(port); } catch (IOException e) { return null; } catch(Throwable t){ t.printStackTrace(); return null; } } private Socket contactSameApplication(int port){ Socket client = null; boolean close = true; try { client = new Socket(InetAddress.getLocalHost(), port); client.setSoTimeout(250); PrintWriter writer = new PrintWriter(client.getOutputStream()); BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream())); writer.println(Requests.RETRIEVE_ID_REQUEST); writer.flush(); String line = reader.readLine(); if(entryPoint.getIdentification().equals(line)){ close = false; return client; } return null; } catch (IOException e) { System.err.println("Error communicating:" + e); return null; } catch (Throwable t){ t.printStackTrace(); return null; } finally{ if(close && (null != client)){ try { client.close(); } catch (Exception e) {} } } } private static class HandshakeServer { private final ServerSocket socket; private final ApplicationEntryPoint entryPoint; public HandshakeServer(ServerSocket socket, ApplicationEntryPoint entryPoint){ if(null == socket){ throw new NullPointerException("socket"); } if(null == entryPoint){ throw new NullPointerException("entryPoint"); } this.socket = socket; this.entryPoint = entryPoint; while(true){ try{ Socket _client = socket.accept(); new Thread(new ClientHandler(_client)).start(); } catch(Throwable t){ t.printStackTrace(); } } } private class ClientHandler implements Runnable{ private final Socket socket; public ClientHandler(Socket socket){ if(null == socket){ throw new NullPointerException("socket"); } this.socket = socket; } public void run(){ try{ BufferedReader _reader = new BufferedReader(new InputStreamReader( socket.getInputStream())); PrintWriter _writer = new PrintWriter(socket.getOutputStream()); String _line; while((_line = _reader.readLine()) != null){ String _s = handleLine(_line); if(null != _s){ _writer.println(_s); _writer.flush(); } else{ socket.close(); break; } } } catch(IOException ex){ ex.printStackTrace(); System.out.println(ex); } } private String handleLine(String line){ if(Requests.RETRIEVE_ID_REQUEST.equalsIgnoreCase(line)){ return entryPoint.getIdentification(); } if(Requests.DISCONNECT_REQUEST.equalsIgnoreCase(line)){ return null; } if(line.startsWith(Requests.STARTUP_REQUEST)){ String params = null; if(line.length() > Requests.STARTUP_REQUEST.length()){ params = line.substring(Requests.STARTUP_REQUEST.length()); } startup(params); return "OK"; } return "UNKNOWN:" + line; } private void startup(String line){ String[] params = null; if(null != line){ params = line.split(","); } final String[] p = params; new Thread(new Runnable(){ public void run(){ entryPoint.startup(p); } }, "STARTUP").start(); } } } private static class Requests{ public static final String STARTUP_REQUEST = "STARTUP_"; public static final String DISCONNECT_REQUEST = "HANDSHAKE_DISCONNECT"; public static final String RETRIEVE_ID_REQUEST = "WHO_ARE_YOU"; private Requests(){} } } |