[Mulgara-svn] r1720 - in trunk: . src/jar src/jar/krule/java/org/mulgara/krule src/jar/query/java/org/mulgara/query/rdf src/jar/swrl src/jar/swrl/java src/jar/swrl/java/org src/jar/swrl/java/org/mulgara src/jar/swrl/java/org/mulgara/swrl
alexhall at mulgara.org
alexhall at mulgara.org
Mon Jun 8 19:47:58 UTC 2009
Author: alexhall
Date: 2009-06-08 12:47:56 -0700 (Mon, 08 Jun 2009)
New Revision: 1720
Added:
trunk/src/jar/query/java/org/mulgara/query/rdf/SWRL.java
trunk/src/jar/swrl/
trunk/src/jar/swrl/build.xml
trunk/src/jar/swrl/java/
trunk/src/jar/swrl/java/org/
trunk/src/jar/swrl/java/org/mulgara/
trunk/src/jar/swrl/java/org/mulgara/swrl/
trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java
trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLStructureException.java
trunk/src/jar/swrl/swrl-build.properties
Modified:
trunk/.classpath
trunk/build.xml
trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
trunk/src/jar/krule/java/org/mulgara/krule/RuleStructure.java
Log:
Initial implementation of a rule loader for SWRL rules. This is only a basic parser with enough functionality to load and execute simple SWRL examples. Future improvements include adding support for builtins; adding a test suite; and modifying the RuleLoader interface to allow for multiple rule loaders to be configured in the system.
Modified: trunk/.classpath
===================================================================
--- trunk/.classpath 2009-06-05 04:04:36 UTC (rev 1719)
+++ trunk/.classpath 2009-06-08 19:47:56 UTC (rev 1720)
@@ -50,6 +50,7 @@
<classpathentry kind="src" path="src/jar/store-stringpool-xa/java"/>
<classpathentry kind="src" path="src/jar/store-stringpool-xa11/java"/>
<classpathentry kind="src" path="src/jar/store-xa/java"/>
+ <classpathentry kind="src" path="src/jar/swrl/java"/>
<classpathentry kind="src" path="src/jar/tag/java"/>
<classpathentry kind="src" path="src/jar/tuples/java"/>
<classpathentry kind="src" path="src/jar/tuples-hybrid/java"/>
Modified: trunk/build.xml
===================================================================
--- trunk/build.xml 2009-06-05 04:04:36 UTC (rev 1719)
+++ trunk/build.xml 2009-06-08 19:47:56 UTC (rev 1720)
@@ -61,6 +61,7 @@
<property file="${jar.src.dir}/store-stringpool-memory/store-stringpool-memory-build.properties"/>
<property file="${jar.src.dir}/store-stringpool-xa/store-stringpool-xa-build.properties"/>
<property file="${jar.src.dir}/store-stringpool-xa11/store-stringpool-xa11-build.properties"/>
+ <property file="${jar.src.dir}/swrl/swrl-build.properties"/>
<property file="${jar.src.dir}/tag/tag-build.properties"/>
<property file="${jar.src.dir}/tuples-hybrid/tuples-hybrid-build.properties"/>
<property file="${jar.src.dir}/tuples/tuples-build.properties"/>
@@ -124,6 +125,7 @@
<import file="${jar.src.dir}/store-stringpool-memory/build.xml"/>
<import file="${jar.src.dir}/store-stringpool-xa/build.xml"/>
<import file="${jar.src.dir}/store-stringpool-xa11/build.xml"/>
+ <import file="${jar.src.dir}/swrl/build.xml"/>
<import file="${jar.src.dir}/tag/build.xml"/>
<import file="${jar.src.dir}/tuples-hybrid/build.xml"/>
<import file="${jar.src.dir}/tuples/build.xml"/>
@@ -306,7 +308,7 @@
server-rmi-dist, krule-dist,
store-stringpool-dist, store-stringpool-memory-dist,
store-stringpool-xa-dist,
- store-stringpool-xa11-dist, tag-dist,
+ store-stringpool-xa11-dist, swrl-dist, tag-dist,
tuples-dist, tuples-hybrid-dist,
util-dist, util-xa-dist, web-dist"
description="Creates the distribution base jars">
@@ -745,7 +747,7 @@
server-jar, server-rmi-jar,
krule-jar,
store-stringpool-jar,
- store-stringpool-memory-jar, store-stringpool-xa-jar, store-stringpool-xa11-jar,
+ store-stringpool-memory-jar, store-stringpool-xa-jar, store-stringpool-xa11-jar, swrl-jar,
tuples-jar, tuples-hybrid-jar, util-jar, util-xa-jar, web-jar"
unless="javadoc.uptodate"
description="Creates the project javadoc">
@@ -784,6 +786,7 @@
org.mulgara.store.stringpool.xa.*,
org.mulgara.store.tuples.*,
org.mulgara.store.xa.*,
+ org.mulgara.swrl.*,
org.mulgara.webquery.*,
org.mulgara.util,
org.mulgara.xml.*"
@@ -863,6 +866,7 @@
<sourcepath path="${store-stringpool-memory.src.dir}/java"/>
<sourcepath path="${store-stringpool-xa.src.dir}/java"/>
<sourcepath path="${store-stringpool-xa11.src.dir}/java"/>
+ <sourcepath path="${swrl.src.dir}/java"/>
<sourcepath path="${tuples.src.dir}/java"/>
<sourcepath path="${tuples-hybrid.src.dir}/java"/>
<sourcepath path="${util.src.dir}/java"/>
@@ -911,7 +915,7 @@
krule-javadoc,
store-stringpool-javadoc,
store-stringpool-memory-javadoc, store-stringpool-xa-javadoc,
- store-stringpool-xa11-javadoc,
+ store-stringpool-xa11-javadoc, swrl-javadoc,
tag-javadoc, tuples-hybrid-javadoc, tuples-javadoc,
util-xa-javadoc, util-javadoc"
unless="javadoc.uptodate"
@@ -1637,6 +1641,7 @@
store-stringpool-memory-jar,
store-stringpool-xa-jar,
store-stringpool-xa11-jar,
+ swrl-jar,
tuples-jar,
tuples-hybrid-jar,
util-jar,
@@ -1755,6 +1760,7 @@
<zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**"/>
<zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**"/>
<zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**"/>
+ <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**"/>
<zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**"/>
@@ -1830,6 +1836,7 @@
store-stringpool-memory-jar,
store-stringpool-xa-jar,
store-stringpool-xa11-jar,
+ swrl-jar,
tuples-jar,
tuples-hybrid-jar,
util-jar,
@@ -1893,6 +1900,7 @@
<zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**"/>
<zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**"/>
<zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**"/>
+ <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**"/>
<zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**"/>
@@ -1957,6 +1965,7 @@
store-stringpool-memory-jar,
store-stringpool-xa-jar,
store-stringpool-xa11-jar,
+ swrl-jar,
tuples-jar,
tuples-hybrid-jar,
util-jar,
@@ -2016,6 +2025,7 @@
<zipfileset src="${bin.dir}/${dtd.jar}" excludes="**/*.xml, META-INF/**"/>
<zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="**/*.xml, META-INF/**"/>
<zipfileset src="${bin.dir}/${krule.jar}" excludes="**/*.xml, META-INF/**"/>
+ <zipfileset src="${bin.dir}/${swrl.jar}" excludes="**/*.xml, META-INF/**"/>
<!-- Schemas -->
<fileset dir="${src.dir}/jar/dtd" includes="DTD/**"/>
@@ -2086,6 +2096,7 @@
store-stringpool-memory-jar,
store-stringpool-xa-jar,
store-stringpool-xa11-jar,
+ swrl-jar,
tuples-jar,
tuples-hybrid-jar,
util-jar,
@@ -2189,6 +2200,7 @@
<zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**"/>
<zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**"/>
<zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**"/>
+ <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**"/>
<zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**"/>
@@ -2277,7 +2289,7 @@
</target>
<target name="utils-test"
- depends="ant-task-test, dtd-test, krule-test, tag-test, util-test, util-xa-test"
+ depends="ant-task-test, dtd-test, krule-test, swrl-test, tag-test, util-test, util-xa-test"
description="Runs miscellaneous utility tests">
</target>
Modified: trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java 2009-06-05 04:04:36 UTC (rev 1719)
+++ trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java 2009-06-08 19:47:56 UTC (rev 1720)
@@ -62,20 +62,17 @@
/** Logger. */
private static Logger logger = Logger.getLogger(QueryStruct.class.getName());
- /** The selection list. */
- private ConstraintElement[] select;
-
/** List of elements which are variables, or ConstantValues. */
- private List<SelectElement> variables;
+ private List<SelectElement> variables = null;
/** The graph expresison for the query. */
- private GraphExpression graphs;
+ private GraphExpression graphs = null;
/** The where clause of the query. */
- private ConstraintExpression where;
+ private ConstraintExpression where = null;
/** The having clause for the query. */
- private ConstraintHaving having;
+ private ConstraintHaving having = null;
/**
@@ -109,10 +106,10 @@
// set up a list of variables
variables = new ArrayList<SelectElement>();
- select = new ConstraintElement[vs.length];
// convert the parameters to usable objects
for (int i = 0; i < vs.length; i++) {
+ ConstraintElement select = null;
URIReference element = vs[i];
// check the type
if (types[i].equals(Krule.URI_REF)) {
@@ -121,15 +118,15 @@
if (varsOnly) throw new IllegalArgumentException("Wrong number of elements for a rule query: " + vs.length);
// get the referred value from the map
- select[i] = (URIReferenceImpl)uriReferences.get(element);
+ select = (URIReferenceImpl)uriReferences.get(element);
// assume that literals do not have the "Value" type inferred
- variables.add(new ConstantValue(variableFactory.newVariable(), (URIReferenceImpl)select[i]));
+ variables.add(new ConstantValue(variableFactory.newVariable(), (URIReferenceImpl)select));
} else if (types[i].equals(Krule.VARIABLE)) {
// get the variable
- select[i] = (Variable)varReferences.get(element);
- variables.add((Variable)select[i]);
+ select = (Variable)varReferences.get(element);
+ variables.add((Variable)select);
} else if (types[i].equals(Krule.LITERAL)) {
@@ -141,20 +138,41 @@
if (varsOnly) throw new IllegalArgumentException("Wrong number of elements for a rule query: " + vs.length);
// get the literal
- select[i] = (LiteralImpl)litReferences.get(element);
- variables.add(new ConstantValue(variableFactory.newVariable(), (LiteralImpl)select[i]));
+ select = (LiteralImpl)litReferences.get(element);
+ variables.add(new ConstantValue(variableFactory.newVariable(), (LiteralImpl)select));
} else {
throw new IllegalArgumentException("Unknown selection type in rule query.");
}
- if (select[i] == null) {
+ if (select == null) {
throw new IllegalArgumentException("Unable to resolve a reference for: " + element);
}
}
-
- graphs = null;
- having = null;
}
+
+ /**
+ * Construct a query structure with a known list of select elements.
+ * @param vars The select elements for this query.
+ */
+ public QueryStruct(List<SelectElement> vars) {
+ if (vars.size() <= 0) throw new IllegalArgumentException("Wrong number of elements for a rule query");
+ this.variables = new ArrayList<SelectElement>(vars);
+
+ // If there is a non-multiple of 3 in the selection variables, then this is a check rule
+ // and we can only select variables in check rules
+ boolean varsOnly = variables.size() % 3 != 0;
+
+ // Validate the select elements.
+ for (int i = 0; i < variables.size(); i++) {
+ SelectElement var = variables.get(i);
+ if (varsOnly && !(var instanceof Variable)) {
+ throw new IllegalArgumentException("Wrong number of elements for a rule query: " + variables.size());
+ }
+ if ((var instanceof ConstantValue) && (((ConstantValue)var).getValue() instanceof Literal) && i % 3 != 2) {
+ throw new IllegalArgumentException("Selection literal in illegal position in query");
+ }
+ }
+ }
/**
@@ -162,24 +180,11 @@
* @return The number of selection elements from the query.
*/
public int elementCount() {
- return select.length;
+ return variables.size();
}
/**
- * Retrieve the element <em>n</em>.
- *
- * @param n The element number to retrieve.
- * @return The <em>n</em>th element.
- * @throws IndexOutOfBoundsException If n is larger than 3.
- */
- public ConstraintElement getElement(int n) {
- assert n < select.length;
- return select[n];
- }
-
-
- /**
* Sets the where clause for the query.
*
* @param constraints The constraint expression defining the where clause.
Modified: trunk/src/jar/krule/java/org/mulgara/krule/RuleStructure.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/RuleStructure.java 2009-06-05 04:04:36 UTC (rev 1719)
+++ trunk/src/jar/krule/java/org/mulgara/krule/RuleStructure.java 2009-06-08 19:47:56 UTC (rev 1720)
@@ -135,6 +135,17 @@
public void setAxioms(Set<org.jrdf.graph.Triple> axioms) {
this.axioms = axioms;
}
+
+
+ /**
+ * Adds a single axiom to these rules.
+ *
+ * @param axiom A triple comprising an axiomatic statement.
+ */
+ public void addAxiom(org.jrdf.graph.Triple axiom) {
+ if (axioms == null) axioms = new HashSet<org.jrdf.graph.Triple>();
+ axioms.add(axiom);
+ }
/**
Added: trunk/src/jar/query/java/org/mulgara/query/rdf/SWRL.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/rdf/SWRL.java (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/rdf/SWRL.java 2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,137 @@
+/*
+ * 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.query.rdf;
+
+import java.net.URI;
+
+/**
+ * URI constants for SWRL rules.
+ *
+ * @created Jun 4, 2009
+ * @author Alex Hall
+ * @copyright © 2009 <a href="http://www.revelytix.com">Revelytix, Inc.</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SWRL {
+
+ /** URI for the SWRL namespace. */
+ public static final String SWRL = "http://www.w3.org/2003/11/swrl#";
+
+ /** URI for a variable reference. */
+ public static final String VARIABLE_STR = SWRL + "Variable";
+
+ /** URI for an implication (i.e. rule) */
+ public static final String IMP_STR = SWRL + "Imp";
+
+ /** URI for a rule head. */
+ public static final String HEAD_STR = SWRL + "head";
+
+ /** URI for a rule body. */
+ public static final String BODY_STR = SWRL + "body";
+
+ /** URI for a class membership atom. */
+ public static final String CLASS_ATOM_STR = SWRL + "ClassAtom";
+
+ /** URI for an individual-valued property atom. */
+ public static final String INDIVIDUAL_ATOM_STR = SWRL + "IndividualPropertyAtom";
+
+ /** URI for a datatype-valued property atom. */
+ public static final String DATA_ATOM_STR = SWRL + "DatavaluedPropertyAtom";
+
+ /** URI for an individual identity atom. */
+ public static final String SAME_INDIVIDUALS_ATOM_STR = SWRL + "SameIndividualsAtom";
+
+ /** URI for an individual difference atom. */
+ public static final String DIFFERENT_INDIVIDUALS_ATOM_STR = SWRL + "DifferentIndividualsAtom";
+
+ /** URI for a builtin atom. */
+ public static final String BUILTIN_ATOM_STR = SWRL + "BuiltinAtom";
+
+ /** URI for a data range atom. */
+ public static final String DATA_RANGE_ATOM_STR = SWRL + "DataRangeAtom";
+
+ /** URI for a class atom predicate. */
+ public static final String CLASS_PREDICATE_STR = SWRL + "classPredicate";
+
+ /** URI for an individual or datatype property atom predicate. */
+ public static final String PROPERTY_PREDICATE_STR = SWRL + "propertyPredicate";
+
+ /** URI for a builtin atom operator. */
+ public static final String BUILTIN_STR = SWRL + "builtin";
+
+ /** URI for a data range atom predicate. */
+ public static final String DATA_RANGE_STR = SWRL + "dataRange";
+
+ /** URI to identify the first argument to an atom. */
+ public static final String ARG_1_STR = SWRL + "argument1";
+
+ /** URI to identify the second argument to an atom. */
+ public static final String ARG_2_STR = SWRL + "argument2";
+
+ /** URI to identify the argument list for a builtin atom. */
+ public static final String ARGS_STR = SWRL + "arguments";
+
+ /** URI reference for a variable reference. */
+ public static final URIReferenceImpl VARIABLE = new URIReferenceImpl(URI.create(VARIABLE_STR));
+
+ /** URI reference for an implication (i.e. rule) */
+ public static final URIReferenceImpl IMP = new URIReferenceImpl(URI.create(IMP_STR));
+
+ /** URI reference for a rule head. */
+ public static final URIReferenceImpl HEAD = new URIReferenceImpl(URI.create(HEAD_STR));
+
+ /** URI reference for a rule body. */
+ public static final URIReferenceImpl BODY = new URIReferenceImpl(URI.create(BODY_STR));
+
+ /** URI reference for a class membership atom. */
+ public static final URIReferenceImpl CLASS_ATOM = new URIReferenceImpl(URI.create(CLASS_ATOM_STR));
+
+ /** URI reference for an individual-valued property atom. */
+ public static final URIReferenceImpl INDIVIDUAL_ATOM = new URIReferenceImpl(URI.create(INDIVIDUAL_ATOM_STR));
+
+ /** URI reference for a datatype-valued property atom. */
+ public static final URIReferenceImpl DATA_ATOM = new URIReferenceImpl(URI.create(DATA_ATOM_STR));
+
+ /** URI reference for an individual identity atom. */
+ public static final URIReferenceImpl SAME_INDIVIDUALS_ATOM = new URIReferenceImpl(URI.create(SAME_INDIVIDUALS_ATOM_STR));
+
+ /** URI reference for an individual difference atom. */
+ public static final URIReferenceImpl DIFFERENT_INDIVIDUALS_ATOM = new URIReferenceImpl(URI.create(DIFFERENT_INDIVIDUALS_ATOM_STR));
+
+ /** URI reference for a builtin atom. */
+ public static final URIReferenceImpl BUILTIN_ATOM = new URIReferenceImpl(URI.create(BUILTIN_ATOM_STR));
+
+ /** URI reference for a data range atom. */
+ public static final URIReferenceImpl DATA_RANGE_ATOM = new URIReferenceImpl(URI.create(DATA_RANGE_ATOM_STR));
+
+ /** URI reference for a class atom predicate. */
+ public static final URIReferenceImpl CLASS_PREDICATE = new URIReferenceImpl(URI.create(CLASS_PREDICATE_STR));
+
+ /** URI reference for an individual or datatype property atom predicate. */
+ public static final URIReferenceImpl PROPERTY_PREDICATE = new URIReferenceImpl(URI.create(PROPERTY_PREDICATE_STR));
+
+ /** URI reference for a builtin atom operator. */
+ public static final URIReferenceImpl BUILTIN = new URIReferenceImpl(URI.create(BUILTIN_STR));
+
+ /** URI reference for a data range atom predicate. */
+ public static final URIReferenceImpl DATA_RANGE = new URIReferenceImpl(URI.create(DATA_RANGE_STR));
+
+ /** URI reference to identify the first argument to an atom. */
+ public static final URIReferenceImpl ARG_1 = new URIReferenceImpl(URI.create(ARG_1_STR));
+
+ /** URI reference to identify the second argument to an atom. */
+ public static final URIReferenceImpl ARG_2 = new URIReferenceImpl(URI.create(ARG_2_STR));
+
+ /** URI reference to identify the argument list for a builtin atom. */
+ public static final URIReferenceImpl ARGS = new URIReferenceImpl(URI.create(ARGS_STR));
+
+}
Added: trunk/src/jar/swrl/build.xml
===================================================================
--- trunk/src/jar/swrl/build.xml (rev 0)
+++ trunk/src/jar/swrl/build.xml 2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE project>
+
+<!-- =================================================================== -->
+<!-- Project definition -->
+<!-- =================================================================== -->
+<project name="swrl" default="swrl.jar" basedir="../../..">
+
+ <!-- =================================================================== -->
+ <!-- Property Definitions -->
+ <!-- =================================================================== -->
+
+ <!-- =================================================================== -->
+ <!-- Imports -->
+ <!-- =================================================================== -->
+
+ <!-- =================================================================== -->
+ <!-- Path Definitions -->
+ <!-- =================================================================== -->
+ <path id="swrl-classpath">
+
+ <path refid="common-classpath"/>
+
+ <pathelement path="${query.dist.dir}/${query.jar}"/>
+ <pathelement path="${driver.dist.dir}/${driver.jar}"/>
+ <pathelement path="${util.dist.dir}/${util.jar}"/>
+ <pathelement path="${querylang.dist.dir}/${querylang.jar}"/>
+ <pathelement path="${tuples.dist.dir}/${tuples.jar}"/>
+ <pathelement path="${resolver.dist.dir}/${resolver.jar}"/>
+ <pathelement path="${krule.dist.dir}/${krule.jar}"/>
+ </path>
+
+ <path id="swrl-test-classpath">
+
+ <path refid="swrl-classpath"/>
+
+ <fileset file="${swrl.dist.dir}/${swrl.jar}"/>
+ </path>
+
+ <target name="swrl-clean"
+ description="Removes all compile generated files for the swrl">
+
+ <tstamp/>
+
+ <delete dir="${swrl.obj.dir}"/>
+ <delete dir="${swrl.test.dir}"/>
+ <delete dir="${swrl.dist.dir}"/>
+ </target>
+
+ <target name="-swrl-prepare"
+ description="Creates all directories associated with the swrl's compilation"
+ depends="-prepare-build">
+
+ <mkdir dir="${swrl.obj.dir}"/>
+ <mkdir dir="${swrl.test.dir}"/>
+ <mkdir dir="${swrl.dist.dir}"/>
+ <mkdir dir="${swrl.obj.dir}/classes"/>
+ </target>
+
+ <target name="swrl-compile"
+ depends="-swrl-prepare, driver-jar, querylang-jar, tuples-jar, resolver-jar, krule-jar"
+ description="Compiles all swrl related files included generated source code">
+
+ <javac destdir="${swrl.obj.dir}/classes" debug="on"
+ deprecation="on" source="1.5">
+
+ <classpath refid="swrl-classpath"/>
+
+ <src path="${swrl.src.dir}/java"/>
+ </javac>
+ </target>
+
+ <target name="swrl-jar"
+ depends="swrl-compile, -swrl-jar-uptodate"
+ unless="swrl.jar.uptodate"
+ description="Builds the NodeType Resolver JAR">
+
+ <jar jarfile="${swrl.dist.dir}/${swrl.jar}">
+ <fileset dir="${swrl.obj.dir}/classes"/>
+ </jar>
+ </target>
+
+ <target name="-swrl-jar-uptodate">
+
+ <uptodate property="swrl.jar.uptodate"
+ targetfile="${swrl.dist.dir}/${swrl.jar}">
+ <srcfiles dir="${swrl.obj.dir}/classes" includes="**/*"/>
+ </uptodate>
+ </target>
+
+ <target name="swrl-dist"
+ depends="swrl-jar"
+ unless="swrl.uptodate"
+ description="Performs all tasks related to finalising this swrl and readying it for distribution">
+
+ <!-- All that's involved in the final version of the swrl library
+ is the jar so we don't need to do anything because the dependencies
+ take care of the work. -->
+ </target>
+
+ <target name="swrl-test"
+ depends="swrl-jar"
+ description="Carries out unit testing for this swrl">
+
+ <antcall target="component-test">
+
+ <param name="classpath.id" value="swrl-test-classpath"/>
+ <param name="dir" value="${swrl.src.dir}"/>
+ <param name="jar" value="${swrl.jar}"/>
+ </antcall>
+ </target>
+
+ <target name="swrl-javadoc"
+ depends="swrl-jar"
+ description="Creates the javadoc for this swrl">
+
+ <antcall target="javadoc">
+
+ <param name="javadoc.package" value="org.mulgara.swrl.*"/>
+ <param name="javadoc.classpath" value="swrl-classpath"/>
+ <param name="javadoc.sourcepath" value="${swrl.src.dir}/java"/>
+ </antcall>
+ </target>
+
+ <target name="swrl-help"
+ description="Displays the help information for this swrl">
+
+ <!-- This is similar to the main project's help except the information
+ is specific to this swrl -->
+
+ <echo message="Welcome to the build script for ${swrl.name}."/>
+ <echo message=""/>
+ <echo message="These targets can be invoked as follows:"/>
+ <echo message=" ./build.sh <target>"/>
+ <echo message=""/>
+
+ <java fork="false" classname="org.apache.tools.ant.Main"
+ newenvironment="false">
+
+ <jvmarg value="${arch.bits}"/>
+
+ <arg line="-buildfile ${swrl.src.dir}/build.xml -projecthelp"/>
+ </java>
+ </target>
+</project>
Added: trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java
===================================================================
--- trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java (rev 0)
+++ trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java 2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,916 @@
+/*
+ * 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.swrl;
+
+import java.net.URI;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.jrdf.graph.BlankNode;
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.jrdf.graph.ObjectNode;
+import org.jrdf.graph.PredicateNode;
+import org.jrdf.graph.SubjectNode;
+import org.jrdf.graph.Triple;
+import org.jrdf.graph.URIReference;
+import org.jrdf.vocabulary.OWL;
+import org.jrdf.vocabulary.RDF;
+import org.mulgara.itql.VariableFactoryImpl;
+import org.mulgara.krule.ConsistencyCheck;
+import org.mulgara.krule.KruleStructureException;
+import org.mulgara.krule.QueryStruct;
+import org.mulgara.krule.Rule;
+import org.mulgara.krule.RuleStructure;
+import org.mulgara.query.Answer;
+import org.mulgara.query.ConstantValue;
+import org.mulgara.query.ConstraintConjunction;
+import org.mulgara.query.ConstraintDisjunction;
+import org.mulgara.query.ConstraintElement;
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintFilter;
+import org.mulgara.query.ConstraintImpl;
+import org.mulgara.query.ConstraintIs;
+import org.mulgara.query.ConstraintOperation;
+import org.mulgara.query.GraphExpression;
+import org.mulgara.query.GraphResource;
+import org.mulgara.query.Order;
+import org.mulgara.query.Query;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.SelectElement;
+import org.mulgara.query.SingleTransitiveConstraint;
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.UnconstrainedAnswer;
+import org.mulgara.query.Value;
+import org.mulgara.query.Variable;
+import org.mulgara.query.VariableFactory;
+import org.mulgara.query.filter.And;
+import org.mulgara.query.filter.Equals;
+import org.mulgara.query.filter.Filter;
+import org.mulgara.query.filter.RDFTerm;
+import org.mulgara.query.filter.value.DataTypeFn;
+import org.mulgara.query.filter.value.IRI;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.Var;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.SWRL;
+import org.mulgara.query.rdf.TripleImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+import org.mulgara.query.rdf.VariableNodeImpl;
+import org.mulgara.resolver.OperationContext;
+import org.mulgara.rules.InitializerException;
+import org.mulgara.rules.RuleLoader;
+import org.mulgara.rules.Rules;
+import org.mulgara.util.functional.Pair;
+
+/**
+ * Implementation of a rule loader which parses rule definitions from an RDF
+ * graph according to the SWRL schema.
+ *
+ * @created Jun 4, 2009
+ * @author Alex Hall
+ * @copyright © 2009 <a href="http://www.revelytix.com">Revelytix, Inc.</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SWRLLoader implements RuleLoader {
+
+ private static final Logger logger = Logger.getLogger(SWRLLoader.class.getName());
+
+ /** A field used in queries to indicate no prior constraints on the answer. */
+ private static final UnconstrainedAnswer UNCONSTRAINED = new UnconstrainedAnswer();
+
+ /** RDF reference for rdf:type. */
+ public static final URIReferenceImpl RDF_TYPE = new URIReferenceImpl(RDF.TYPE);
+
+ /** The graph from which rule definitions are being read. */
+ private final GraphResource ruleGraph;
+ /** The graph expression containing the base statements. */
+ private final GraphExpression baseGraph;
+ /** The graph where entailed statements will be inserted. */
+ private final URI destGraph;
+
+ /** The database session for querying. */
+ private OperationContext operationContext;
+
+ /** Factory for creating unique variables in the rule queries. */
+ private VariableFactory varFactory = new VariableFactoryImpl();
+
+ /**
+ * Factory method.
+ * @param ruleGraph The graph URI that contains the SWRL rule definitions.
+ * @param baseGraph The graph expression that contains the base statements.
+ * @param destGraph The graph URI that will receive the entailed statements.
+ * @return The rule loader which will process the rule definitions.
+ */
+ public static RuleLoader newInstance(URI ruleGraph, GraphExpression baseGraph, URI destGraph) {
+ return new SWRLLoader(ruleGraph, baseGraph, destGraph);
+ }
+
+ /**
+ * Initialize the rule loader with the rule, base, and destination graphs.
+ * @param ruleGraph The graph containing the rules to load.
+ * @param baseGraph The graph expression containing the base statements.
+ * @param destGraph The destination graph for entailed statements.
+ */
+ SWRLLoader(URI ruleGraph, GraphExpression baseGraph, URI destGraph) {
+ this.ruleGraph = new GraphResource(ruleGraph);
+ this.baseGraph = baseGraph;
+ this.destGraph = destGraph;
+ }
+
+ /* (non-Javadoc)
+ * @see org.mulgara.rules.RuleLoader#readRules(java.lang.Object)
+ */
+ @Override
+ public Rules readRules(Object session) throws InitializerException, RemoteException {
+ this.operationContext = (OperationContext)session;
+
+ RuleStructure rules = new RuleStructure();
+ rules.setTargetModel(destGraph);
+
+ try {
+ Map<URIReference,Variable> vars = findVariables();
+ if (logger.isDebugEnabled()) logger.debug("Found variables: " + vars);
+
+ List<Node> ruleNodes = findRules();
+ if (logger.isDebugEnabled()) logger.debug("Found rules: " + ruleNodes);
+
+ Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms = new HashMap<Node,Pair<URI,ConstraintImpl>>();
+ Map<Node,Pair<URI,Filter>> filterAtoms = new HashMap<Node,Pair<URI,Filter>>();
+ findAtoms(constraintAtoms, filterAtoms, vars);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Found constraint atoms: " + constraintAtoms);
+ logger.debug("Found filter atoms: " + filterAtoms);
+ }
+
+ for (Node ruleNode : ruleNodes) {
+ buildRule(ruleNode, rules, constraintAtoms, filterAtoms);
+ }
+
+ processTriggers(rules);
+ } catch (TuplesException te) {
+ logger.error("Exception while accessing rule data.", te);
+ throw new InitializerException("Problem accessing rule data", te);
+ } catch (QueryException qe) {
+ logger.error("Exception while reading rules.", qe);
+ throw new InitializerException("Problem reading rules", qe);
+ } catch (SWRLStructureException se) {
+ logger.error("Error in rule RDF data:" + se.getMessage(), se);
+ throw new InitializerException("Problem in rules RDF", se);
+ }
+
+ return rules;
+ }
+
+ /**
+ * Find all variable declarations in the rule graph. Variable references are
+ * identified using an <tt>rdf:type</tt> of <tt>swrl:Variable</tt>.
+ * @return A mapping of variable URI reference to a variable object which will
+ * represent that reference in all subsequent queries.
+ */
+ private Map<URIReference,Variable> findVariables() throws QueryException, TuplesException {
+ // select $var from <ruleGraph> where $var <rdf:type> <swrl:Variable>
+ Variable varV = new Variable("var");
+ ConstraintExpression where = new ConstraintImpl(varV, RDF_TYPE, SWRL.VARIABLE);
+ Query query = createQuery(where, varV);
+ if (logger.isDebugEnabled()) logger.debug("Variable query: " + query);
+ Answer answer = doQuery(query);
+
+ Map<URIReference,Variable> variables = new HashMap<URIReference,Variable>();
+
+ try {
+ answer.beforeFirst();
+ while (answer.next()) {
+ Object obj = answer.getObject(varV.getName());
+ if (logger.isDebugEnabled()) logger.debug("Found variable: " + obj);
+ if (obj instanceof URIReference) {
+ Variable var = varFactory.newVariable();
+ variables.put((URIReference)obj, var);
+ }
+ }
+ } finally {
+ answer.close();
+ }
+
+ return variables;
+ }
+
+ /**
+ * Find all resources in the rule graph that represent SWRL rules (a.k.a. implications).
+ * A rule is identified by an <tt>rdf:type</tt> of <tt>swrl:Imp</tt>.
+ * @return A list of RDF nodes that represent rule resources.
+ */
+ private List<Node> findRules() throws QueryException, TuplesException {
+ // select $rule from <ruleGraph> where $rule <rdf:type> <swrl:Imp>
+ Variable ruleVar = new Variable("rule");
+ ConstraintExpression where = new ConstraintImpl(ruleVar, RDF_TYPE, SWRL.IMP);
+ Query query = createQuery(where, ruleVar);
+ if (logger.isDebugEnabled()) logger.debug("Rule query: " + query);
+ Answer answer = doQuery(query);
+
+ List<Node> rules = new ArrayList<Node>();
+ try {
+ answer.beforeFirst();
+ while (answer.next()) {
+ rules.add((Node)answer.getObject(ruleVar.getName()));
+ }
+ } finally {
+ answer.close();
+ }
+
+ return rules;
+ }
+
+ /**
+ * Finds all SWRL atoms in the rule graph, and convert them into query triple patterns
+ * or filters as appropriate. The triple patterns and filters are inserted into the supplied
+ * maps, and variable mappings are performed when the patterns and filters are constructed.
+ * @param constraintAtoms This object will be populated with SWRL atoms that convert to RDF
+ * triple patterns. The mapping is from the atom's RDF node to a [atom type URI, triple pattern] pair.
+ * @param filterAtoms This object will be populated with SWRL atoms that convert to SPARQL
+ * filters. The mapping is from the atom's RDF node to a [atom type URI, filter] pair.
+ * @param varMap A map of variable URI references to variable objects to use when constructing
+ * triple patterns and filters.
+ */
+ private void findAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<Node,Pair<URI,Filter>> filterAtoms, Map<URIReference,Variable> varMap)
+ throws QueryException, TuplesException, SWRLStructureException {
+ findClassAtoms(constraintAtoms, varMap);
+ findIndividualAtoms(constraintAtoms, varMap);
+ findDataAtoms(constraintAtoms, varMap);
+ findIdentityAtoms(constraintAtoms, varMap);
+ findDataRangeAtoms(filterAtoms, varMap);
+ findBuiltinAtoms(filterAtoms, varMap);
+ }
+
+ /**
+ * Find all atoms in the rule graph of type <tt>swrl:ClassAtom</tt> and insert the resulting
+ * triple patterns into the supplied map. Note that only named classes are supported.
+ * A class atom has the form:
+ * <pre>
+ * _:x rdf:type swrl:ClassAtom .
+ * _:x swrl:classPredicate ex:MyClass .
+ * _:x swrl:argument1 rule:varX .
+ * </pre>
+ * and will be translated into the triple pattern: <tt>[$varX rdf:type ex:MyClass]</tt>
+ * @param constraintAtoms The map into which the triple patterns are inserted.
+ * @param varMap The variable reference map which is used to construct the triple patterns.
+ */
+ private void findClassAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<URIReference,Variable> varMap)
+ throws QueryException, TuplesException, SWRLStructureException {
+ // select $atom $class $arg from <ruleGraph>
+ // where $atom <rdf:type> <swrl:ClassAtom> and $atom <swrl:classPredicate> $class and $atom <swrl:argument1> $arg
+ Variable atomVar = new Variable("atom");
+ Variable classVar = new Variable("class");
+ Variable argVar = new Variable("arg");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(atomVar, RDF_TYPE, SWRL.CLASS_ATOM),
+ new ConstraintImpl(atomVar, SWRL.CLASS_PREDICATE, classVar),
+ new ConstraintImpl(atomVar, SWRL.ARG_1, argVar)
+ );
+
+ Query query = createQuery(where, atomVar, classVar, argVar);
+ Answer answer = doQuery(query);
+
+ try {
+ answer.beforeFirst();
+ while (answer.next()) {
+ Node atom = (Node)answer.getObject(atomVar.getName());
+ Object classObj = answer.getObject(classVar.getName());
+ checkClass(classObj, URIReference.class, "Only named classes may be used with class atoms.");
+ Object argObj = answer.getObject(argVar.getName());
+ checkClass(argObj, URIReference.class, "Argument of a class atom may only be a URI or variable reference");
+ constraintAtoms.put(atom, new Pair<URI,ConstraintImpl>(SWRL.CLASS_ATOM.getURI(),
+ toConstraint((URIReference)argObj, RDF_TYPE, (URIReference)classObj, varMap)));
+ }
+ } finally {
+ answer.close();
+ }
+ }
+
+ /**
+ * Find all atoms in the rule graph of type <tt>swrl:IndividualPropertyAtom</tt> and insert
+ * the resulting triple patterns into the supplied map. An individual property atom has the form:
+ * <pre>
+ * _:x rdf:type swrl:IndividualPropertyAtom .
+ * _:x swrl:propertyPredicate ex:myObjectProperty .
+ * _:x swrl:argument1 ex:myIndividual .
+ * _:x swrl:argument2 rule:varX .
+ * </pre>
+ * and will be translated to the triple pattern: <tt>[ex:myIndividual ex:myObjectProperty $varX]</tt>.
+ * @param constraintAtoms The map into which the triple patterns are inserted.
+ * @param varMap The variable reference map which is used to construct the triple patterns.
+ */
+ private void findIndividualAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<URIReference,Variable> varMap)
+ throws QueryException, TuplesException, SWRLStructureException {
+ // select $atom $property $arg1 $arg2 from <ruleGraph>
+ // where $atom <rdf:type> <swrl:IndividualPropertyAtom> and $atom <swrl:propertyPredicate> $property
+ // and $atom <swrl:argument1> $arg1 and $atom <swrl:argument2> $arg2;
+ Variable atomVar = new Variable("atom");
+ Variable propertyVar = new Variable("property");
+ Variable arg1Var = new Variable("arg1");
+ Variable arg2Var = new Variable("arg2");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(atomVar, RDF_TYPE, SWRL.INDIVIDUAL_ATOM),
+ new ConstraintImpl(atomVar, SWRL.PROPERTY_PREDICATE, propertyVar),
+ new ConstraintImpl(atomVar, SWRL.ARG_1, arg1Var),
+ new ConstraintImpl(atomVar, SWRL.ARG_2, arg2Var)
+ );
+
+ Query query = createQuery(where, atomVar, propertyVar, arg1Var, arg2Var);
+ Answer answer = doQuery(query);
+
+ try {
+ answer.beforeFirst();
+ while (answer.next()) {
+ Node atom = (Node)answer.getObject(atomVar.getName());
+ Object subjectObj = answer.getObject(arg1Var.getName());
+ checkClass(subjectObj, URIReference.class, "Subject of an individual property atom must be a URI or variable reference");
+ Object propertyObj = answer.getObject(propertyVar.getName());
+ checkClass(propertyObj, URIReference.class, "Predicate of an individual property atom must be a URI");
+ Node object = (Node)answer.getObject(arg2Var.getName());
+ constraintAtoms.put(atom, new Pair<URI,ConstraintImpl>(SWRL.INDIVIDUAL_ATOM.getURI(),
+ toConstraint((URIReference)subjectObj, (URIReference)propertyObj, object, varMap)));
+ }
+ } finally {
+ answer.close();
+ }
+ }
+
+ /**
+ * Find all atoms in the rule graph of type <tt>swrl:DatavaluedPropertyAtom</tt> and insert
+ * the resulting triple patterns into the supplied map. An individual property atom has the form:
+ * <pre>
+ * _:x rdf:type swrl:DatavaluedPropertyAtom .
+ * _:x swrl:propertyPredicate ex:myDataProperty .
+ * _:x swrl:argument1 ex:myIndividual .
+ * _:x swrl:argument2 rule:varX .
+ * </pre>
+ * and will be translated to the triple pattern: <tt>[ex:myIndividual ex:myDataProperty $varX]</tt>.
+ * @param constraintAtoms The map into which the triple patterns are inserted.
+ * @param varMap The variable reference map which is used to construct the triple patterns.
+ */
+ private void findDataAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<URIReference,Variable> varMap)
+ throws QueryException, TuplesException, SWRLStructureException {
+ // select $atom $property $arg1 $arg2 from <ruleGraph>
+ // where $atom <rdf:type> <swrl:DatavaluedPropertyAtom> and $atom <swrl:propertyPredicate> $property
+ // and $atom <swrl:argument1> $arg1 and $atom <swrl:argument2> $arg2;
+ Variable atomVar = new Variable("atom");
+ Variable propertyVar = new Variable("property");
+ Variable arg1Var = new Variable("arg1");
+ Variable arg2Var = new Variable("arg2");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(atomVar, RDF_TYPE, SWRL.DATA_ATOM),
+ new ConstraintImpl(atomVar, SWRL.PROPERTY_PREDICATE, propertyVar),
+ new ConstraintImpl(atomVar, SWRL.ARG_1, arg1Var),
+ new ConstraintImpl(atomVar, SWRL.ARG_2, arg2Var)
+ );
+
+ Query query = createQuery(where, atomVar, propertyVar, arg1Var, arg2Var);
+ Answer answer = doQuery(query);
+
+ try {
+ answer.beforeFirst();
+ while (answer.next()) {
+ Node atom = (Node)answer.getObject(atomVar.getName());
+ Object subjectObj = answer.getObject(arg1Var.getName());
+ checkClass(subjectObj, URIReference.class, "Subject of a data-valued property atom must be a URI or variable reference");
+ Object propertyObj = answer.getObject(propertyVar.getName());
+ checkClass(propertyObj, URIReference.class, "Predicate of a data-valued property atom must be a URI");
+ Node object = (Node)answer.getObject(arg2Var.getName());
+ constraintAtoms.put(atom, new Pair<URI,ConstraintImpl>(SWRL.DATA_ATOM.getURI(),
+ toConstraint((URIReference)subjectObj, (URIReference)propertyObj, object, varMap)));
+ }
+ } finally {
+ answer.close();
+ }
+ }
+
+ /**
+ * Find all identity atoms in the rule graph (i.e. atoms of type <tt>swrl:SameIndividualsAtom</tt>
+ * and <tt>swrl:DifferentIndividualsAtom</tt>) an insert the resulting triple patterns into
+ * the supplied map. Identity atoms take the following form:
+ * <pre>
+ * _:x rdf:type swrl:SameIndividualsAtom .
+ * _:x swrl:argument1 ex:individualA .
+ * _:x swrl:argument2 rule:varX .
+ *
+ * _:y rdf:type swrl:DifferentIndividualsAtom .
+ * _:x swrl:argument1 ex:individualB .
+ * _:x swrl:argument2 rule:varY .
+ * </pre>
+ * and are translated into the triple patterns: <tt>[ex:individualA owl:sameAs $varX]</tt>
+ * and <tt>[ex:individualB owl:differentFrom $varY]</tt>.
+ * @param constraintAtoms The map into which the triple patterns are inserted.
+ * @param varMap The variable reference map which is used to construct the triple patterns.
+ */
+ private void findIdentityAtoms(Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<URIReference,Variable> varMap)
+ throws QueryException, TuplesException, SWRLStructureException {
+ // select $atom $type $arg1 $arg2 from <ruleGraph>
+ // where $atom <rdf:type> $type and $atom <swrl:argument1> $arg1 and $atom <swrl:argument2> $arg2
+ // and ($type <mulgara:is> <swrl:SameIndividualsAtom> or $type <mulgara:is> <swrl:DifferentIndividualsAtom>)
+ Variable atomVar = new Variable("atom");
+ Variable typeVar = new Variable("type");
+ Variable arg1Var = new Variable("arg1");
+ Variable arg2Var = new Variable("arg2");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(atomVar, RDF_TYPE, typeVar),
+ new ConstraintImpl(atomVar, SWRL.ARG_1, arg1Var),
+ new ConstraintImpl(atomVar, SWRL.ARG_2, arg2Var),
+ new ConstraintDisjunction(
+ new ConstraintIs(typeVar, SWRL.SAME_INDIVIDUALS_ATOM),
+ new ConstraintIs(typeVar, SWRL.DIFFERENT_INDIVIDUALS_ATOM))
+ );
+
+ Query query = createQuery(where, atomVar, typeVar, arg1Var, arg2Var);
+ Answer answer = doQuery(query);
+
+ try {
+ answer.beforeFirst();
+ while (answer.next()) {
+ Node atom = (Node)answer.getObject(atomVar.getName());
+ URIReference type = (URIReference)answer.getObject(typeVar.getName());
+ Object arg1Obj = answer.getObject(arg1Var.getName());
+ checkClass(arg1Obj, URIReference.class, "Arguments to identity atoms must be URI or variable references");
+ Object arg2Obj = answer.getObject(arg2Var.getName());
+ checkClass(arg2Obj, URIReference.class, "Arguments to identity atoms must be URI or variable references");
+
+ URIReference pred = null;
+ if (SWRL.SAME_INDIVIDUALS_ATOM.equals(type)) {
+ pred = new URIReferenceImpl(OWL.SAME_AS);
+ } else if (SWRL.DIFFERENT_INDIVIDUALS_ATOM.equals(type)) {
+ pred = new URIReferenceImpl(OWL.DIFFERENT_FROM);
+ } else {
+ throw new IllegalStateException("Unexpected type result for identiy atom: " + type);
+ }
+
+ constraintAtoms.put(atom, new Pair<URI,ConstraintImpl>(type.getURI(),
+ toConstraint((URIReference)arg1Obj, pred, (URIReference)arg2Obj, varMap)));
+ }
+ } finally {
+ answer.close();
+ }
+ }
+
+ /**
+ * Find all atoms in the rule graph of type <tt>swrl:DataRangeAtom</tt> and insert the
+ * resulting filters into the supplied map. Note that only named datatypes are supported.
+ * A data range atom has the form:
+ * <pre>
+ * _:x rdf:type swrl:DataRangeAtom .
+ * _:x swrl:dataRange xsd:integer .
+ * _:x swrl:argument1 rule:varX .
+ * </pre>
+ * and is mapped to the SPARQL filter clause: <tt>FILTER( datatype(?varX) = xsd:integer )</tt>.
+ * @param filterAtoms The map into which the filters are inserted.
+ * @param varMap The variable reference map which is used to construct the triple patterns.
+ */
+ private void findDataRangeAtoms(Map<Node,Pair<URI,Filter>> filterAtoms, Map<URIReference,Variable> varMap)
+ throws QueryException, TuplesException, SWRLStructureException {
+ // select $atom $range $arg from <ruleGraph>
+ // where $atom <rdf:type> <swrl:DataRangeAtom> and $atom <swrl:dataRange> $range and $atom <swrl:argument1> $arg
+ Variable atomVar = new Variable("atom");
+ Variable rangeVar = new Variable("range");
+ Variable argVar = new Variable("arg");
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(atomVar, RDF_TYPE, SWRL.DATA_RANGE_ATOM),
+ new ConstraintImpl(atomVar, SWRL.DATA_RANGE, rangeVar),
+ new ConstraintImpl(atomVar, SWRL.ARG_1, argVar)
+ );
+
+ Query query = createQuery(where, atomVar, rangeVar, argVar);
+ Answer answer = doQuery(query);
+
+ try {
+ answer.beforeFirst();
+ while (answer.next()) {
+ Node atom = (Node)answer.getObject(atomVar.getName());
+ Object rangeObj = answer.getObject(rangeVar.getName());
+ checkClass(rangeObj, URIReference.class, "Data range atom must specify a named datatype or variable reference");
+ Node arg = (Node)answer.getObject(argVar.getName());
+ Filter filter = new Equals(toRdfTerm((URIReference)rangeObj, varMap), new DataTypeFn(toRdfTerm(arg, varMap)));
+ filterAtoms.put(atom, new Pair<URI,Filter>(SWRL.DATA_RANGE_ATOM.getURI(), filter));
+ }
+ } finally {
+ answer.close();
+ }
+ }
+
+ /**
+ * Find all atoms in the rule graph of type <tt>swrl:BuiltinAtom</tt> and insert the
+ * resulting filters into the supplied map. Currently unimplemented.
+ * @param filterAtoms The map into which the filters are inserted.
+ * @param varMap The variable reference map which is used to construct the triple patterns.
+ */
+ private void findBuiltinAtoms(Map<Node,Pair<URI,Filter>> filterAtoms, Map<URIReference,Variable> varMap)
+ throws QueryException, TuplesException, SWRLStructureException {
+ // TODO Implement me.
+ }
+
+ /**
+ * Builds the rule identified by the given RDF node, and inserts it into the supplied
+ * rule structure. Rules handled by this method may be ordinary rules, consistency checks,
+ * or axioms, depending on the number of atoms in the body and head of the SWRL implication.
+ * @param ruleNode The RDF node that identifies the rule description to build.
+ * @param rules The rule structure to hold the new rule.
+ * @param constraintAtoms A pre-loaded map containing all triple-pattern atoms in the rule graph.
+ * @param filterAtoms A pre-loaded map containing all filter atoms in the rule graph.
+ */
+ private void buildRule(Node ruleNode, RuleStructure rules,
+ Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms, Map<Node,Pair<URI,Filter>> filterAtoms)
+ throws QueryException, TuplesException, SWRLStructureException {
+ if (logger.isDebugEnabled()) logger.debug("Building structure for rule: " + ruleNode);
+
+ Set<Node> bodyAtoms = getListMembers(ruleNode, SWRL.BODY);
+ if (logger.isDebugEnabled()) logger.debug("Found body atoms: " + bodyAtoms);
+
+ Set<Node> headAtoms = getListMembers(ruleNode, SWRL.HEAD);
+ if (logger.isDebugEnabled()) logger.debug("Found head atoms: " + headAtoms);
+
+ if (bodyAtoms.isEmpty() && headAtoms.isEmpty()) throw new SWRLStructureException("Rule must have at least one atom: " + ruleNode);
+
+ if (bodyAtoms.isEmpty()) {
+ // Empty body means it's an axiom
+ for (Node headAtom : headAtoms) {
+ rules.addAxiom(toAxiom(getHeadAtom(headAtom, constraintAtoms, filterAtoms)));
+ }
+ } else {
+ // Either a regular rule or a consistency check; both have queries.
+ ConstraintExpression whereClause = buildWhereClause(bodyAtoms, constraintAtoms, filterAtoms);
+ Rule rule = null;
+ List<SelectElement> selectVars = null;
+
+ if (headAtoms.isEmpty()) {
+ rule = new ConsistencyCheck(ruleNode.toString());
+ selectVars = new ArrayList<SelectElement>(whereClause.getVariables());
+ } else {
+ rule = new Rule(ruleNode.toString());
+ selectVars = getSelectElements(headAtoms, constraintAtoms, filterAtoms);
+ }
+
+ QueryStruct queryStruct = new QueryStruct(selectVars);
+ queryStruct.setWhereClause(whereClause);
+ queryStruct.setGraphExpression(baseGraph, destGraph);
+ try {
+ rule.setQueryStruct(queryStruct);
+ } catch (KruleStructureException e) {
+ throw new SWRLStructureException("Illegal query structure", e);
+ }
+ rules.add(rule);
+ }
+ }
+
+ /**
+ * Gets the triple pattern identified by the given atom node, or throws an exception if
+ * the given atom does not map to a triple pattern.
+ * @param node The RDF node representing an atom appearing in a rule head.
+ * @param constraintAtoms All triple-pattern atoms in the rule graph.
+ * @param filterAtoms All filter atoms in the rule graph.
+ * @return The triple pattern mapped to the given RDF node.
+ * @throws SWRLStructureException if the RDF node does not represent a triple pattern atom.
+ */
+ private ConstraintImpl getHeadAtom(Node node, Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms,
+ Map<Node,Pair<URI,Filter>> filterAtoms) throws SWRLStructureException {
+ if (constraintAtoms.containsKey(node)) {
+ return constraintAtoms.get(node).second();
+ } else if (filterAtoms.containsKey(node)) {
+ throw new SWRLStructureException("Atoms in rule head must map to triple patterns; found: " + filterAtoms.get(node).first());
+ } else {
+ throw new SWRLStructureException("Unable to map entry in rule head to an atom: " + node);
+ }
+ }
+
+ /**
+ * Converts a query triple pattern to an axiomatic statement.
+ * @param pattern A query triple pattern.
+ * @return The equivalent axiomatic statement.
+ * @throws SWRLStructureException if any position in the triple pattern contains a variable.
+ */
+ private Triple toAxiom(ConstraintImpl pattern) throws SWRLStructureException {
+ ConstraintElement c = pattern.getElement(0);
+ if (c instanceof Variable) throw new SWRLStructureException("Axioms may not contain variables.");
+ SubjectNode s = (SubjectNode)c;
+ c = pattern.getElement(1);
+ if (c instanceof Variable) throw new SWRLStructureException("Axioms may not contain variables.");
+ PredicateNode p = (PredicateNode)c;
+ c = pattern.getElement(2);
+ if (c instanceof Variable) throw new SWRLStructureException("Axioms may not contain variables.");
+ ObjectNode o = (ObjectNode)c;
+ return new TripleImpl(s, p, o);
+ }
+
+ /**
+ * Builds the where clause for a query given a collection of atoms in a rule body.
+ * The atoms from the rule body may map to triple patterns or filters, but at least one
+ * atom must map to a triple pattern.
+ * @param bodyAtoms A collection of RDF nodes that are atoms in the body of a SWRL implication.
+ * @param constraintAtoms All triple-pattern atoms in the rule graph.
+ * @param filterAtoms All filter atoms in the rule graph.
+ * @return The where clause for a query that represents the rule body.
+ */
+ private ConstraintExpression buildWhereClause(Set<Node> bodyAtoms, Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms,
+ Map<Node,Pair<URI,Filter>> filterAtoms) throws SWRLStructureException {
+ List<ConstraintExpression> triplePatterns = new ArrayList<ConstraintExpression>();
+ List<Filter> filters = new ArrayList<Filter>();
+
+ for (Node bodyAtom : bodyAtoms) {
+ if (constraintAtoms.containsKey(bodyAtom)) {
+ triplePatterns.add(constraintAtoms.get(bodyAtom).second());
+ } else if (filterAtoms.containsKey(bodyAtom)) {
+ filters.add(filterAtoms.get(bodyAtom).second());
+ } else {
+ throw new SWRLStructureException("Unable to map entry in rule head to an atom: " + bodyAtom);
+ }
+ }
+
+ if (triplePatterns.isEmpty()) {
+ throw new SWRLStructureException("Rule body must contain at least one triple pattern.");
+ }
+
+ ConstraintExpression whereClause = new ConstraintConjunction(triplePatterns);
+ if (!filters.isEmpty()) {
+ Filter filter = (filters.size() == 1) ? filters.get(0) : new And(filters.toArray(new Filter[filters.size()]));
+ whereClause = new ConstraintFilter(whereClause, filter);
+ }
+ return whereClause;
+ }
+
+ /**
+ * Construct a list of select elements that are specified by triple patterns in
+ * the head of a SWRL rule. The select elements may be either variables or constant values.
+ * @param headNodes A collection of RDF nodes that comprise the atoms in the head of a SWRL rule.
+ * @param constraintAtoms All triple-pattern atoms in the rule graph.
+ * @param filterAtoms All filter atoms in the rule graph.
+ * @return The list of elements that represent statements to be entailed by the rule.
+ */
+ private List<SelectElement> getSelectElements(Set<Node> headNodes, Map<Node,Pair<URI,ConstraintImpl>> constraintAtoms,
+ Map<Node,Pair<URI,Filter>> filterAtoms) throws SWRLStructureException {
+ List<SelectElement> selectElements = new ArrayList<SelectElement>();
+ for (Node headNode : headNodes) {
+ ConstraintImpl pattern = getHeadAtom(headNode, constraintAtoms, filterAtoms);
+ for (int i = 0; i < 3; i++) {
+ ConstraintElement e = pattern.getElement(i);
+ selectElements.add(e instanceof Variable ? (Variable)e : new ConstantValue(varFactory.newVariable(), (Value)e));
+ }
+ }
+ return selectElements;
+ }
+
+ /**
+ * Utility method to get all members of the RDF list whose head is the object of
+ * an RDF statement with the given subject and predicate.
+ * @param subject The subject of a statement which identifies the list.
+ * @param predicate The predicate of a statement which identifies the list.
+ * @return A collection of RDF nodes which comprise the given list.
+ */
+ private Set<Node> getListMembers(Node subject, URIReferenceImpl predicate) throws QueryException, TuplesException {
+ // select $value from <ruleGraph>
+ // where <parent> <predicate> $head
+ // and (trans($head <rdf:rest> $node) or $head <rdf:rest> $node)
+ // and ($head <rdf:first> $value or $node <rdf:first> $value)
+ Variable valueVar = new Variable("value");
+ Variable headVar = new Variable("head");
+ Variable nodeVar = new Variable("node");
+ URIReferenceImpl rdfRest = new URIReferenceImpl(RDF.REST);
+ URIReferenceImpl rdfFirst = new URIReferenceImpl(RDF.FIRST);
+ ConstraintExpression where = new ConstraintConjunction(
+ new ConstraintImpl(toElement(subject), predicate, headVar),
+ new ConstraintDisjunction(
+ new SingleTransitiveConstraint(new ConstraintImpl(headVar, rdfRest, nodeVar)),
+ new ConstraintImpl(headVar, rdfRest, nodeVar)),
+ new ConstraintDisjunction(
+ new ConstraintImpl(headVar, rdfFirst, valueVar),
+ new ConstraintImpl(nodeVar, rdfFirst, valueVar))
+ );
+
+ Query query = createQuery(where, valueVar);
+ Answer answer = doQuery(query);
+ Set<Node> values = new HashSet<Node>();
+ try {
+ answer.beforeFirst();
+ while (answer.next()) values.add((Node)answer.getObject(valueVar.getName()));
+ } finally {
+ answer.close();
+ }
+ return values;
+ }
+
+ /**
+ * Detect and add all trigger dependencies between rules to the given rule structure.
+ * @param rules The rule structure for which to process triggers.
+ */
+ private void processTriggers(RuleStructure rules) {
+ for (Iterator<Rule> it1 = rules.getRuleIterator(); it1.hasNext(); ) {
+ Rule trigger = it1.next();
+ for (Iterator<Rule> it2 = rules.getRuleIterator(); it2.hasNext(); ) {
+ Rule potentialTarget = it2.next();
+ if (triggersRule(trigger, potentialTarget)) trigger.addTriggerTarget(potentialTarget);
+ }
+ }
+ }
+
+ /**
+ * Determine if a rule triggers a potential terget.
+ * @param trigger The rule which may potentially trigger another rule.
+ * @param potentialTarget The potential target of the rule.
+ * @return <tt>true</tt> iff the given rule has a head atom which matches one of
+ * the body atoms of the potential target.
+ */
+ private boolean triggersRule(Rule trigger, Rule potentialTarget) {
+ // Consistency checks never trigger other rules (they throw exceptions instead).
+ if (trigger instanceof ConsistencyCheck) return false;
+
+ List<SelectElement> products = trigger.getQuery().getVariableList();
+ if (products.size() % 3 != 0) throw new IllegalStateException("Invalid number of select elements for rule query: " + trigger.getQuery());
+
+ for (int index = 0; index < products.size(); index += 3) {
+ List<SelectElement> triggerProduct = products.subList(index, index + 3);
+ if (matchesExpression(triggerProduct, potentialTarget.getQuery().getConstraintExpression())) return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Determine whether the head atom represented by the product list matches any part of
+ * the given constraint expression.
+ * @param product A triple pattern appearing as the product of a rule.
+ * @param expr The body of a potential target rule.
+ * @return <tt>true</tt> iff the triple pattern matches any part of the potential target.
+ */
+ private boolean matchesExpression(List<SelectElement> product, ConstraintExpression expr) {
+ assert product.size() == 3;
+ // Only triple patterns, conjunctions, and filters are created by the rule loader; ignore other
+ // constraint types.
+ if (expr instanceof ConstraintImpl) return matchesPattern(product, (ConstraintImpl)expr);
+ else if (expr instanceof ConstraintOperation) {
+ // An operation matches if any of the operands matches.
+ boolean matches = false;
+ for (ConstraintExpression operand : ((ConstraintOperation)expr).getElements()) {
+ matches = matches || matchesExpression(product, operand);
+ }
+ return matches;
+ } else if (expr instanceof ConstraintFilter) {
+ // Only the unfiltered part of a constraint can trigger a match (filters restrict the results from the unfiltered part).
+ return matchesExpression(product, ((ConstraintFilter)expr).getUnfilteredConstraint());
+ }
+ return false;
+ }
+
+ /**
+ * Determine whether a triple product in the head of one rule matches the triple pattern
+ * in the body of another rule.
+ * @param product A triple product.
+ * @param pattern A triple pattern.
+ * @return <tt>true</tt> if the product and pattern match at every position. A match is
+ * defined as both constants with the same value, or both variables (regardless of
+ * variable name).
+ */
+ private boolean matchesPattern(List<SelectElement> product, ConstraintImpl pattern) {
+ assert product.size() == 3;
+ for (int i = 0; i < product.size(); i++) {
+ SelectElement productTerm = product.get(i);
+ if ((productTerm instanceof ConstantValue) && !(((ConstantValue)productTerm).getValue().equals(pattern.getElement(i)))) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Utility method to create a query.
+ * @param constraintExpression The constraint expression making up the WHERE clause of the query.
+ * @param selection The variables to select in the query.
+ * @return The new query.
+ */
+ @SuppressWarnings("unchecked")
+ private Query createQuery(ConstraintExpression constraintExpression, Variable... selection) {
+ List<Variable> selectList = Arrays.asList(selection);
+ return new Query(
+ selectList, // SELECT
+ ruleGraph, // FROM
+ constraintExpression, // WHERE
+ null, // HAVING
+ (List<Order>)Collections.EMPTY_LIST, // ORDER BY
+ null, // LIMIT
+ 0, // OFFSET
+ UNCONSTRAINED // GIVEN
+ );
+ }
+
+ /**
+ * Local wrapper for querying on an OperationContext. Since {@link OperationContext#doQuery(Query)}
+ * throws an {@link Exception}, this is captured and wrapped in or cast to a {@link QueryException}.
+ * @param q The query to execute.
+ * @return The Answer to the query.
+ * @throws QueryException If the query fails.
+ */
+ private Answer doQuery(Query q) throws QueryException {
+ try {
+ if (operationContext != null) return operationContext.doQuery(q);
+ throw new IllegalStateException("No environment to query the database in");
+ } catch (Exception e) {
+ if (e instanceof QueryException) throw (QueryException)e;
+ throw new QueryException("Unable to execute query", e);
+ }
+ }
+
+ /**
+ * Converts an RDF node into an RDF term used in a filter. Variable mappings from the
+ * rule graph are applied as part of this conversion.
+ * @param node A node from an RDF graph.
+ * @param varMap The variable mappings defined by the rule graph.
+ * @return The corresponding RDF term.
+ */
+ private RDFTerm toRdfTerm(Node node, Map<URIReference,Variable> varMap) throws QueryException, SWRLStructureException {
+ if (varMap.containsKey(node)) return new Var(varMap.get(node).getName());
+ if (node instanceof URIReference) return new IRI(((URIReference)node).getURI());
+ if (node instanceof Literal) {
+ Literal l = (Literal)node;
+ return TypedLiteral.newLiteral(l.getLexicalForm(), l.getDatatypeURI(), l.getLanguage());
+ }
+ throw new SWRLStructureException("RDF term in an atom must be a URI, literal, or variable reference");
+ }
+
+ /**
+ * Constructs a query triple pattern from a subject, predicate, and object RDF node.
+ * Variable mappings from the rule graph are applied as part of this operation.
+ * @param s The subject URI reference.
+ * @param p The predicate URI reference.
+ * @param o The object node.
+ * @param varMap The variable mappings defined by the rule graph.
+ * @return The corresponding triple pattern.
+ */
+ private ConstraintImpl toConstraint(URIReference s, URIReference p, Node o, Map<URIReference,Variable> varMap) throws SWRLStructureException {
+ ConstraintElement subject = varMap.containsKey(s) ? varMap.get(s): (s instanceof URIReferenceImpl ? (URIReferenceImpl)s : new URIReferenceImpl(s.getURI()));
+ ConstraintElement predicate = varMap.containsKey(p) ? varMap.get(p): (p instanceof URIReferenceImpl ? (URIReferenceImpl)p : new URIReferenceImpl(p.getURI()));
+ ConstraintElement object = null;
+ if (o instanceof URIReference) {
+ URIReference oUri = (URIReference)o;
+ object = varMap.containsKey(oUri) ? varMap.get(oUri) : (oUri instanceof URIReferenceImpl ? (URIReferenceImpl)oUri : new URIReferenceImpl(oUri.getURI()));
+ } else if (o instanceof Literal) {
+ object = toLiteralElement((Literal)o);
+ } else {
+ throw new SWRLStructureException("Object of a triple pattern must be a URI, literal, or variable reference; found: " + o);
+ }
+ return new ConstraintImpl(subject, predicate, object);
+ }
+
+ /**
+ * Converts a JRDF node to a query constraint element.
+ * @param node The JRDF node.
+ * @return The query constraint element.
+ */
+ private ConstraintElement toElement(Node node) {
+ if (node instanceof ConstraintElement) return (ConstraintElement)node;
+ if (node instanceof URIReference) {
+ return new URIReferenceImpl(((URIReference)node).getURI());
+ } else if (node instanceof Literal) {
+ return toLiteralElement((Literal)node);
+ } else if (node instanceof BlankNode) {
+ return new VariableNodeImpl(((BlankNode)node).getID());
+ }
+ throw new IllegalArgumentException("Unable to convert to constraint element: " + node);
+ }
+
+ /**
+ * Converts a JRDF literal node to a query constraint element.
+ * @param lit The JRDF literal node.
+ * @return The query constraint element.
+ */
+ private LiteralImpl toLiteralElement(Literal lit) {
+ if (lit instanceof LiteralImpl) return (LiteralImpl)lit;
+ else if (lit.getDatatypeURI() != null) return new LiteralImpl(lit.getLexicalForm(), lit.getDatatypeURI());
+ else if (lit.getLanguage() != null && lit.getLanguage().length() > 0) return new LiteralImpl(lit.getLexicalForm(), lit.getLanguage());
+ else return new LiteralImpl(lit.getLexicalForm());
+ }
+
+ /**
+ * Utility method to do type checking on an object extracted from query results.
+ * @param <T> The expected class.
+ * @param obj The object that was extracted from a query answer.
+ * @param expected The expected class of the object.
+ * @param msg The message to use when throwing an exception if the class doesn't match.
+ * @throws SWRLStructureException if the actual class of the object doesn't match the expected class.
+ */
+ private <T> void checkClass(Object obj, Class<T> expected, String msg) throws SWRLStructureException {
+ if (!expected.isAssignableFrom(obj.getClass())) {
+ throw new SWRLStructureException(msg);
+ }
+ }
+}
Added: trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLStructureException.java
===================================================================
--- trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLStructureException.java (rev 0)
+++ trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLStructureException.java 2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,42 @@
+/*
+ * 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.swrl;
+
+/**
+ * Exception to indicate an error in the structure of an RDF graph describing
+ * a collection of SWRL rules.
+ *
+ * @created Jun 5, 2009
+ * @author Alex Hall
+ * @copyright © 2009 <a href="http://www.revelytix.com">Revelytix, Inc.</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SWRLStructureException extends Exception {
+
+ private static final long serialVersionUID = -8536158307400743724L;
+
+ /**
+ * @param message The exception message.
+ */
+ public SWRLStructureException(String message) {
+ super(message);
+ }
+
+ /**
+ * @param message The exception message.
+ * @param cause The exception cause.
+ */
+ public SWRLStructureException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
Added: trunk/src/jar/swrl/swrl-build.properties
===================================================================
--- trunk/src/jar/swrl/swrl-build.properties (rev 0)
+++ trunk/src/jar/swrl/swrl-build.properties 2009-06-08 19:47:56 UTC (rev 1720)
@@ -0,0 +1,17 @@
+#
+# Properties used by the SWRL module
+#
+# $Id: krule-build.properties,v 1.1 2005/06/26 12:41:14 pgearon Exp $
+#
+
+# Module Name
+swrl.name = SWRL
+
+# General module properties
+swrl.conf.dir = ${conf.dir}
+swrl.src.dir = ${jar.src.dir}/swrl
+swrl.obj.dir = ${jar.obj.dir}/swrl
+swrl.dist.dir = ${bin.dir}
+swrl.test.dir = ${test.dir}/swrl
+swrl.jxtest.dir = ${jxtest.dir}/swrl
+swrl.jar = swrl-base-${mulgara-version}.jar
More information about the Mulgara-svn
mailing list