001: /*
002: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: [See end of file]ispo
004: $Id: GraphTestBase.java,v 1.35 2008/01/02 12:05:34 andy_seaborne Exp $
005: */
006:
007: package com.hp.hpl.jena.graph.test;
008:
009: /**
010: An extension of JenaTestBase (which see) with Graph-specific methods.
011: @author kers
012: */
013:
014: import com.hp.hpl.jena.util.*;
015: import com.hp.hpl.jena.util.iterator.*;
016: import com.hp.hpl.jena.graph.*;
017: import com.hp.hpl.jena.graph.impl.GraphBase;
018: import com.hp.hpl.jena.shared.*;
019: import com.hp.hpl.jena.test.*;
020:
021: import java.lang.reflect.Constructor;
022: import java.util.*;
023:
024: public class GraphTestBase extends JenaTestBase {
025: public GraphTestBase(String name) {
026: super (name);
027: }
028:
029: /**
030: Answer a Node as described by <code>x</code>; a shorthand for
031: <code>Node.create(x)</code>, which see.
032: */
033: public static Node node(String x) {
034: return NodeCreateUtils.create(x);
035: }
036:
037: /**
038: Answer a set containing the elements from the iterator <code>it</code>;
039: a shorthand for <code>IteratorCollection.iteratorToSet(it)</code>,
040: which see.
041: */
042: public static Set iteratorToSet(Iterator it) {
043: return IteratorCollection.iteratorToSet(it);
044: }
045:
046: /**
047: Answer a list containing the elements from the iterator <code>it</code>,
048: in order; a shorthand for <code>IteratorCollection.iteratorToList(it)</code>,
049: which see.
050: */
051: public static List iteratorToList(Iterator it) {
052: return IteratorCollection.iteratorToList(it);
053: }
054:
055: /**
056: Answer a set of the nodes described (as per <code>node()</code>) by
057: the space-separated substrings of <code>nodes</code>.
058: */
059: public Set nodeSet(String nodes) {
060: Set result = CollectionFactory.createHashedSet();
061: StringTokenizer st = new StringTokenizer(nodes);
062: while (st.hasMoreTokens())
063: result.add(node(st.nextToken()));
064: return result;
065: }
066:
067: /**
068: Answer a set of the elements of <code>A</code>.
069: */
070: public Set arrayToSet(Object[] A) {
071: return CollectionFactory.createHashedSet(Arrays.asList(A));
072: }
073:
074: /**
075: Answer a triple described by the three space-separated node descriptions
076: in <code>fact</code>; a shorthand for <code>Triple.create(fact)</code>,
077: which see.
078: */
079: public static Triple triple(String fact) {
080: return Triple.create(fact);
081: }
082:
083: /**
084: Answer a triple described by the three space-separated node descriptions
085: in <code>fact</code>, using prefix-mappings from <code>pm</code>; a
086: shorthand for <code>Triple.create(pm, fact)</code>, which see.
087: */
088: public static Triple triple(PrefixMapping pm, String fact) {
089: return Triple.create(pm, fact);
090: }
091:
092: /**
093: Answer an array of triples; each triple is described by one of the
094: semi-separated substrings of <code>facts</code>, as per
095: <code>triple</code> with prefix-mapping <code>Extended</code>.
096: */
097: public static Triple[] tripleArray(String facts) {
098: ArrayList al = new ArrayList();
099: StringTokenizer semis = new StringTokenizer(facts, ";");
100: while (semis.hasMoreTokens())
101: al.add(triple(PrefixMapping.Extended, semis.nextToken()));
102: return (Triple[]) al.toArray(new Triple[al.size()]);
103: }
104:
105: /**
106: Answer a set of triples where the elements are described by the
107: semi-separated substrings of <code>facts</code>, as per
108: <code>triple</code>.
109: */
110: public static Set tripleSet(String facts) {
111: Set result = new HashSet();
112: StringTokenizer semis = new StringTokenizer(facts, ";");
113: while (semis.hasMoreTokens())
114: result.add(triple(semis.nextToken()));
115: return result;
116: }
117:
118: /**
119: Answer a list of nodes, where the nodes are described by the
120: space-separated substrings of <code>items</code> as per
121: <code>node()</code>.
122: */
123: public static List nodeList(String items) {
124: ArrayList nl = new ArrayList();
125: StringTokenizer nodes = new StringTokenizer(items);
126: while (nodes.hasMoreTokens())
127: nl.add(node(nodes.nextToken()));
128: return nl;
129: }
130:
131: /**
132: Answer an array of nodes, where the nodes are described by the
133: space-separated substrings of <code>items</code> as per
134: */
135: public static Node[] nodeArray(String items) {
136: List nl = nodeList(items);
137: return (Node[]) nl.toArray(new Node[nl.size()]);
138: }
139:
140: /**
141: Answer the graph <code>g</code> after adding to it every triple
142: encoded in <code>s</code> in the fashion of <code>tripleArray</code>,
143: a semi-separated sequence of space-separated node descriptions.
144: */
145: public static Graph graphAdd(Graph g, String s) {
146: StringTokenizer semis = new StringTokenizer(s, ";");
147: while (semis.hasMoreTokens())
148: g.add(triple(PrefixMapping.Extended, semis.nextToken()));
149: return g;
150: }
151:
152: /**
153: Answer a new memory-based graph with Extended prefixes.
154: */
155: public static Graph newGraph() {
156: Graph result = Factory.createGraphMem();
157: result.getPrefixMapping().setNsPrefixes(PrefixMapping.Extended);
158: return result;
159: }
160:
161: /**
162: Answer a new memory-based graph with initial contents as described
163: by <code>s</code> in the fashion of <code>graphAdd()</code>.
164: Not over-ridable; do not use for abstraction.
165: */
166: public static Graph graphWith(String s) {
167: return graphAdd(newGraph(), s);
168: }
169:
170: /**
171: Assert that the graph <code>g</code> is isomorphic to the graph
172: described by <code>template</code> in the fashion of
173: <code>graphWith</code>.
174: */
175: public static void assertEqualsTemplate(String title, Graph g,
176: String template) {
177: assertIsomorphic(title, graphWith(template), g);
178: }
179:
180: /**
181: Assert that the supplied graph <code>got</code> is isomorphic with the
182: the desired graph <code>expected</code>; if not, display a readable
183: description of both graphs.
184: */
185: public static void assertIsomorphic(String title, Graph expected,
186: Graph got) {
187: if (!expected.isIsomorphicWith(got)) {
188: Map map = CollectionFactory.createHashedMap();
189: fail(title + ": wanted " + nice(expected, map)
190: + "\nbut got " + nice(got, map));
191: }
192: }
193:
194: /**
195: Answer a string which is a newline-separated list of triples (as
196: produced by niceTriple) in the graph <code>g</code>. The map
197: <code>bnodes</code> maps already-seen bnodes to their "nice" strings.
198: */
199: public static String nice(Graph g, Map bnodes) {
200: StringBuffer b = new StringBuffer(g.size() * 100);
201: ExtendedIterator it = GraphUtil.findAll(g);
202: while (it.hasNext())
203: niceTriple(b, bnodes, (Triple) it.next());
204: return b.toString();
205: }
206:
207: /**
208: Append to the string buffer <code>b</code> a "nice" representation
209: of the triple <code>t</code> on a new line, using (and updating)
210: <code>bnodes</code> to supply "nice" strings for any blank nodes.
211: */
212: protected static void niceTriple(StringBuffer b, Map bnodes,
213: Triple t) {
214: b.append("\n ");
215: appendNode(b, bnodes, t.getSubject());
216: appendNode(b, bnodes, t.getPredicate());
217: appendNode(b, bnodes, t.getObject());
218: }
219:
220: /**
221: A counter for new bnode strings; it starts at 1000 so as to make
222: the bnode strings more uniform (at least for the first 9000 bnodes).
223: */
224: protected static int bnc = 1000;
225:
226: /**
227: Append to the string buffer <code>b</code> a space followed by the
228: "nice" representation of the node <code>n</code>. If <code>n</code>
229: is a bnode, re-use any existing string for it from <code>bnodes</code>
230: or make a new one of the form <i>_bNNNN</i> with NNNN a new integer.
231: */
232: protected static void appendNode(StringBuffer b, Map bnodes, Node n) {
233: b.append(' ');
234: if (n.isBlank()) {
235: Object already = bnodes.get(n);
236: if (already == null)
237: bnodes.put(n, already = "_b" + bnc++);
238: b.append(already);
239: } else
240: b.append(nice(n));
241: }
242:
243: /**
244: Answer the "nice" representation of this node, the string returned by
245: <code>n.toString(PrefixMapping.Extended,true)</code>.
246: */
247: protected static String nice(Node n) {
248: return n.toString(PrefixMapping.Extended, true);
249: }
250:
251: /**
252: Assert that the computed graph <code>got</code> is isomorphic with the
253: desired graph <code>expected</code>; if not, fail with a default
254: message (and pretty output of the graphs).
255: */
256: public static void assertIsomorphic(Graph expected, Graph got) {
257: assertIsomorphic("graphs must be isomorphic", expected, got);
258: }
259:
260: /**
261: Assert that the graph <code>g</code> must contain the triple described
262: by <code>s</code>; if not, fail with pretty output of both graphs
263: and a message containing <code>name</code>.
264: */
265: public static void assertContains(String name, String s, Graph g) {
266: assertTrue(name + " must contain " + s, g.contains(triple(s)));
267: }
268:
269: /**
270: Assert that the graph <code>g</code> contains all the triples described
271: by the string <code>s</code; if not, fail with a message containing
272: <code>name</code>.
273: */
274: public static void assertContainsAll(String name, Graph g, String s) {
275: StringTokenizer semis = new StringTokenizer(s, ";");
276: while (semis.hasMoreTokens())
277: assertContains(name, semis.nextToken(), g);
278: }
279:
280: /**
281: Assert that the graph <code>g</code> does not contain the triple
282: described by <code>s<code>; if it does, fail with a message containing
283: <code>name</code>.
284: */
285: public static void assertOmits(String name, Graph g, String s) {
286: assertFalse(name + " must not contain " + s, g
287: .contains(triple(s)));
288: }
289:
290: /**
291: Assert that the graph <code>g</code> contains none of the triples
292: described by <code>s</code> in the usual way; otherwise, fail with
293: a message containing <code>name</code>.
294: */
295: public static void assertOmitsAll(String name, Graph g, String s) {
296: StringTokenizer semis = new StringTokenizer(s, ";");
297: while (semis.hasMoreTokens())
298: assertOmits(name, g, semis.nextToken());
299: }
300:
301: /**
302: Assert that <code>g</code> contains the triple described by
303: <code>fact</code> in the usual way.
304: */
305: public static boolean contains(Graph g, String fact) {
306: return g.contains(triple(fact));
307: }
308:
309: /**
310: Assert that <code>g</code> contains every triple in <code>triples</code>.
311: */
312: public void testContains(Graph g, Triple[] triples) {
313: for (int i = 0; i < triples.length; i += 1)
314: assertTrue("contains " + triples[i], g.contains(triples[i]));
315: }
316:
317: /**
318: Assert that <code>g</code> contains every triple in <code>triples</code>.
319: */
320: public void testContains(Graph g, List triples) {
321: for (int i = 0; i < triples.size(); i += 1)
322: assertTrue(g.contains((Triple) triples.get(i)));
323: }
324:
325: /**
326: Assert that <code>g</code> contains every triple in <code>it</code>.
327: */
328: public void testContains(Graph g, Iterator it) {
329: while (it.hasNext())
330: assertTrue(g.contains((Triple) it.next()));
331: }
332:
333: /**
334: Assert that <code>g</code> contains every triple in <code>other</code>.
335: */
336: public void testContains(Graph g, Graph other) {
337: testContains(g, GraphUtil.findAll(other));
338: }
339:
340: /**
341: Assert that <code>g</code> contains none of the triples in
342: <code>triples</code>.
343: */
344: public void testOmits(Graph g, Triple[] triples) {
345: for (int i = 0; i < triples.length; i += 1)
346: assertFalse("", g.contains(triples[i]));
347: }
348:
349: /**
350: Assert that <code>g</code> contains none of the triples in
351: <code>triples</code>.
352: */
353: public void testOmits(Graph g, List triples) {
354: for (int i = 0; i < triples.size(); i += 1)
355: assertFalse("", g.contains((Triple) triples.get(i)));
356: }
357:
358: /**
359: Assert that <code>g</code> contains none of the triples in
360: <code>it</code>.
361: */
362: public void testOmits(Graph g, Iterator it) {
363: while (it.hasNext())
364: assertFalse("", g.contains((Triple) it.next()));
365: }
366:
367: /**
368: Assert that <code>g</code> contains none of the triples in
369: <code>other</code>.
370: */
371: public void testOmits(Graph g, Graph other) {
372: testOmits(g, GraphUtil.findAll(other));
373: }
374:
375: /**
376: Answer an instance of <code>graphClass</code>. If <code>graphClass</code> has
377: a constructor that takes a <code>ReificationStyle</code> argument, then that
378: constructor is run on <code>style</code> to get the instance. Otherwise, if it has a #
379: constructor that takes an argument of <code>wrap</code>'s class before the
380: <code>ReificationStyle</code>, that constructor is used; this allows non-static inner
381: classes to be used for <code>graphClass</code>, with <code>wrap</code> being
382: the outer class instance. If no suitable constructor exists, a JenaException is thrown.
383:
384: @param wrap the outer class instance if graphClass is an inner class
385: @param graphClass a class implementing Graph
386: @param style the reification style to use
387: @return an instance of graphClass with the given style
388: @throws RuntimeException or JenaException if construction fails
389: */
390: public static Graph getGraph(Object wrap, Class graphClass,
391: ReificationStyle style) {
392: try {
393: Constructor cons = getConstructor(graphClass,
394: new Class[] { ReificationStyle.class });
395: if (cons != null)
396: return (Graph) cons.newInstance(new Object[] { style });
397: Constructor cons2 = getConstructor(graphClass, new Class[] {
398: wrap.getClass(), ReificationStyle.class });
399: if (cons2 != null)
400: return (Graph) cons2.newInstance(new Object[] { wrap,
401: style });
402: throw new JenaException(
403: "no suitable graph constructor found for "
404: + graphClass);
405: } catch (RuntimeException e) {
406: throw e;
407: } catch (Exception e) {
408: throw new JenaException(e);
409: }
410: }
411:
412: protected static Graph getReificationTriples(final Reifier r) {
413: return new GraphBase() {
414: public ExtendedIterator graphBaseFind(TripleMatch m) {
415: return r.find(m);
416: }
417: };
418: }
419:
420: }
421:
422: /*
423: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
424: All rights reserved.
425:
426: Redistribution and use in source and binary forms, with or without
427: modification, are permitted provided that the following conditions
428: are met:
429:
430: 1. Redistributions of source code must retain the above copyright
431: notice, this list of conditions and the following disclaimer.
432:
433: 2. Redistributions in binary form must reproduce the above copyright
434: notice, this list of conditions and the following disclaimer in the
435: documentation and/or other materials provided with the distribution.
436:
437: 3. The name of the author may not be used to endorse or promote products
438: derived from this software without specific prior written permission.
439:
440: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
441: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
442: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
443: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
444: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
445: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
446: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
447: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
448: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
449: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
450: */
|