/** * Copyright (C) 2009 France Telecom * * This file is part of "Mind Compiler" is free software: you can redistribute * it and/or modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 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 Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contact: mind@ow2.org * * Authors: Olivier Lobry * Contributors: Matthieu Leclercq */ package org.ow2.mind.preproc; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import org.antlr.runtime.ANTLRFileStream; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.RecognitionException; import org.antlr.stringtemplate.StringTemplateGroup; import org.ow2.mind.preproc.parser.CPLLexer; import org.ow2.mind.preproc.parser.CPLParser; public class MIND_preproc { // Map<String, CmdOption> of options protected Map<String, CmdOption> options; // name of the MIND cpl file to pre-proceed. protected String cplFileName; // path to the MIND cpl file to pre-proceed. protected String cplFilePath; private final CmdOption propertiesOpt = new CmdPropOption( new String[]{"properties", "prop" }, "a list of property files containing additional options"); private final CmdOption outDirOpt = new CmdOption(new String[]{ "out-path", "out-dir", "o" }, "the path where generated files will be put"); // , "."); private final CmdOption stgOpt = new CmdOption( new String[]{"stg", "string-template-groupe" }, "the path to the StringTemplate Group (.stg) to use", null); private final CmdOption singletonMode = new CmdOption( new String[]{"sm", "singleton", "singleton-mode" }, "singleton mode (true or false)", "false"); private CmdOption[] allCmdOptions; protected MIND_preproc() { options = new HashMap<String, CmdOption>(); this.setOptions(new CmdOption[]{propertiesOpt, outDirOpt, stgOpt, singletonMode}); this.addOptions(this.allCmdOptions); } public static void main(final String args[]) throws Exception { StringTemplateGroup templates = null; final MIND_preproc mind_preproc = new MIND_preproc(); mind_preproc.parseArgs(args); PrintStream p; if (mind_preproc.outDirOpt.value != null) { FileOutputStream out; out = new FileOutputStream(mind_preproc.outDirOpt.value + "_mpp_" + mind_preproc.cplFileName); p = new PrintStream(out); } else { p = System.out; } if (mind_preproc.stgOpt.value != null) { final FileReader groupFileMind_CPL = new FileReader( mind_preproc.stgOpt.value); templates = new StringTemplateGroup(groupFileMind_CPL); groupFileMind_CPL.close(); } final CPLLexer lex = new CPLLexer(new ANTLRFileStream( mind_preproc.cplFilePath + mind_preproc.cplFileName)); final CommonTokenStream tokens = new CommonTokenStream(lex); final CPLParser mpp = new CPLParser(tokens); mpp.setOutputStream(p); mpp.setSingletonMode(mind_preproc.singletonMode.getValue().equals("true")); if (templates != null) { mpp.setTemplateLib(templates); } try { mpp.parseFile(); } catch (final RecognitionException e) { e.printStackTrace(); } } private void addOptions(final CmdOption[] options) { for (final CmdOption option : options) { for (final String option2 : option.options) { if (this.options.put(option2, option) != null) { throw new InternalError("Duplicated option '" + option2 + "'"); } } } } private void setOptions(final CmdOption[] options) { allCmdOptions = new CmdOption[options.length]; System.arraycopy(options, 0, allCmdOptions, 0, options.length); } private void parseArgs(final String[] args) { for (final String arg : args) { if (arg.startsWith("-")) { final int index = arg.indexOf('='); if (index < 2) { parseError(arg); } final String optionName = arg.substring(1, index); final String optionValue = arg.substring(index + 1); // validate option final CmdOption cmdOption = options.get(optionName); if (cmdOption == null) parseError(arg); cmdOption.setValue(optionValue); } else { if (cplFileName == null) { cplFileName = arg.substring(arg.lastIndexOf("/") + 1); cplFilePath = arg.substring(0, arg.lastIndexOf("/") + 1); } else parseError(arg); } } readProperyFiles(); // archList = getArchs(); // // readArchProperties(); // prepareOutDir(); // prepareSourceClassLoader(); } private void readProperyFiles() { final String propertyList = propertiesOpt.getValue(); if (propertyList == null) return; final List<String> l = parsePathList(propertyList); final Iterator<String> iterator = l.iterator(); while (iterator.hasNext()) { final String path = iterator.next(); final Properties p = new Properties(); loadProperties(p, new File(path)); final Iterator propIterator = p.entrySet().iterator(); while (propIterator.hasNext()) { final Map.Entry propEntry = (Map.Entry) propIterator.next(); final CmdOption cmdOption = options.get(propEntry.getKey()); if (cmdOption == null) { continue; } cmdOption.setValue((String) propEntry.getValue()); } } } private List<String> parsePathList(String paths) { final List<String> l = new ArrayList<String>(); int index = paths.indexOf(File.pathSeparatorChar); while (index != -1) { l.add(paths.substring(0, index)); paths = paths.substring(index + 1); index = paths.indexOf(File.pathSeparatorChar); } l.add(paths); return l; } private void loadProperties(final Properties p, final File f) { try { p.load(new FileInputStream(f)); } catch (final FileNotFoundException e) { error("Can't find property file '" + f.getAbsolutePath() + "'", 2); } catch (final IOException e) { error( "Can't read property file '" + f.getAbsolutePath() + "'. " + e.getMessage(), 3); } } private void error(final String message, final int exitVal) { // if (exitOnFailure) { System.err.println(message); printFullUsage(System.err); System.exit(exitVal); // } else { // throw new Error(message); // } } private void parseError(final String arg) { error("Unknown option '" + arg + "'", 1); } protected void printUsage(final PrintStream ps) { ps.println("Usage: MIND_preproc [OPTIONS] <file>"); ps.println(" where <file> is the name of the MIND CPL file component to be pre-proceed,"); } private void printFullUsage(final PrintStream ps) { printUsage(ps); ps.println(); ps.println("Available options are (from command line, options must be prefix with '-') :"); int maxCol = 0; for (final CmdOption opt : allCmdOptions) { int col = 2 + opt.options[0].length(); if (opt.options.length > 1) { col += opt.options[1].length() + 2; if (opt.options.length > 2) for (int j = 2; j < opt.options.length; j++) { col += opt.options[j].length() + 2; } else col += 2; } if (col > maxCol) maxCol = col; } for (final CmdOption opt : allCmdOptions) { final StringBuffer sb = new StringBuffer(" "); sb.append(opt.options[0]); if (opt.options.length > 1) { sb.append(" ("); for (int j = 1; j < opt.options.length; j++) { sb.append(opt.options[j]); if (j < opt.options.length - 1) sb.append(", "); } sb.append(") "); } while (sb.length() < maxCol) sb.append(' '); sb.append(": ").append(opt.info); ps.println(sb); } } private class CmdOption { protected final String[] options; protected final String info; protected final String defaulValue; protected String value; protected CmdOption(final String[] options, final String info, final String defaulValue) { this.options = options; this.info = info; this.defaulValue = defaulValue; } protected CmdOption(final String[] options, final String info) { this(options, info, null); } protected CmdOption(final String option, final String info) { this(new String[]{option}, info, null); } protected final String getValue() { return (value == null) ? defaulValue : value; } protected void setValue(final String value) { this.value = value; } // protected void setCommadLineValue(final String value) { // this.value = value; // } // // protected void setPropertyValue(final String value) { // this.value = value; // } // protected void setArchPropertyValue(final String value) { // if (this.value == null) this.value = value; // } } protected class CmdPropOption extends CmdOption { protected CmdPropOption(final String option, final String info) { super(option, info); } protected CmdPropOption(final String[] options, final String info, final String initialValue) { super(options, info, initialValue); } protected CmdPropOption(final String[] options, final String info) { super(options, info); } /** Append new value at end. */ @Override protected void setValue(final String value) { this.value = (this.value == null) ? value : this.value + value; } /** Append new value at end. */ protected void setPropertyValue(final String value) { error("Can't specify property files inside property file", 20); } // /** Append new value at begining. */ // protected void setArchPropertyValue(final String value) { // error("Can't specify property files inside arch file", 20); // } } }