at.spardat.xma.boot.BootRuntime.java Source code

Java tutorial

Introduction

Here is the source code for at.spardat.xma.boot.BootRuntime.java

Source

/*******************************************************************************
 * Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     s IT Solutions AT Spardat GmbH - initial API and implementation
 *******************************************************************************/

/*
 * Created on : 04.2003
 * Created by : s3595
 */

package at.spardat.xma.boot;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.util.StringTokenizer;

import org.apache.commons.logging.LogFactory;

import at.spardat.xma.boot.cache.FileCache;
import at.spardat.xma.boot.cleanup.Cleaner;
import at.spardat.xma.boot.comp.AppManager;
import at.spardat.xma.boot.logger.LogLevel;
import at.spardat.xma.boot.logger.LogManager;
import at.spardat.xma.boot.logger.Logger;
import at.spardat.xma.boot.logger.XmaBrtLogger;
import at.spardat.xma.boot.natives.Natives;
import at.spardat.xma.boot.transport.HTTPTransport;
import at.spardat.xma.boot.transport.XMA_URI;

/**
 * The BootRuntime holds information about the client/machine environment for the boot runtime.
 *
 * @author s3595 <a href="mailto:schaeferc@spardat.at">Chris Schfer (CGS)</a>
 * @version $Id: BootRuntime.java 9782 2012-08-15 20:11:35Z hoenninger $
 */
public class BootRuntime {

    /** this is a singleton */
    private static BootRuntime instance_;

    /**
     * Boot Runtime Installation Directory
     */
    private File installDirectory;

    /**
     * directory for cache, logging and other temporary data
     */
    private File dataDirectory;

    /** debug mode */
    private Boolean debug;

    /** file cache */
    private FileCache fc;

    /** app manager */
    private AppManager appm_;

    /** logger */
    private Logger bootLogger;

    /** configuration */
    private Properties props;

    /** handler for cleanup daemon tasks */
    private Cleaner cleaner;

    /**
     * The BootRuntime constructor is private, because it is a singleton got only via initialize.
     * the constructor initializes the process properties and the basic directories.
     * the initialization of modules is seperated into 'initializeModules'.
     *
     * @param baseDir xma base dir.
     * @param logger  an existing logger [optional ].
     */
    private BootRuntime(File baseDir, Logger l) throws IOException {

        setInstallDirectory(baseDir);

        props = readBootCfgProperties(baseDir, l);

        /*
         * check data directory path information
         */
        String strDataDirectory = props.getProperty(Statics.CFG_PROP_DATAPATH);
        //if the prop CFG_PROP_DATAPATH is marked with CFG_PROP_DATAPATH_USER_HOME_VALUE then "user.home" is used
        if (strDataDirectory != null && strDataDirectory.startsWith(Statics.CFG_PROP_DATAPATH_USER_HOME_VALUE)) {
            strDataDirectory = System.getProperty("user.home")
                    + strDataDirectory.substring(Statics.CFG_PROP_DATAPATH_USER_HOME_VALUE.length());
            props.put(Statics.CFG_PROP_DATAPATH, strDataDirectory);
            l.log(LogLevel.FINE,
                    "Datapath Property set to " + Statics.CFG_PROP_DATAPATH_USER_HOME_VALUE + ", using: {0}",
                    strDataDirectory);
        }
        //if the prop CFG_PROP_DATAPATH has no value then "user.dir" is used
        if (strDataDirectory == null || strDataDirectory.length() == 0) {
            strDataDirectory = System.getProperty("user.dir");
            props.put(Statics.CFG_PROP_DATAPATH, strDataDirectory);
            l.log(LogLevel.FINE, "Datapath Property not found defaults to user.dir: {0}", strDataDirectory);
        }

        dataDirectory = new File(strDataDirectory);
        if (!dataDirectory.exists()) {
            dataDirectory.mkdirs();
        }
        if (!dataDirectory.isDirectory()) {
            throw new RuntimeException("datapath '" + dataDirectory.getAbsolutePath() + "' is not a directory");
        }

        props.setProperty(Statics.CFG_PROP_LOGDIRECTORY, strDataDirectory);

        LogManager.getLogManager().setConfiguration(props);
        XMA_URI.setProperties(props);

        if (l != null)
            this.bootLogger = l;
        else
            this.bootLogger = Logger.getLogger("bootrt.bootRuntime"); //$NON-NLS-1$

        // tell apache.commons.logging to use the logger of XMABootRuntime
        LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log", XmaBrtLogger.class.getName());

        String strDebug = (String) props.get(Statics.CFG_PROP_LOGLEVEL); //$NON-NLS-1$
        LogLevel level = LogLevel.getLogLevelNamed(strDebug);

        // extended output to files and other tracing information only on high log levels
        if (LogLevel.ALL.equals(level) || LogLevel.FINE.equals(level)) {
            setDebug(Boolean.TRUE);
            debugJavaParameter();
        } else {
            setDebug(Boolean.FALSE);
        }

        // read caching properties from registry
        String useRegistry = props.getProperty(Statics.CFG_PROP_USEREGISTRY, "true");
        if (Boolean.valueOf(useRegistry).booleanValue()) {
            getProxySettings(props, bootLogger);
        }

    }

    /**
     * Read the BootCfg properties. First the default properties are read from a
     * property file in the class path. In a second step these properties are overloaded
     * from the bootruntime configuration file located in the base directory.
     * 
     * @param baseDir
     * @param l
     * @return
     * @throws IOException
     */
    static Properties readBootCfgProperties(File baseDir, Logger l) throws IOException {

        Properties props = new Properties();

        /* load default properties from classpath */
        InputStream is = BootRuntime.class.getClassLoader()
                .getResourceAsStream("at/spardat/xma/boot/bootcfg.properties");
        props.load(is); //$NON-NLS-1$
        is.close();

        /* load additional properties from runtime directory, if exist.
         * can replace default properties.
         */
        File configFile = new File(baseDir, Statics.SETTINGS_DIRNAME + "/" + Statics.BRT_CONFIGFILE); //$NON-NLS-1$
        if (configFile.exists()) {
            l.log(LogLevel.FINE, "Using Configuration File: {0}", configFile.toString());
            InputStream cfis = new FileInputStream(configFile);
            props.load(cfis);
            cfis.close();
        }

        return props;
    }

    /**
     * initialize all modules for the boot runtime.
     *
     * @throws IOException
     */
    private void initializeModules() throws IOException {

        HTTPTransport.init(props);

        fc = FileCache.initialize(this);

        appm_ = AppManager.initialize(props);

        /*
         * create and start cleaner
         * !! Cleaner requires an initialized filecache !!
         */
        cleaner = new Cleaner(this);
        cleaner.startCleanup();
    }

    /**
     * debug java environment parameters.
     */
    public void debugJavaParameter() {
        bootLogger.log(LogLevel.ALL, "java system properties are:");
        Properties p = System.getProperties();
        Enumeration enumer = p.keys();
        while (enumer.hasMoreElements()) {
            String element = (String) enumer.nextElement();
            bootLogger.log(LogLevel.ALL, "{0} : {1}", new Object[] { element, p.getProperty(element) });
        }
    }

    /**
     * @return the root working-directory for this machine
     */
    public File getInstallDirectory() {
        return installDirectory;
    }

    /**
     * @return   AppManager  the application manager instance
     */
    public AppManager getAppManager() {
        return appm_;
    }

    /**
     * @param   file   the root working-directory for this machine
     */
    private void setInstallDirectory(File fileBaseDir) {
        if (!fileBaseDir.exists())
            throw new IllegalArgumentException("Installation-Directory does not exist"); //$NON-NLS-1$

        this.installDirectory = fileBaseDir;
    }

    /**
     * @return   BootRuntime   runtimce instance
     */
    public static BootRuntime getInstance() {
        if (instance_ == null)
            throw new IllegalStateException("runtime not initialized"); //$NON-NLS-1$
        else
            return instance_;
    }

    /**
     * initialize before usage
     *
     * @param fileBaseDir   base directory
     * @throws IllegalArgumentException if file does not exist.
     */
    public static synchronized BootRuntime initialize(File fileBaseDir, Logger l) throws IOException {
        if (instance_ == null)
            instance_ = new BootRuntime(fileBaseDir, l);
        instance_.initializeModules();
        return instance_;
    }

    /**
     * @return boolean  true for debug mode
     */
    public Boolean getDebug() {
        return debug;
    }

    /**
     * @param   debug  true for debug
     */
    private void setDebug(Boolean debugIn) {
        if (debugIn == null)
            debug = Boolean.FALSE;
        else
            debug = debugIn;
    }

    /**
     * @return configuration properties
     */
    public Properties getConfigProperties() {
        return props;
    }

    /**
     * @param properties configuration information
     */
    public void setConfigProperties(Properties properties) {
        props = properties;
    }

    /**
     * @return File data directory
     */
    public File getDataDirectory() {
        return dataDirectory;
    }

    //    private void getProxySettings( Properties props ) {
    //        try {
    //
    //        String strkey          = "HKEY_CURRENT_USER";
    //        String strSub          = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
    //        String strProxyServer  = "ProxyServer";
    //        String strProxyEnable  = "ProxyEnable";
    //
    //        Natives natives = new Natives();
    //
    //        String strProxyValue = natives.getRegistryKey( strkey, strSub, strProxyServer );
    //        if( strProxyValue != null ) {
    //            int pos = strProxyValue.indexOf(':');
    //            if( pos != -1 && pos < strProxyValue.length()) {
    //                String valProxy = strProxyValue.substring(0, pos);
    //                String valPort  = strProxyValue.substring(pos+1, strProxyValue.length() );
    //
    //                props.put( Statics.CFG_PROP_PROXYSERVER, valProxy );
    //                props.put( Statics.CFG_PROP_PROXYPORT, valPort );
    //            }
    //        }
    //        } catch( Exception e) {
    //            System.out.println( "error on loading proxy values ");
    //        }
    //    }

    /**
     *  Returns OS dependent proxy settings - only Windows is implemented yet.
     */
    private void getProxySettings(Properties props, Logger l) {
        String os = System.getProperty("os.name");

        if (os.trim().toLowerCase().indexOf("windows") == 0) {
            getWindowsProxySettings(props, l);
        }
    }

    /**
     * Format des Registy-Eintrags ProxyServer:
     * wenn fr alle Protokolle der selbe proxy:
     * <host>[:port>] port ist optional z.b.: proxy-sd.s-mxs.net:8080
     *
     * sonst:
     * <protocol>=<host>[:<port>][;<protocoll>=<host>[:<port>][;...]]
     * z.b.: ftp=proxy-sd.s-mxs.net:8080;gopher=proxy-sd.s-mxs.net:8080;http=proxy-sd.s-mxs.net:8080;https=proxy-sd.s-mxs.net:8080
     * wenn nur http proxy ausgefllt ist und nicht fr alle Protokolle der selbe proxy: http=proxy-sd.s-mxs.net:8080
     */
    private void getWindowsProxySettings(Properties props, Logger l) {
        String strkey = "HKEY_CURRENT_USER";
        String strSub = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
        String strProxyEnable = "ProxyEnable";
        String strProxyServer = "ProxyServer";
        String strProxyOverride = "ProxyOverride";
        String strProxyScript = "AutoConfigURL";

        props.remove(Statics.CFG_PROP_PROXYENABLE);
        props.remove(Statics.CFG_PROP_PROXYSERVER);
        props.remove(Statics.CFG_PROP_PROXYPORT);
        props.remove(Statics.CFG_PROP_SECUREPROXYSERVER);
        props.remove(Statics.CFG_PROP_SECUREPROXYPORT);
        props.remove(Statics.CFG_PROP_PROXYOVERRIDE);
        try {
            Natives natives = new Natives();
            String strProxyEnableValue = natives.getRegistryKey(strkey, strSub, strProxyEnable);
            if (strProxyEnableValue != null) {
                // String der Lnge 1 mit binrer 1 fr true
                // String der Lnge 0 fr false
                if (strProxyEnableValue.length() == 1) {
                    int value = strProxyEnableValue.charAt(0);
                    props.put(Statics.CFG_PROP_PROXYENABLE, Boolean.toString(value != 0));
                } else {
                    props.put(Statics.CFG_PROP_PROXYENABLE, Boolean.toString(false));
                }
            }

            String strProxyValue = natives.getRegistryKey(strkey, strSub, strProxyServer);
            if (strProxyValue != null && strProxyValue.trim().length() > 0) {
                int pos = strProxyValue.indexOf("=");
                if (pos < 0) { // one entry for all protocols
                    StringTokenizer tok = new StringTokenizer(strProxyValue, ":");
                    String valProxy = tok.nextToken();
                    props.put(Statics.CFG_PROP_PROXYSERVER, valProxy);
                    props.put(Statics.CFG_PROP_SECUREPROXYSERVER, valProxy);
                    if (tok.hasMoreTokens()) {
                        String valPort = tok.nextToken();
                        props.put(Statics.CFG_PROP_PROXYPORT, valPort);
                        props.put(Statics.CFG_PROP_SECUREPROXYPORT, valPort);
                    } else { // default port is 80 for http and https proxies
                        props.put(Statics.CFG_PROP_PROXYPORT, "80");
                        props.put(Statics.CFG_PROP_SECUREPROXYPORT, "80");
                    }
                } else { // different entrys per protocol
                    for (StringTokenizer ptok = new StringTokenizer(strProxyValue, ";"); ptok.hasMoreTokens();) {
                        String strProtocolProxyValue = ptok.nextToken();
                        StringTokenizer tok = new StringTokenizer(strProtocolProxyValue, "=:");
                        String valProtocol = tok.nextToken();
                        if ("http".equals(valProtocol)) {
                            String valProxy = tok.nextToken();
                            props.put(Statics.CFG_PROP_PROXYSERVER, valProxy);
                            if (tok.hasMoreTokens()) {
                                String valPort = tok.nextToken();
                                props.put(Statics.CFG_PROP_PROXYPORT, valPort);
                            } else { // default port is 80 for http proxy
                                props.put(Statics.CFG_PROP_PROXYPORT, "80");
                            }
                        } else if ("https".equals(valProtocol)) {
                            String valProxy = tok.nextToken();
                            props.put(Statics.CFG_PROP_SECUREPROXYSERVER, valProxy);
                            if (tok.hasMoreTokens()) {
                                String valPort = tok.nextToken();
                                props.put(Statics.CFG_PROP_SECUREPROXYPORT, valPort);
                            } else { // default port is 80 for https proxy
                                props.put(Statics.CFG_PROP_SECUREPROXYPORT, "80");
                            }
                        }
                    }
                }
            }
            String strProxyOverrideValue = natives.getRegistryKey(strkey, strSub, strProxyOverride);
            if (strProxyOverrideValue != null) {
                props.put(Statics.CFG_PROP_PROXYOVERRIDE, strProxyOverrideValue);
            }
            String strProxyScriptValue = natives.getRegistryKey(strkey, strSub, strProxyScript);
            if (strProxyScriptValue != null && strProxyScriptValue.length() > 0) {
                l.log(LogLevel.WARNING, "automatic proxy script '" + strProxyScriptValue + "' not supported");
            }
        } catch (Exception e) {
            l.log(LogLevel.WARNING, "error loading proxy values: ", e);
        } catch (UnsatisfiedLinkError err) {
            l.log(LogLevel.WARNING, "error loading proxy values: ", err);
        }
    }
}