[Mulgara-svn] r1617 - branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog

pag at mulgara.org pag at mulgara.org
Tue Mar 17 19:51:27 UTC 2009


Author: pag
Date: 2009-03-17 12:51:26 -0700 (Tue, 17 Mar 2009)
New Revision: 1617

Modified:
   branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java
Log:
Recursive descent into imported data

Modified: branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java
===================================================================
--- branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java	2009-03-17 19:50:43 UTC (rev 1616)
+++ branches/consistency/src/jar/content-rlog/java/org/mulgara/krule/rlog/Rlog.java	2009-03-17 19:51:26 UTC (rev 1617)
@@ -17,6 +17,9 @@
 package org.mulgara.krule.rlog;
 
 import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
 import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -24,8 +27,8 @@
 import java.util.Collection;
 import java.util.Set;
 
+import org.apache.log4j.Logger;
 import org.mulgara.krule.rlog.ast.*;
-import org.mulgara.krule.rlog.ast.output.KruleWriter;
 import org.mulgara.krule.rlog.parser.TypeException;
 import org.mulgara.krule.rlog.parser.URIParseException;
 import org.mulgara.krule.rlog.rdf.MulgaraGraphs;
@@ -41,6 +44,9 @@
  */
 public class Rlog implements Interpreter {
 
+  /** Logger. */
+  private static final Logger logger = Logger.getLogger(Rlog.class.getName());
+
   /** The label used on all generated rules. */
   private static String ruleLabel = "rule";
 
@@ -54,45 +60,6 @@
   private List<Rule> rules;
 
   /**
-   * Parse input data into an AST and process.
-   * @param args May contain a filename with the code to be parsed.  All other parameters ignored.
-   * @throws IOException If there was an error reading from the specified file, or standard in.
-   * @throws beaver.Parser.Exception If there was a parsing exception.
-   */
-  public static void main(String[] args) throws IOException, ParseException {
-    // get the input
-    Reader intReader;
-    if (args.length > 0) {
-      File inFile = new File(args[0]);
-      if (!inFile.exists() || !inFile.canRead()) {
-        System.err.println("Unable to open file: " + inFile);
-        return;
-      }
-      // borrow the filename for labelling rules
-      intReader = new FileReader(inFile);
-      String filename = inFile.getName();
-      ruleLabel = filename.substring(0, filename.lastIndexOf('.'));
-    } else {
-      intReader = new InputStreamReader(System.in);
-    }
-    Reader input = new BufferedReader(intReader);
-
-    try {
-      // parse the input
-      Rlog rlog = new Rlog(input);
-      // emit to output
-      new KruleWriter(rlog).emit(System.out);
-    } catch (TypeException te) {
-      System.err.println(te.getMessage());
-      return;
-    } catch (URIParseException e) {
-      System.err.println(e.getMessage());
-      return;
-    }
-
-  }
-
-  /**
    * Sets the label to use for each rule. The rule names are made up of this label
    * plus an incremening number.
    * @param label The text label to use on rules.
@@ -104,15 +71,13 @@
   /**
    * Create an rlog interpreter for building an AST from a stream Reader object.
    * @param input The stream Reader.
+   * @param inputLocation The location the input comes from.
    * @throws IOException There was an IO Exception on the input.
    * @throws beaver.Parser.Exception There was a parser exception in the input data.
    * @throws URIParseException If the rules contain illegal URIs.
    */
-  public Rlog(Reader input) throws IOException, ParseException, TypeException, URIParseException {
-    // parse the rlog into statements
-    RlogParser parser = new RlogParser(input);
-
-    Program program = parser.getProgram();
+  public Rlog(Reader input, URI inputLocation) throws IOException, ParseException, TypeException, URIParseException {
+    Program program = loadProgram(input, inputLocation);
     statements = program.getStatements();
 
     // separate out the rules from the axioms
@@ -131,7 +96,35 @@
     calculateRuleDependencies();
   }
 
+
   /**
+   * Loads a program from an input Reader.
+   * @param input The Reader to get the program from.
+   * @param baseLocation The location context to load the program in. This is used for relative
+   *        import declartations.
+   * @return The fully loaded program, including imports.
+   * @throws IOException Due to an IO error while loading the program.
+   * @throws ParseException If the program contains an error.
+   */
+  private Program loadProgram(Reader input, URI baseLocation) throws IOException, ParseException {
+    // parse the rlog into statements
+    RlogParser parser = new RlogParser(input);
+
+    try {
+      Program program = parser.getProgram();
+      loadImports(program, baseLocation);
+      return program;
+    } catch (ParseException e) {
+      logger.error("Error parsing program: " + e.getMessage());
+      throw e;
+    } catch (IOException e) {
+      logger.error("IO Error reading program: " + e.getMessage());
+      throw e;
+    }
+  }
+
+
+  /**
    * Find all the variables in every rule.
    * @return A complete collection of all the variables that were parsed.
    */
@@ -141,6 +134,7 @@
     return vars;
   }
 
+
   /**
    * Gets all the URIs referenced in the rules.
    * @return All URIs in order of appearance within axioms, then rules.
@@ -154,6 +148,7 @@
     return refs;
   }
 
+
   /**
    * Get all the axioms appearing in the rule set.
    * @return A list of axioms.
@@ -162,6 +157,7 @@
     return Collections.unmodifiableList(axioms);
   }
 
+
   /**
    * Get all the rules appearing in the rule set.
    * @return A list of rules.
@@ -170,6 +166,7 @@
     return Collections.unmodifiableList(rules);
   }
 
+
   /**
    * Determine which rules are dependent on the result of which other rules,
    * and set the rule objects accordingly.
@@ -183,4 +180,53 @@
     }
   }
 
+
+  /**
+   * Load all imports into the given program.
+   * @param prog The program to load its imports into.
+   * @param currentLocation A URI for the location of the program. Used for relative loads.
+   * @throws IOException If the import files cannot be read.
+   * @throws ParseException If an imported program has an error.
+   */
+  private void loadImports(Program prog, URI currentLocation) throws IOException, ParseException {
+    List<URI> imports = prog.getImports();
+    for (URI imp: imports) {
+      URL importLocation = makeAbsolute(currentLocation, imp);
+      if (logger.isDebugEnabled()) logger.debug("Importing " + importLocation);
+      Reader input = new InputStreamReader(importLocation.openStream());
+      Program impProgram;
+      try {
+        impProgram = loadProgram(input, currentLocation);
+      } catch (ParseException e) {
+        logger.error("Error in imported program <" + importLocation + ">");
+        throw e;
+      } finally {
+        input.close();
+      }
+      prog.merge(impProgram);
+    }
+  }
+
+
+  /**
+   * Calculate a URL from a given URI, relative to the current base location.
+   * @param base The base to calculate the final URL from. Must be a URL if <var>rel</var> is relative.
+   * @param rel The URL that is relative to the base. If absolute, then <var>base</var> is ignored.
+   * @return A new URL, which is <var>rel</var> if it is absolute, or a merge of <var>rel</var> and
+   *         <var>base</var> if <var>rel</var> is relative.
+   * @throws IllegalArgumentException If <var>rel</var> is relative and <var>base</var> is not a URL,
+   *         or if <var>rel</var> (or <var>base</var>+<var>rel</var>) is not a valid URL.
+   */
+  private URL makeAbsolute(URI base, URI rel) {
+    try {
+      if (!rel.isAbsolute()) {
+        if (base == null) throw new IllegalArgumentException("Relative URL used in import with no current location set");
+        return new URL(base.toURL(), rel.toString());
+      } else {
+        return rel.toURL();
+      }
+    } catch (MalformedURLException e) {
+      throw new IllegalArgumentException("Invalid URL for import of (" + rel + ")" + ": "+ e.getMessage());
+    }
+  }
 }




More information about the Mulgara-svn mailing list