001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.repository;
007:
008: import junit.framework.TestCase;
009: import junit.framework.TestSuite;
010:
011: import org.openrdf.model.Literal;
012: import org.openrdf.model.URI;
013: import org.openrdf.model.Value;
014: import org.openrdf.model.ValueFactory;
015: import org.openrdf.model.impl.ValueFactoryImpl;
016: import org.openrdf.model.vocabulary.RDF;
017: import org.openrdf.model.vocabulary.XMLSchema;
018: import org.openrdf.query.MalformedQueryException;
019: import org.openrdf.query.QueryEvaluationException;
020: import org.openrdf.query.QueryLanguage;
021: import org.openrdf.query.TupleQuery;
022: import org.openrdf.query.TupleQueryResult;
023: import org.openrdf.repository.Repository;
024: import org.openrdf.repository.RepositoryConnection;
025: import org.openrdf.repository.RepositoryException;
026:
027: public abstract class EquivalentTest extends TestCase {
028: private static ValueFactory vf = ValueFactoryImpl.getInstance();
029: private static Literal xyz_simple = vf.createLiteral("xyz");
030: private static Literal xyz_en = vf.createLiteral("xyz", "en");
031: private static Literal xyz_EN = vf.createLiteral("xyz", "EN");
032: private static Literal xyz_string = vf.createLiteral("xyz",
033: XMLSchema.STRING);
034: private static Literal xyz_integer = vf.createLiteral("xyz",
035: XMLSchema.INTEGER);
036: private static Literal xyz_unknown = vf.createLiteral("xyz", vf
037: .createURI("http://example/unknown"));
038: private static URI xyz_uri = vf.createURI("http://example/xyz");
039: private static Literal abc_simple = vf.createLiteral("abc");
040: private static Literal abc_en = vf.createLiteral("abc", "en");
041: private static Literal abc_EN = vf.createLiteral("abc", "EN");
042: private static Literal abc_string = vf.createLiteral("abc",
043: XMLSchema.STRING);
044: private static Literal abc_integer = vf.createLiteral("abc",
045: XMLSchema.INTEGER);
046: private static Literal abc_unknown = vf.createLiteral("abc", vf
047: .createURI("http://example/unknown"));
048: private static URI abc_uri = vf.createURI("http://example/abc");
049: private static URI t1 = vf.createURI("http://example/t1");
050: private static URI t2 = vf.createURI("http://example/t2");
051: private static final String IND = "?";
052: private static final String EQ = "=";
053: private static final String NEQ = "!=";
054: private static final String PREFIX = "PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>\n"
055: + "PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>"
056: + "PREFIX ex:<http://example/>";
057: private static String matrix = "\"xyz\" \"xyz\" eq\n"
058: + "\"xyz\" \"xyz\"@en neq\n" + "\"xyz\" \"xyz\"@EN neq\n"
059: + "\"xyz\" \"xyz\"^^xsd:string eq\n"
060: + "\"xyz\" \"xyz\"^^xsd:integer ind\n"
061: + "\"xyz\" \"xyz\"^^ex:unknown ind\n"
062: + "\"xyz\" _:xyz neq\n" + "\"xyz\" :xyz neq\n"
063: + "\"xyz\"@en \"xyz\" neq\n" + "\"xyz\"@en \"xyz\"@en eq\n"
064: + "\"xyz\"@en \"xyz\"@EN eq\n"
065: + "\"xyz\"@en \"xyz\"^^xsd:string neq\n"
066: + "\"xyz\"@en \"xyz\"^^xsd:integer neq\n"
067: + "\"xyz\"@en \"xyz\"^^ex:unknown neq\n"
068: + "\"xyz\"@en _:xyz neq\n" + "\"xyz\"@en :xyz neq\n"
069: + "\"xyz\"@EN \"xyz\" neq\n" + "\"xyz\"@EN \"xyz\"@en eq\n"
070: + "\"xyz\"@EN \"xyz\"@EN eq\n"
071: + "\"xyz\"@EN \"xyz\"^^xsd:string neq\n"
072: + "\"xyz\"@EN \"xyz\"^^xsd:integer neq\n"
073: + "\"xyz\"@EN \"xyz\"^^ex:unknown neq\n"
074: + "\"xyz\"@EN _:xyz neq\n" + "\"xyz\"@EN :xyz neq\n"
075: + "\"xyz\"^^xsd:string \"xyz\" eq\n"
076: + "\"xyz\"^^xsd:string \"xyz\"@en neq\n"
077: + "\"xyz\"^^xsd:string \"xyz\"@EN neq\n"
078: + "\"xyz\"^^xsd:string \"xyz\"^^xsd:string eq\n"
079: + "\"xyz\"^^xsd:string \"xyz\"^^xsd:integer ind\n"
080: + "\"xyz\"^^xsd:string \"xyz\"^^ex:unknown ind\n"
081: + "\"xyz\"^^xsd:string _:xyz neq\n"
082: + "\"xyz\"^^xsd:string :xyz neq\n"
083: + "\"xyz\"^^xsd:integer \"xyz\" ind\n"
084: + "\"xyz\"^^xsd:integer \"xyz\"@en neq\n"
085: + "\"xyz\"^^xsd:integer \"xyz\"@EN neq\n"
086: + "\"xyz\"^^xsd:integer \"xyz\"^^xsd:string ind\n"
087: + "\"xyz\"^^xsd:integer \"xyz\"^^xsd:integer eq\n"
088: + "\"xyz\"^^xsd:integer \"xyz\"^^ex:unknown ind\n"
089: + "\"xyz\"^^xsd:integer _:xyz neq\n"
090: + "\"xyz\"^^xsd:integer :xyz neq\n"
091: + "\"xyz\"^^ex:unknown \"xyz\" ind\n"
092: + "\"xyz\"^^ex:unknown \"xyz\"@en neq\n"
093: + "\"xyz\"^^ex:unknown \"xyz\"@EN neq\n"
094: + "\"xyz\"^^ex:unknown \"xyz\"^^xsd:string ind\n"
095: + "\"xyz\"^^ex:unknown \"xyz\"^^xsd:integer ind\n"
096: + "\"xyz\"^^ex:unknown \"xyz\"^^ex:unknown eq\n"
097: + "\"xyz\"^^ex:unknown _:xyz neq\n"
098: + "\"xyz\"^^ex:unknown :xyz neq\n" + "_:xyz \"xyz\" neq\n"
099: + "_:xyz \"xyz\"@en neq\n" + "_:xyz \"xyz\"@EN neq\n"
100: + "_:xyz \"xyz\"^^xsd:string neq\n"
101: + "_:xyz \"xyz\"^^xsd:integer neq\n"
102: + "_:xyz \"xyz\"^^ex:unknown neq\n" + "_:xyz _:xyz eq\n"
103: + "_:xyz :xyz neq\n" + ":xyz \"xyz\" neq\n"
104: + ":xyz \"xyz\"@en neq\n" + ":xyz \"xyz\"@EN neq\n"
105: + ":xyz \"xyz\"^^xsd:string neq\n"
106: + ":xyz \"xyz\"^^xsd:integer neq\n"
107: + ":xyz \"xyz\"^^ex:unknown neq\n" + ":xyz _:xyz neq\n"
108: + ":xyz :xyz eq\n" + "\"xyz\" \"abc\" neq \n"
109: + "\"xyz\" \"abc\"@en neq \n"
110: + "\"xyz\" \"abc\"@EN neq \n"
111: + "\"xyz\" \"abc\"^^xsd:string neq \n"
112: + "\"xyz\" \"abc\"^^xsd:integer ind\n"
113: + "\"xyz\" \"abc\"^^:unknown ind\n"
114: + "\"xyz\" _:abc neq \n" + "\"xyz\" :abc neq \n"
115: + "\"xyz\"@en \"abc\" neq \n"
116: + "\"xyz\"@en \"abc\"@en neq \n"
117: + "\"xyz\"@en \"abc\"@EN neq \n"
118: + "\"xyz\"@en \"abc\"^^xsd:string neq \n"
119: + "\"xyz\"@en \"abc\"^^xsd:integer neq \n"
120: + "\"xyz\"@en \"abc\"^^:unknown neq \n"
121: + "\"xyz\"@en _:abc neq \n" + "\"xyz\"@en :abc neq \n"
122: + "\"xyz\"@EN \"abc\" neq \n"
123: + "\"xyz\"@EN \"abc\"@en neq \n"
124: + "\"xyz\"@EN \"abc\"@EN neq \n"
125: + "\"xyz\"@EN \"abc\"^^xsd:string neq \n"
126: + "\"xyz\"@EN \"abc\"^^xsd:integer neq \n"
127: + "\"xyz\"@EN \"abc\"^^:unknown neq \n"
128: + "\"xyz\"@EN _:abc neq \n" + "\"xyz\"@EN :abc neq \n"
129: + "\"xyz\"^^xsd:string \"abc\" neq \n"
130: + "\"xyz\"^^xsd:string \"abc\"@en neq \n"
131: + "\"xyz\"^^xsd:string \"abc\"@EN neq \n"
132: + "\"xyz\"^^xsd:string \"abc\"^^xsd:string neq \n"
133: + "\"xyz\"^^xsd:string \"abc\"^^xsd:integer ind\n"
134: + "\"xyz\"^^xsd:string \"abc\"^^:unknown ind\n"
135: + "\"xyz\"^^xsd:string _:abc neq \n"
136: + "\"xyz\"^^xsd:string :abc neq \n"
137: + "\"xyz\"^^xsd:integer \"abc\" ind\n"
138: + "\"xyz\"^^xsd:integer \"abc\"@en neq \n"
139: + "\"xyz\"^^xsd:integer \"abc\"@EN neq \n"
140: + "\"xyz\"^^xsd:integer \"abc\"^^xsd:string ind\n"
141: + "\"xyz\"^^xsd:integer \"abc\"^^xsd:integer ind\n"
142: + "\"xyz\"^^xsd:integer \"abc\"^^:unknown ind\n"
143: + "\"xyz\"^^xsd:integer _:abc neq \n"
144: + "\"xyz\"^^xsd:integer :abc neq \n"
145: + "\"xyz\"^^:unknown \"abc\" ind\n"
146: + "\"xyz\"^^:unknown \"abc\"@en neq \n"
147: + "\"xyz\"^^:unknown \"abc\"@EN neq \n"
148: + "\"xyz\"^^:unknown \"abc\"^^xsd:string ind\n"
149: + "\"xyz\"^^:unknown \"abc\"^^xsd:integer ind\n"
150: + "\"xyz\"^^:unknown \"abc\"^^:unknown ind\n"
151: + "\"xyz\"^^:unknown _:abc neq \n"
152: + "\"xyz\"^^:unknown :abc neq \n"
153: + "_:xyz \"abc\" neq \n" + "_:xyz \"abc\"@en neq \n"
154: + "_:xyz \"abc\"@EN neq \n"
155: + "_:xyz \"abc\"^^xsd:string neq \n"
156: + "_:xyz \"abc\"^^xsd:integer neq \n"
157: + "_:xyz \"abc\"^^:unknown neq \n" + "_:xyz _:abc neq \n"
158: + "_:xyz :abc neq \n" + ":xyz \"abc\" neq \n"
159: + ":xyz \"abc\"@en neq \n" + ":xyz \"abc\"@EN neq \n"
160: + ":xyz \"abc\"^^xsd:string neq \n"
161: + ":xyz \"abc\"^^xsd:integer neq \n"
162: + ":xyz \"abc\"^^:unknown neq \n" + ":xyz _:abc neq \n"
163: + ":xyz :abc neq ";
164:
165: public static TestSuite suite() throws Exception {
166: return new TestSuite();
167: }
168:
169: public static TestSuite suite(
170: Class<? extends EquivalentTest> subclass) throws Exception {
171: TestSuite suite = new TestSuite(subclass.getName());
172: for (String row : matrix.split("\n")) {
173: if (row.contains("_:"))
174: continue;
175: EquivalentTest test = subclass.newInstance();
176: String[] fields = row.split("\t", 3);
177: if (fields[2].contains("neq")) {
178: test.setName(fields[0] + " " + NEQ + " " + fields[1]);
179: } else if (fields[2].contains("eq")) {
180: test.setName(fields[0] + " " + EQ + " " + fields[1]);
181: } else if (fields[2].contains("ind")) {
182: test.setName(fields[0] + " " + IND + " " + fields[1]);
183: } else {
184: throw new AssertionError(row);
185: }
186: suite.addTest(test);
187: }
188: return suite;
189: }
190:
191: private Value term1;
192: private Value term2;
193: private String operator;
194: private Repository repository;
195: private RepositoryConnection con;
196:
197: public EquivalentTest() {
198: super ();
199: }
200:
201: public EquivalentTest(String name) {
202: setName(name);
203: }
204:
205: @Override
206: public void setName(String name) {
207: super .setName(name);
208: String[] fields = name.split(" ", 3);
209: term1 = getTerm(fields[0]);
210: operator = fields[1];
211: term2 = getTerm(fields[2]);
212: }
213:
214: @Override
215: protected void setUp() throws Exception {
216: repository = createRepository();
217: con = repository.getConnection();
218: con.clear();
219: con.add(t1, RDF.VALUE, term1);
220: con.add(t2, RDF.VALUE, term2);
221: }
222:
223: @Override
224: protected void tearDown() throws Exception {
225: con.close();
226: repository.shutDown();
227: }
228:
229: @Override
230: protected void runTest() throws Throwable {
231: assertEquals(null, operator, compare(term1, term2));
232: }
233:
234: protected Repository createRepository() throws Exception {
235: Repository repository = newRepository();
236: repository.initialize();
237: RepositoryConnection con = repository.getConnection();
238: con.clear();
239: con.clearNamespaces();
240: con.close();
241: return repository;
242: }
243:
244: protected abstract Repository newRepository();
245:
246: private Value getTerm(String label) {
247: if (label.contains("xyz")) {
248: if (label.contains("integer"))
249: return xyz_integer;
250: if (label.contains("string"))
251: return xyz_string;
252: if (label.contains("unknown"))
253: return xyz_unknown;
254: if (label.contains("en"))
255: return xyz_en;
256: if (label.contains("EN"))
257: return xyz_EN;
258: if (label.contains(":xyz"))
259: return xyz_uri;
260: if (label.contains("\"xyz\""))
261: return xyz_simple;
262: }
263: if (label.contains("abc")) {
264: if (label.contains("integer"))
265: return abc_integer;
266: if (label.contains("string"))
267: return abc_string;
268: if (label.contains("unknown"))
269: return abc_unknown;
270: if (label.contains("en"))
271: return abc_en;
272: if (label.contains("EN"))
273: return abc_EN;
274: if (label.contains(":abc"))
275: return abc_uri;
276: if (label.contains("\"abc\""))
277: return abc_simple;
278: }
279: throw new AssertionError(label);
280: }
281:
282: private String compare(Value term1, Value term2) throws Exception {
283: boolean eq = evaluate(EQ);
284: boolean neq = evaluate(NEQ);
285: assertTrue(!eq || !neq);
286: if (eq && !neq)
287: return EQ;
288: if (!eq && neq)
289: return NEQ;
290: if (!eq && !neq)
291: return IND;
292: throw new AssertionError();
293: }
294:
295: private boolean evaluate(String op) throws RepositoryException,
296: MalformedQueryException, QueryEvaluationException {
297: String qry = PREFIX
298: + "SELECT ?term1 ?term2 "
299: + "WHERE {ex:t1 rdf:value ?term1 . ex:t2 rdf:value ?term2 "
300: + "FILTER (?term1 " + op + " ?term2)}";
301: return evaluateSparql(qry);
302: }
303:
304: private boolean evaluateSparql(String qry)
305: throws RepositoryException, MalformedQueryException,
306: QueryEvaluationException {
307: TupleQuery query = con.prepareTupleQuery(QueryLanguage.SPARQL,
308: qry);
309: TupleQueryResult evaluate = query.evaluate();
310: try {
311: return evaluate.hasNext();
312: } finally {
313: evaluate.close();
314: }
315: }
316: }
|