KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > graph > impl > GraphBase


1 /*
2   (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
3   [See end of file]
4   $Id: GraphBase.java,v 1.39 2005/03/17 13:51:42 chris-dollin Exp $
5 */

6
7 package com.hp.hpl.jena.graph.impl;
8
9 import com.hp.hpl.jena.graph.*;
10 import com.hp.hpl.jena.graph.query.*;
11 import com.hp.hpl.jena.util.iterator.*;
12
13 import com.hp.hpl.jena.shared.*;
14 import com.hp.hpl.jena.shared.impl.PrefixMappingImpl;
15
16 /**
17     GraphBase is an implementation of Graph that provides some convenient
18     base functionality for Graph implementations.
19 <p>
20     Subtypes of GraphBase must provide performAdd(Triple), performDelete(Triple),
21     graphBaseFind(TripleMatch,TripleAction), and graphBaseSize(). GraphBase
22     provides default implementations of the other methods, including the other finds
23     (on top of that one), a simple-minded prepare, and contains. GraphBase also
24     handles the event-listening and registration interfaces.
25 <p>
26     When a GraphBase is closed, future operations on it may throw an exception.
27     
28     @author kers
29 */

30
31 public abstract class GraphBase implements GraphWithPerform
32     {
33     /**
34          The reification style of this graph, used when the reifier is created (and
35          nowhere else, as it happens, which is good).
36     */

37     protected final ReificationStyle style;
38     
39     /**
40          Whether or not this graph has been closed - used to report ClosedExceptions
41          when an operation is attempted on a closed graph.
42     */

43     protected boolean closed = false;
44
45     /**
46          Initialise this graph as one with reification style Minimal.
47     */

48     public GraphBase()
49         { this( ReificationStyle.Minimal ); }
50     
51     /**
52          Initialise this graph with the given reification style (which will be supplied to
53          the reifier when it is created).
54     */

55     public GraphBase( ReificationStyle style )
56         { this.style = style; }
57         
58     /**
59          Utility method: throw a ClosedException if this graph has been closed.
60     */

61     protected void checkOpen()
62         { if (closed) throw new ClosedException( "already closed", this ); }
63
64     /**
65          Close this graph. Subgraphs may extend to discard resources.
66     */

67     public void close()
68         { closed = true;
69         if (reifier != null) reifier.close(); }
70             
71     /**
72          Default implemenentation answers <code>true</code> iff this graph is the
73          same graph as the argument graph.
74     */

75     public boolean dependsOn( Graph other )
76         { return this == other; }
77
78     /**
79         Answer a QueryHandler bound to this graph. The default implementation
80         returns the same SimpleQueryHandler each time ti is called; sub-classes
81         may override if they need specialed query handlers.
82     */

83     public QueryHandler queryHandler()
84         {
85         if (queryHandler == null) queryHandler = new SimpleQueryHandler(this);
86         return queryHandler;
87         }
88     
89     /**
90          The query handler for this graph, or null if queryHandler() has not been
91          called yet.
92     */

93     protected QueryHandler queryHandler;
94     
95     /**
96         Answer the event manager for this graph; allocate a new one if required.
97         Subclasses may override if they have a more specialed event handler.
98         The default is a SimpleEventManager.
99     */

100     public GraphEventManager getEventManager()
101         {
102         if (gem == null) gem = new SimpleEventManager( this );
103         return gem;
104         }
105     
106     /**
107         The event manager that this Graph uses to, well, manage events; allocated on
108         demand.
109     */

110     protected GraphEventManager gem;
111
112         
113     /**
114         Tell the event manager that the triple <code>t</code> has been added to the graph.
115     */

116     public void notifyAdd( Triple t )
117         { getEventManager().notifyAddTriple( this, t ); }
118         
119     /**
120         Tell the event manager that the triple <code>t</code> has been deleted from the
121         graph.
122     */

123     public void notifyDelete( Triple t )
124         { getEventManager().notifyDeleteTriple( this, t ); }
125         
126     /**
127          Answer a transaction handler bound to this graph. The default is
128          SimpleTransactionHandler, which handles <i>no</i> transactions.
129     */

130     public TransactionHandler getTransactionHandler()
131         { return new SimpleTransactionHandler(); }
132         
133     /**
134          Answer a BulkUpdateHandler bound to this graph. The default is a
135          SimpleBulkUpdateHandler, which does bulk update by repeated simple
136          (add/delete) updates; the same handler is returned on each call. Subclasses
137          may override if they have specialised implementations.
138     */

139     public BulkUpdateHandler getBulkUpdateHandler()
140         {
141         if (bulkHandler == null) bulkHandler = new SimpleBulkUpdateHandler( this );
142         return bulkHandler;
143         }
144
145     /**
146          The allocated BulkUpdateHandler, or null if no handler has been allocated yet.
147     */

148     protected BulkUpdateHandler bulkHandler;
149     
150     /**
151          Answer the capabilities of this graph; the default is an AllCapabilities object
152          (the same one each time, not that it matters - Capabilities should be
153          immutable).
154     */

155     public Capabilities getCapabilities()
156         {
157         if (capabilities == null) capabilities = new AllCapabilities();
158         return capabilities;
159         }
160
161     /**
162          The allocated Capabilities object, or null if unallocated.
163     */

164     protected Capabilities capabilities = null;
165     
166     /**
167          Answer the PrefixMapping object for this graph, the same one each time.
168          Subclasses are unlikely to want to modify this.
169     */

170     public PrefixMapping getPrefixMapping()
171         { return pm; }
172
173     protected PrefixMapping pm = new PrefixMappingImpl();
174     
175     /**
176        Add a triple, and notify the event manager. Subclasses should not need to
177        override this - we might make it final. The triple is added using performAdd,
178        and notification done by notifyAdd.
179     */

180     public void add( Triple t )
181         {
182         checkOpen();
183         performAdd( t );
184         notifyAdd( t );
185         }
186     
187     /**
188          Add a triple to the triple store. The default implementation throws an
189          AddDeniedException; subclasses must override if they want to be able to
190          add triples.
191     */

192     public void performAdd( Triple t )
193         { throw new AddDeniedException( "GraphBase::performAdd" ); }
194
195     /**
196        Delete a triple, and notify the event manager. Subclasses should not need to
197        override this - we might make it final. The triple is added using performDelete,
198        and notification done by notifyDelete.
199      */

200     
201     public final void delete( Triple t )
202         {
203         checkOpen();
204         performDelete( t );
205         notifyDelete( t );
206         }
207         
208     /**
209          Remove a triple from the triple store. The default implementation throws
210          a DeleteDeniedException; subclasses must override if they want to be able
211          to remove triples.
212     */

213     public void performDelete( Triple t )
214         { throw new DeleteDeniedException( "GraphBase::delete" ); }
215
216     /**
217          Answer an (extended) iterator over all the triples in this Graph matching
218          <code>m</code>. Subclasses cannot over-ride this, because it implements
219          the appending of reification quadlets; instead they must implement
220          graphBaseFind(TripleMatch).
221     */

222     public final ExtendedIterator find( TripleMatch m )
223         { checkOpen();
224         return reifierTriples( m ) .andThen( graphBaseFind( m ) ); }
225
226     /**
227         Answer an iterator over all the triples held in this graph's non-reified triple store
228         that match <code>m</code>. Subclasses <i>must</i> override; it is the core
229         implementation for <code>find(TripleMatch)</code>.
230     */

231     protected abstract ExtendedIterator graphBaseFind( TripleMatch m );
232
233     /**
234          
235     */

236     public final ExtendedIterator find( Node s, Node p, Node o )
237         { checkOpen();
238         return graphBaseFind( s, p, o ); }
239     
240     protected ExtendedIterator graphBaseFind( Node s, Node p, Node o )
241         { return find( Triple.createMatch( s, p, o ) ); }
242
243     /**
244         Answer <code>true</code> iff <code>t</code> is in the graph as revealed by
245         <code>find(t)</code> being non-empty. <code>t</code> may contain ANY
246         wildcards. Sub-classes may over-ride reifierContains and graphBaseContains
247         for efficiency.
248     */

249     public final boolean contains( Triple t )
250         { checkOpen();
251         return reifierContains( t ) || graphBaseContains( t ); }
252     
253     /**
254          Answer true if the reifier contains a quad matching <code>t</code>. The
255          default implementation uses the reifier's <code>findExposed</code> method.
256          Subclasses probably don't need to override (if they're interested, they
257          probably have specialised reifiers).
258     */

259     protected boolean reifierContains( Triple t )
260         { ClosableIterator it = getReifier().findExposed( t );
261         try { return it.hasNext(); } finally { it.close(); } }
262
263     /**
264          Answer true if the graph contains any triple matching <code>t</code>.
265          The default implementation uses <code>find</code> and checks to see
266          if the iterator is non-empty.
267     */

268     protected boolean graphBaseContains( Triple t )
269         { return containsByFind( t ); }
270
271     /**
272          Answer <code>true</code> if this graph contains <code>(s, p, o)</code>;
273          this canonical implementation cannot be over-ridden.
274     */

275     public final boolean contains( Node s, Node p, Node o ) {
276         checkOpen();
277         return contains( Triple.create( s, p, o ) );
278     }
279     
280     /**
281         Utility method: answer true iff we can find at least one instantiation of
282         the triple in this graph using find(TripleMatch).
283         
284         @param t Triple that is the pattern to match
285         @return true iff find(t) returns at least one result
286     */

287     final protected boolean containsByFind( Triple t )
288         {
289         ClosableIterator it = find( t );
290         try { return it.hasNext(); } finally { it.close(); }
291         }
292     
293     /**
294          Answer an iterator over all the triples exposed in this graph's reifier that
295         match <code>m</code>. The default implementation delegates this to
296         the reifier; subclasses probably don't need to override this.
297     */

298     protected ExtendedIterator reifierTriples( TripleMatch m )
299         { return getReifier().findExposed( m ); }
300
301     /**
302          Answer this graph's reifier. The reifier may be lazily constructed, and it
303          must be the same reifier on each call. The default implementation is a
304          SimpleReifier.
305     */

306     public Reifier getReifier()
307         {
308         if (reifier == null) reifier = new SimpleReifier( this, style );
309         return reifier;
310         }
311     
312     /**
313          The cache variable for the allocated Reifier.
314     */

315     protected Reifier reifier = null;
316     
317     /**
318          Answer the size of this graph (ie the number of exposed triples). Defined as
319          the size of the triple store plus the size of the reification store. Subclasses
320          must override graphBaseSize() to reimplement (and reifierSize if they have
321          some special reason for redefined that).
322     */

323     public final int size()
324         { checkOpen();
325         return graphBaseSize() + reifierSize(); }
326     
327     /**
328          Answer the number of visible reification quads. Subclasses will not normally
329          need to override this, since it just invokes the reifier's size() method, and
330          they can implement their own reifier.
331     */

332     protected int reifierSize()
333         { return getReifier().size(); }
334
335     /**
336          Answer the number of triples in this graph. Default implementation counts its
337          way through the results of a findAll. Subclasses must override if they want
338          size() to be efficient.
339     */

340     protected int graphBaseSize()
341         {
342         ExtendedIterator it = GraphUtil.findAll( this );
343         int tripleCount = 0;
344         while (it.hasNext()) { it.next(); tripleCount += 1; }
345         return tripleCount;
346         }
347
348     /**
349         Answer true iff this graph contains no triples (hidden reification quads do
350         not count). The default implementation is <code>size() == 0</code>, which is
351         fine if <code>size</code> is reasonable efficient. Subclasses may override
352         if necessary. This method may become final and defined in terms of other
353         methods.
354     */

355     public boolean isEmpty()
356         { return size() == 0; }
357
358     /**
359          Answer true iff this graph is isomorphic to <code>g</code> according to
360          the algorithm (indeed, method) in <code>GraphMatcher</code>.
361     */

362     public boolean isIsomorphicWith( Graph g )
363         { checkOpen();
364         return g != null && GraphMatcher.equals( this, g ); }
365
366     /**
367          Answer a human-consumable representation of this graph. Not advised for
368          big graphs, as it generates a big string: intended for debugging purposes.
369     */

370
371     public String JavaDoc toString()
372         { return toString( (closed ? "closed " : ""), this ); }
373         
374     /**
375          Answer a human-consumable representation of <code>that</code>. The
376          string <code>prefix</code> will appear near the beginning of the string. Nodes
377          may be prefix-compressed using <code>that</code>'s prefix-mapping. This
378          default implementation will display all the triples exposed by the graph (ie
379          including reification triples if it is Standard).
380     */

381     public static String JavaDoc toString( String JavaDoc prefix, Graph that )
382         {
383         PrefixMapping pm = that.getPrefixMapping();
384         StringBuffer JavaDoc b = new StringBuffer JavaDoc( prefix + " {" );
385         String JavaDoc gap = "";
386         ClosableIterator it = GraphUtil.findAll( that );
387         while (it.hasNext())
388             {
389             b.append( gap );
390             gap = "; ";
391             b.append( ((Triple) it.next()).toString( pm ) );
392             }
393         b.append( "}" );
394         return b.toString();
395        }
396
397 }
398
399 /*
400     (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
401     All rights reserved.
402
403     Redistribution and use in source and binary forms, with or without
404     modification, are permitted provided that the following conditions
405     are met:
406
407     1. Redistributions of source code must retain the above copyright
408        notice, this list of conditions and the following disclaimer.
409
410     2. Redistributions in binary form must reproduce the above copyright
411        notice, this list of conditions and the following disclaimer in the
412        documentation and/or other materials provided with the distribution.
413
414     3. The name of the author may not be used to endorse or promote products
415        derived from this software without specific prior written permission.
416
417     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
418     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
419     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
420     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
421     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
422     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
423     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
424     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
425     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
426     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
427 */

428
Popular Tags