Package org.dtk.util

Source Code of org.dtk.util.ContextListener

package org.dtk.util;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.dtk.resources.Build;
import org.dtk.resources.Dependencies;
import org.dtk.resources.Packages;
import org.dtk.resources.build.BuildRequest;
import org.dtk.resources.build.manager.BuildStatusManager;
import org.dtk.resources.packages.PackageRepository;

/**
* Simple context listener to set package paths context parameter
* on the single instance of the package repository.
*
* @author James Thomas
*/

public class ContextListener implements ServletContextListener {

  /** Current application context, reference passed in during initialization */
  protected ServletContext currentContext;
 
  /** System property for fixed build result cache path */
  protected static final String cachePathParam = "cachepath";

  /** User property to override default location for package repository */
  protected static final String packageRepoPathParam = "packagespath";
 
  /** Relative path to custom Dojo build script */
  protected static final String buildModulePathParam = "/js/build/bdbuild/";

  /** Relative path to custom Dojo build script */
  protected static final String loaderModulePathParam = "/js/build/amd_loader/dojo.js";
 
  /** Relative path to custom build parameters configuration */
  protected static final String buildParametersConfig = "/WEB-INF/config/build_options.json";

  /** Relative directory path for default package details directory */
  protected static final String defaultPackageRepoPath = "/WEB-INF/config/packages/";
 
  /** Relative directory path for transform jobs profile text */
  protected static final String transformJobsRelativePath = "/WEB-INF/resources/transform_jobs.txt";
 
  /** Class loggers which should be logged to a file **/
  protected static final List<String> fileLoggingClasses = Arrays.asList(
    Feedback.class.getName(),
    Build.class.getName(),
    Dependencies.class.getName(),
    Packages.class.getName()
  );
 
  /** Log filename format for application logs **/
  public static final String LOG_FILE_FORMAT = "logs/%1$s.log";
 
  /** Error message when exception caught adding log file handler **/
  protected static final String LOG_HANDLER_ERROR = "Unable to add file handler to logger for %1$s. " +
    "All application logs will be lost when the application exits.";
 
  /** Log path information statement **/
  protected static final String LOG_HANDLER_INFO = "Logging all logs from %1$s to '%2$s'";
 
  /** Listener logging class */
  protected static Logger logger = Logger.getLogger(ContextListener.class.getName());
 
  @Override
  public void contextDestroyed(ServletContextEvent contextEvent) {
    // Intentionally empty...
  }

  /**
   * Event listener fired when context is initialised. Check for existance
   * of correct context parameter, confirming this is a valid parameter,
   * and then set of the single instance of the package repository.
   *
   * @param contextEvent - Handle to servlet context
   */
  @Override
  public void contextInitialized(ServletContextEvent contextEvent) {
    currentContext = contextEvent.getServletContext();
   
    // Check for user configuration overrides to cache and package
    // directories
    String cachePath = getCacheDirectoryPath();
    String packagePath = getPackageRepoPath();
   
    String builderModulePath = currentContext.getRealPath(buildModulePathParam);
    String loaderModulePath = currentContext.getRealPath(loaderModulePathParam);
    BuildRequest.transformJobsPaths = currentContext.getRealPath(transformJobsRelativePath);

    PackageRepository packageRepo = PackageRepository.getInstance();
    packageRepo.setPackageBaseLocation(packagePath);
    packageRepo.setBuildParametersLocation(currentContext.getRealPath(buildParametersConfig));
   
    BuildStatusManager buildStatusManager = BuildStatusManager.getInstance();
    buildStatusManager.setBuildResultCachePath(cachePath);
    buildStatusManager.setBuildModulePath(builderModulePath);
    buildStatusManager.setLoaderModulePath(loaderModulePath);
   
    // Add file handlers to certain class loggers
    initialiseLoggingHandlers();
  }
 
  /**
   * Add file handlers for all configured class loggers. All these logs will
   * be persisted in appending log files.
   */
  protected void initialiseLoggingHandlers()  {
    for(String classLoggerName: fileLoggingClasses) {
      Logger classLogger = Logger.getLogger(classLoggerName);
      try {
        String logFile = String.format(LOG_FILE_FORMAT, classLoggerName);       
        // Set log file output and change format from XML to simple text.
        FileHandler handler = new FileHandler(logFile, true);
        handler.setFormatter(new SimpleFormatter());
       
        classLogger.addHandler(handler);
        logger.log(Level.INFO, String.format(LOG_HANDLER_INFO, classLoggerName, logFile));
      } catch (IOException io) {
        logger.log(Level.WARNING, String.format(LOG_HANDLER_ERROR, classLoggerName));
     
    }   
  };
 
    /**
     * Retrieve the cache directory for build results. By default, create a new temporary
     * directory to hold the build results unless the user has manually specified the location
     * using the context parameter property or system property, cachepath.
     *
     * @return Directory path for built result cache
     */
    protected String getCacheDirectoryPath() {
      String dirPath = lookupUsersConfigParam(cachePathParam);

      // If parameter wasn't specified or it's an empty string, create a new temporary
      // cache path.
    if (isParameterMissing(dirPath)) {
      try {
        dirPath = FileUtil.createTempDirectory().getAbsolutePath();
      } catch (IOException ioe) {
        throw new NullPointerException("Fatal error create temporary cache path, try to specify this " +
          "manually using context parameter or system property: cachepath");
      }
    }
     
    // Sanity check the path value to ensure it exists and is a directory.   
    if (!isValidDirectory(dirPath)) {
      throw new NullPointerException("Cache path, "+ dirPath +", does not exist or is not a directory.");
    }
   
        return dirPath;
    }
   
    /**
     * Retrieve the directory path for the package repository. This value
     * may be overridden by the user, if missing we fall back to a local default
     * value, packages_path, as a init or system parameter.
     *
     * Value will be checked to ensure it's an actual directory and errors
     * thrown if not.
     *
     * @return Directory path to package repository 
     */
    protected String getPackageRepoPath() {
      String dirPath = lookupUsersConfigParam(packageRepoPathParam);
     
      // If user hasn't given a path, use default
      if (isParameterMissing(dirPath)) {
        dirPath = currentContext.getRealPath(defaultPackageRepoPath);
      }
     
      if (!isValidDirectory(dirPath)) {
        throw new NullPointerException("Packages path, "+ dirPath +", does not exist or is not a directory.");
      }       
     
      return dirPath;
    }
   
    /**
     * Look up a user configurable parameter value.
     *
     * Properties are resolved as init parameters in the local application context,
     * failing back to system properties if missing no value was found.
     *
     * We also resolve environment variables here in case these are included in
     * the path string.
     *
     * @return User's cache path parameter if available
     */
    protected String lookupUsersConfigParam(String configParamName) {
    String configParam = currentContext.getInitParameter(configParamName);
   
    if (isParameterMissing(configParam)) {
      configParam = System.getProperty(configParamName);
    }
   
    // Resolve environment variables in user's parameter to
    // actual values.
    configParam = FileUtil.resolveEnvironmentVariables(configParam);
   
      return configParam;
    }   
   
    /**
     * Confirm the path parameter points to an existing directory
     * on the system.
     *
     * @param dirPath - Path to directory
     * @return Path is a valid directory
     */
    protected boolean isValidDirectory(String dirPath) {
    File dirPathFile = new File(dirPath);   
    return (dirPathFile.exists() && dirPathFile.isDirectory());
    }
   
    /**
     * Missing parameter values are either null values of empty
     * strings.
     *
     * @param parameterValue - User configuration parameter value
     * @return Parameter is missing valid value
     */
    private boolean isParameterMissing(String parameterValue) {
      return (parameterValue == null || parameterValue.isEmpty());
    }
}
TOP

Related Classes of org.dtk.util.ContextListener

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.