/* * BEASTGen.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST 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 2 * of the License, or (at your option) any later version. * * BEAST 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 BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.app.beastgen; import dr.app.beauti.options.DateGuesser; import dr.app.util.Arguments; import dr.evolution.io.Importer; import freemarker.template.*; import java.io.*; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class BEASTGen { public BEASTGen(DateGuesser guesser, Map argumentMap, String treeFileName, String templateFileName, String inputFileName, String outputFileName) throws IOException { Configuration cfg = new Configuration(); cfg.setObjectWrapper(new DefaultObjectWrapper()); cfg.setDefaultEncoding("UTF-8"); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER); cfg.setIncompatibleImprovements(new Version(2, 3, 20)); // FreeMarker 2.3.20 Map root = null; try { root = constructDataModel(inputFileName, treeFileName, guesser); } catch (Importer.ImportException ie) { System.err.println("Error importing file: " + ie.getMessage()); System.exit(1); } root.putAll(argumentMap); Template template = cfg.getTemplate(templateFileName); try { Writer out = (outputFileName != null ? new FileWriter(new File(outputFileName)) : new OutputStreamWriter(System.out)); template.process(root, out); } catch (TemplateException te) { System.err.println("Error processing template, " + templateFileName + ": " + te.getMessage()); System.exit(1); } } private Map constructDataModel(String inputFileName, String treeFileName, DateGuesser guesser) throws IOException, Importer.ImportException { DataModelImporter importer = new DataModelImporter(guesser); Map root = importer.importFromFile(new File(inputFileName)); if (treeFileName != null) { importer.importFromTreeFile(treeFileName, root); } return root; } public static void centreLine(String line, int pageWidth) { int n = pageWidth - line.length(); int n1 = n / 2; for (int i = 0; i < n1; i++) { System.out.print(" "); } System.out.println(line); } public static void printTitle() { System.out.println(); centreLine("BEASTGen v1.0.1, 2013-2014", 60); centreLine("BEAST input file generator", 60); centreLine("Andrew Rambaut, University of Edinburgh", 60); System.out.println(); } public static void printUsage(Arguments arguments) { arguments.printUsage("beastgen", "<template-file-name> <input-file-name> [<output-file-name>]"); System.out.println(); System.out.println(" Example: beastgen template.beast test.nex test.xml"); System.out.println(" Example: beastgen -help"); System.out.println(); } public static void main(String[] args) { // There is a major issue with languages that use the comma as a decimal separator. // To ensure compatibility between programs in the package, enforce the US locale. Locale.setDefault(Locale.US); Arguments arguments = new Arguments( new Arguments.Option[]{ new Arguments.IntegerOption("date_order", "The order of the date field (negative numbers from last)"), new Arguments.StringOption("date_prefix", "prefix", "A string that is the prefix to the date field"), new Arguments.StringOption("date_regex", "regex", "A string that gives the regular expression to match the date"), new Arguments.StringOption("date_format", "format", "A string that gives the date format for parsing"), new Arguments.Option("date_precision", "Specifies the date is a variable precision yyyy-MM-dd format"), new Arguments.StringOption("tree", "tree-file-name", "Read a tree from a file"), new Arguments.StringOption("D", "\"key=value,key=value...\"", "Properties for exchange in templates"), new Arguments.Option("version", "Print the version and credits and stop"), new Arguments.Option("help", "Print this information and stop"), }); try { arguments.parseArguments(args); } catch (Arguments.ArgumentException ae) { printTitle(); System.out.println(); System.out.println(ae.getMessage()); System.out.println(); printUsage(arguments); System.exit(1); } DateGuesser guesser = new DateGuesser(); // guesser.guessDates = false; // guesser.guessType = DateGuesser.GuessType.ORDER; // guesser.fromLast = false; // guesser.order = 0; // guesser.prefix = null; // guesser.regex = null; // guesser.offset = 0.0; // guesser.unlessLessThan = 0.0; // guesser.offset2 = 0.0; // guesser.parseCalendarDates = false; // guesser.parseCalendarDatesAndPrecision = false; // guesser.calendarDateFormat = "yyyy-MM-dd"; if (arguments.hasOption("date_order")) { guesser.guessDates = true; int order = arguments.getIntegerOption("date_order"); if (order < 0) { guesser.order = 1 + order; guesser.fromLast = true; } else if (order > 0) { guesser.order = order - 1; guesser.fromLast = false; } else { guesser.order = 0; guesser.fromLast = false; } } if (arguments.hasOption("date_prefix")) { guesser.guessDates = true; guesser.prefix = arguments.getStringOption("date_prefix"); guesser.guessType = DateGuesser.GuessType.PREFIX; } if (arguments.hasOption("date_regex")) { guesser.guessDates = true; guesser.regex = arguments.getStringOption("date_regex"); guesser.guessType = DateGuesser.GuessType.REGEX; } if (arguments.hasOption("date_format")) { guesser.guessDates = true; guesser.calendarDateFormat = arguments.getStringOption("date_format"); guesser.parseCalendarDates = true; } if (arguments.hasOption("date_precision")) { guesser.guessDates = true; guesser.parseCalendarDatesAndPrecision = true; } String treeFileName = null; if (arguments.hasOption("tree")) { treeFileName = arguments.getStringOption("tree"); } Map argumentMap = new HashMap(); if (arguments.hasOption("D")) { String properties = arguments.getStringOption("D"); for (String property : properties.split("\\s*,\\s*")) { String[] keyValue = property.split("="); if (keyValue.length != 2) { System.err.println("Properties should take the form: key=value"); System.exit(1); } String key = keyValue[0].trim(); String value = keyValue[1].trim(); if (key.isEmpty()) { System.err.println("Properties should take the form: key=value"); System.exit(1); } argumentMap.put(key, value); } } if (arguments.hasOption("help")) { printTitle(); printUsage(arguments); System.exit(0); } if (arguments.hasOption("version")) { printTitle(); } String[] args2 = arguments.getLeftoverArguments(); if (args2.length < 1) { printTitle(); printUsage(arguments); System.exit(0); } if (args2.length < 2 || args2.length > 3) { System.err.println("Unknown option: " + args2[0]); System.err.println(); printUsage(arguments); System.exit(1); } try { new BEASTGen(guesser, argumentMap, treeFileName, args2[0], args2[1], (args2.length == 3 ? args2[2] : null)); } catch (IOException e) { e.printStackTrace(); System.exit(1); } } }