/*=============================================================================# # Copyright (c) 2008-2016 Stephan Wahlbrink (WalWare.de) and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of either (per the licensee's choosing) # - the Eclipse Public License v1.0 # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html, or # - the GNU Lesser General Public License v2.1 or newer # which accompanies this distribution, and is available at # http://www.gnu.org/licenses/lgpl.html # # Contributors: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.rj.server; import java.rmi.NotBoundException; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.registry.Registry; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.logging.Level; import java.util.logging.LogRecord; import de.walware.rj.server.srvImpl.AbstractServerControl; import de.walware.rj.server.srvImpl.DefaultServerImpl; import de.walware.rj.server.srvext.ServerAuthMethod; /** * Provides java and command line interface to control the RMI server. */ public class RMIServerControl extends AbstractServerControl { public static void main(final String[] args) { final String command = cliCommandName(args); if ("start".equals(command)) { final String name = cliGetName(args); final RMIServerControl server = new RMIServerControl(name, cliGetArgs(args, 2)); server.start(); return; } if ("clean".equals(command)) { final String name = cliGetName(args); final RMIServerControl server = new RMIServerControl(name, cliGetArgs(args, 2)); server.clean(); return; } cliInvalidArgs("Invalid server command '"+command+"'"); } private static String cliCommandName(final String[] args) { if (args.length <= 0 || args[0].startsWith("-")) { cliInvalidArgs("Missing server command"); } return args[0]; } private static String cliGetName(final String[] args) { if (args.length <= 1) { cliInvalidArgs("Missing server name"); } return args[1]; } private static void cliInvalidArgs(final String message) { System.err.println(message); cliPrintHelp(); exit(EXIT_ARGS_INVALID); } private static void cliPrintHelp() { System.out.println("= Usage of RJserver command line control ================"); System.out.println("commands:"); System.out.println(" start <name> adds server to RMIregistry"); System.out.println(" clean <name> stops server/remove from RMIregistry"); System.out.println("name: unique name in RMIregistry"); System.out.println("options:"); System.out.println(" -verbose verbose logging"); System.out.println(" -plugins=<..> list of plugins"); System.out.println(" -auth=<..> authetification method"); } public RMIServerControl(final String name, final Map<String, String> args) { super(name, args); } public void start() { LOGGER.log(Level.INFO, "{0} initialize server...", this.logPrefix); ServerAuthMethod authMethod; try { authMethod = createServerAuth(this.args.remove("auth")); } catch (final Exception e) { exit(AbstractServerControl.EXIT_INIT_AUTHMETHOD_ERROR); throw new IllegalStateException(); } final DefaultServerImpl server = new DefaultServerImpl(this, authMethod); if (!initREngine(server)) { exit(EXIT_INIT_RENGINE_ERROR | 1); } publishServer(server); } public void clean() { final int dead = unbindDead(); if (dead == 0) { exit(0); return; } if (dead == EXIT_REGISTRY_SERVER_STILL_ACTIVE && !this.args.containsKey("force")) { exit(EXIT_REGISTRY_SERVER_STILL_ACTIVE); } try { final Registry registry = getRegistry(); registry.unbind(getName()); LOGGER.log(Level.INFO, "{0} server removed from registry.", this.logPrefix); } catch (final NotBoundException e) { exit(0); } catch (final RemoteException e) { final LogRecord record = new LogRecord(Level.SEVERE, "{0} removing server from registry failed."); record.setParameters(new Object[] { this.logPrefix }); record.setThrown(e); LOGGER.log(record); exit(EXIT_REGISTRY_CONNECTING_ERROR); } } void scheduleCleanup() { new Timer().schedule(new TimerTask() { @Override public void run() { checkCleanup(); } }, 2000); } @Override protected int unbindDead() { Remote remote; try { final Registry registry = getRegistry(); remote = registry.lookup(getName()); } catch (final NotBoundException lookupException) { return 0; } catch (final RemoteException lookupException) { return EXIT_REGISTRY_CONNECTING_ERROR; } if (!(remote instanceof Server)) { return 2; } try { ((Server) remote).getInfo(); return EXIT_REGISTRY_SERVER_STILL_ACTIVE; } catch (final RemoteException deadException) { try { final Registry registry = getRegistry(); registry.unbind(getName()); LOGGER.log(Level.INFO, "{0} dead server removed from registry.", this.logPrefix); return 0; } catch (final Exception unbindException) { return EXIT_REGISTRY_CLEAN_FAILED; } } } }