Package com.pugh.sockso

Source Code of com.pugh.sockso.Main

package com.pugh.sockso;

import com.pugh.sockso.cache.ObjectCacheGC;
import com.pugh.sockso.db.DBExporter;
import com.pugh.sockso.db.Database;
import com.pugh.sockso.gui.Splash;
import com.pugh.sockso.inject.SocksoModule;
import com.pugh.sockso.music.CollectionManager;
import com.pugh.sockso.music.DBCollectionManager;
import com.pugh.sockso.music.indexing.Indexer;
import com.pugh.sockso.music.scheduling.SchedulerRunner;
import com.pugh.sockso.resources.Locale;
import com.pugh.sockso.resources.LocaleFactory;
import com.pugh.sockso.resources.Resources;
import com.pugh.sockso.web.Dispatcher;
import com.pugh.sockso.web.HttpServer;
import com.pugh.sockso.web.IpFinder;
import com.pugh.sockso.web.Server;
import com.pugh.sockso.web.SessionCleaner;

import com.google.inject.Guice;
import com.google.inject.Injector;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.logging.LogManager;

import joptsimple.OptionParser;
import joptsimple.OptionSet;

public class Main {

    private static final Logger log = Logger.getLogger( Main.class );

    private static volatile boolean shutdownStarted = false;

    private static Dispatcher dispatcher;
    private static Database db;
    private static Properties p;
    private static Server sv;
    private static CollectionManager cm;
    private static Manager manager;
    private static Resources r;
    private static Locale locale;
    private static Indexer indexer;
    private static SchedulerRunner sched;
    private static Injector injector;

    /**
     *  application entry point
     *
     *  @param args the command line arguments
     *
     */

    public static void main( final String[] args ) throws Exception{

        Runtime.getRuntime().addShutdownHook( new Shutdown() );

        initLogger( getLogPropsFile("default") );
        initJavaLogger();

        //
        //  do initial setup, we're gonna need to parse the command line
        //  arguments, and make sure we're connected to the database
        //

        final OptionParser parser = Options.getParser();
        OptionSet options = null;
        try {
            options = parser.parse(args);
        } catch ( final Exception e ) {
            System.err.println( "Invalid command line switch!" );
        }

        // check if user asked for basic things as early as we can, don't
        // wanna go doing anything we don't need to.
        if ( options == null || options.has(Options.OPT_HELP) ) {
            parser.printHelpOn( System.out );
            exit( false );
        }
       
        // print version info?
        if ( options.has(Options.OPT_VERSION) ) {
            System.out.println( "Sockso " +Sockso.VERSION );
            exit( false );
        }

        // set a user-defined data directory?
        if ( options.hasArgument(Options.OPT_DATADIR) ) {
            final File dir = new File( (String) options.valueOf(Options.OPT_DATADIR) );
            Utils.setApplicationDirectory( dir );
        }

        setupAppDirectory();

        //
        //  final setup from command line options before we try and do
        //  something kinda useful
        //

        if ( options.hasArgument(Options.OPT_LOGTYPE) ) {
            PropertyConfigurator.configure( getLogPropsFile(options.valueOf(Options.OPT_LOGTYPE).toString()) );
        }

        injector = Guice.createInjector( new SocksoModule(options) );

        try {
            db = injector.getInstance( Database.class );
            db.connect( options );
        }
        catch ( final Exception e ) {
            log.error( e );
            exit( 1 );
        }

        //
        //  now decide exactly what we're gonna be doing, hmm...
        //

        // perform a database query
        if ( options.has(Options.OPT_QUERY) ) {
            actionQuery( options );
        }

        // default is start sockso normally
        else {
            actionDefault( options );
        }

    }

    /**
     *  performs a database query and outputs the results
     *
     *  @param options
     *
     */
   
    private static void actionQuery( final OptionSet options ) {

        BufferedReader in = null;
       
        try {

            String sql = "", line = "";

            // if we were given a filename use that as input, otherwise
            // read from stdin
            in = new BufferedReader(
                options.hasArgument(Options.OPT_QUERY)
                    ? new FileReader( options.valueOf(Options.OPT_QUERY).toString() )
                    : new InputStreamReader( System.in )
            );

            // read in query, then output xml
            while ( (line = in.readLine()) != null )
                sql += line + "\n";
           
            final DBExporter exporter = new DBExporter( db );
            System.out.print(
                exporter.export( sql, DBExporter.Format.XML )
            );

        }
       
        catch ( final IOException e ) {
            log.error( e );
        }
       
        finally { Utils.close(in); }
       
    }
   
    /**
     *  starts sockso normally in either GUI or Console mode
     *
     *  @param options
     *
     *  @throws java.sql.SQLException
     *
     */
   
    private static void actionDefault( final OptionSet options ) throws Exception {

        final boolean useGui = getUseGui( options );
        final String localeString = getLocale( options );
       
        log.info( "Initializing Resources (" + locale + ")" );
        r = injector.getInstance( Resources.class );
        r.init( localeString );

        LocaleFactory localeFactory = injector.getInstance( LocaleFactory.class );
        localeFactory.init( localeString );
       
        if ( useGui ) {
            Splash.start( r );
        }

        log.info( "Loading Properties" );
        p = injector.getInstance( Properties.class );
        p.init();

        log.info( "Starting Scheduler" );
        sched = injector.getInstance( SchedulerRunner.class );
        sched.start();

        indexer = injector.getInstance( Indexer.class );
       
        log.info( "Starting Collection Manager" );
        cm = injector.getInstance( CollectionManager.class );
        indexer.addIndexListener( (DBCollectionManager) cm );

        injector.getInstance( CommunityUpdater.class ).start();

        injector.getInstance( SessionCleaner.class ).init();
       
        injector.getInstance( ObjectCacheGC.class ).start();

        final IpFinder ipFinder = injector.getInstance( IpFinder.class );
        ipFinder.init();

        final int port = getSavedPort( p );
        final String protocol = getProtocol( options );

        dispatcher = injector.getInstance( Dispatcher.class );
        dispatcher.init( protocol, port );
       
        log.info( "Starting Web Server" );
        sv = injector.getInstance( Server.class );
        sv.start( options, port );

        if ( options.has(Options.OPT_UPNP) ) {
            log.info( "Trying UPNP Magic" );
            UPNP.tryPortForwarding( sv.getPort() );
        }

        manager = injector.getInstance( Manager.class );

        final VersionChecker versionChecker = injector.getInstance( VersionChecker.class );
        versionChecker.addLatestVersionListener( manager );
        versionChecker.fetchLatestVersion();
       
        manager.open();

    }

    /**
     *  returns a boolean indicating if we should start the GUI or not
     *
     *  @param options
     *
     *  @return
     *
     */
   
    protected static boolean getUseGui( final OptionSet options ) {

        return !options.has( Options.OPT_NOGUI );
       
    }
   
    /**
     *  returns the locale to use (eg. "en", "nb", etc...)
     *
     *  @param options
     *
     *  @return
     *
     */
   
    protected static String getLocale( final OptionSet options ) {

        return options.has( Options.OPT_LOCALE )
            ? options.valueOf(Options.OPT_LOCALE).toString()
            : Resources.DEFAULT_LOCALE;

    }
   
    /**
     *  Returns the protocol to use for web serving
     *
     *  @param options
     *
     *  @return
     *
     */
   
    protected static String getProtocol( final OptionSet options ) {
       
        return options.has( Options.OPT_SSL )
            ? "https"
            : "http";
       
    }

    /**
     *  fetches the port stored in the application properties, if this isn't
     *  something acceptable then it'll return the DEFAULT_PORT
     *
     *  @param p
     *
     *  @return
     *
     */

    protected static int getSavedPort( final Properties props ) {

        int thePort = HttpServer.DEFAULT_PORT;

        try {
            thePort = Integer.parseInt(props.get(Constants.SERVER_PORT));
        }
        catch ( final NumberFormatException e ) {
            log.error( "Invalid port number: " + e );
        }

        return thePort;

    }

    /**
     *  returns name of logger properties file for given type
     *
     *  @param type the logging type
     *  @return the path to the props file
     *
     */

    private static String getLogPropsFile( final String type ) {
        return Constants.LOG_DIR + File.separator + type + ".properties";
    }

        /**
     *  returns name of test logger properties file for given type
     *
     *  @param type the logging type
     *  @return the path to the props file
     *
     */

    private static String getTestLogPropsFile( final String type ) {
        return Constants.TEST_LOG_DIR + File.separator + type + ".properties";
    }

    /**
     *  shuts down the application
     *
     */

    public static void exit() {
        exit( 0, true );
    }

    public static void exit( int status ) {
        exit( status, true );
    }
   
    public static void exit( boolean showOutput ) {
        exit( 0, showOutput );
    }
   
    /**
     *  shuts down the application and exits with the specifed exit code
     *
     *  @param status the exit code
     *
     */

    public static void exit( final int status, final boolean showOutput ) {

        if ( showOutput ) {
            log.info( "Shutting Down" );
        }

        shutdown();

        if ( showOutput ) {
            log.info( "Thank you for your attention, bye!" );
        }

        System.exit( status );

    }

    /**
     *  Shuts down application components
     *
     */

    protected static void shutdown() {

        if ( !shutdownStarted ) {

            shutdownStarted = true;

            if ( indexer != null ) {
                // @TODO
            }

            if ( sv != null ) {
                sv.shutdown();
                sv = null;
            }

            if ( manager != null) {
                manager.close();
                manager = null;
            }

            shutdownDatabase();

        }

    }

    /**
     *  Shuts down the database connection if it's open
     *
     *  @return
     *
     */
   
    public static void shutdownDatabase() {

        // finally shutdown database (do this last so
        // anything can still be written here from the
        // other components)
        if ( db != null ) {
            db.close();
            db = null;
        }

    }
   
    /**
     *  creates the folder in the users home directory that is used
     *  to store application stuff (the database)
     *
     */
   
    private static void setupAppDirectory() {
       
        final String[] dirs = {
            Utils.getApplicationDirectory(),
            Utils.getCoversDirectory()
        };
       
        for ( final String dir : dirs ) {
            final File file = new File( dir );
            if ( !file.exists() ) {
                if ( !file.mkdir() ) {
                    log.fatal( "Unable to create directory: " + dir );
                    exit( 1 );
                }
            }
        }

    }

    /**
     *  Initializes the logger for the test cases
     *
     */

    public static void initTestLogger() {

        initLogger( getTestLogPropsFile("test") );

    }

    /**
     *  Inits the logging framework with the specified props file
     *
     *  @param propsFile the properties file to use
     *
     */


    private static void initLogger( final String propsFile ) {

        if ( new File(propsFile).exists() ) {
            PropertyConfigurator.configure( propsFile );
        }

    }

    /**
     *  Inits loggers using java.util.logging
     *
     */

    private static void initJavaLogger() throws IOException {

        final File propsFile = new File( getLogPropsFile("javalogging") );

        if ( propsFile.exists() ) {

            final InputStream is = new FileInputStream( propsFile );

            LogManager.getLogManager().readConfiguration(is);

            Utils.close( is );

        }

    }

}
TOP

Related Classes of com.pugh.sockso.Main

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.