/* * Copyright (c) 2010 Ecole des Mines de Nantes. * * This file is part of Entropy. * * Entropy 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. * * Entropy 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 Entropy. If not, see <http://www.gnu.org/licenses/>. */ package entropy.vjob.builder; import java.io.File; import java.io.IOException; import org.antlr.runtime.ANTLRFileStream; import org.antlr.runtime.ANTLRStringStream; import org.antlr.runtime.CharStream; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.RecognitionException; import entropy.vjob.BasicVJob; import entropy.vjob.VJob; /** * Build VJobs from textual descriptions. * A prolog vjob may be used to consider predefined variables. * * @author Fabien Hermenier */ public class VJobBuilder { /** * An optional prolog where to get variables. */ private VJob prolog; /** * The builder to instantiate new elements. */ private VJobElementBuilder elemBuilder; /** * The catalog of available constraints. */ private ConstraintsCatalog catalog; /** * Make a new builder. * * @param eBuilder the builder to instantiate new elements * @param c the catalog of available constraints */ public VJobBuilder(VJobElementBuilder eBuilder, ConstraintsCatalog c) { elemBuilder = eBuilder; catalog = c; prolog = null; } /** * Set the prolog to use. * * @param p the vjob to use as prolog */ public void setProlog(VJob p) { prolog = p; } /** * Get the prolog. * * @return the vjob used as a prolog if defined, {@code null} otherwise */ public VJob getProlog() { return prolog; } /** * Get the builder to make managed elements. * * @return the builder */ public VJobElementBuilder getElementBuilder() { return elemBuilder; } /** * Build a VJob from a file containing the description. * * @param id the identifier of the vjob * @param f the file to read * @return the builded vjob * @throws VJobBuilderException if an error occurred while building the vjob * @throws IOException if an error occurred while reading the file */ public VJob build(String id, File f) throws VJobBuilderException, IOException { try { return build(id, new ANTLRFileStream(f.getAbsolutePath())); } catch (IOException e) { throw new VJobBuilderException(e.getMessage(), e); } } /** * Build a VJob from a String. * * @param id the identifier of the vjob * @param description the description of the vjob * @return the builded vjob * @throws VJobBuilderException if an error occurred while buildeing the vjob */ public VJob build(String id, String description) throws VJobBuilderException { return build(id, new ANTLRStringStream(description)); } /** * Internal method to build a vjob from a stream. * * @param id the identifier of the vjob * @param cs the stream to analyze * @return the builded vjob * @throws VJobBuilderException in an error occurred while building the vjob */ private VJob build(String id, CharStream cs) throws VJobBuilderException { ANTLRVJob3Lexer lexer = new ANTLRVJob3Lexer(cs); CommonTokenStream tokens = new CommonTokenStream(lexer); ANTLRVJob3Parser parser = new ANTLRVJob3Parser(tokens); final VJob v = new BasicVJob(id); final SemanticErrors errs = new SemanticErrors(); parser.setTreeAdaptor(new VJobTreeAdaptor(errs, new SymbolsTable(getProlog()), elemBuilder, v, catalog)); try { VJobTree tree = (VJobTree) parser.vjob_decl().getTree(); if (tree == null) { //No tokens, empty VJob return v; } if (tree.token != null) { tree.go(tree); //Single instruction } else { for (int i = 0; i < tree.getChildCount(); i++) { ((VJobTree) tree.getChild(i)).go(tree); } } } catch (RecognitionException e) { throw new VJobBuilderException(e.getMessage(), e); } if (errs.size() > 0) { throw new VJobBuilderException(errs.toString()); } return v; } /** * Get the used constraint catalog. * * @return a catalog, may be null if no catalog was specified as instantiation. */ public ConstraintsCatalog getCatalog() { return catalog; } }