Package com.scooterframework.admin

Source Code of com.scooterframework.admin.ApplicationConfig

/*
*   This software is distributed under the terms of the FSF
*   Gnu Lesser General Public License (see lgpl.txt).
*
*   This program is distributed WITHOUT ANY WARRANTY. See the
*   GNU General Public License for more details.
*/
package com.scooterframework.admin;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.scooterframework.autoloader.AutoLoaderConfig;
import com.scooterframework.autoloader.ClassWorkHelper;
import com.scooterframework.autoloader.FileMonitor;
import com.scooterframework.common.logging.LogConfig;
import com.scooterframework.common.logging.LogUtil;
import com.scooterframework.common.util.FileUtil;
import com.scooterframework.i18n.I18nConfig;
import com.scooterframework.orm.activerecord.ReferenceDataLoader;
import com.scooterframework.orm.sqldataexpress.config.DatabaseConfig;
import com.scooterframework.orm.sqldataexpress.config.SqlConfig;
import com.scooterframework.web.controller.ActionContext;
import com.scooterframework.web.route.RouteConfig;

/**
* <p>
* ApplicationConfig class configures an application in one of the three modes.
* <ol>
*   <li>WEB</li>
*   <li>APP</li>
*   <li>ORM</li>
* </ol>
* </p>
*
* <p>
* In the <tt>WEB</tt> mode, the application runs in a web container. Its file
* structure follows Scooter's file structure, unless you reset locations of
* some files as specified below.
* </p>
*
* <p>
* In the <tt>APP</tt> mode, the application runs outside of a web container.
* Its file structure follows Scooter's file structure, unless you reset
* locations of some files as specified below.
* Scooter's JUnit test uses this mode.
* </p>
*
* <p>
* In the <tt>ORM</tt> mode, no web container is necessary to use scooter.
* Any application can use Scooter's Active Record or SQL Data Express (SDE)
* capability in their data access layer. This can be achieved by just using
* scooter.jar file and some config property files (<tt>database.properties</tt>,
* <tt>environment.properties</tt>, <tt>log4j.properties</tt>, and
* <tt>sql.properties</tt>). The config files must be on the classpath of the
* running application. </p>
*
* <p>
* In the <tt>ORM</tt> mode, application's file structure does not need to
* follow Scooter's file structure. This is good for those applications that
* want to include Scooter in their own data access layers.
* </p>
*
* <p>See sample stand-alone application <tt>scooter-orm</tt> for more details.</p>
*
* <p>
* For either <tt>WEB</tt> or <tt>APP</tt> mode, application path is
* required. It is automatically set by <tt>WebApplicationStartListener</tt>
* for web application or detected for non-web application.
* </p>
*
* <p>For example, it the application is located in
* <tt>c:\>project\petclinic</tt>, then the application path would
* be '<tt>c:\>project\petclinic</tt>'.
* </p>
*
* <p>In either <tt>WEB</tt> or <tt>APP</tt> mode, the following properties can
* be set through System property from command line. </p>
*
* <pre>
* Configurable System Properties and corresponding default values for web application:
*         class.file.location => {app.path}/WEB-INF/classes
*      property.file.location => {app.path}/WEB-INF/config
*        source.file.location => {app.path}/WEB-INF/src
*     reference.file.location => {scooter.home}/lib
* </pre>
*
* @author (Fei) John Chen
*/
public class ApplicationConfig {
    private static LogUtil log = null;
    public static boolean noConsoleDisplay = false;
    public static final String SYSTEM_KEY_CLASSFILE = "class.file.location";
    public static final String SYSTEM_KEY_PROPERTYFILE = "property.file.location";
    public static final String SYSTEM_KEY_SOURCEFILE = "source.file.location";
    public static final String SYSTEM_KEY_PLUGINFILE = "plugin.file.location";
    public static final String SYSTEM_KEY_REFERENCEFILE = "reference.file.location";
   
    private static volatile ApplicationConfig me;
    private String configuredMode;
    private String runningEnvironment = Constants.RUNNING_ENVIRONMENT_DEVELOPMENT;
   
    private ApplicationConfig(String configuredMode, String appPath, String contextName) {
        if (appPath == null) {
            throw new IllegalArgumentException("Application path cannot be null.");
        }
       
        this.applicationPath = appPath;
        this.contextName = contextName;
        this.configuredMode = configuredMode;
       
        log("Initializing " + configuredMode + " application ... ");
       
        if (Constants.CONFIGURED_MODE_SCOOTER_WEB.equals(configuredMode)) {
            log("           context name: " + contextName);
            log("               app path: " + applicationPath);
            initializeWeb();
        }
        else if (Constants.CONFIGURED_MODE_SCOOTER_APP.equals(configuredMode)) {
            log("           context name: " + contextName);
            log("               app path: " + applicationPath);
          initializeApp();
        }
        else if (Constants.CONFIGURED_MODE_SCOOTER_ORM.equals(configuredMode)) {
          initializeORM();
        }
        else {
            throw new IllegalArgumentException("Configured mode \"" +
                configuredMode + "\" is not supported");
        }
    }
 
  private void log(String s) {
    if (!noConsoleDisplay) System.out.println(s);
  }
 
  private void initializePlugins() {
    PluginManager.getInstance().startPlugins();
  }
   
   
    /**
     * Returns an instance of ApplicationConfig for web application.
     *
     * This method should be called the first time the application is
     * accessed or by a start-up method of a web application.
     */
    public static synchronized ApplicationConfig configInstanceForWeb(
        String webappPath, String contextName) {
        if (me == null) {
            me = new ApplicationConfig(Constants.CONFIGURED_MODE_SCOOTER_WEB,
                webappPath, contextName);
        }
        return me;
    }
   
    /**
     * Returns an instance of ApplicationConfig for non-web application based
     * on Scooter's directory structure.
     *
     * This method should be called in the application start program.
     * Subsequent use of ApplicationConfig can then use
     * <tt>ApplicationConfig.getInstance()</tt>.
     *
     * <p>This method assumes the current directory as the application's root
     * directory.
     * </p>
     */
    public static synchronized ApplicationConfig configInstanceForApp() {
        if (me == null) {
            String path = detectRootPath();
            me = new ApplicationConfig(Constants.CONFIGURED_MODE_SCOOTER_APP,
                path, detectContextName(path));
        }
        return me;
    }
   
    /**
     * Returns an instance of ApplicationConfig for non-web application using
     * only Scooter's ORM.
     *
     * This method should be called in the application start program.
     * Subsequent use of ApplicationConfig can then use
     * <tt>ApplicationConfig.getInstance()</tt>.
     *
     * <p>This method assumes that Scooter's config files are on classpath of
     * the calling application.
     * </p>
     */
    public static synchronized ApplicationConfig configInstanceForOrmAlone() {
        if (me == null) {
            String path = detectRootPath();
            me = new ApplicationConfig(Constants.CONFIGURED_MODE_SCOOTER_ORM,
                path, detectContextName(path));
        }
        return me;
    }
   
    /**
     * Returns an instance of ApplicationConfig. You
     * should call either <tt>getInstanceForWeb()</tt> or
     * <tt>getInstanceForApp()</tt> or
     * <tt>getInstanceForOrmAlone()</tt> method before using this
     * <tt>getInstance()</tt> method.
     */
    public static ApplicationConfig getInstance() {
        if (me == null) {
            throw new IllegalArgumentException("You should use either " +
            "'getInstanceForWeb()' or 'getInstanceForApp()' or " +
            "'getInstanceForOrmAlone()' method before " +
            "using this 'getInstance()' method. If this is a web app, check your context path.");
        }
       
        return me;
    }
   
    public void startORMApplication() {
        if (applicationStarted) return;
    applicationStartTime = System.currentTimeMillis();
   
    configInstanceForOrmAlone();
       
    LogUtil.enableLogger();
   
    try {
      EnvConfig.getInstance();
    }
    catch(NoClassDefFoundError er) {
      if (!"org/apache/commons/fileupload/FileItemFactory".equals(er.getMessage())) {
        log.error("Error in EnvConfig.getInstance()", er);
      }
    }
    DatabaseConfig dbc = DatabaseConfig.getInstance();
        SqlConfig.getInstance();
       
        //
        //store some important information about the server
        //
        Map<String, Object> props = new HashMap<String, Object>();
        props.put(Constants.APP_KEY_JAVA_VERSION, System.getProperty("java.version"));
       
        props.put(Constants.APP_KEY_SCOOTER_VERSION, Version.CURRENT_VERSION);
       
        props.put(Constants.APP_KEY_RUNNING_ENVIRONMENT, runningEnvironment);
        props.put(Constants.APP_KEY_APPLICATION_START_TIME, new Date(applicationStartTime));
        props.put(Constants.APP_KEY_APPLICATION_ROOT_PATH, applicationPath);
        props.put(Constants.APP_KEY_APPLICATION_CONTEXT_NAME, contextName);
        props.put(Constants.APP_KEY_APPLICATION_DATABASE_NAME, dbc.getDefaultDatabaseConnectionName());
       
        ActionContext.storeToGlobal(Constants.APP_KEY_SCOOTER_PROPERTIES, props);
       
        initializePlugins();
       
        applicationStarted = true;
    }
   
    public void startApplication() {
        if (applicationStarted) return;
       
    applicationStartTime = System.currentTimeMillis();
       
        if (isWebApp()) {
            PropertyFileChangeMonitor.getInstance();
        }
       
        //need to do the following:
        logConfig.enableMonitoring();
       
        EnvConfig.getInstance();
       
        if (isInDevelopmentEnvironment() && isWebApp()) {
            PropertyFileChangeMonitor.getInstance().start();
        }
       
        AutoLoaderConfig.getInstance();
       
        if (isInDevelopmentEnvironment() && isWebApp()) {
          FileMonitor.getInstance().start();
        }
       
        DatabaseConfig dbc = DatabaseConfig.getInstance();
       
        SqlConfig.getInstance();
       
        if (isWebApp()) RouteConfig.getInstance();
       
        if (isWebApp() && !ReferenceDataLoader.isStarted()) {
            rdLoader = new ReferenceDataLoader();
            rdLoader.start();
        }
       
        I18nConfig.getInstance();
       
        if (isInDevelopmentEnvironment() && isWebApp()) {
          DirChangeMonitor.getInstance().start();
        }
       
        //
        //store some important information about the server
        //
        Map<String, Object> props = new HashMap<String, Object>();
        props.put(Constants.APP_KEY_JAVA_VERSION, System.getProperty("java.version"));
       
        props.put(Constants.APP_KEY_SCOOTER_VERSION, Version.CURRENT_VERSION);
       
        props.put(Constants.APP_KEY_RUNNING_ENVIRONMENT, runningEnvironment);
        props.put(Constants.APP_KEY_APPLICATION_START_TIME, new Date(applicationStartTime));
        props.put(Constants.APP_KEY_APPLICATION_ROOT_PATH, applicationPath);
        props.put(Constants.APP_KEY_APPLICATION_CONTEXT_NAME, contextName);
        props.put(Constants.APP_KEY_APPLICATION_DATABASE_NAME, dbc.getDefaultDatabaseConnectionName());

        ActionContext.storeToGlobal(Constants.APP_KEY_SCOOTER_PROPERTIES, props);
       
        if(isApp() && "true".equals(System.getProperty(Constants.ALLOW_CLASSWORK))) {
            try {
                ClassWorkHelper.preloadClasses(sourceFileLocationPath);
      } catch (Exception ex) {
        log.error("Error in preloadClasses", ex);
      }
        }
       
        initializePlugins();
       
        applicationStarted = true;
        if (log != null) {
          String startMsg = "Application started in " + runningEnvironment +
      " with Scooter version: " + Version.CURRENT_VERSION;
          log.info(startMsg);
          if (log.isLogLevelGreaterThanInfo()) {
            System.out.println(startMsg);
          }
        }
    }
   
    public void endApplication() {
        if (rdLoader != null && ReferenceDataLoader.isStarted()) {
            rdLoader.stop();
        }
       
        PropertyFileChangeMonitor.getInstance().stop();
       
        FileMonitor.getInstance().stop();
       
        //started by I18nConfig
        DirChangeMonitor.getInstance().stop();
       
        DatabaseConfig.getInstance().destroy();
       
        applicationStarted = false;
       
        PluginManager.getInstance().stopPlugins();
       
        if (log != null) log.info("Application ended.");
    }
   
    public static String detectRootPath() {
        String path = "";
        try {
            path = (new File("")).getCanonicalPath();
        }
        catch(Exception ex) {
          ex.printStackTrace();
            String errorMessage = "Failed to detect root path from current directory: " + ex.getMessage();
            System.err.println(errorMessage);
            System.out.println("Stop initializtion process. Exit now ...");
        }
        return path;
    }
   
    /**
     * Returns number of sessions in the container.
     */
    public static int getSessionCount() {
      return WebSessionListener.getSessionCount();
    }
   
    public long getApplicationStartTime() {
        return applicationStartTime;
    }
   
    public String getApplicationPath() {
        return applicationPath;
    }
   
    public String getContextName() {
        return contextName;
    }
   
    public boolean applicationStarted() {
        return applicationStarted;
    }
   
    public String getConfiguredMode() {
        return configuredMode;
    }
   
    /**
     * Return true if the current app is configured as a web app.
     */
    public boolean isWebApp() {
        return Constants.CONFIGURED_MODE_SCOOTER_WEB.equals(configuredMode);
    }
   
    /**
     * Return true if the current app is configured as a regular app.
     */
    public boolean isApp() {
        return Constants.CONFIGURED_MODE_SCOOTER_APP.equals(configuredMode);
    }
   
    /**
     * Return true if the current app is configured to use orm alone.
     */
    public boolean isOrmAlone() {
        return Constants.CONFIGURED_MODE_SCOOTER_ORM.equals(configuredMode);
    }

    /**
     * Returns running environment
     */
    public String getRunningEnvironment() {
        return runningEnvironment;
    }
   
    public void setRunningEnvironment(String runningEnvironment) {
      this.runningEnvironment = runningEnvironment;
    }

    /**
     * Checks if the current running environment is development environment.
     *
     * @return true if the current running environment is development.
     */
    public boolean isInDevelopmentEnvironment() {
        return Constants.RUNNING_ENVIRONMENT_DEVELOPMENT.equals(runningEnvironment);
    }

    /**
     * Checks if the current running environment is test environment.
     *
     * @return true if the current running environment is test.
     */
    public boolean isInTestEnvironment() {
        return Constants.RUNNING_ENVIRONMENT_TEST.equals(runningEnvironment);
    }

    /**
     * Checks if the current running environment is production environment.
     *
     * @return true if the current running environment is production.
     */
    public boolean isInProductionEnvironment() {
        return Constants.RUNNING_ENVIRONMENT_PRODUCTION.equals(runningEnvironment);
    }
   
    public String getClassFileLocationPath() {
        return classFileLocationPath;
    }
   
    public String getPropertyFileLocationPath() {
        return propertyFileLocationPath;
    }
   
    public String getSourceFileLocationPath() {
        return sourceFileLocationPath;
    }
   
    public String getWebappLibPath() {
        return webappLibPath;
    }
   
    public String getPluginsPath() {
        return pluginsPath;
    }
   
    public String getReferencesLibPath() {
        return referencesLibPath;
    }
   
    public void setClassFileLocationPath(String classFileLocationPath) {
        this.classFileLocationPath = classFileLocationPath;
    }
   
    public void setPropertyFileLocationPath(String propertyFileLocationPath) {
        this.propertyFileLocationPath = propertyFileLocationPath;
    }
   
    public void setSourceFileLocationPath(String sourceFileLocationPath) {
        this.sourceFileLocationPath = sourceFileLocationPath;
    }
   
    private void initializeWeb() {
      webappLibPath = applicationPath
              + File.separatorChar + "WEB-INF"
              + File.separatorChar + "lib";
       
        String cfl = System.getProperty(SYSTEM_KEY_CLASSFILE, "");
        if ("".equals(cfl)) {
            cfl = applicationPath
              + File.separatorChar + "WEB-INF"
              + File.separatorChar + "classes";
        }
        classFileLocationPath = cfl;
       
        String pfl = System.getProperty(SYSTEM_KEY_PROPERTYFILE, "");
        if ("".equals(pfl)) {
            pfl = applicationPath
              + File.separatorChar + "WEB-INF"
              + File.separatorChar + "config";
        }
        propertyFileLocationPath = pfl;
       
        String sfl = System.getProperty(SYSTEM_KEY_SOURCEFILE, "");
        if ("".equals(sfl)) {
            String srcPath = applicationPath
                    + File.separatorChar + "WEB-INF"
                    + File.separatorChar + "src";
           
            String unitTestPath = applicationPath
                    + File.separatorChar + "WEB-INF"
                    + File.separatorChar + "test"
                    + File.separatorChar + "unit";
           
            String functionalTestPath = applicationPath
                    + File.separatorChar + "WEB-INF"
                    + File.separatorChar + "test"
                    + File.separatorChar + "functional";
           
            sfl = srcPath + File.pathSeparatorChar + unitTestPath
                    + File.pathSeparatorChar + functionalTestPath;
        }
        sourceFileLocationPath = sfl;
       
        String pgl = System.getProperty(SYSTEM_KEY_PLUGINFILE, "");
        if ("".equals(pgl)) {
          String sh = System.getProperty("scooter.home");
          if (sh != null) {
              pgl = sh + File.separatorChar + "plugins";
          }
        }
        pluginsPath = pgl;
       
        String rfl = System.getProperty(SYSTEM_KEY_REFERENCEFILE, "");
        if ("".equals(rfl)) {
            rfl = System.getProperty("scooter.home") + File.separatorChar + "lib";
            if (!FileUtil.pathExistAndHasFiles(rfl)) {
                rfl = applicationPath
              + File.separatorChar + "WEB-INF"
              + File.separatorChar + "lib";
            }
        }
        referencesLibPath = rfl;
       
        log("    " + SYSTEM_KEY_CLASSFILE + ": " + classFileLocationPath);
        log(" " + SYSTEM_KEY_PROPERTYFILE + ": " + propertyFileLocationPath);
        log("   " + SYSTEM_KEY_SOURCEFILE + ": " + sourceFileLocationPath);
        log("" + SYSTEM_KEY_REFERENCEFILE + ": " + referencesLibPath);
       
        if (pluginsPath != null  && !"".equals(pluginsPath)) {
            log("   " + SYSTEM_KEY_PLUGINFILE + ": " + pluginsPath);
        }
        else {
          log("INFO: If jars under scooter/plugins are needed, use -Dscooter.home=... to setup path to the plugin directory.");
        }
       
        //make sure there are files in the property file location
        String[] fileNames = (new File(propertyFileLocationPath)).list();
        if (fileNames == null || fileNames.length == 0) {
            log("ERROR ERROR ERROR => There are no property files in the property file location.");
            log("Stop initializtion process. Exit now ...");
        }
       
        //initialized other stuff if not started
        logConfig = LogConfig.getInstance(propertyFileLocationPath);
        log = LogUtil.getLogger(ApplicationConfig.class.getName());
       
       
    }
   
    private void initializeApp() {
      webappLibPath = applicationPath + File.separatorChar + "lib";
       
        String cfl = System.getProperty(SYSTEM_KEY_CLASSFILE, "");
        if ("".equals(cfl)) {
            cfl = applicationPath + File.separatorChar + "build"
                                      + File.separatorChar + "classes";
        }
        classFileLocationPath = cfl;
       
        String pfl = System.getProperty(SYSTEM_KEY_PROPERTYFILE, "");
        if ("".equals(pfl)) {
            pfl = applicationPath + File.separatorChar + "source"
                        + File.separatorChar + "test"
                        + File.separatorChar + "config";
        }
        propertyFileLocationPath = pfl;
       
        String sfl = System.getProperty(SYSTEM_KEY_SOURCEFILE, "");
        if ("".equals(sfl)) {
            sfl = applicationPath + File.separatorChar + "source"
                        + File.separatorChar + "test";
        }
        sourceFileLocationPath = sfl;
       
        String pgl = System.getProperty(SYSTEM_KEY_PLUGINFILE, "");
        if ("".equals(pgl)) {
          pgl = System.getProperty("scooter.home") + File.separatorChar + "plugins";
        }
        pluginsPath = pgl;
       
        String rfl = System.getProperty(SYSTEM_KEY_REFERENCEFILE, "");
        if ("".equals(rfl)) {
            rfl = webappLibPath;
        }
        referencesLibPath = rfl;
       
        //log("    " + SYSTEM_KEY_CLASSFILE + ": " + classFileLocationPath);
        log(" " + SYSTEM_KEY_PROPERTYFILE + ": " + propertyFileLocationPath);
        //log("   " + SYSTEM_KEY_SOURCEFILE + ": " + sourceFileLocationPath);
        log("" + SYSTEM_KEY_REFERENCEFILE + ": " + referencesLibPath);
       
        //make sure there are files in the property file location
        String[] fileNames = (new File(propertyFileLocationPath)).list();
        if (fileNames == null || fileNames.length == 0) {
            log("ERROR ERROR ERROR => There are no property files in the property file location.");
            log("Stop initializtion process. Exit now ...");
        }
       
        if (!FileUtil.pathExistAndHasFiles(referencesLibPath)) {
            log("ERROR ERROR ERROR => There are no jar files in the lib location.");
            log("Stop initializtion process. Exit now ...");
        }
       
        //initialized other stuff if not started
        logConfig = LogConfig.getInstance(propertyFileLocationPath);
        log = LogUtil.getLogger(ApplicationConfig.class.getName());
    }
   
    private void initializeORM() {
        //initialized other stuff if not started
        log = LogUtil.getLogger(ApplicationConfig.class.getName());
        LogUtil.enableLogger();
    }
   
    private static String detectContextName(String path) {
        if (path.endsWith(File.separator)) path = path.substring(0, path.length() -1);
        return path.substring(path.lastIndexOf(File.separatorChar) + 1);
    }
   
    private LogConfig logConfig;
    private long applicationStartTime = 0L;
    private boolean applicationStarted;
    private String applicationPath;
    private String contextName;
    private String classFileLocationPath;
    private String propertyFileLocationPath;
    private String sourceFileLocationPath;
    private String webappLibPath;
    private String pluginsPath;
    private String referencesLibPath;
    private ReferenceDataLoader rdLoader = null;
}
TOP

Related Classes of com.scooterframework.admin.ApplicationConfig

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.