/* * The contents of this file are subject to the Open Software License * Version 3.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.opensource.org/licenses/osl-3.0.txt * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. */ package org.mulgara.krule.rlog; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.log4j.Logger; import org.mulgara.krule.rlog.ast.CanonicalStatement; import org.mulgara.krule.rlog.ast.Statement; /** * Represents a complete program, including annotations. * A program is mostly a list of statements, but can also include other elements * such as "imports" of other programs. * * @created Mar 3, 2009 * @author Paula Gearon * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a> * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a> */ public class Program { /** Logger. */ private static final Logger logger = Logger.getLogger(Program.class.getName()); /** All the statement that make up the program */ private List<Statement> statements; /** The canonical forms of the statements that make up the program */ private List<CanonicalStatement> canonicalStatements; /** The list of imports */ private List<URI> imports; /** * Constructs an empty program. */ public Program() { statements = new ArrayList<Statement>(); canonicalStatements = new ArrayList<CanonicalStatement>(); imports = new ArrayList<URI>(); } /** * Retrieve the statements from this program. * @return A list of statements in the program. */ public List<Statement> getStatements() { return statements; } /** * Merges the statements from another program into this one. * Note that the parsing context of the foreign statements is maintained. * @param p The foreign program to merge. */ public void merge(Program p) { logger.debug("Merging programs"); for (Statement s: p.getStatements()) add(s); } /** * Adds a statement to this program. If the statement is already present it is skipped. * @param s The statement to add. */ public void add(Statement s) { CanonicalStatement canonical = s.getCanonical(); if (!statementPresent(s, canonical)) { statements.add(s); canonicalStatements.add(canonical); } else { logger.debug("Not adding: " + s); } } /** * Adds an import directive to the program. */ public void addImport(String imp) throws ParseException { try { URI u = new URI(imp); imports.add(u); } catch (URISyntaxException e) { throw new ParseException("Bad URL in import"); } } /** * Get all the import URIs for the document * @return A List of URIs. These can be absolute or relative. */ public List<URI> getImports() { return imports; } /** * Get an iterator for the statements in this program. * @return A new iterator that returns statements. */ public Iterator<Statement> stmtIterator() { return statements.iterator(); } /** @see java.lang.Object#toString() */ public String toString() { StringBuilder sb = new StringBuilder(); for (Statement s: statements) { sb.append(s).append("\n"); } return sb.toString(); } /** * Tests if a statement is already present in the program. * Attempts to canonicalize statements for comparison. * @param stmt The statement to look for. Included for logging purposes. * @param canonical The canonicalized form of the statement to look for. * @return <code>true</code> if an equivalent statement is found, <code>false</code> otherwise. */ private boolean statementPresent(Statement stmt, CanonicalStatement canonical) { if (logger.isDebugEnabled()) logger.debug("Testing for presence of: " + stmt); for (CanonicalStatement s: canonicalStatements) { if (canonical.equals(s)) { if (logger.isDebugEnabled()) logger.debug(canonical.toString() + " == " + s); return true; } if (logger.isDebugEnabled()) logger.debug(canonical.toString() + " != " + s); } if (logger.isDebugEnabled()) logger.debug("New statement: " + stmt); return false; } }