[Mulgara-svn] r795 - in branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter: . arithmetic value
pag at mulgara.org
pag at mulgara.org
Thu Apr 17 04:29:45 UTC 2008
Author: pag
Date: 2008-04-16 21:29:44 -0700 (Wed, 16 Apr 2008)
New Revision: 795
Added:
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java
Modified:
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotEquals.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/IRI.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java
branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/Var.java
Log:
Extensive testing of the filter package. This led to bugfixes and a few interface updates
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -13,6 +13,7 @@
import org.mulgara.query.QueryException;
import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.ComparableExpression;
import org.mulgara.query.filter.value.IRI;
import org.mulgara.query.filter.value.SimpleLiteral;
import org.mulgara.query.filter.value.ValueLiteral;
@@ -48,6 +49,9 @@
/** @see org.mulgara.query.filter.value.ValueLiteral#getType() */
public IRI getType() throws QueryException { return Bool.IRI_TYPE; }
+ /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+ public boolean isSimple() throws QueryException { return false; }
+
/**
* @see org.mulgara.query.filter.value.ValueLiteral#getLexical()
* @throws QueryException if this function does not resolve to a literal
@@ -94,6 +98,38 @@
/** @see org.mulgara.query.filter.RDFTerm#sameTerm(org.mulgara.query.filter.RDFTerm) */
public boolean sameTerm(RDFTerm v) throws QueryException { return resolve().sameTerm(v); }
+ /////////////////////////////////////////////////////////////////
+ // The following all implement the ComparableExpression interface
+ /////////////////////////////////////////////////////////////////
+
+ /** @see org.mulgara.query.filter.value.ComparableExpression#greaterThan(org.mulgara.query.filter.value.ComparableExpression) */
+ public boolean greaterThan(ComparableExpression v) throws QueryException {
+ if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
+ return ((ValueLiteral)resolve()).greaterThan(v);
+ }
+
+ /** @see org.mulgara.query.filter.value.ComparableExpression#greaterThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
+ public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
+ if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
+ return ((ValueLiteral)resolve()).greaterThanEqualTo(v);
+ }
+
+ /** @see org.mulgara.query.filter.value.ComparableExpression#lessThan(org.mulgara.query.filter.value.ComparableExpression) */
+ public boolean lessThan(ComparableExpression v) throws QueryException {
+ if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
+ return ((ValueLiteral)resolve()).lessThan(v);
+ }
+
+ /** @see org.mulgara.query.filter.value.ComparableExpression#lessThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
+ public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
+ if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
+ return ((ValueLiteral)resolve()).lessThanEqualTo(v);
+ }
+
+ /////////////////////////////////////////////////////////////////
+ // End of the ComparableExpression interface
+ /////////////////////////////////////////////////////////////////
+
/** @see org.mulgara.query.filter.RDFTerm#getContextOwner() */
public ContextOwner getContextOwner() { return contextOwner; }
Added: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java (rev 0)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -0,0 +1,365 @@
+/**
+ * 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.filter;
+
+import java.net.URI;
+import java.util.Date;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.ComparableExpression;
+import org.mulgara.query.filter.value.DateTime;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.Var;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the inequality functions.
+ *
+ * @created Apr 16, 2008
+ * @author Paul 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 BinaryComparisonUnitTest extends TestCase {
+
+ protected URI xsdInt = URI.create(XSD_NS + "int");
+ protected URI xsdFloat = URI.create(XSD_NS + "float");
+ protected URI xsdString = URI.create(XSD_NS + "string");
+ protected URI xsdDate = URI.create(XSD_NS + "dateTime");
+ Bool t = Bool.TRUE;
+ Bool f = Bool.FALSE;
+
+ /**
+ * Build the unit test.
+ * @param name The name of the test
+ */
+ public BinaryComparisonUnitTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Hook for test runner to obtain a test suite from.
+ * @return The test suite
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(new BinaryComparisonUnitTest("testLiteral"));
+ suite.addTest(new BinaryComparisonUnitTest("testVarCompatible"));
+ suite.addTest(new BinaryComparisonUnitTest("testVarInCompatible"));
+ return suite;
+ }
+
+ public void testLiteral() throws Exception {
+ // integers
+ ComparableExpression smaller = TypedLiteral.newLiteral(7);
+ ComparableExpression larger = TypedLiteral.newLiteral(8);
+ compatibleTest(smaller, larger);
+ // floats
+ smaller = TypedLiteral.newLiteral(7.0);
+ larger = TypedLiteral.newLiteral(8.0);
+ compatibleTest(smaller, larger);
+ // float/integer
+ larger = TypedLiteral.newLiteral(8);
+ compatibleTest(smaller, larger);
+
+ // simple literals
+ smaller = TypedLiteral.newLiteral("foo", null, null);
+ larger = TypedLiteral.newLiteral("goo", null, null);
+ compatibleTest(smaller, larger);
+ // simple literals, with language codes
+ smaller = TypedLiteral.newLiteral("foo", null, "en");
+ larger = TypedLiteral.newLiteral("foo", null, "fr");
+ compatibleTest(smaller, larger);
+ larger = TypedLiteral.newLiteral("goo", null, "en");
+ compatibleTest(smaller, larger);
+ // typed literal strings
+ smaller = TypedLiteral.newLiteral("foo");
+ larger = TypedLiteral.newLiteral("goo");
+ compatibleTest(smaller, larger);
+
+ // booleans
+ smaller = f;
+ larger = t;
+ compatibleTest(smaller, larger);
+
+ // typed literal strings
+ Date time = new Date();
+ smaller = new DateTime(time);
+ time = new Date();
+ time.setTime(time.getTime() + 100);
+ larger = new DateTime(time);
+ compatibleTest(smaller, larger);
+
+ // compare unequal literal types starting with an int
+ smaller = TypedLiteral.newLiteral(7);
+ larger = TypedLiteral.newLiteral("7", null, null);
+ incompatibleTest(smaller, larger);
+ larger = TypedLiteral.newLiteral("foo", null, "en");
+ incompatibleTest(smaller, larger);
+ larger = TypedLiteral.newLiteral("foo");
+ incompatibleTest(smaller, larger);
+ larger = t;
+ incompatibleTest(smaller, larger);
+ larger = new DateTime(time);
+ incompatibleTest(smaller, larger);
+
+ // compare unequal literal types starting with a float
+ smaller = TypedLiteral.newLiteral(7.0);
+ larger = TypedLiteral.newLiteral("7", null, null);
+ incompatibleTest(smaller, larger);
+ larger = TypedLiteral.newLiteral("foo", null, "en");
+ incompatibleTest(smaller, larger);
+ larger = TypedLiteral.newLiteral("foo");
+ incompatibleTest(smaller, larger);
+ larger = t;
+ incompatibleTest(smaller, larger);
+ larger = new DateTime(time);
+ incompatibleTest(smaller, larger);
+
+ // compare unequal literal types starting with a simple literal
+ smaller = TypedLiteral.newLiteral("foo", null, null);
+ larger = TypedLiteral.newLiteral("foo");
+ incompatibleTest(smaller, larger);
+ larger = t;
+ incompatibleTest(smaller, larger);
+ larger = new DateTime(time);
+ incompatibleTest(smaller, larger);
+
+ // compare unequal literal types starting with a language coded simple literal
+ smaller = TypedLiteral.newLiteral("foo", null, "en");
+ larger = TypedLiteral.newLiteral("foo");
+ incompatibleTest(smaller, larger);
+ larger = t;
+ incompatibleTest(smaller, larger);
+ larger = new DateTime(time);
+ incompatibleTest(smaller, larger);
+
+ // compare unequal literal types starting with a string literal
+ smaller = TypedLiteral.newLiteral("foo");
+ larger = t;
+ incompatibleTest(smaller, larger);
+ larger = new DateTime(time);
+ incompatibleTest(smaller, larger);
+
+ // compare unequal literal types
+ smaller = t;
+ larger = new DateTime(time);
+ incompatibleTest(smaller, larger);
+
+
+ smaller = TypedLiteral.newLiteral("foo", null, null);
+ larger = TypedLiteral.newLiteral("foo", xsdString, null);
+ incompatibleTest(smaller, larger);
+
+ }
+
+ private void compatibleTest(ComparableExpression smaller, ComparableExpression larger) throws Exception {
+ assertTrue(t.equals(new LessThan(smaller, larger)));
+ assertTrue(f.equals(new LessThan(larger, smaller)));
+ assertTrue(f.equals(new GreaterThan(smaller, larger)));
+ assertTrue(t.equals(new GreaterThan(larger, smaller)));
+ assertTrue(t.equals(new LessThanEqualTo(smaller, larger)));
+ assertTrue(f.equals(new LessThanEqualTo(larger, smaller)));
+ assertTrue(t.equals(new LessThanEqualTo(smaller, smaller)));
+ assertTrue(f.equals(new GreaterThanEqualTo(smaller, larger)));
+ assertTrue(t.equals(new GreaterThanEqualTo(larger, smaller)));
+ assertTrue(t.equals(new GreaterThanEqualTo(smaller, smaller)));
+ }
+
+ private void checkIncompatible(BinaryComparisonFilter op) throws Exception {
+ try {
+ op.getValue();
+ fail("Successfully compared incompatible types");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Type Error:"));
+ }
+ }
+
+ private void incompatibleTest(ComparableExpression lhs, ComparableExpression rhs) throws Exception {
+ checkIncompatible(new LessThan(lhs, rhs));
+ checkIncompatible(new LessThan(rhs, lhs));
+ checkIncompatible(new GreaterThan(lhs, rhs));
+ checkIncompatible(new GreaterThan(rhs, lhs));
+ checkIncompatible(new LessThanEqualTo(lhs, rhs));
+ checkIncompatible(new LessThanEqualTo(rhs, lhs));
+ checkIncompatible(new GreaterThanEqualTo(lhs, rhs));
+ checkIncompatible(new GreaterThanEqualTo(rhs, lhs));
+ }
+
+ public void testVarCompatible() throws Exception {
+ Var x = new Var("x");
+ Var y = new Var("y");
+ BinaryComparisonFilter ltT = new LessThan(x, y);
+ BinaryComparisonFilter ltF = new LessThan(y, x);
+ BinaryComparisonFilter gtT = new GreaterThan(x, y);
+ BinaryComparisonFilter gtF = new GreaterThan(y, x);
+
+ BinaryComparisonFilter lteT = new LessThanEqualTo(x, y);
+ BinaryComparisonFilter lteF = new LessThanEqualTo(y, x);
+ BinaryComparisonFilter lteE = new LessThanEqualTo(x, x);
+ BinaryComparisonFilter gteT = new GreaterThanEqualTo(x, y);
+ BinaryComparisonFilter gteF = new GreaterThanEqualTo(y, x);
+ BinaryComparisonFilter gteE = new GreaterThanEqualTo(x, x);
+
+ BinaryComparisonFilter[] comps = new BinaryComparisonFilter[] { ltT, ltF, gtT, gtF, lteT, lteF, lteE, gteT, gteF, gteE };
+
+ Literal seven = new LiteralImpl("7", xsdInt);
+ Literal eight = new LiteralImpl("8", xsdInt);
+ Literal sevenF = new LiteralImpl("7.0", xsdFloat);
+ Literal eightF = new LiteralImpl("8.0", xsdFloat);
+ Literal simpleFoo = new LiteralImpl("foo");
+ Literal simpleGoo = new LiteralImpl("goo");
+ Literal simpleFooEn = new LiteralImpl("foo", "en");
+ Literal simpleFooFr = new LiteralImpl("foo", "fr");
+ Literal simpleGooEn = new LiteralImpl("goo", "en");
+ Literal foo = new LiteralImpl("foo", xsdString);
+ Literal goo = new LiteralImpl("goo", xsdString);
+ Literal litFalse = new LiteralImpl("false", t.getType().getValue());
+ Literal litTrue = new LiteralImpl("true", t.getType().getValue());
+ Literal now = new LiteralImpl("2008-04-16T21:57:00Z", xsdDate);
+ Literal soon = new LiteralImpl("2008-04-16T21:58:01Z", xsdDate);
+ Node[][] rows = {
+ new Node[] {seven, eight},
+ new Node[] {sevenF, eightF},
+
+ new Node[] {simpleFoo, simpleGoo},
+ new Node[] {simpleFooEn, simpleFooFr},
+ new Node[] {simpleFooEn, simpleGooEn},
+ new Node[] {foo, goo},
+ new Node[] {litFalse, litTrue},
+ new Node[] {now, soon}
+ };
+ TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+ c.beforeFirst();
+ TestContextOwner ctxOwner = new TestContextOwner(c);
+ for (BinaryComparisonFilter f: comps) f.setContextOwner(ctxOwner);
+
+ // check the context setting
+ for (BinaryComparisonFilter f: comps) f.setCurrentContext(c);
+
+ // run the tests
+ while (c.next()) compatibleTest(c, comps);
+ }
+
+ private void compatibleTest(TestContext c, BinaryComparisonFilter[] comps) throws Exception {
+ assertTrue(t.equals(comps[0]));
+ assertTrue(f.equals(comps[1]));
+ assertTrue(f.equals(comps[2]));
+ assertTrue(t.equals(comps[3]));
+ assertTrue(t.equals(comps[4]));
+ assertTrue(f.equals(comps[5]));
+ assertTrue(t.equals(comps[6]));
+ assertTrue(f.equals(comps[7]));
+ assertTrue(t.equals(comps[8]));
+ assertTrue(t.equals(comps[9]));
+ }
+
+ public void testVarInCompatible() throws Exception {
+ Var x = new Var("x");
+ Var y = new Var("y");
+ BinaryComparisonFilter ltT = new LessThan(x, y);
+ BinaryComparisonFilter ltF = new LessThan(y, x);
+ BinaryComparisonFilter gtT = new GreaterThan(x, y);
+ BinaryComparisonFilter gtF = new GreaterThan(y, x);
+ BinaryComparisonFilter lteT = new LessThanEqualTo(x, y);
+ BinaryComparisonFilter lteF = new LessThanEqualTo(y, x);
+ BinaryComparisonFilter gteT = new GreaterThanEqualTo(x, y);
+ BinaryComparisonFilter gteF = new GreaterThanEqualTo(y, x);
+
+ BinaryComparisonFilter[] comps = new BinaryComparisonFilter[] { ltT, ltF, gtT, gtF, lteT, lteF, gteT, gteF };
+
+ Literal seven = new LiteralImpl("7", xsdInt);
+ Literal sevenSimple = new LiteralImpl("7");
+ Literal sevenF = new LiteralImpl("7.0", xsdFloat);
+ Literal simpleFoo = new LiteralImpl("foo");
+ Literal simpleFooEn = new LiteralImpl("foo", "en");
+ Literal foo = new LiteralImpl("foo", xsdString);
+ Literal litTrue = new LiteralImpl("true", t.getType().getValue());
+ Literal now = new LiteralImpl("2008-04-16T21:57:00Z", xsdDate);
+ URIReferenceImpl intRef = new URIReferenceImpl(xsdInt);
+ BlankNodeImpl bn = new BlankNodeImpl(101);
+ Node[][] rows = {
+ new Node[] {seven, sevenSimple},
+ new Node[] {seven, simpleFooEn},
+ new Node[] {seven, foo},
+ new Node[] {seven, litTrue},
+ new Node[] {seven, now},
+ new Node[] {sevenF, sevenSimple},
+ new Node[] {sevenF, simpleFooEn},
+ new Node[] {sevenF, foo},
+ new Node[] {sevenF, litTrue},
+ new Node[] {sevenF, now},
+ new Node[] {simpleFoo, foo},
+ new Node[] {simpleFoo, litTrue},
+ new Node[] {simpleFoo, now},
+ new Node[] {simpleFooEn, foo},
+ new Node[] {simpleFooEn, litTrue},
+ new Node[] {simpleFooEn, now},
+ new Node[] {foo, litTrue},
+ new Node[] {foo, now}, // 17
+ new Node[] {litTrue, now},
+ new Node[] {seven, intRef}, //19
+ new Node[] {sevenF, intRef},
+ new Node[] {simpleFoo, intRef},
+ new Node[] {simpleFooEn, intRef},
+ new Node[] {foo, intRef},
+ new Node[] {litTrue, intRef},
+ new Node[] {now, intRef},
+ new Node[] {seven, bn},
+ new Node[] {sevenF, bn},
+ new Node[] {simpleFoo, bn},
+ new Node[] {simpleFooEn, bn},
+ new Node[] {foo, bn},
+ new Node[] {litTrue, bn},
+ new Node[] {now, bn}
+ };
+ TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+ c.beforeFirst();
+ TestContextOwner ctxOwner = new TestContextOwner(c);
+ for (BinaryComparisonFilter f: comps) f.setContextOwner(ctxOwner);
+
+ // check the context setting
+ for (BinaryComparisonFilter f: comps) f.setCurrentContext(c);
+
+ // run the tests
+ int r = 0;
+ while (c.next()) {
+ int test = 0;
+ try {
+ for (BinaryComparisonFilter f: comps) {
+ checkIncompatible(f);
+ test++;
+ }
+ } catch (Error e) {
+ System.err.println("Failed on row: " + r + " test=" + test);
+ throw e;
+ }
+ r++;
+ }
+ }
+
+}
Added: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java (rev 0)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -0,0 +1,306 @@
+/**
+ * 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.filter;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.BlankNodeValue;
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.IRI;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.Var;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the equals, not-equals, and sameTerm functions.
+ *
+ * @created Apr 15, 2008
+ * @author Paul 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 EqualityComparisonUnitTest extends TestCase {
+
+ protected URI xsdInt = URI.create(XSD_NS + "int");
+ protected URI xsdFloat = URI.create(XSD_NS + "float");
+ protected URI xsdString = URI.create(XSD_NS + "string");
+ Bool t = Bool.TRUE;
+ Bool f = Bool.FALSE;
+
+ /**
+ * Build the unit test.
+ * @param name The name of the test
+ */
+ public EqualityComparisonUnitTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Hook for test runner to obtain a test suite from.
+ * @return The test suite
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(new EqualityComparisonUnitTest("testLiteral"));
+ suite.addTest(new EqualityComparisonUnitTest("testVar"));
+ return suite;
+ }
+
+ public void testLiteral() throws Exception {
+ // compares two equal literals
+ Equals fn = new Equals(t, t);
+ assertTrue(t.equals(fn));
+ assertTrue(fn.equals(t));
+ assertTrue(t.equals(new SameTerm(t, t)));
+ assertTrue(f.equals(new NotEquals(t, t)));
+
+ // compares two other equal literals
+ fn = new Equals(f, f);
+ assertTrue(t.equals(fn));
+ assertTrue(fn.equals(t));
+ assertTrue(t.equals(new SameTerm(f, f)));
+ assertTrue(f.equals(new NotEquals(f, f)));
+
+ // compare unequal literals
+ RDFTerm lhs = t;
+ RDFTerm rhs = f;
+ try {
+ assertTrue(f.equals(new Equals(lhs, rhs)));
+ fail("Unequal literals should throw an exception when compared for equality");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Type Error"));
+ }
+ assertTrue(f.equals(new SameTerm(lhs, rhs)));
+ assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+ // compare equivalent but different literals
+ lhs = TypedLiteral.newLiteral(7);
+ rhs = TypedLiteral.newLiteral(7.0);
+ try {
+ assertTrue(f.equals(new Equals(lhs, rhs)));
+ fail("Unequal literals should throw an exception when compared for equality");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Type Error"));
+ }
+ assertTrue(f.equals(new SameTerm(lhs, rhs)));
+ assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+ // compare unequal literal strings
+ lhs = TypedLiteral.newLiteral("foo", null, null);
+ rhs = TypedLiteral.newLiteral("fool", null, null);
+ try {
+ assertTrue(f.equals(new Equals(lhs, rhs)));
+ fail("Unequal literals should throw an exception when compared for equality");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Type Error"));
+ }
+ assertTrue(f.equals(new SameTerm(lhs, rhs)));
+ assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+ // compare unequal literals types
+ lhs = TypedLiteral.newLiteral("foo", null, null);
+ rhs = TypedLiteral.newLiteral("foo", xsdString, null);
+ try {
+ assertTrue(f.equals(new Equals(lhs, rhs)));
+ fail("Unequal literals should throw an exception when compared for equality");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Type Error"));
+ }
+ assertTrue(f.equals(new SameTerm(lhs, rhs)));
+ assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+ // compare unequal languages
+ lhs = TypedLiteral.newLiteral("foo", null, "en");
+ rhs = TypedLiteral.newLiteral("foo", null, "fr");
+ try {
+ assertTrue(f.equals(new Equals(lhs, rhs)));
+ fail("Unequal literals should throw an exception when compared for equality");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Type Error"));
+ }
+ assertTrue(f.equals(new SameTerm(lhs, rhs)));
+ assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+ // compare equal languages
+ lhs = TypedLiteral.newLiteral("foo", null, "en");
+ rhs = TypedLiteral.newLiteral("foo", null, "en");
+ assertTrue(t.equals(new Equals(lhs, rhs)));
+ assertTrue(t.equals(new SameTerm(lhs, rhs)));
+ assertTrue(f.equals(new NotEquals(lhs, rhs)));
+
+ // compare different URIs
+ lhs = new IRI(URI.create("http://mulgara.org/path/to/data.rdf"));
+ rhs = new IRI(URI.create("http://mulgara.org/path/to/../to/data.rdf"));
+ assertTrue(f.equals(new Equals(lhs, rhs)));
+ assertTrue(f.equals(new SameTerm(lhs, rhs)));
+ assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+ // compare the same URIs
+ lhs = new IRI(URI.create("http://mulgara.org/path/to/data.rdf"));
+ rhs = new IRI(URI.create("http://mulgara.org/path/to/data.rdf"));
+ assertTrue(t.equals(new Equals(lhs, rhs)));
+ assertTrue(t.equals(new SameTerm(lhs, rhs)));
+ assertTrue(f.equals(new NotEquals(lhs, rhs)));
+
+ // compare different blank nodes
+ lhs = new BlankNodeValue(new BlankNodeImpl(101));
+ rhs = new BlankNodeValue(new BlankNodeImpl(102));
+ assertTrue(f.equals(new Equals(lhs, rhs)));
+ assertTrue(f.equals(new SameTerm(lhs, rhs)));
+ assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+ // compare the same blank nodes
+ lhs = new BlankNodeValue(new BlankNodeImpl(42));
+ rhs = new BlankNodeValue(new BlankNodeImpl(42));
+ assertTrue(t.equals(new Equals(lhs, rhs)));
+ assertTrue(t.equals(new SameTerm(lhs, rhs)));
+ assertTrue(f.equals(new NotEquals(lhs, rhs)));
+ }
+
+ public void testVar() throws Exception {
+ Var x = new Var("x");
+ Var y = new Var("y");
+ AbstractFilterValue eq = new Equals(x, y);
+ AbstractFilterValue same = new SameTerm(x, y);
+ AbstractFilterValue ne = new NotEquals(x, y);
+
+ Literal seven = new LiteralImpl("7", xsdInt);
+ Literal sevenF = new LiteralImpl("7.0", xsdFloat);
+ Literal simple = new LiteralImpl("foo");
+ Literal str = new LiteralImpl("foo", xsdString);
+ Literal strEn = new LiteralImpl("foo", "en");
+ Literal strFr = new LiteralImpl("foo", "fr");
+ Node[][] rows = {
+ new Node[] {seven, seven},
+ new Node[] {seven, sevenF},
+
+ new Node[] {simple, simple},
+ new Node[] {simple, str},
+ new Node[] {simple, strEn},
+ new Node[] {simple, strFr},
+
+ new Node[] {str, str},
+ new Node[] {str, strEn},
+ new Node[] {strEn, strEn},
+ new Node[] {strEn, strFr},
+
+ new Node[] {str, new URIReferenceImpl(xsdInt)},
+ new Node[] {str, new BlankNodeImpl(101)},
+
+ new Node[] {new URIReferenceImpl(xsdInt), new URIReferenceImpl(xsdInt)},
+ new Node[] {new URIReferenceImpl(xsdInt), new URIReferenceImpl(xsdFloat)},
+ new Node[] {new URIReferenceImpl(xsdInt), new BlankNodeImpl(100)},
+
+ new Node[] {null, str},
+
+ new Node[] {new BlankNodeImpl(101), new BlankNodeImpl(101)},
+ new Node[] {new BlankNodeImpl(101), new BlankNodeImpl(102)}
+ };
+ TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+ c.beforeFirst();
+ eq.setContextOwner(new TestContextOwner(c));
+ same.setContextOwner(new TestContextOwner(c));
+ ne.setContextOwner(new TestContextOwner(c));
+ // check the context setting
+ eq.setCurrentContext(c);
+ same.setCurrentContext(c);
+ ne.setCurrentContext(c);
+
+ String results = "tl tlll tltl ff tff x tf";
+ runTests(c, eq, same, ne, results);
+
+ }
+
+ private void runTests(TestContext c, AbstractFilterValue eq, AbstractFilterValue same, AbstractFilterValue ne, String results) throws Exception {
+ c.beforeFirst();
+ for (char result: results.toCharArray()) {
+ if (result == ' ') continue;
+ assertTrue(c.next());
+ switch (result) {
+ case 't': // equal
+ assertTrue(t.equals(eq));
+ assertTrue(t.equals(same));
+ assertTrue(f.equals(ne));
+ break;
+
+ case 'f': // unequal
+ assertTrue(f.equals(eq));
+ assertTrue(f.equals(same));
+ assertTrue(t.equals(ne));
+ break;
+
+ case 'l': // unequal literals
+ assertTrue(f.equals(same));
+ assertTrue(t.equals(ne));
+ try {
+ assertTrue(f.equals(eq));
+ fail("Unequal literals should throw an exception when compared for equality");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Type Error"));
+ }
+ break;
+
+ case 'e': // equivalent but unequal
+ assertTrue(t.equals(same));
+ assertTrue(t.equals(ne));
+ try {
+ assertTrue(f.equals(eq));
+ fail("Unequal literals should throw an exception when compared for equality");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Type Error"));
+ }
+ break;
+
+ case 'x': // exception due to unbound
+ try {
+ assertTrue(f.equals(eq));
+ fail("No exception when testing an unbound value for equality");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Unbound column"));
+ }
+ try {
+ assertTrue(f.equals(same));
+ fail("No exception when testing an unbound value for equivalency");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Unbound column"));
+ }
+ try {
+ assertTrue(f.equals(ne));
+ fail("No exception when testing an unbound value for inequality");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Unbound column"));
+ }
+ break;
+
+ default:
+ fail("Bad test data");
+ }
+ }
+ assertFalse(c.next());
+ }
+
+}
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotEquals.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotEquals.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotEquals.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -24,12 +24,6 @@
*/
public class NotEquals extends BinaryTestFilter {
- /** The first operand */
- protected RDFTerm lhs;
-
- /** The second operand */
- protected RDFTerm rhs;
-
NotEquals(RDFTerm lhs, RDFTerm rhs) {
super(lhs, rhs);
}
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -32,7 +32,7 @@
/**
- * Tests the AND operation.
+ * Tests the NOT operation.
*
* @created Apr 14, 2008
* @author Paul Gearon
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -131,4 +131,9 @@
return NumericLiteral.getTypeFor(getValue());
}
+ /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+ public boolean isSimple() throws QueryException {
+ return false;
+ }
+
}
\ No newline at end of file
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -50,4 +50,34 @@
public void setCurrentContext(Context context) {
if (!(context.equals(getContextOwner().getCurrentContext()))) throw new AssertionError("Function context being set differently to initial calling context.");
}
+
+ public boolean greaterThan(ComparableExpression v) throws QueryException {
+ return resolveComparable().greaterThan(v);
+ }
+
+ /** @see org.mulgara.query.filter.value.ComparableExpression#greaterThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
+ public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
+ return resolveComparable().greaterThanEqualTo(v);
+ }
+
+ /** @see org.mulgara.query.filter.value.ComparableExpression#lessThan(org.mulgara.query.filter.value.ComparableExpression) */
+ public boolean lessThan(ComparableExpression v) throws QueryException {
+ return resolveComparable().lessThan(v);
+ }
+
+ /** @see org.mulgara.query.filter.value.ComparableExpression#lessThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
+ public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
+ return resolveComparable().lessThanEqualTo(v);
+ }
+
+ /**
+ * Resolves this function to a value that can be compared, or throws an exception if it cannot be compared.
+ * @return A value that can be compared for inequality.
+ * @throws QueryException If there was a problem resolving the function, or if the value is not comparable.
+ */
+ protected ComparableExpression resolveComparable() throws QueryException {
+ RDFTerm result = resolve();
+ if (!(result instanceof ComparableExpression)) throw new QueryException("Type error: cannot compare with a: " + result.getClass().getSimpleName());
+ return (ComparableExpression)result;
+ }
}
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -27,11 +27,13 @@
/** {@inheritDoc} */
public boolean lessThan(ComparableExpression v) throws QueryException {
+ compatibilityTest(v);
return compare(getValue(), v.getValue()) < 0;
}
/** {@inheritDoc} */
public boolean greaterThan(ComparableExpression v) throws QueryException {
+ compatibilityTest(v);
return compare(getValue(), v.getValue()) > 0;
}
@@ -52,10 +54,20 @@
/** {@inheritDoc} */
public boolean notEquals(ComparableExpression v) throws QueryException {
- return compare(getValue(), v.getValue()) != 0;
+ return !equals(v);
}
/**
+ * Tests a value to see if it is a simple literal, and throws an exception if it is.
+ * Simple literals do a similar test when compared with a ComparableExpression.
+ * @param v The comparable expression to test.
+ * @throws QueryException If the comparable expression resolves to a {@link SimpleLiteral}.
+ */
+ private void compatibilityTest(ComparableExpression v) throws QueryException {
+ if (v.isLiteral() && ((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal with a: " + getClass().getSimpleName());
+ }
+
+ /**
* Compares elements of the type handled by the implementing class.
* @param left The LHS of the comparison
* @param right The RHS of the comparison
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -69,36 +69,23 @@
public boolean isLiteral() { return true; }
/** {@inheritDoc} */
- public boolean sameTerm(RDFTerm v) {
- try {
- if (!(v instanceof ValueLiteral)) return false;
- IRI type = ((ValueLiteral)v).getType();
- if (type == null || !type.equals(getType())) return false;
- return getValue().equals(v.getValue());
- } catch (QueryException qe) {
- return false;
- }
+ public boolean sameTerm(RDFTerm v) throws QueryException {
+ if (!v.isLiteral()) return false;
+ return equalLiteralTypes((ValueLiteral)v) && getValue().equals(v.getValue());
}
-
/**
* {@inheritDoc}
- * This method will only return <code>true</code> when the elements are identical,
- * or if they have differing numeric types compare equal in number space.
+ * This method will only return <code>true</code> when the elements are identical.
* Since this object is a literal, then an incorrect comparison will throw an exception.
* {@link http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal}
+ * <em>produces a type error if the arguments are both literal but are not the same RDF term</em>
*/
public boolean equals(RDFTerm v) throws QueryException {
- if (!(v instanceof ValueLiteral)) return false;
- IRI type = ((ValueLiteral)v).getType();
- // check for differing types
- if (type == null || !type.equals(getType())) {
- // only handle equivalent numbers
- return numberCompare(v);
- }
- // terms are the same type
- if (getValue().equals(v.getValue())) return true;
- throw new QueryException("Terms are not equal");
+ if (!v.isLiteral()) return false;
+ // compare types, and then check values
+ if (equalLiteralTypes((ValueLiteral)v) && getValue().equals(v.getValue())) return true;
+ throw new QueryException("Type Error: Terms are not equal");
}
/**
@@ -115,11 +102,32 @@
}
/**
- * Extended numerical comparison function, for use with equals.
+ * Compares the type of this object to the type of another object. This takes into account
+ * that Simple Literals claim to have a string type, when they have no type at all.
+ * @param vl The object to test.
+ * @return <code>true</code> if the types are exactly the same. If both types are strings,
+ * then both objects have to be typed literals, or untyped literals.
+ * @throws QueryException If there is an error accessing the type data.
+ */
+ private boolean equalLiteralTypes(ValueLiteral vl) throws QueryException {
+ IRI opType = vl.getType();
+ IRI thisType = getType();
+ assert opType != null && thisType != null;
+ // if the types differ, then not equal
+ if (!opType.equals(thisType)) return false;
+ // types are the same. If they are not strings, then definitely equal
+ if (!opType.equals(SimpleLiteral.STRING_TYPE)) return true;
+ // both types are strings. Only true if the other object is not a simple literal
+ return !vl.isSimple();
+ }
+
+ /**
+ * Extended numerical comparison function. Currently unused.
* @param v The term to compare against.
* @return <code>true</code> if this compares against v with semantic equivalence, regardless of lexical equivalence
* @throws QueryException Thrown when a value cannot be resolved, or if the types are no numbers.
*/
+ @SuppressWarnings("unused")
private boolean numberCompare(RDFTerm v) throws QueryException {
if (!(value instanceof Number) || !(v.getValue() instanceof Number)) throw new QueryException("Terms are not equal");
return compare(value, v) == 0;
@@ -134,7 +142,7 @@
*/
protected int compare(Object left, Object right) throws QueryException {
DataCompare cmpFn = typeMap.get(left.getClass());
- if (cmpFn == null) throw new QueryException("Cannot compare a " + left.getClass() + " to a " + right.getClass());
+ if (cmpFn == null) throw new QueryException("Type Error: Cannot compare a " + left.getClass() + " to a " + right.getClass());
return cmpFn.compare(left, right);
}
@@ -174,7 +182,7 @@
/** Implements string comparisons */
private static class StringCompare implements DataCompare {
public int compare(Object left, Object right) throws QueryException {
- if (!(right instanceof String)) throw new QueryException("Cannot compare a String to a: " + right.getClass());
+ if (!(right instanceof String)) throw new QueryException("Type Error: Cannot compare a String to a: " + right.getClass());
return ((String)left).compareTo((String)right);
}
public ValueLiteral newLiteral(Object data) { return new TypedLiteral((String)data, SimpleLiteral.STRING_TYPE.getValue()); }
@@ -183,7 +191,7 @@
/** Implements string comparisons */
private static class DateCompare implements DataCompare {
public int compare(Object left, Object right) throws QueryException {
- if (!(right instanceof Date)) throw new QueryException("Cannot compare a Date to a: " + right.getClass());
+ if (!(right instanceof Date)) throw new QueryException("Type Error: Cannot compare a Date to a: " + right.getClass());
return ((Date)left).compareTo((Date)right);
}
public ValueLiteral newLiteral(Object data) { return new DateTime((Date)data); }
@@ -192,7 +200,7 @@
/** Implements boolean comparisons */
private static class BooleanCompare implements DataCompare {
public int compare(Object left, Object right) throws QueryException {
- if (!(right instanceof Boolean)) throw new QueryException("Cannot compare a boolean to a: " + right.getClass());
+ if (!(right instanceof Boolean)) throw new QueryException("Type Error: Cannot compare a boolean to a: " + right.getClass());
return ((Boolean)left).compareTo((Boolean)right);
}
public ValueLiteral newLiteral(Object data) { return new Bool((Boolean)data); }
@@ -202,7 +210,7 @@
private static class FloatCompare implements DataCompare {
public int compare(Object left, Object right) throws QueryException {
Float fleft = (Float)left;
- if (!(right instanceof Number)) throw new QueryException("Cannot compare a float to a: " + right.getClass());
+ if (!(right instanceof Number)) throw new QueryException("Type Error: Cannot compare a float to a: " + right.getClass());
// if right has more precision, then promote lfloat, and compare the other way around
if (right instanceof Double) return -((Double)right).compareTo(fleft.doubleValue());
return fleft.compareTo(((Number)right).floatValue());
@@ -213,7 +221,7 @@
/** Implements double precision floating point comparisons */
private static class DoubleCompare implements DataCompare {
public int compare(Object left, Object right) throws QueryException {
- if (!(right instanceof Number)) throw new QueryException("Cannot compare a double to a: " + right.getClass());
+ if (!(right instanceof Number)) throw new QueryException("Type Error: Cannot compare a double to a: " + right.getClass());
return ((Double)left).compareTo(((Number)right).doubleValue());
}
public ValueLiteral newLiteral(Object data) { return new NumericLiteral((Double)data); }
@@ -222,7 +230,7 @@
/** Implements integer comparisons */
private static class DecimalCompare implements DataCompare {
public int compare(Object left, Object right) throws QueryException {
- if (!(right instanceof Number)) throw new QueryException("Cannot compare a decimal number to a: " + right.getClass());
+ if (!(right instanceof Number)) throw new QueryException("Type Error: Cannot compare a decimal number to a: " + right.getClass());
Long lleft = ((Number)left).longValue();
return lleft.compareTo(((Number)right).longValue());
}
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -45,12 +45,12 @@
/** {@inheritDoc} */
public boolean equals(RDFTerm v) throws QueryException {
- return v instanceof BlankNodeValue && node.equals(((BlankNodeValue)v).node);
+ return v.isBlank() && node.equals(v.getValue());
}
/** {@inheritDoc} */
public boolean notEquals(RDFTerm v) throws QueryException {
- return !(v instanceof BlankNodeValue) || !node.equals(((BlankNodeValue)v).node);
+ return !equals(v);
}
/** {@inheritDoc} */
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -73,4 +73,14 @@
if (!operand.isLiteral()) throw new QueryException("Disallowed type in DATATYPE function. Expected a Literal. Got a : " + operand.getClass().getSimpleName());
return ((ValueLiteral)operand).getType();
}
+
+ /**
+ * The return value of this class is not comparable, so always throw an exception.
+ * @return never returns a value.
+ * @throws QueryException To indicate that this class cannot be compared.
+ */
+ protected ComparableExpression resolveComparable() throws QueryException {
+ throw new QueryException("Type error: datatypes are IRIs which cannot be compared for anything but equality");
+ }
+
}
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/IRI.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/IRI.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/IRI.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -47,7 +47,7 @@
/** {@inheritDoc} */
public boolean equals(RDFTerm v) throws QueryException {
- return v.isIRI() && value.equals(((IRI)v).getValue());
+ return v.isIRI() && value.equals(v.getValue());
}
/** {@inheritDoc} */
@@ -68,8 +68,8 @@
public boolean isLiteral() { return false; }
/** {@inheritDoc} */
- public boolean sameTerm(RDFTerm v) {
- return v instanceof IRI && value.equals(((IRI)v).getValue());
+ public boolean sameTerm(RDFTerm v) throws QueryException {
+ return equals(v);
}
/** This value does not need a context */
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -49,10 +49,15 @@
return resolve().isLiteral();
}
+ /** @see org.mulgara.query.filter.AbstractFilterValue#isSimple() */
+ public boolean isSimple() throws QueryException {
+ return ((ValueLiteral)resolve()).isSimple();
+ }
+
/**
- *
- * @return
- * @throws QueryException
+ * Applies this function to its operands to get back a result.
+ * @return A language code for the operand.
+ * @throws QueryException If the operand was not a literal.
*/
protected RDFTerm resolve() throws QueryException {
if (!operand.isLiteral()) throw new QueryException("Disallowed type in LANG function. Expected a Literal. Got a : " + operand.getClass().getSimpleName());
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -14,6 +14,7 @@
import org.mulgara.query.QueryException;
import org.mulgara.query.filter.Context;
import org.mulgara.query.filter.ContextOwner;
+import org.mulgara.query.filter.RDFTerm;
/**
@@ -27,7 +28,7 @@
public class SimpleLiteral extends AbstractComparableLiteral {
/** An empty simple literal */
- public static final SimpleLiteral EMPTY = new SimpleLiteral("");
+ public static final SimpleLiteral EMPTY = new SimpleLiteral("", "");
/** The language tag for a simple literal */
private SimpleLiteral lang = EMPTY;
@@ -74,6 +75,11 @@
return STRING_TYPE;
}
+ /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+ public boolean isSimple() throws QueryException {
+ return true;
+ }
+
/**
* @see org.mulgara.query.filter.value.ComparableExpression#test()
*/
@@ -87,4 +93,70 @@
/** This value does not need a context */
public void setContextOwner(ContextOwner owner) { }
+ /** {@inheritDoc} */
+ public boolean sameTerm(RDFTerm v) throws QueryException {
+ if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) return false;
+ return getValue().equals(v.getValue()) && compareLangEquals((ValueLiteral)v);
+ }
+
+ /**
+ * {@inheritDoc}
+ * This method will only return <code>true</code> when the elements are identical.
+ * Since this object is a literal, then an incorrect comparison will throw an exception.
+ * {@link http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal}
+ * <em>produces a type error if the arguments are both literal but are not the same RDF term</em>
+ */
+ public boolean equals(RDFTerm v) throws QueryException {
+ if (!v.isLiteral()) return false;
+ if (((ValueLiteral)v).isSimple()) {
+ // check values and language codes
+ if (getValue().equals(v.getValue()) && compareLangEquals((ValueLiteral)v)) return true;
+ }
+ throw new QueryException("Type Error: Terms are not equal");
+ }
+
+ /** {@inheritDoc} */
+ public boolean lessThan(ComparableExpression v) throws QueryException {
+ if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal to a: " + v.getClass().getSimpleName());
+ int result = compareLang(convertToLiteral(v));
+ if (result == 0) return compare(getValue(), v.getValue()) < 0;
+ else return result < 0;
+ }
+
+ /** {@inheritDoc} */
+ public boolean greaterThan(ComparableExpression v) throws QueryException {
+ if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal to a: " + v.getClass().getSimpleName());
+ int result = compareLang(convertToLiteral(v));
+ if (result == 0) return compare(getValue(), v.getValue()) > 0;
+ else return result > 0;
+ }
+
+ /**
+ * Convert a comparable expression to a Literal, or throw an exception if it cannot be resolved this way.
+ * @param v The object to convert after testing
+ * @return The object as a ValueLiteral
+ * @throws QueryException Indicating that v is not a SimpleLiteral.
+ */
+ private ValueLiteral convertToLiteral(ComparableExpression v) throws QueryException {
+ if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal to a: " + v.getClass().getSimpleName());
+ return (ValueLiteral)v;
+ }
+
+ /**
+ * Tests equality for the language code to the language code of the given SimpleLiteral.
+ * @param sl The simple literal to compare against.
+ * @return <code>true</code> if the codes are equal, <code>false</code> otherwise.
+ */
+ private boolean compareLangEquals(ValueLiteral sl) throws QueryException {
+ return lang.equals(sl.getLang());
+ }
+
+ /**
+ * Compares the language code to the language code of the given SimpleLiteral.
+ * @param sl The simple literal to compare against.
+ * @return -1 if this code is less than the code of s1, +1 if greater, and 0 if they are equal
+ */
+ private int compareLang(ValueLiteral sl) throws QueryException {
+ return ((String)lang.getValue()).compareTo((String)sl.getLang().getValue());
+ }
}
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -42,6 +42,11 @@
return SimpleLiteral.EMPTY;
}
+ /** @see org.mulgara.query.filter.AbstractFilterValue#isSimple() */
+ public boolean isSimple() throws QueryException {
+ return ((ValueLiteral)resolve()).isSimple();
+ }
+
/**
* @see org.mulgara.query.filter.value.ValueLiteral#getLexical()
* @throws QueryException if the operand does not resolve
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -96,6 +96,11 @@
return new IRI(type);
}
+ /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+ public boolean isSimple() throws QueryException {
+ return false;
+ }
+
/**
* Gets the language ID of this literal
* @return The language ID for this literal
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -13,8 +13,10 @@
import java.net.URI;
+import org.mulgara.query.QueryException;
import org.mulgara.query.filter.Context;
import org.mulgara.query.filter.TestContext;
+
import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
import junit.framework.Test;
@@ -82,7 +84,12 @@
assertFalse(l.test(c));
l = (TypedLiteral)TypedLiteral.newLiteral("foobar", URI.create("foo:bar"), null);
- assertFalse(l.test(c));
+ try {
+ l.test(c);
+ fail("Got an EBV from an unknown literal type");
+ } catch (QueryException qe) {
+ assertTrue(qe.getMessage().startsWith("Type Error:"));
+ }
l = (TypedLiteral)TypedLiteral.newLiteral(Long.valueOf(5));
assertTrue(l.test(c));
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -25,7 +25,7 @@
* @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 interface ValueLiteral extends RDFTerm, Filter {
+public interface ValueLiteral extends RDFTerm, Filter, ComparableExpression {
/**
* Returns the data represented by this expression.
@@ -51,6 +51,12 @@
*/
public SimpleLiteral getLang() throws QueryException;
+ /**
+ * Tests if this literal is a simple literal. If it is, then the type should be xsd:string.
+ * @return <code>true</code> if this literal is simple.
+ * @throws QueryException Resolving the data for this value leads to an error.
+ */
+ public boolean isSimple() throws QueryException;
/**
* Gets the type of this literal
@@ -66,5 +72,5 @@
* @throws QueryException There was an error during resolving the literal.
*/
public boolean test(Context context) throws QueryException;
-
+
}
Modified: branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/Var.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/Var.java 2008-04-16 19:55:04 UTC (rev 794)
+++ branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/Var.java 2008-04-17 04:29:44 UTC (rev 795)
@@ -93,12 +93,18 @@
return e.getValue().toString();
}
+ /**@see org.mulgara.query.filter.value.ValueLiteral#getType() */
public IRI getType() throws QueryException {
ComparableExpression e = resolveComparable();
if (!e.isLiteral()) throw new QueryException("Only literals are typed");
return ((ValueLiteral)e).getType();
}
+ /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+ public boolean isSimple() throws QueryException {
+ return ((ValueLiteral)resolve()).isSimple();
+ }
+
/** {@inheritDoc} */
public boolean equals(RDFTerm v) throws QueryException {
return resolve().equals(v);
@@ -136,7 +142,7 @@
*/
public ComparableExpression resolveComparable() throws QueryException {
RDFTerm v = resolve();
- if (!(v instanceof ComparableExpression)) throw new QueryException("Cannot compare against a " + v.getClass().getSimpleName());
+ if (!(v instanceof ComparableExpression)) throw new QueryException("Type Error: Cannot compare against a: " + v.getClass().getSimpleName());
return (ComparableExpression)v;
}
More information about the Mulgara-svn
mailing list