Java tutorial
package datasphere.catalog; /* Copyright (C) 2010 J.Goulding, R. Mortier This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.jivesoftware.smack.XMPPConnection; import org.restlet.data.Protocol; import datasphere.catalog.http.DSWebServer; import datasphere.catalog.xmpp.DSChatServer; import datasphere.dataware.DSException; import datasphere.dataware.DSLogFormatter; public final class DSCatalog { public static final int XMPP = 0; public static final int HTTP = 1; public static final int ALL_PROTOCOLS = 2; private static Logger logger = Logger.getLogger(DSCatalog.class.getName()); private static Handler handler = new ConsoleHandler(); public static DSDataManager db = null; private Properties config = null; private Integer httpPort = null; private Integer xmppPort = null; private String password = null; private boolean debug = false; private boolean httpStartable = true; private boolean xmppStartable = true; private DSWebServer httpServer = null; private DSChatServer xmppServer = null; private boolean systemWipe = false; private boolean systemCreate = false; private boolean isRunning = false; /////////////////////////////// /** * @param databaseManager The database object which manages persistence for the game. */ public DSCatalog(DSDataManager databaseManager) { db = databaseManager; setupLogging(); } /////////////////////////////// /** * setup log formatting */ public void setupLogging() { handler.setFormatter(new DSLogFormatter()); handler.setLevel(Level.FINEST); logger.addHandler(handler); logger.setUseParentHandlers(false); logger.setLevel(Level.FINEST); } /////////////////////////////// /** * load config file for the server */ public void setupConfiguration() { config = new Properties(); InputStream configStream = getClass().getClassLoader().getResourceAsStream("conf/ds.cfg"); //-- if it exists extract the properties contained within if (configStream != null) { try { config.load(configStream); configStream.close(); String xmpp = config.getProperty("XMPP_PORT"); if (xmpp != null && xmppPort == null) this.xmppPort = Integer.parseInt(xmpp); String http = config.getProperty("HTTP_PORT"); if (http != null && httpPort == null) this.httpPort = Integer.parseInt(http); if (password == null) this.password = config.getProperty("DSADMIN_PASS"); logger.config("--- DSCatalog: loading configuration file... [SUCCESS]"); } catch (IOException e) { logger.config("--- DSCatalog: loading configuration file... [FAILED]"); logger.warning("--- DSCatalog: config file has invalid syntax. continuing with defaults."); } } else logger.config("--- DSCatalog: no configuration file detected. continuing with defaults... [SUCCESS]"); } /////////////////////////////// /** * The server will do nothing until start() is called, at which point it will * initialize system resources and initialise connections to necessary XMPP servers * N.b. This method will block indefinitely unless a <i>non-startable</i> command * line argument has been supplied (such as -help), in which case it will return false. * N.b. that an exception will be thrown if sufficient parameters have not been * supplied either via the constructor or {@link #setArgs(String[])}. * @exception DSException thrown if the specified port number is illegal or * if the ruleset or a database manager has not been supplied. */ public void start() throws DSException { //-- check that we actually have something to start up if (!(httpStartable || xmppStartable)) return; else this.isRunning = true; //-- setup configuration files setupConfiguration(); //-- check that the server has been supplied with a persistence layer if (db == null) { logger.severe("--- DSCatalog: Checking persistence layer... [FAILED]"); throw new DSException("Insufficient parameters - " + "A DSDatabaseManager object must be supplied"); } //-- check whether that database actually exists try { logger.info("Establishing database connection and checking integrity..."); db.setPassword(this.password); db.connect(); //-- attempt to clear the system tables if requested if (systemWipe == true) db.clearSystemTables(); //-- attempt system table creation if requested if (systemCreate == true) db.createSystemTables(); //-- check to see that table integrity is ok db.checkSystemTables(); //-- start the servers up and running logger.info("Attempting to start server components..."); if (httpStartable) startHTTP(); if (xmppStartable) startXMPP(); } catch (DSException e) { logger.info("--- DSCatalog: Unable to connect to database. " + "Make sure you have specified the correct password via -p or your config file."); } //-- announce success if (xmppServer != null && httpServer != null) { logger.info("Datasphere setup and ready for FULL service..."); } else if (xmppServer != null || httpServer != null) { logger.info("Datasphere setup and ready for \"partial\" service..."); } else { logger.info("Datasphere startup failed. No service is available."); return; } while (isRunning) ; } /////////////////////////////// public void pleaseStop() { this.isRunning = false; } /////////////////////////////// /** * create an instance of the http server * @throws DSException */ public void startHTTP() throws DSException { if (httpStartable) { try { httpServer = new DSWebServer(httpPort); if (debug) { httpServer.useProtocol(Protocol.FILE); } else { httpServer.useProtocol(Protocol.CLAP); } httpServer.start(); logger.info("--- DSCatalog: HTTP server setup...[SUCCESS]"); } catch (Exception e) { logger.severe("--- DSCatalog: HTTP server setup...[FAILED]"); e.printStackTrace(); httpServer = null; } } } /////////////////////////////// /** * create an instance of the xmpp server * @throws DSException */ public void startXMPP() throws DSException { if (xmppStartable) { try { if (debug) { XMPPConnection.DEBUG_ENABLED = true; } xmppServer = new DSChatServer(xmppPort); xmppServer.start(); logger.info("--- DSCatalog: XMPP server setup...[SUCCESS]"); } catch (DSException e) { logger.severe("--- DSCatalog: XMPP server setup...[FAILED]"); e.printStackTrace(); xmppServer = null; } } } /////////////////////////////// /** * The Catalog class also handles management of the datasphere server's logging * facilities - as such the logging level can be set here (the level's * are as specified in java.util.logging). * @param level The minimum level for which log messages will be displayed. */ public void setLoggingLevel(Level level) { handler.setLevel(level); logger.setLevel(level); } /////////////////////////////// /** * */ public void setStartable(int protocol) { if (protocol == XMPP) { xmppStartable = true; httpStartable = false; } else if (protocol == HTTP) { xmppStartable = false; httpStartable = true; } else if (protocol == ALL_PROTOCOLS) { xmppStartable = true; httpStartable = true; } } /////////////////////////////// /** * Allows command line arguments to be passed into the framework - any parameters * supplied in this fashion will override any that were previously being held. * @param args The command line arguments supplied on running of the server instance. * @exception DSException Thrown if the supplied port number is illegal or already in use. */ public void setArgs(String[] args) throws DSException { try { //-- create Options object Options options = new Options(); options.addOption("w", "wipe", false, "clears the system databases on startup"); options.addOption("d", "debug", false, "pulls up a debugger window for each XMPP connection"); options.addOption("x", "xmpp", true, "specify the port the xmpp server listens on. default is " + DSChatServer.DEFAULT_SERVER_PORT); options.addOption("t", "http", true, "specify the port the http server listens on. default is " + DSWebServer.DEFAULT_SERVER_PORT); options.addOption("p", "password", true, "specify the admin password for the system"); options.addOption("l", "log-level", true, "specify the log level (0-1000) to display"); options.addOption("c", "create", false, "Automatically generates required system tables"); options.addOption("h", "help", false, "prints this message"); options.addOption("v", "version", false, "returns version information"); options.addOption("b", "verbose", false, "posts all logger information to the console"); options.addOption("bt", "verbose-http", false, "posts all http log information to the console"); options.addOption("bx", "verbose-xmpp", false, "posts all xmpp log information to the console"); options.addOption("vf", "version-full", false, "returns full version, build and authorship information"); CommandLineParser parser = new PosixParser(); CommandLine cmd = parser.parse(options, args); for (String s : cmd.getArgs()) System.out.println("(" + s + ")"); //-- automatically generate the help statement if (cmd.hasOption("help")) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("DSCatalog.jar", options); xmppStartable = false; httpStartable = false; return; } //-- determine if version information is being asked for if (cmd.hasOption("version") || cmd.hasOption("version-full")) { //-- load config file for the server Properties v = new Properties(); InputStream is = getClass().getClassLoader().getResourceAsStream("version.info"); //-- if it exists extract the properties contained within if (is != null) { try { v.load(is); is.close(); System.out.println("version: datasphere.catalog " + v.getProperty("version")); if (cmd.hasOption("version-full")) { System.out.println("compiler: " + v.getProperty("compiled-by")); System.out.println("built: " + v.getProperty("build-time") + ""); System.out.println("Java: " + v.getProperty("java-version")); } } catch (IOException e) { System.out.println("version: information cannot be loaded"); } } else { System.out.println("version: information cannot be found"); } xmppStartable = false; httpStartable = false; return; } //-- determine if system databases should be cleaned if (cmd.hasOption("wipe")) { systemWipe = true; } //-- determine if user is attempting to create the system database if (cmd.hasOption("create")) { systemCreate = true; } //-- determine if user is attempting to create the system database if (cmd.hasOption("debug")) { this.debug = true; } //-- check the validity of any log-level supplied if (cmd.hasOption("log-level")) { try { setLoggingLevel(Level.parse(cmd.getOptionValue("log-level").toUpperCase())); } catch (IllegalArgumentException e) { throw new ParseException("Logging error: " + e.getMessage()); } } //-- determine if a port number is being specified if (cmd.hasOption("password")) { try { this.password = cmd.getOptionValue("p"); } catch (NumberFormatException e) { throw new ParseException("Invalid password specified"); } } //-- determine if an xmpp port number is being specified if (cmd.hasOption("xmpp")) { try { xmppPort = Integer.parseInt(cmd.getOptionValue("x")); } catch (NumberFormatException e) { throw new ParseException("Invalid XMPP Port Number specified"); } } //-- determine if an xmpp port number is being specified if (cmd.hasOption("http")) { try { httpPort = Integer.parseInt(cmd.getOptionValue("t")); } catch (NumberFormatException e) { throw new ParseException("Invalid HTTP Port Number specified"); } } } catch (ParseException e) { throw new DSException(e.getMessage() + "\n" + "Please try '--help' for more information"); } } }