[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