Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/hp/hpl/jena/enhanced/test/TestPackage.java


1   /*
2     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
3     [See end of file]
4     $Id: TestPackage.java,v 1.14 2005/02/21 12:03:42 andy_seaborne Exp $
5   */
6   /*
7    * EnhancedTestSuite.java
8    *
9    * Created on 27 November 2002, 04:53
10   */
11  
12  package com.hp.hpl.jena.enhanced.test;
13  import com.hp.hpl.jena.mem.*;
14  import com.hp.hpl.jena.graph.*;
15  import com.hp.hpl.jena.graph.test.*;
16  import com.hp.hpl.jena.enhanced.*;
17  
18  import junit.framework.*;
19  
20  /**
21   * These tests give a small version of a model-like interface
22   {@link TestModel} with different views
23   * over the nodes in the graph {@link TestSubject},
24   *{@link TestProperty} {@link TestObject} 
25   *Any node can be any one of these three, but the interface only works
26   *if the node is the subject, property or object, respectively,
27    of some triple in the graph.
28   *There are two implementations of the three interfaces. We use four
29   * different
30   *personalities, in the tests, from various combinations of the implementation
31   *classes with the interface classes. A more realistic test would be a basic set
32   *of interfaces with implementations, and then some more extended interfaces and
33   *implementations which can work together.
34   *
35   *These tests only test EnhNode polymorphism and not EnhGraph polymorphism.
36   *EnhGraph polymorphism currently will not work.
37   *(For Jena2.0 I am imagining that there will be ModelCom and DAMLModelImpl as
38   *the only two implementations, and they can inherit one from the other).
39   * @author  jjc
40   */
41  public class TestPackage extends GraphTestBase  {
42      
43    static final private  GraphPersonality split = new GraphPersonality();
44          
45    static final private GraphPersonality combo = new GraphPersonality();
46          
47          
48    static final private GraphPersonality bitOfBoth = new GraphPersonality();
49    static final private GraphPersonality broken = new GraphPersonality();
50    static {
51              // Setting up the personalities, involves registering how
52              // each interface is implemented by default.
53              // Note this does not guarantee that the only implementations
54              // of each interface will be the one specified.
55              // See bitOfBoth.
56          split.add( TestObject.class, TestObjectImpl.factory );
57          split.add( TestSubject.class, TestSubjectImpl.factory );
58          split.add( TestProperty.class, TestPropertyImpl.factory );
59          
60          combo.add( TestObject.class, TestAllImpl.factory );
61          combo.add( TestSubject.class, TestAllImpl.factory );
62          combo.add( TestProperty.class, TestAllImpl.factory );
63          
64          bitOfBoth.add( TestObject.class, TestObjectImpl.factory );
65          bitOfBoth.add( TestSubject.class, TestSubjectImpl.factory );
66          bitOfBoth.add( TestProperty.class, TestAllImpl.factory );
67          
68          // broken is misconfigured and must throw an exception.
69          broken.add(TestObject.class, TestObjectImpl.factory );
70          broken.add( TestSubject.class, TestSubjectImpl.factory );
71          broken.add( TestProperty.class, TestObjectImpl.factory );
72    }
73      /** Creates a new instance of EnhancedTestSuite */
74       public TestPackage(String name)
75      {
76      super( name );
77      }
78      
79      public static TestSuite suite()
80          { return new TestSuite( TestPackage.class ); }
81      
82      /**
83          test that equals works on an EnhNode (after hedgehog introduced FrontsNode
84          it didn't).
85      */
86      public void testEquals()
87          {
88          EnhNode a = new EnhNode( Node.create( "eg:example" ), null );
89          assertEquals( a, a );
90          }
91          
92      /**
93       * View n as intf. This is supported iff rslt.
94       */
95      private static void miniAsSupports(String title, TestNode n, Class intf, boolean rslt ) {
96          assertTrue(title +":sanity",n instanceof Polymorphic);
97          
98          // It is always possible to view any node with any interface.
99          TestNode as1 = (TestNode)((EnhNode)n).viewAs(intf);
100         TestNode as2 = (TestNode)((EnhNode)n).viewAs(intf);
101         
102         // caching should ensure we get the same result both times.
103         assertTrue( title + ":idempotency", as1==as2 );
104         
105         // Whether the interface is actually useable depends on the underlying
106         // graph. This factoid is the rslt parameter.
107         assertEquals( title +":support",rslt,((EnhNode) as1).supports( intf ) ); 
108     }
109     
110     private static void oneNodeAsSupports(String title, TestNode n, boolean rslts[] ) {
111       // Try n with all three interfaces.
112         miniAsSupports(title+"/TestSubject",n,TestSubject.class,rslts[0]);
113         miniAsSupports(title+"/TestProperty",n,TestProperty.class,rslts[1]);
114         miniAsSupports(title+"/TestObject",n,TestObject.class,rslts[2]);
115     }
116     
117     private static void manyNodeAsSupports(String title, TestNode n[], boolean rslts[][] ) {
118       // Try each n with each interface.
119         for (int i=0;i<n.length;i++){
120           oneNodeAsSupports(title+"["+i+"]",n[i],rslts[i]);
121         }
122     }
123     
124 
125     /** This test show the basic format of an enhanced test.
126      *  This test access data in an enhanced fashion. 
127      *  All modifications are done through the underlying graph.
128      *  The methods tested are as and supports.
129      */
130     private static void basic(String title, Personality p) {
131         Graph g = new GraphMem();
132         TestModel model =  new TestModelImpl(g,p);
133         // create some data
134         graphAdd( g, "x R y;" );
135         
136         // The graph has three nodes, extract them as TestNode's,
137         // using the minimalist ModelAPI.
138         TestNode nodes[] = new TestNode[]{
139             model.aSubject(),
140             model.aProperty(),
141             model.anObject()
142         };
143         
144         // Run the basic tests.
145         manyNodeAsSupports(title+"(a)",nodes, 
146            new boolean[][]{
147                new boolean[]{true,false,false}, // nodes[0] is subj, but not prop, or obj
148                new boolean[]{false,true,false},
149                new boolean[]{false,false,true}
150         });
151         
152         graphAdd(g,"y R x;" );
153         
154         // The expected results are now different.
155         // (A node is appropriate for the TestSubject interface if it is
156         // the subject of some triple in the graph, so the third node
157         // can now be a TestSubject).
158         manyNodeAsSupports(title+"(b)",nodes, 
159            new boolean[][]{
160                new boolean[]{true,false,true}, // nodes[0] is subj and obj, but not prop
161                new boolean[]{false,true,false},
162                new boolean[]{true,false,true}
163         });
164         
165         g.delete( triple( "x R y" ) );
166 
167       // The expected results are now different again.
168       // (A node is appropriate for the TestSubject interface if it is
169       // the subject of some triple in the graph, so the third node
170       // can now be a TestSubject).
171         
172         manyNodeAsSupports(title+"(c)",nodes, 
173            new boolean[][]{
174                new boolean[]{false,false,true}, 
175                new boolean[]{false,true,false},
176                new boolean[]{true,false,false}
177         });
178         
179         
180     }
181 
182     /** 
183         Would like to get rid of these, but the abstraction is hard to find at the
184         moment. At least they're now just local to this test class.
185     */
186     static final int S = 1;
187     static final int P = 2;
188     static final int O = 3;
189     
190     // This is like the earlier test: miniAsSupports (the last part of it).
191     // However, this time instead of asking whether the interface will work
192     // or not, we just try it.
193     // Obviously sometimes it is broken, which should be reported using
194     // an IllegalStateException.
195   private  void canImplement(String title, TestNode n, int wh, boolean rslt ) {
196     try {
197       switch (wh) {
198         case S:
199           n.asSubject().aProperty();
200           break;
201         case P:
202           n.asProperty().anObject();
203           break;
204         case O:
205           n.asObject().aSubject();
206           break;
207       }
208       assertTrue("IllegalStateException expected.",rslt);
209     }
210     catch (IllegalStateException e) {
211       assertFalse("IllegalStateException at the wrong time.",rslt);
212     }
213   }
214 
215   private  void canImplement(String title, TestNode n, boolean rslts[] ) {
216     canImplement(title+"/TestSubject",n,S,rslts[0]);
217     canImplement(title+"/TestProperty",n,P,rslts[1]);
218     canImplement(title+"/TestObject",n,O,rslts[2]);
219   }
220   private  void canImplement(String title, TestNode n[], boolean rslts[][] ) {
221     for (int i=0;i<n.length;i++){
222       canImplement(title+"["+i+"]",n[i],rslts[i]);
223     }
224   }
225   
226     private  void follow(String title, Personality p) {
227         Graph g = new GraphMem();
228         TestModel model =  new TestModelImpl(g,p);
229         // create some data
230         graphAdd( g, "a b c;" );
231         TestNode nodes[] = new TestNode[]{
232             model.aSubject(),
233             model.aProperty(),
234             model.anObject()
235         };
236         
237         // Similar to the basic test.
238         canImplement(title+"(a)",nodes, 
239            new boolean[][]{
240                new boolean[]{true,false,false}, 
241                new boolean[]{false,true,false},
242                new boolean[]{false,false,true}
243         });
244         
245         graphAdd(g, "b a c;" );
246 
247       // Again like in the basic test the triples have now changed,
248       // so different methods will now work.
249         canImplement(title+"(b)",nodes, 
250            new boolean[][]{
251                new boolean[]{true,true,false}, 
252                new boolean[]{true,true,false},
253                new boolean[]{false,false,true}
254         });
255         
256         g.delete(triple( "a b c" ) );
257 
258 
259       // Again like in the basic test the triples have now changed,
260       // so different methods will now work.
261         canImplement(title+"(c)",nodes, 
262            new boolean[][]{
263                new boolean[]{false,true,false}, 
264                new boolean[]{true,false,false},
265                new boolean[]{false,false,true}
266         });
267 
268         // Another twist.
269         canImplement(title+"(c)",new TestNode[]{
270             nodes[1].asSubject().aProperty(),
271             nodes[2].asObject().aSubject(),
272             nodes[0].asProperty().anObject()
273         }, 
274            new boolean[][]{
275                new boolean[]{false,true,false}, 
276                new boolean[]{true,false,false},
277                new boolean[]{false,false,true}
278         });                
279         assertTrue("Model cache test",nodes[0].asProperty().anObject()==nodes[2]);
280     }
281     private  void cache(String title, Personality p) {
282         Graph g = new GraphMem();
283         TestModel model =  new TestModelImpl(g,p);
284         // create some data
285         graphAdd( g, "a b a;" );
286         
287         // get the same node in two different ways.
288         assertTrue("Caching is on",model.aSubject().asObject()==model.anObject());
289         
290         ((TestModelImpl)model).getNodeCacheControl().setEnabled(false);
291         
292 
293       // get the same node in two different ways; if there isn't any caching
294       // then we reconstruct the node.
295         assertFalse("Caching is off",model.aSubject()==model.anObject());
296         
297     }
298     public static void testSplitBasic() {
299        basic("Split: ",split);
300     }
301     public static void testComboBasic() {
302      basic("Combo: ",combo);
303     }
304     public  void testSplitFollow() {
305        follow("Split: ",split);
306     }
307     public  void testComboFollow() {
308      follow("Combo: ",combo);
309     }
310     
311     public  void testSplitCache() {
312         cache("Split: ",split);
313     }
314     public  void testComboCache() {
315      cache("Combo: ",combo);
316     }
317     
318     public static void testBitOfBothBasic() {
319        basic("bob: ",bitOfBoth);
320     }
321     public  void testBitOfBothFollow() {
322        follow("bob: ",bitOfBoth);
323     }
324     
325     public  void testBitOfBothCache() {
326         cache("bob: ",bitOfBoth);
327     }
328     
329     public static void testBitOfBothSurprise() {
330       // bitOfBoth is a surprising personality ...
331       // we can have two different java objects implementing the same interface.
332       
333     Graph g = new GraphMem();
334     TestModel model =  new TestModelImpl(g,bitOfBoth);
335     // create some data
336     graphAdd( g, "a a a;" );
337     TestSubject testSubjectImpl = model.aSubject();
338     assertTrue("BitOfBoth makes subjects using TestSubjectImpl",
339              testSubjectImpl instanceof TestSubjectImpl);
340     TestProperty testAllImpl = testSubjectImpl.aProperty();
341       assertTrue("BitOfBoth makes properties using TestAllImpl",
342            testAllImpl instanceof TestAllImpl);
343       assertTrue("turning a TestAllImpl into a TestSubject is a no-op",
344                 testAllImpl == testAllImpl.asSubject() );
345       assertTrue("turning a TestAllImpl into a TestSubject is a no-op",
346             testSubjectImpl != testAllImpl.asSubject() );
347       assertTrue("turning a TestAllImpl into a TestSubject is a no-op",
348             testSubjectImpl.asSubject() != testSubjectImpl.asSubject().asProperty().asSubject() );
349                 
350     }
351     
352     public static void testBrokenBasic() {
353       try {
354         // Any of the tests ought to work up and til the point
355         // that they don't. At that point they need to detect the
356         // error and throw the PersonalityConfigException.
357            basic("Broken: ",broken);
358            fail("broken is a misconfigured personality, but it wasn't detected.");
359       } 
360       catch (PersonalityConfigException e ) {
361         
362       }
363     }
364     
365     static class Example 
366         {
367         static final Implementation factory = new Implementation()
368             {
369             public EnhNode wrap( Node n, EnhGraph g ) { return new EnhNode( n, g ); }
370             
371             public boolean canWrap( Node n, EnhGraph g ) { return n.isURI(); }
372             };
373         }
374     
375     public void testSimple()
376         {
377         Graph g = new GraphMem();
378         Personality ours = BuiltinPersonalities.model.copy().add( Example.class, Example.factory );
379         EnhGraph eg = new EnhGraph( g, ours ); 
380         Node n = Node.createURI( "spoo:bar" );
381         EnhNode eNode = new EnhNode( Node.createURI( "spoo:bar" ), eg );
382         EnhNode eBlank = new EnhNode( Node.createAnon(), eg );
383         assertTrue( "URI node can be an Example", eNode.supports( Example.class ) );
384         assertFalse( "Blank node cannot be an Example", eBlank.supports( Example.class ) );
385         }
386         
387     static class AnotherExample 
388         {
389         static final Implementation factory = new Implementation()
390             {
391             public EnhNode wrap( Node n, EnhGraph g ) { return new EnhNode( n, g ); }
392             
393             public boolean canWrap( Node n, EnhGraph g ) { return n.isURI(); }
394             };
395         }
396     
397     public void testAlreadyLinkedViewException()
398         {
399          Graph g = new GraphMem();
400          Personality ours = BuiltinPersonalities.model.copy().add( Example.class, Example.factory );
401          EnhGraph eg = new EnhGraph( g, ours ); 
402          Node n = Node.create( "spoo:bar" );
403          EnhNode eNode = new EnhNode( n, eg );
404          eNode.viewAs( Example.class );
405          try
406             { 
407             eNode.addView( eNode ); 
408             fail( "should raise an AlreadyLinkedViewException " );
409             }
410         catch (AlreadyLinkedViewException e)
411             {}                
412         }
413         
414     /**
415         Test that an attempt to polymorph an enhanced node into a class that isn't
416         supported by the enhanced graph generates an UnsupportedPolymorphism
417         exception. 
418     */
419     public void testNullPointerTrap()
420         {
421         EnhGraph eg = new EnhGraph( new GraphMem(), BuiltinPersonalities.model );
422         Node n = Node.create( "eh:something" );
423         EnhNode en = new EnhNode( n, eg );
424         try 
425             { 
426             en.as( TestPackage.class ); 
427             fail( "oops" ); 
428             }
429         catch (UnsupportedPolymorphismException e) 
430             {
431             assertTrue( "exception should have cuplprit graph", eg == e.getBadGraph() );
432             assertTrue( "exception should have culprit class", TestPackage.class == e.getBadClass() );
433             }
434         }
435 
436 }
437 
438 /*
439     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
440     All rights reserved.
441 
442     Redistribution and use in source and binary forms, with or without
443     modification, are permitted provided that the following conditions
444     are met:
445 
446     1. Redistributions of source code must retain the above copyright
447        notice, this list of conditions and the following disclaimer.
448 
449     2. Redistributions in binary form must reproduce the above copyright
450        notice, this list of conditions and the following disclaimer in the
451        documentation and/or other materials provided with the distribution.
452 
453     3. The name of the author may not be used to endorse or promote products
454        derived from this software without specific prior written permission.
455 
456     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
457     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
458     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
459     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
460     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
461     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
462     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
463     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
464     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
465     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
466 */