Package org.jostraca

Source Code of org.jostraca.Jostraca

/*
* Name:    Jostraca
* Authors: Richard Rodger
*
* Copyright (c) 2000-2006 Richard Rodger
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/

// package
package org.jostraca;


// import
import org.jostraca.util.CommandLineUserMessageHandler;
import org.jostraca.util.FileUtil;
import org.jostraca.util.ErrorUtil;
import org.jostraca.util.PropertySet;
import org.jostraca.util.Standard;
import org.jostraca.util.StandardException;
import org.jostraca.util.UserMessageHandler;
import org.jostraca.util.TextUtil;
import org.jostraca.util.ArgUtil;

import org.jostraca.comp.gnu.getopt.Getopt;

import java.io.File;
import java.io.IOException;

import java.util.List;
import java.util.ArrayList;


/** Command line user interface to the Jostraca system.
*/
public class Jostraca {   
 
  // public static

  public static final String CN = Jostraca.class.getName();

  // Command Line Options
  // ...

  // REVIEW: -S for do not save code writer

  public static final char ARG_CONFIG            = 'f'; // primary configuration file
  public static final char ARG_ADD_CONFIG        = 'F'; // additional configuration files
  public static final char ARG_WRITER_FORMAT     = 'W'; // writer format file
  public static final char ARG_TEMPLATE_LIST     = 't'; // text file listing templates one per line
  public static final char ARG_OUTPUT_FOLDER     = 'o'; // output folder for generated files
  public static final char ARG_WORK_FOLDER       = 'w'; // work folder for code writer programs
  public static final char ARG_ARGUMENT          = 'a'; // argument for code writer
  public static final char ARG_DUMP              = 'd'; // dump internal state
  public static final char ARG_DEFINE            = 'D'; // define a setting on the command line
  public static final char ARG_BACKUP_FOLDER     = 'b'; // backup folder for previously generated files
  public static final char ARG_ALL_TEMPLATES     = 'l'; // everything on the command line is a template
  public static final char ARG_NO_BACKUP         = 'B'; // do not make backups of previously generated files
  public static final char ARG_LOW_VERBOSE       = 'V'; // display lots of debugging info
  public static final char ARG_HIGH_VERBOSE      = 'v'; // display minimal info
  public static final char ARG_COMPILE           = 'c'; // force template compilation
  public static final char ARG_NO_COMPILE        = 'C'; // prevent template compilation
  public static final char ARG_GENERATE          = 'g'; // force generation
  public static final char ARG_NO_GENERATE       = 'G'; // prevent generation
  public static final char ARG_TEMPLATE_DOC      = 'h'; // display template documentation, if any
  public static final char ARG_NON_STANDARD      = 'X'; // specify a non standard option
  public static final char ARG_META_FOLDER       = 'm'; // specify meta folder
  public static final char ARG_NO_META           = 'M'; // specify meta folder

  public static final String SPECIAL_ARG_CHECK   = "check";   // check installation
  public static final String SPECIAL_ARG_VERSION = "version"; // display version info
  public static final String SPECIAL_ARG_HELP    = "help";    // display help

  // non standard options
  public static final String NSA_old    = "old";    // use old template processing
  public static final String NSA_noexit = "noexit"; // do not exit JVM after running
  public static final String NSA_track  = "track:"; // enable and set tracking file with syntax track:filepath

  public static final String DEFAULT_ConfigPath = "conf/system.conf"// relative to jostraca folder




  // private static

  private static final String JOSTRACA_TEMPLATE_SUFFIX = ".jtm";
  private static final String CMD_NAME                 = "Jostraca";      

  // options spec string - colon => has args
  private static final String CMD_SPEC_Options         
    = ARG_CONFIG          + Standard.COLON
    + ARG_ADD_CONFIG      + Standard.COLON
    + ARG_WRITER_FORMAT   + Standard.COLON
    + ARG_TEMPLATE_LIST   + Standard.COLON
    + ARG_OUTPUT_FOLDER   + Standard.COLON
    + ARG_WORK_FOLDER     + Standard.COLON
    + ARG_ARGUMENT        + Standard.COLON
    + ARG_DUMP            + Standard.COLON
    + ARG_DEFINE          + Standard.COLON
    + ARG_BACKUP_FOLDER   + Standard.COLON
    + ARG_META_FOLDER     + Standard.COLON
    + ARG_ALL_TEMPLATES
    + ARG_NO_BACKUP
    + ARG_LOW_VERBOSE
    + ARG_HIGH_VERBOSE
    + ARG_NO_COMPILE
    + ARG_COMPILE
    + ARG_NO_GENERATE
    + ARG_GENERATE
    + ARG_NO_META
    + ARG_TEMPLATE_DOC
    + ARG_NON_STANDARD    + Standard.COLON
    ;



  private static final boolean DEFAULT_CheckInstallation = false;

  // relays messages to user
  private static CommandLineUserMessageHandler sUserMessageHandler
    = new CommandLineUserMessageHandler();

  private static boolean sExitProgram = true; // by default, terminate the JVM on completion




  // private instance
  //private String      iConfigPath            = DEFAULT_ConfigPath;        // path to system config file
  //private PropertySet iConfig                = new PropertySet();         // PropertySet representing config file data
  //private PropertySet iCmdLine               = new PropertySet();         // PropertySet representing cmd line options
  //private Vector      iTemplatePaths         = new Vector();              // list of template paths
  //private Vector      iAdditionalConfigPaths = new Vector();              // additional config file paths
  private boolean     iCheckInstallation     = DEFAULT_CheckInstallation; // check installation valid flag




  // public methods

  /** Set path to configuration file.
   *  @param pConfigPath file path
   */
  /*
  public void setConfigPath( String pConfigPath ) {
    if( ErrorUtil.not_null( pConfigPath, "pConfigPath" ) ) {
      iConfigPath = pConfigPath;
    }
  }
  */


  /** Get path to config file. */
  /*
  public String getConfigPath() {
    return iConfigPath;
  }
  */


  /** Add an additional config path.
   *  These are applied in order of presentation on command line to the
   *  system config file before other config settings are applied.
   *  @param pAdditionalConfigPath additional configuration file path
   */
  /*
  public void addAdditionalConfigPath( String pAdditionalConfigPath ) {
    if( ErrorUtil.not_null( pAdditionalConfigPath, "pAdditionalConfigPath" ) ) {
      iAdditionalConfigPaths.addElement( pAdditionalConfigPath );
    }
  }
  */


  /** Set system config PropertySet.
   *  @param pConfig PropertySet of config data
   */
  /*
  public void setSystemConfig( PropertySet pConfig ) {
    if( ErrorUtil.not_null( pConfig, "pConfig" ) ) {
      iConfig = pConfig;
    }
  }
  */


  /** Get system config PropertySet. */
  /*
  public PropertySet getSystemConfig() {
    return iConfig;
  }
  */


  /** Get UserMessageHandler that recieves a series of plain
   *  text messages for the user. 
   */
  public UserMessageHandler getUserMessageHandler() {
    return sUserMessageHandler;
  }



  /** Set CheckInstallation mode.
   *  true => just check install and don't try to generate anything
   *  @param pCheckInstallation boolean
   */
  public void setCheckInstallation( boolean pCheckInstallation ) {
    iCheckInstallation = pCheckInstallation;
  }



  /** Get CheckInstallation mode. */
  public boolean getCheckInstallation() {
    return iCheckInstallation;
  }



  /** Set command line PropertySet.
   *  @param pCmdLine PropertySet
   */
  /*
  public void setCmdLinePropertySet( PropertySet pCmdLine ) {
    if( ErrorUtil.not_null( pCmdLine, "pCmdLine" ) ) {
      iCmdLine = pCmdLine;
    }
  }
  */


  /** Get command line PropertySet. */
  /*
  public PropertySet getCmdLinePropertySet() {
    return iCmdLine;
  }
  */


  /** Clear paths to template files. */
  /*
  public void clearTemplatePaths() {
    iTemplatePaths.removeAllElements();
  }
  */


  /** Add paths to template files using a List of Strings or TemplatePath objects.
   *  @param pTemplates          list of templates to modify
   *  @param pTemplatePathsToAdd paths to template files
   */
  public static void addTemplatePaths( List pTemplates, List pTemplatePathsToAdd ) throws TemplateException {
    if( ErrorUtil.is_null( pTemplatePathsToAdd, "pTemplatePaths" ) ) {
      // REVIEW: need to determine a standard behaviour in Jostraca object for bad args
      return; // do not accept null value
    }

    Object o            = null;
    String templatePath = null;
    int    numTemplates = pTemplatePathsToAdd.size();
    for( int templateI = 0; templateI < numTemplates; templateI++ ) {
      o = (Object) pTemplatePathsToAdd.get( templateI );
      if( null == o ) {
        continue;
      }
      else if( o instanceof String ) {
        templatePath = String.valueOf(o).trim();
        BasicTemplatePath btp = new BasicTemplatePath( templatePath );
        pTemplates.add( btp );
      }
      else if( o instanceof TemplatePath ) {
        pTemplates.add( o );
      }
    }
  }



  /** Get paths to template files. */
  /*
  public List getTemplatePaths() {
    return iTemplatePaths;
  }
  */


  /** Send informational text message to user.
   *  @param pMessage text
   */
  public void displayInfo( String pMessage ) {
    sUserMessageHandler.info( pMessage );
  }



  /** Send error text message to user.
   *  @param pMessage text
   */
  public static void displayErr( String pMessage ) {
    sUserMessageHandler.error( "PROBLEM: ", pMessage );
  }



  /** Send exception description to user.
   *  @param pException exception
   */
  public static void displayErr( Exception pException ) {
    sUserMessageHandler.error( "PROBLEM: ", pException );
  }



  // REVIEW: kill
  /** Display user error messages.
   *  @param pUserErrors list of String text messages
   */
  /*
  public static void displayUserErrors( Vector pUserErrors ) {
    try {
      int numErr = pUserErrors.size();
      if( 0 < numErr ) {
        sUserMessageHandler.error("Generation failed for some templates due to the following errors:");
        for(int errI = 0; errI < numErr; errI++) {
          sUserMessageHandler.error( String.valueOf( pUserErrors.elementAt(errI) ) );
        }
      }
    }
    catch( Exception e ) {
      sUserMessageHandler.error( "Generation failed; internal error: org.jostraca.Jostraca(@line:342).", e );
    }
  }
  */


  /** Display installation ok message. */
  public static final void displayInstallationOKMessage( String pHomeFolder ) {
    String homeFolder     = pHomeFolder;
    File   homeFolderFile = new File( pHomeFolder )
    try {
      homeFolder = homeFolderFile.getCanonicalPath();
    }
    catch( IOException ioe ) {
      homeFolder = homeFolderFile.getAbsolutePath();
    }

    sUserMessageHandler.info( "Jostraca Installation OK." );   
    sUserMessageHandler.info( "Home folder: '"+homeFolder+"'." );   
  }



  /** Display version information. */
  public static final void displayVersion() {
    sUserMessageHandler.info
      (
       "\n"
       +"Jostraca, version "+Service.VERSION_NUMBER+" (release "+Service.RELEASE_NAME+")\n"
       +"\n"
       +"Jostraca may be distributed only under the terms and \n"
       +"conditions of the GNU General Public License.\n"
       +"(see http://www.gnu.org/copyleft/gpl.html or LICENSE.txt)\n"
       +"\n"
       +"Documentation can be found in the doc folder of the\n"
       +"distribution or at: http://www.jostraca.org.\n"
       +"\n"
       +"Enter jostraca -help for a list of command line options.\n"
       );   
  }



  /** Display usage. */
  private static final void displayUsage() {
    sUserMessageHandler.info
      (
       "usage: \n"
       +"jostraca [OPTIONS] template[.jtm] [TEMPLATE_OPTIONS]\n"
       +"jostraca -l [OPTIONS] template1[.jtm] template2[.jtm] ...\n"
       +"\n"
       +"options: \n"
       +"         -" + ARG_OUTPUT_FOLDER     + " output-folder         output folder\n"
       +"         -" + ARG_WORK_FOLDER       + " work-folder           work folder\n"
       +"         -" + ARG_ALL_TEMPLATES     + "                       all arguments are templates\n"
       +"         -" + ARG_ARGUMENT          + " \"TEMPLATE_OPTIONS\"    code writer options\n"
       +"         -" + ARG_TEMPLATE_LIST     + " file                  template list file\n"
       +"\n"
       +"         -" + ARG_BACKUP_FOLDER     + " folder                backup folder\n"
       +"         -" + ARG_NO_BACKUP         + "                       don't backup\n"
       +"         -" + ARG_META_FOLDER       + " folder                metadata folder\n"
       +"         -" + ARG_NO_META           + "                       don't store metadata\n"
       +"\n"
       +"         -" + ARG_COMPILE           + "                       compile template\n"
       +"         -" + ARG_NO_COMPILE        + "                       don't compile template\n"
       +"         -" + ARG_GENERATE          + "                       generate output files\n"
       +"         -" + ARG_NO_GENERATE       + "                       don't generate output files\n"
       +"\n"
       +"         -" + ARG_WRITER_FORMAT     + " file                  writer format file\n"
       +"         -" + ARG_ADD_CONFIG        + " file                  additional configuration files\n"
       +"         -" + ARG_CONFIG            + " file                  configuration file\n"
       +"         -" + ARG_DEFINE            + "some.Option=value      set an option explicitly\n"
       +"         -" + ARG_NON_STANDARD      + " option-list           non-standard options\n"
       +"           " +                        " old : use old template processor\n"
       +"\n"
       +"         -" + ARG_HIGH_VERBOSE      + "                       verbose\n"
       +"         -" + ARG_LOW_VERBOSE       + "                       quiet\n"
       +"         -" + ARG_DUMP              + " settings,template     dump template and/or settings\n"
       +"         -" + ARG_TEMPLATE_DOC      + " template[.jtm]        show template documentation\n"
       +"\n"
       +"jostraca -" + SPECIAL_ARG_VERSION   + "                 display version information\n"
       +"jostraca -" + SPECIAL_ARG_HELP      + "                    display usage information\n"
       +"jostraca -" + SPECIAL_ARG_CHECK     + "                   check installation"
       );
  }


  private static final void displayQuickUsage() {
    sUserMessageHandler.info( "\n(jostraca -help gives a list of command line options)" );
  }




  // private methods

  private void handleCommandLineOptions( PropertySet pCmdLineOptions ) throws Exception {
    try {
      String msgLevel = pCmdLineOptions.get( Property.main_MessageLevel );
      if( "".equals( msgLevel ) ) {
        sUserMessageHandler.setThreshold( UserMessageHandler.INFO );
      }
      else {
        sUserMessageHandler.setThreshold( UserMessageHandler.TypeNameUtil.getTypeForName( msgLevel ) );
      }

    }
    catch( TemplateException te ) {
      if( StandardException.Code.CAT_user == te.getCat() ) {
        displayErr( te.getMessage() );
        exitProgram(1);
      }
      else {
        throw te;
      }
    }
  }


  public static PropertySet parseCommandLine( String pArgString, ArrayList pTemplates, ArrayList pAdditionalConfig ) throws Exception {
    String[] args = ArgUtil.splitQuoted( pArgString );
    return parseCommandLine( args, pTemplates, pAdditionalConfig );
  }


  /** Parse cmd line used to invoke Jostraca.
   *  @param pArgs array of command line arguments
   */
  public static PropertySet parseCommandLine( String[] pArgs, ArrayList pTemplates, ArrayList pAdditionalConfig ) throws Exception {

    boolean      argumentsAreTemplateNames = false;
    boolean      usingTemplateListFile     = false;
    StringBuffer codeWriterOptions         = new StringBuffer();
    boolean      usingDefaultConf          = true; // unless -f is found
    PropertySet  cmdLineOptions            = new PropertySet();
    String       configPath                = null;
    ArrayList    additionalConfigFiles     = new ArrayList();
    ArrayList    cmdlinetemplates          = new ArrayList();


    // parse command line
    Getopt g = new Getopt( CMD_NAME, pArgs, ":"+CMD_SPEC_Options );
    g.setOpterr( false ); // handle errors manually
    int    c;
    String arg;

    while( -1 != ( c = g.getopt() ) ) {

      switch( c ) {

      case ARG_CONFIG : // configuration file
        configPath = g.getOptarg();
        usingDefaultConf = false;
        break;

      case ARG_ADD_CONFIG : // additional configuration file
        String addConfigPath = g.getOptarg();
        pAdditionalConfig.add( addConfigPath );
        break;

      case ARG_WRITER_FORMAT : // writer format
        String writerFormatPath = g.getOptarg().trim();
        checkDataFile( "WriterFormat", writerFormatPath );
        cmdLineOptions.set( Property.main_CodeWriterFormat, writerFormatPath );
        break;

      case ARG_TEMPLATE_DOC : // show documentation
        cmdLineOptions.set( Property.main_ShowDocumentation, Standard.YES );
        break;

      case ARG_OUTPUT_FOLDER : // output folder
        String outputFolder = g.getOptarg().trim();
        checkFolder( "Output", outputFolder );
        cmdLineOptions.set( Property.main_OutputFolder, outputFolder );
        break;

      case ARG_WORK_FOLDER : // work folder
        String workFolder = g.getOptarg().trim();
        checkFolder( "Work", workFolder );
        cmdLineOptions.set( Property.main_WorkFolder, workFolder );
        break;

      case ARG_TEMPLATE_LIST : // templates listed in separate file
        String templateList = g.getOptarg().trim();
        checkDataFile( "Template list", templateList );
        addTemplatesFromFile( new File( templateList ), cmdlinetemplates );
        usingTemplateListFile = true;
        break;

      case ARG_ARGUMENT : // template arguments
        codeWriterOptions.append( g.getOptarg() );
        codeWriterOptions.append( Standard.SPACE );
        break;

      case ARG_ALL_TEMPLATES : // all arguments are templates
        argumentsAreTemplateNames = true;
        break;

      case ARG_BACKUP_FOLDER : // set backup folder and make backups
        String backupFolder = g.getOptarg().trim();
        cmdLineOptions.set( Property.main_BackupFolder, backupFolder );
        cmdLineOptions.set( Property.main_MakeBackup, Standard.YES );
        break;

      case ARG_NO_BACKUP : // don't backup
        cmdLineOptions.set( Property.main_MakeBackup, Standard.NO );
        break;

      case ARG_META_FOLDER : // set meta folder and store metadata
        String metaFolder = g.getOptarg().trim();
        cmdLineOptions.set( Property.main_MetaFolder, metaFolder );
        cmdLineOptions.set( Property.main_EnableMeta, Standard.YES );
        break;

      case ARG_NO_META : // don't store metadata
        cmdLineOptions.set( Property.main_EnableMeta, Standard.NO );
        break;

      case ARG_COMPILE : // compile code writer
        cmdLineOptions.set( Property.main_CompileCodeWriter, Standard.YES );
        break;

      case ARG_NO_COMPILE : // don't compile code writer
        cmdLineOptions.set( Property.main_CompileCodeWriter, Standard.NO );
        break;

      case ARG_GENERATE : // execute code writer, that is, generate output files
        cmdLineOptions.set( Property.main_ExecuteCodeWriter, Standard.YES );
        break;

      case ARG_NO_GENERATE : // don't execute code writer, that is, don't generate output files
        cmdLineOptions.set( Property.main_ExecuteCodeWriter, Standard.NO );
        break;

      case ARG_DUMP : // dump template, settings, etc
        String dumpSpec = g.getOptarg().trim();
        Service.parseDumpSpec( dumpSpec, cmdLineOptions );
        break;

      case ARG_DEFINE : // config setting
        // REVIEW: this parsing should be somewhere else, probably TextUtil
        String nameValue = g.getOptarg().trim();
        int equalsPos = nameValue.indexOf("=");
        if( -1 != equalsPos ) {
          cmdLineOptions.set
            ( nameValue.substring(0, equalsPos).trim(),
              nameValue.substring(equalsPos + 1).trim()
              );
        }
        break;

      case ARG_NON_STANDARD : // non-standard options
        String nsOptions = g.getOptarg();
        parseNonStandardOptions( nsOptions, cmdLineOptions, sUserMessageHandler );
        break;

      case ARG_LOW_VERBOSE : // low verbosity
        cmdLineOptions.set( Property.main_MessageLevel, UserMessageHandler.TypeNameUtil.getNameForType( UserMessageHandler.WARN ) );
        break;

      case ARG_HIGH_VERBOSE : // high verbosity
        cmdLineOptions.set( Property.main_MessageLevel, UserMessageHandler.TypeNameUtil.getNameForType( UserMessageHandler.DEBUG ) );
        break;

      case ':': // missing argument to option
        throw new JostracaException( "Option " + (char)g.getOptopt() + " requires an argument." );

      default: // everything else is a template or a template srgument
        break;
      }
    }
   
    // get template path specifiers and arguments
    int start   = g.getOptind();
    int numArgs = pArgs.length;
    for( int tpsI = start; tpsI < numArgs; tpsI++ ) {
      String argument = pArgs[tpsI].trim();
      if( ( ( !usingTemplateListFile && start == tpsI )
            || argumentsAreTemplateNames
            || argument.toLowerCase().endsWith( JOSTRACA_TEMPLATE_SUFFIX ) ) )
        {
          cmdlinetemplates.add( argument );
        }
      else {
        codeWriterOptions.append( TextUtil.quoteSpaces( argument ) );
        codeWriterOptions.append( Standard.SPACE );
      }
    }

    addTemplatePaths( pTemplates, cmdlinetemplates );

    cmdLineOptions.set( Property.main_CodeWriterOptions, codeWriterOptions.toString() );
     
    cmdLineOptions.set( Property.jostraca_ConfigFile, configPath );
    cmdLineOptions.set( Property.jostraca_ConfigFolder, resolveConfigFolder( configPath ) );

    return cmdLineOptions;
  }


 
  /** Handle non-standard options.
   *  @param pNSA non-standard options list
   *  @param pCmdLineOptions settings placed here
   *  @param pUserMessageHandler user messages concerning non-standard option sent here
   */
  private static void parseNonStandardOptions( String             pNSA,
                                               PropertySet        pCmdLineOptions,
                                               UserMessageHandler pUserMessageHandler )
  {
    if( null == pNSA ) {
      displayErr( "Please specify an option-list for -"+ARG_NON_STANDARD+"." );
    }

    if( -1 != pNSA.indexOf( NSA_old ) ) {
      pCmdLineOptions.set( Property.jostraca_old, Standard.YES );
      pUserMessageHandler.info( "Using old template processor." );
    }

    if( -1 != pNSA.indexOf( NSA_noexit ) ) {
      pCmdLineOptions.set( Property.jostraca_noexit, Standard.YES );
      sExitProgram = false;
    }

    if( pNSA.startsWith( NSA_track ) ) {
      String filepath = pNSA.substring( NSA_track.length() );
      File   trackF       = new File( filepath );
      Service.activateTracking( trackF );
      pCmdLineOptions.set( Property.jostraca_TrackFile, trackF.getAbsolutePath() );
    }

  }



  /** Validate file path:
   *  1. Check file exists.
   *  2. Check file is readable
   *  @param pFileDescription user friendly name for file
   *  @param pDataFilePath data file path to check
   */
  private static void checkDataFile( String pFileDescription, String pDataFilePath ) {
    File dataFilePath = new File( pDataFilePath );
    if( ! dataFilePath.exists() ) {
      displayErr( pFileDescription + " file '"+pDataFilePath+"' does not exist." );
      displayQuickUsage();
      exitProgram(1);
    }
    if( ! dataFilePath.canRead() ) {
      displayErr( pFileDescription + " file '"+pDataFilePath+"' permissions prevent reading." );
      displayQuickUsage();
      exitProgram(1);
    }
  }



  /** Validate folder for output:
   *  1. Check folder exists.
   *  2. Check folder is writable
   *  @param pFolderDescription user friendly name for folder
   *  @param pFolderPath folder path to check
   */
  private static void checkFolder( String pFolderDescription, String pFolderPath ) {
    File folderPath = new File( pFolderPath );
    if( ! folderPath.exists() ) {
      displayErr( pFolderDescription + " folder '"+pFolderPath+"' does not exist." );
      displayQuickUsage();
      exitProgram(1);
    }
    if( ! folderPath.canWrite() ) {
      displayErr( pFolderDescription + " folder '"+pFolderPath+"' permissions prevent writing." );
      displayQuickUsage();
      exitProgram(1);
    }
  }



  /** Add templates from file.
   *  @param pFile path to file containing template name list
   */
  private static void addTemplatesFromFile( File pFile, ArrayList pTemplates ) {
    addTemplatePaths( pTemplates, Service.buildTemplateListFromFile( pFile ) );
  }


  // REVIEW: this should be done in Service
  // REVIEW: how to handle main.Location
  /** Load base config files: system.conf and local.conf.
   *  @param pUseDefaultConf true => try to use default if config path is not specified
   */
    /*
  private PropertySet loadBaseConfigFiles( String pConfigPath, boolean pUseDefaultConf ) throws Exception {

    // load system config file - use default if -f was not specified
    String configPath = pConfigPath
    File   configFile = new File( configPath );

    if( !pUseDefaultConf ) {
      checkDataFile( "System Configuration", configPath );
    }

    PropertySet system = new PropertySet();

    try {
      system.load( configFile );
      Tools.produceJostracaLocation( system, configFile );
    }
    catch( Exception e ) {
      system = DefaultPropertySets.makeSystemPropertySet();
    }

    PropertySet local           = new PropertySet();
    File        localConfigFile = new File( getConfigFolder(), system.get( Property.jostraca_LocalConfigFileName ) );
    if( localConfigFile.exists() && !localConfigFile.isDirectory() ) {
      local.load( localConfigFile  );
      system.overrideWith( local );
    }
    else {
      // if local.conf does not exist, ignore
    }

    return system;
  }
    */





  /** Validate config file
   *  @param pConfig configuration to validate
   *  REVIEW: what relation to Service.validateMergedPropertySet?
   */
  private void validateConfig( PropertySet pConfig ) {
   
    // this expression defaults to yes unless it is actually evaluates to no
    if( ! pConfig.isNo( Property.jostraca_strict_version ) ) {

      // check version number - only accept version 0.1
      // this may change as time progresses to something more useful
      String version = pConfig.get( Property.jostraca_version );
      if( ! version.startsWith( Service.VERSION_NUMBER ) ) {
        if( version.startsWith( "0.3" )
            || version.startsWith( "0.2" )
            || version.startsWith( "0.1" )
            ) {
          // compatible
        }
        else {
          displayErr("Jostraca version "+Service.VERSION_NUMBER+" configuration file required.");
          displayQuickUsage();
          exitProgram(1);
        }
      }
    }
  }



  /** If version info or help requested, display and exit.
   *  @param pArgs command line args
   */
  private final void handleSpecialArgs( String[] pArgs ) {

    // WARNING: Hack
    // The standard distribution uses a script to run
    // Jostraca. This script places -f path as the first
    // two arguments. Hence the -version or -help args
    // can be the first or third arguments.

    if( 0 < pArgs.length ) {
      String firstArg = pArgs[0];
      String checkArg = firstArg;

      if( (Standard.MINUS+ARG_CONFIG).equals( firstArg ) && 3 == pArgs.length ) {
        checkArg = pArgs[2];
      }

      if( (Standard.MINUS+SPECIAL_ARG_VERSION).equalsIgnoreCase( checkArg )
          || (Standard.MINUS+Standard.MINUS+SPECIAL_ARG_VERSION).equalsIgnoreCase( checkArg )          
          ) {
        displayVersion();
        exitProgram(0);
      }

      else if( (Standard.MINUS+SPECIAL_ARG_HELP).equalsIgnoreCase( checkArg )
          || (Standard.MINUS+Standard.MINUS+SPECIAL_ARG_HELP).equalsIgnoreCase( checkArg )
          ) {
        displayUsage();
        exitProgram(0);
      }

      else if( (Standard.MINUS+SPECIAL_ARG_CHECK).equalsIgnoreCase( checkArg )
          || (Standard.MINUS+Standard.MINUS+SPECIAL_ARG_CHECK).equalsIgnoreCase( checkArg )
          ) {
        setCheckInstallation( true );
      }
    }
  }
 

  /** Get path to config folder. */
  private static String resolveConfigFolder( String pConfigPath ) {
    return FileUtil.getParent( pConfigPath );
  }


  /* Private Methods >> */




  /* Main << */

  /** Main entry point to command line Jostraca application.
   *  @param pArgs command line arguments
   */
  public static void main( String[] pArgs ) {
    Throwable t = null;
   
    try {
      try {           
        execute( pArgs );
      }
      catch( StandardException se ) {
        displayErr( se );
      }
    }
    catch( Throwable tt ) {
      t = tt;
    }

    // something is terribly wrong if we get here
    // assume everything is broken and only use standard java
    if( null != t ) {
      System.out.println( "Jostraca Internal Error:" );
      t.printStackTrace();
    }
  }



  /** Main execution point.
   *  @param pArgs command line arguments
   */
  public static void execute( String[] pArgs ) throws Exception {

    // create new cmd line app and parse cmd line args
    Jostraca js = new Jostraca();
    js.handleSpecialArgs( pArgs );

    ArrayList   templatePaths    = new ArrayList()
    ArrayList   additionalConfig = new ArrayList()
    PropertySet cmdLineOptions   = js.parseCommandLine( pArgs, templatePaths, additionalConfig );
    js.handleCommandLineOptions( cmdLineOptions );

    String configFolder = cmdLineOptions.get( Property.jostraca_ConfigFolder );

    // create new service object and set templates
    Service s = new Service();
    s.loadConfigFromFolder( new File( configFolder ), additionalConfig );


    // are we just checking the install
    if( js.getCheckInstallation() ) {
      displayVersion();
      displayInstallationOKMessage( s.getCurrentConfig().get(Property.jostraca_Location) );

      // REVIEW: program exit codes should be defined in Standard
      exitProgram(0);
    }

    // at least one template must be specified
    if( 0 == templatePaths.size() ) {
      displayErr("No templates specified.");
      displayQuickUsage();
      exitProgram(1);
    }


    s.setTemplatePaths( templatePaths );

    // set standard properties
    s.addPropertySet( Service.CONF_cmdline, cmdLineOptions );

    s.setUserMessageHandler( js.getUserMessageHandler() );

    // generate output files from templates
    s.build();
  }



  /** Exit the JVM.
   *  @param pExitCode numerical exit code
   */
  private static final void exitProgram( int pExitCode ) {
    if( sExitProgram ) {
      System.exit( pExitCode );
    }
    else {
      // REVIEW: store exit code and allow retreival?
    }
  }

}
TOP

Related Classes of org.jostraca.Jostraca

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.