001: /*
002: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: [See end of file]
004: $Id: AbstractTestReifiedStatements.java,v 1.18 2008/01/02 12:04:43 andy_seaborne Exp $
005: */
006:
007: package com.hp.hpl.jena.rdf.model.test;
008:
009: import com.hp.hpl.jena.rdf.model.*;
010: import com.hp.hpl.jena.util.CollectionFactory;
011: import com.hp.hpl.jena.vocabulary.RDF;
012: import com.hp.hpl.jena.graph.test.*;
013:
014: import java.util.*;
015:
016: /**
017: @author kers
018: */
019: public abstract class AbstractTestReifiedStatements extends
020: ModelTestBase {
021: public AbstractTestReifiedStatements(String name) {
022: super (name);
023: }
024:
025: public abstract Model getModel();
026:
027: private Model model;
028: private Resource S;
029: private Property P;
030: private RDFNode O;
031: private Statement SPO;
032: private Statement SPO2;
033:
034: private static final String aURI = "jena:test/reifying#someURI";
035: private static final String anotherURI = "jena:test/reifying#anotherURI";
036: private static final String anchor = "jena:test/Reifying#";
037:
038: public void setUp() {
039: model = getModel();
040: Resource S2 = model.createResource(anchor + "subject2");
041: S = model.createResource(anchor + "subject");
042: P = model.createProperty(anchor + "predicate");
043: O = model.createLiteral(anchor + "object");
044: SPO = model.createStatement(S, P, O);
045: SPO2 = model.createStatement(S2, P, O);
046: }
047:
048: /**
049: the simplest case: if we assert all the components of a reification quad,
050: we can get a ReifiedStatement that represents the reified statement.
051: */
052: public void testBasicReification() {
053: if (model.getReificationStyle() != ModelFactory.Minimal) {
054: Resource R = model.createResource(aURI);
055: model.add(R, RDF.type, RDF.Statement);
056: model.add(R, RDF.subject, S);
057: model.add(R, RDF.predicate, P);
058: model.add(R, RDF.object, O);
059: RDFNode rs = R.as(ReifiedStatement.class);
060: assertEquals("can recover statement", SPO,
061: ((ReifiedStatement) rs).getStatement());
062: }
063: }
064:
065: /**
066: check that, from a model with any combination of the statements given,
067: we can convert R into a ReifiedStatement iff the four components of the
068: quad are in the model.
069: */
070: public void testReificationCombinations() {
071: Resource RR = model.createResource(aURI), SS = model
072: .createResource(anotherURI);
073: Property PP = (Property) RR.as(Property.class);
074: Object[][] statements = {
075: { model.createStatement(RR, RDF.type, RDF.Statement),
076: new Integer(1) },
077: { model.createStatement(RR, RDF.subject, SS),
078: new Integer(2) },
079: { model.createStatement(RR, RDF.predicate, PP),
080: new Integer(4) },
081: { model.createStatement(RR, RDF.object, O),
082: new Integer(8) },
083: { model.createStatement(SS, PP, O), new Integer(16) },
084: { model.createStatement(RR, PP, O), new Integer(32) },
085: { model.createStatement(SS, RDF.subject, SS),
086: new Integer(64) },
087: { model.createStatement(SS, RDF.predicate, PP),
088: new Integer(128) },
089: { model.createStatement(SS, RDF.object, O),
090: new Integer(256) },
091: { model.createStatement(SS, RDF.type, RDF.Statement),
092: new Integer(512) } };
093: if (model.getReificationStyle() != ModelFactory.Minimal)
094: testCombinations(model, RR, 0, statements,
095: statements.length);
096: }
097:
098: /**
099: walk down the set of statements (represented as an array), recursing with and
100: without each statement being present. The mask bits record those statements
101: that are in the model. At the bottom of the recursion (n == 0), check that R
102: can be reified exactly when all four quad components are present; the other
103: statements don't matter.
104: */
105: private void testCombinations(Model m, Resource R, int mask,
106: Object[][] statements, int n) {
107: if (n == 0) {
108: try {
109: // System.err.println( "| hello. mask = " + mask );
110: ReifiedStatement rs = (ReifiedStatement) R
111: .as(ReifiedStatement.class);
112: // System.err.println( "+ we constructed " + rs );
113: assertTrue(
114: "should not reify: not all components present ["
115: + mask + "]: " + rs, (mask & 15) == 15);
116: // System.err.println( "+ and we passed the assertion." );
117: } catch (DoesNotReifyException e) { // System.err.println( "+ we exploded" );
118: assertFalse("should reify: all components present",
119: mask == 15);
120: }
121: } else {
122: int i = n - 1;
123: Statement s = (Statement) statements[i][0];
124: int bits = ((Integer) statements[i][1]).intValue();
125: testCombinations(m, R, mask, statements, i);
126: m.add(s);
127: testCombinations(m, R, mask + bits, statements, i);
128: m.remove(s);
129: }
130: }
131:
132: public void testThisWillBreak() {
133: Resource R = model.createResource(aURI);
134: SPO.createReifiedStatement(aURI);
135: model.add(R, RDF.subject, R);
136: }
137:
138: /**
139: "dirty" reifications - those with conflicting quadlets - should fail.
140: */
141: public void testDirtyReification() {
142: Resource R = model.createResource(aURI);
143: model.add(R, RDF.type, RDF.Statement);
144: model.add(R, RDF.subject, S);
145: model.add(R, RDF.subject, P);
146: testDoesNotReify("boo", R);
147: }
148:
149: public void testDoesNotReify(String title, Resource r) {
150: try {
151: r.as(ReifiedStatement.class);
152: fail(title + " (" + r + ")");
153: } catch (DoesNotReifyException e) { /* that's what we expect */
154: }
155: }
156:
157: public void testConversion() {
158: final String uri = "spoo:handle";
159: model.createReifiedStatement(uri, SPO);
160: ReifiedStatement rs2 = (ReifiedStatement) model.createResource(
161: uri).as(ReifiedStatement.class);
162: assertEquals("recover statement", SPO, rs2.getStatement());
163: }
164:
165: public void testDoesNotReifyUnknown() {
166: testDoesNotReify("model should not reify rubbish", model
167: .createResource("spoo:rubbish"));
168: }
169:
170: public void testQuintetOfQuadlets() {
171: Resource rs = model.createResource();
172: rs.addProperty(RDF.type, RDF.Statement);
173: model.createResource().addProperty(RDF.value, rs);
174: rs.addProperty(RDF.subject, model.createResource());
175: rs.addProperty(RDF.predicate, model
176: .createProperty("http://example.org/foo"));
177: rs.addProperty(RDF.object, model.createResource());
178: rs.addProperty(RDF.object, model.createResource());
179: StmtIterator it = model.listStatements();
180: while (it.hasNext()) {
181: Statement s = it.nextStatement();
182: assertFalse(s.getObject().equals(s.getSubject()));
183: }
184: }
185:
186: public void testConstructionByURI() {
187: ReifiedStatement rs = model.createReifiedStatement(
188: "spoo:handle", SPO);
189: ReifiedStatement rs2 = SPO
190: .createReifiedStatement("spoo:gripper");
191: assertEquals("recover statement (URI)", SPO, rs.getStatement());
192: assertEquals("recover URI", "spoo:handle", rs.getURI());
193: assertEquals("recover URI", "spoo:gripper", rs2.getURI());
194: }
195:
196: public void testStatementAndModel(String title,
197: ReifiedStatement rs, Model m, Statement st) {
198: assertEquals(title + ": recover statement", st, rs
199: .getStatement());
200: assertEquals(title + ": recover model", m, rs.getModel());
201: }
202:
203: public void testConstructionFromStatements() {
204: testStatementAndModel("fromStatement", SPO
205: .createReifiedStatement(), model, SPO);
206: }
207:
208: public void testConstructionFromModels() {
209: testStatementAndModel("fromModel", model
210: .createReifiedStatement(SPO), model, SPO);
211: }
212:
213: /**
214: utility method: get a set of all the elements delivered by
215: _m.listReifiedStatements_.
216: */
217: public Set getSetRS(Model m) {
218: return GraphTestBase.iteratorToSet(m.listReifiedStatements());
219: }
220:
221: protected static Set empty = CollectionFactory.createHashedSet();
222:
223: /**
224: test that listReifiedStatements produces an iterator that contains
225: the right reified statements. We *don't* test that they're not
226: duplicated, because they might be; disallowing duplicates
227: could be expensive.
228: */
229: public void testListReifiedStatements() {
230: assertEquals("initially: no reified statements", empty,
231: getSetRS(model));
232: ReifiedStatement rs = model.createReifiedStatement(aURI, SPO);
233: // assertEquals( "still: no reified statements", empty, getSetRS( m ) );
234: /* */
235: model.add(rs, P, O);
236: Set justRS = arrayToSet(new Object[] { rs });
237: assertEquals("post-add: one reified statement", justRS,
238: getSetRS(model));
239: model.add(S, P, rs);
240: assertEquals("post-add: still one reified statement", justRS,
241: getSetRS(model));
242: /* */
243: ReifiedStatement rs2 = model.createReifiedStatement(anotherURI,
244: SPO2);
245: Set bothRS = arrayToSet(new Object[] { rs, rs2 });
246: model.add(rs2, P, O);
247: assertEquals("post-add: still one reified statement", bothRS,
248: getSetRS(model));
249: }
250:
251: /**
252: this test appeared when TestStatementResources crashed using reified
253: statements as a step-0 implementation for asSubject()/asObject(). Looks
254: like there was a problem in modelReifier().getRS(), which we're fixing ...
255: */
256: public void testListDoesntCrash() {
257: model.createReifiedStatement(SPO);
258: model.createReifiedStatement(SPO2);
259: assertTrue("should be non-empty", model.listReifiedStatements()
260: .hasNext());
261: }
262:
263: public Set getSetRS(Model m, Statement st) {
264: return GraphTestBase.iteratorToSet(m.listReifiedStatements(st));
265: }
266:
267: public void testListReifiedSpecificStatements() {
268: assertEquals("no statements should match st", empty, getSetRS(
269: model, SPO));
270: /* */
271: ReifiedStatement rs = model.createReifiedStatement(aURI, SPO);
272: ReifiedStatement rs2 = model.createReifiedStatement(anotherURI,
273: SPO2);
274: model.add(rs, P, O);
275: // assertEquals( "still no matching statement", empty, getSetRS( m, stOther ) );
276: /* */
277: Set justRS2 = arrayToSet(new Object[] { rs2 });
278: model.add(rs2, P, O);
279: assertEquals("now one matching statement", justRS2, getSetRS(
280: model, SPO2));
281: }
282:
283: public void testStatementListReifiedStatements() {
284: Statement st = SPO;
285: Model m = model;
286: assertEquals("it's not there yet", empty, GraphTestBase
287: .iteratorToSet(st.listReifiedStatements()));
288: ReifiedStatement rs = m.createReifiedStatement(aURI, st);
289: Set justRS = arrayToSet(new Object[] { rs });
290: m.add(rs, P, O);
291: assertEquals("it's here now", justRS, GraphTestBase
292: .iteratorToSet(st.listReifiedStatements()));
293: }
294:
295: public void testIsReified() {
296: ReifiedStatement rs = model.createReifiedStatement(aURI, SPO);
297: Resource BS = model.createResource(anchor + "BS");
298: Property BP = model.createProperty(anchor + "BP");
299: RDFNode BO = model.createProperty(anchor + "BO");
300: model.add(rs, P, O);
301: assertTrue("st should be reified now", SPO.isReified());
302: assertTrue("m should have st reified now", model.isReified(SPO));
303: assertFalse("this new statement should not be reified", model
304: .createStatement(BS, BP, BO).isReified());
305: }
306:
307: public void testGetAny() {
308: Resource r = model.getAnyReifiedStatement(SPO);
309: assertInstanceOf(ReifiedStatement.class, r);
310: assertEquals("should get me the statement", SPO,
311: ((ReifiedStatement) r).getStatement());
312: }
313:
314: public void testRemoveReificationWorks() {
315: Statement st = SPO;
316: Model m = model;
317: m.createReifiedStatement(aURI, st);
318: assertTrue("st is now reified", st.isReified());
319: m.removeAllReifications(st);
320: assertFalse("st is no longer reified", st.isReified());
321: }
322:
323: /**
324: Leo Bard spotted a problem whereby removing a reified statement from a model
325: with style Standard didn't leave the model empty. Here's a test for it.
326: */
327: public void testLeosBug() {
328: Model A = getModel();
329: Statement st = statement(A, "pigs fly south");
330: ReifiedStatement rst = st.createReifiedStatement("eh:pointer");
331: A.removeReification(rst);
332: assertIsoModels(ModelFactory.createDefaultModel(), A);
333: }
334:
335: public void testRR() {
336: Statement st = SPO;
337: Model m = model;
338: ReifiedStatement rs1 = m.createReifiedStatement(aURI, st);
339: ReifiedStatement rs2 = m.createReifiedStatement(anotherURI, st);
340: m.removeReification(rs1);
341: testNotReifying(m, aURI);
342: assertTrue("st is still reified", st.isReified());
343: m.removeReification(rs2);
344: assertFalse("st should no longer be reified", st.isReified());
345: }
346:
347: private void testNotReifying(Model m, String uri) {
348: try {
349: m.createResource(uri).as(ReifiedStatement.class);
350: fail("there should be no reifiedStatement for " + uri);
351: } catch (DoesNotReifyException e) { /* that's what we require */
352: }
353: }
354:
355: public void testDoesNotReifyElsewhere() {
356: final String uri = "spoo:rubbish";
357: Model m2 = getModel();
358: model.createReifiedStatement(uri, SPO);
359: testDoesNotReify("blue model should not reify rubbish", m2
360: .createResource(uri));
361: }
362: // public void testXXX()
363: // {
364: // String root = "http://root/root#";
365: // Model m = ModelFactory.createDefaultModel();
366: // Model r = ModelFactory.createRDFSModel( m );
367: // Resource S = r.createResource( root + "S" );
368: // Property P = r.createProperty( root + "P" );
369: // RDFNode O = r.createResource( root + "O" );
370: // Statement st = r.createStatement( S, P, O );
371: // ReifiedStatement rs = st.createReifiedStatement( root + "RS" );
372: // }
373: }
374:
375: /*
376: (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
377: All rights reserved.
378:
379: Redistribution and use in source and binary forms, with or without
380: modification, are permitted provided that the following conditions
381: are met:
382:
383: 1. Redistributions of source code must retain the above copyright
384: notice, this list of conditions and the following disclaimer.
385:
386: 2. Redistributions in binary form must reproduce the above copyright
387: notice, this list of conditions and the following disclaimer in the
388: documentation and/or other materials provided with the distribution.
389:
390: 3. The name of the author may not be used to endorse or promote products
391: derived from this software without specific prior written permission.
392:
393: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
394: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
395: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
396: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
397: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
398: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
399: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
400: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
401: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
402: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
403: */
|