Java tutorial
/***************************************************************************************** * *** BEGIN LICENSE BLOCK ***** * * Version: MPL 2.0 * * echocat jConscius, Copyright (c) 2010-2012 echocat * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * *** END LICENSE BLOCK ***** ****************************************************************************************/ package org.echocat.jconscius.cluster.impl.relay.station; import org.apache.commons.cli.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.PrintWriter; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Collection; import java.util.HashSet; @SuppressWarnings({ "CallToSystemExit", "UseOfSystemOutOrSystemErr" }) public class RelayStationLauncher { private static final Logger LOG = LoggerFactory.getLogger(RelayStationLauncher.class); private static final int DEFAULT_PORT = 11256; private static final String DEFAULT_NAME = "default"; private static final int DEFAULT_RECONNECT_TIMEOUT = 1000; private static final Options OPTIONS = new Options(); private static final Option HELP_OPTION = new Option("h", "help", false, "Print this help."); private static final Option LISTEN_OPTION = new Option("l", "listen", true, "Port and address to listen on. Default: 0.0.0.0:" + DEFAULT_PORT); private static final Option NAME_OPTION = new Option("n", "name", true, "Name of this station. This name is unique in the cluster. Default: " + DEFAULT_NAME); private static final Option RECONNECTION_TIMEOUT_OPTION = new Option("t", "reconnect-timeout", true, "The timeout for reconnect in milli seconds if the server socket is broken and have to be reconnected. Default: " + DEFAULT_RECONNECT_TIMEOUT); private RelayStationLauncher() { } static { OPTIONS.addOption(HELP_OPTION); LISTEN_OPTION.setRequired(false); LISTEN_OPTION.setArgName("[address:]port"); LISTEN_OPTION.setValueSeparator(';'); OPTIONS.addOption(LISTEN_OPTION); NAME_OPTION.setRequired(false); NAME_OPTION.setArgName("name"); OPTIONS.addOption(NAME_OPTION); RECONNECTION_TIMEOUT_OPTION.setRequired(false); RECONNECTION_TIMEOUT_OPTION.setArgName("milliseconds"); OPTIONS.addOption(RECONNECTION_TIMEOUT_OPTION); } public static void main(String[] arguments) throws Exception { final RelayStation station = createStation(arguments); if (station != null) { final Object lock = new Object(); final Thread shutdownThread = new Thread("ShutdownHook") { @Override public void run() { LOG.info("Station is going down now..."); station.close(); LOG.info("Station is down! Bye."); synchronized (lock) { lock.notifyAll(); } } }; Runtime.getRuntime().addShutdownHook(shutdownThread); LOG.info("Station is starting..."); station.init(); LOG.info("Station is ready!"); //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (lock) { lock.wait(); } } } private static RelayStation createStation(String[] arguments) { final CommandLineParser parser = new GnuParser(); RelayStation station = null; try { final CommandLine line = parser.parse(OPTIONS, arguments); if (line.hasOption(HELP_OPTION.getOpt())) { printHelper(null); } else { station = new RelayStation(); final String[] listenValues = line.getOptionValues(LISTEN_OPTION.getOpt()); final Collection<SocketAddress> listen = new HashSet<SocketAddress>(); if (listenValues != null) { for (String listenValue : listenValues) { if (listenValue != null) { final String hostName; final String portString; final int lastDouble = listenValue.lastIndexOf(':'); if (lastDouble >= 0) { hostName = listenValue.substring(0, lastDouble); portString = listenValue.substring(lastDouble + 1); } else { hostName = null; portString = listenValue; } final int port = parsePositiveInteger(portString, "port number"); if (hostName != null) { listen.add(new InetSocketAddress(hostName, port)); } else { listen.add(new InetSocketAddress((InetAddress) null, port)); } } } } if (listen.isEmpty()) { listen.add(new InetSocketAddress((InetAddress) null, DEFAULT_PORT)); } station.setAddresses(listen); final String name = line.getOptionValue(NAME_OPTION.getOpt()); station.setName(name != null && !name.isEmpty() ? name : DEFAULT_NAME); final String reconnectTimeoutString = line.getOptionValue(RECONNECTION_TIMEOUT_OPTION.getOpt()); station.setReconnectTimeout(reconnectTimeoutString != null ? parsePositiveInteger(reconnectTimeoutString, "milliseconds") : DEFAULT_RECONNECT_TIMEOUT); } } catch (ParseException e) { printHelper(e); System.exit(1); } return station; } private static int parsePositiveInteger(String string, String messageName) throws ParseException { final int result; try { result = Integer.parseInt(string.trim()); } catch (NumberFormatException ignored) { //noinspection ThrowInsideCatchBlockWhichIgnoresCaughtException throw new ParseException("'" + string + "' is not a valid " + messageName + "."); } if (result <= 0) { throw new ParseException("'" + string + "' is not a valid " + messageName + "."); } return result; } private static void printHelper(ParseException e) { final HelpFormatter formatter = new HelpFormatter(); final PrintWriter writer = new PrintWriter(e != null ? System.err : System.out); writer.println("RelayStation 1.0"); if (e != null) { writer.println("error: " + e.getMessage()); } formatter.printHelp(writer, HelpFormatter.DEFAULT_WIDTH, "station [arguments]", "arguments:", OPTIONS, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null); writer.flush(); } }