/* Copyright (C) 2009 Diego Darriba 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package es.uvigo.darwin.prottest.util.factory; import static es.uvigo.darwin.prottest.global.ApplicationGlobals.*; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.Calendar; import java.text.SimpleDateFormat; import pal.alignment.Alignment; import pal.tree.Tree; import es.uvigo.darwin.prottest.exe.PhyMLv3AminoAcidRunEstimator; import es.uvigo.darwin.prottest.exe.RaxMLAminoAcidRunEstimator; import es.uvigo.darwin.prottest.exe.RunEstimator; import es.uvigo.darwin.prottest.global.AminoAcidApplicationGlobals; import es.uvigo.darwin.prottest.global.ApplicationGlobals; import es.uvigo.darwin.prottest.global.RaxmlAminoAcidApplicationGlobals; import es.uvigo.darwin.prottest.global.options.ApplicationOptions; import es.uvigo.darwin.prottest.model.AminoAcidModel; import es.uvigo.darwin.prottest.model.Model; import es.uvigo.darwin.prottest.selection.printer.AminoAcidPrintFramework; import es.uvigo.darwin.prottest.selection.printer.PrintFramework; import es.uvigo.darwin.prottest.util.argumentparser.AminoAcidArgumentParser; import es.uvigo.darwin.prottest.util.argumentparser.ProtTestArgumentParser; import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException; import es.uvigo.darwin.prottest.util.logging.ProtTestLogFormatter; import java.io.File; import java.io.FileOutputStream; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.StreamHandler; /** * A factory for creating ProtTest objects. */ public class ProtTestFactory { /** The Constant PROTEIC. */ public static final int PROTEIC = 1; /** The Constant NUCLEIC. */ public static final int NUCLEIC = 2; /** The Constant MAX_SORT. */ private static final int MAX_SORT = 2; /** The instance. */ private static ProtTestFactory instance; /** The sort. */ private int sort; /** Unique log handler. */ private Handler logHandler; /** * Instantiates a new prot test factory. * * @param sort the sort * * @throws IllegalArgumentException the illegal argument exception */ private ProtTestFactory(int sort) throws IllegalArgumentException { if (sort <= 0 || sort > MAX_SORT) { throw new IllegalArgumentException( "Cannot create factory (unexistent sort : " + sort + ")"); } this.sort = sort; } /** * Initialize. * * @param args the args * * @return the string[] */ public static String[] initialize(String[] args) { if (instance == null) { int sort; List<String> argList = new ArrayList<String>(Arrays.asList(args)); int index = argList.indexOf(ProtTestArgumentParser.ARG_TOKEN + ProtTestArgumentParser.PARAM_DATA_TYPE); if (index < 0) //set default { sort = PROTEIC; } else { String value = argList.get(index + 1); argList.remove(index + 1); argList.remove(index); args = argList.toArray(new String[0]); if (value.equals(ProtTestArgumentParser.DATA_TYPE_AMINOACID)) { sort = PROTEIC; } else if (value.equals(ProtTestArgumentParser.DATA_TYPE_NUCLEOTIDE)) { sort = NUCLEIC; } else { throw new IllegalArgumentException("Invalid data type " + value); } } instance = new ProtTestFactory(sort); return args; } else { throw new ProtTestInternalException("ProtTestFactory was already initialized"); } } /** * Gets the single instance of ProtTestFactory. * * @return single instance of ProtTestFactory */ public static ProtTestFactory getInstance() { if (instance == null) { initialize(new String[0]); } // throw new ProtTestInternalException("ProtTestFactory should be initialized"); return instance; } /** * Creates a new ProtTest object. * * @param args the args * @param options the options * * @return the prot test argument parser */ public ProtTestArgumentParser createProtTestArgumentParser(String[] args, ApplicationOptions options) throws IllegalArgumentException{ ProtTestArgumentParser mtap = null; switch (sort) { case PROTEIC: mtap = new AminoAcidArgumentParser(args, options); break; case NUCLEIC: throw new ProtTestInternalException("Unsupported operation: nucleic data"); } return mtap; } /** * Gets the application globals. * * @return the application globals */ public ApplicationGlobals getApplicationGlobals() { ApplicationGlobals ap = null; String analyzer = APPLICATION_PROPERTIES.getProperty("analyzer"); switch (sort) { case PROTEIC: if (analyzer.equals(ANALYZER_RAXML)) { ap = new RaxmlAminoAcidApplicationGlobals(); } else if (analyzer.equals(ANALYZER_PHYML)) { ap = new AminoAcidApplicationGlobals(); } else { throw new ProtTestInternalException("Analyzer " + analyzer + " not supported by RunEstimator. Check your prottest.properties file"); } break; case NUCLEIC: throw new ProtTestInternalException("Unsupported operation: nucleic data"); } return ap; } /** * Creates a new ProtTest object. * * @param matrix the matrix * @param distribution the distribution * @param modelProperties the model APPLICATION_PROPERTIES * * @return the model */ public Model createModel(String matrix, int distribution, Properties modelProperties, Alignment alignment, Tree tree, int ncat) { Model model = null; boolean plusF; if (modelProperties != null) { plusF = Boolean.parseBoolean( modelProperties.getProperty( AminoAcidModel.PROP_PLUS_F, "false")); } else { plusF = false; } switch (sort) { case PROTEIC: model = new AminoAcidModel(matrix, distribution, plusF, alignment, tree, ncat); break; case NUCLEIC: throw new ProtTestInternalException("Unsupported operation: nucleic data"); } return model; } /** * Creates a new ProtTest object. * * @param options the options * @param model the model * * @return the run estimator */ public RunEstimator createRunEstimator(ApplicationOptions options, Model model) { return createRunEstimator(options, model, 1); } /** * Creates a new ProtTest object. * * @param options the options * @param model the model * * @return the run estimator */ public RunEstimator createRunEstimator(ApplicationOptions options, Model model, int numberOfThreads) { RunEstimator runEstimator = null; String analyzer = APPLICATION_PROPERTIES.getProperty("analyzer"); if (analyzer.equals(ANALYZER_PHYML)) { switch (sort) { case PROTEIC: runEstimator = new PhyMLv3AminoAcidRunEstimator(options, model, numberOfThreads); break; case NUCLEIC: throw new ProtTestInternalException("Unsupported operation: nucleic data"); } } else if (analyzer.equals(ANALYZER_RAXML)) { switch (sort) { case PROTEIC: runEstimator = new RaxMLAminoAcidRunEstimator(options, model); break; case NUCLEIC: throw new ProtTestInternalException("Unsupported operation: nucleic data"); } } else { throw new ProtTestInternalException("Analyzer " + analyzer + " not supported by RunEstimator"); } return runEstimator; } public Handler createLogHandler() throws IOException { // Log level is configurable: // 'info' Only general information messages are logged (default) // 'fine' General debug information is also logged // 'finer' More complex debug information is logged // 'finest' All activity is tracked if (logHandler == null) { String[] supportedLevels = {"INFO", "FINE", "FINER", "FINEST"}; String logDirName = APPLICATION_PROPERTIES.getProperty("log_dir"); String level = APPLICATION_PROPERTIES.getProperty("log_level", "info").toUpperCase(); boolean supported = false; for (String testLevel : supportedLevels) { supported |= testLevel.equals(level); } if (logDirName != null && supported) { File logDir = new File(logDirName); if (!logDir.isAbsolute()) { logDir = new File(ApplicationGlobals.PATH + File.separator + logDir); } if (!logDir.exists()) { logDir.mkdirs(); } SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); //File logFile = new File(logDir.getAbsolutePath() + File.separator + "prottest3_" + // sdf.format(Calendar.getInstance().getTime())); File logFile = File.createTempFile("prottest3_"+sdf.format(Calendar.getInstance().getTime())+"_", ".log", logDir); FileOutputStream fos = new FileOutputStream(logFile); logHandler = new StreamHandler(fos, new ProtTestLogFormatter()); logHandler.setLevel(Level.parse(level)); } } return logHandler; } /** * Creates a new ProtTest object. * * @return the prints the framework */ public PrintFramework createPrintFramework() { PrintFramework pf = null; switch (sort) { case PROTEIC: pf = new AminoAcidPrintFramework(); break; case NUCLEIC: throw new ProtTestInternalException("Unsupported operation: nucleic data"); } return pf; } }