KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > rdf > model > RDFList


1 /*****************************************************************************
2  * Source code information
3  * -----------------------
4  * Original author Ian Dickinson, HP Labs Bristol
5  * Author email Ian.Dickinson@hp.com
6  * Package Jena 2
7  * Web http://sourceforge.net/projects/jena/
8  * Created 24 Jan 2003
9  * Filename $RCSfile: RDFList.java,v $
10  * Revision $Revision: 1.10 $
11  * Release status @releaseStatus@ $State: Exp $
12  *
13  * Last modified on $Date: 2005/02/21 12:14:21 $
14  * by $Author: andy_seaborne $
15  *
16  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
17  * (see footer for full conditions)
18  *****************************************************************************/

19
20 // Package
21
///////////////
22
package com.hp.hpl.jena.rdf.model;
23
24
25 // Imports
26
///////////////
27
import com.hp.hpl.jena.util.iterator.*;
28
29 import java.util.*;
30
31
32 /**
33  * <p>
34  * Provides a convenience encapsulation for lists formed from chains of RDF
35  * statements arranged to form a head/tail cons-cell structure. The properties
36  * that form the links between cells, and from cells to values, are specified by
37  * a vocabulary interface, so this abstraction is designed to cope equally well
38  * with DAML lists, RDF lists, and user-defined lists.
39  * </p>
40  * <p>
41  * A well-formed list has cells that are made up of three statements: one
42  * denoting the <code>rdf:type</code> of the list cell, one denoting the link
43  * to the value of the list at that point, and one pointing to the list tail. If
44  * a list cell is not well-formed, list operations may fail in unpredictable
45  * ways. However, to explicitly check that the list is well-formed at all times
46  * is expensive. Therefore the list operates in two modes: in <i>strict</i>
47  * mode, the well-formedness of the list is checked at the start of each list
48  * operation, and an {@link InvalidListException} is thrown if the list is not
49  * well- formed. This ensures that list operations are safe, but will slow down
50  * processing. In <i>non-strict</i> mode, this checking is switched off, but can
51  * be invoked explicitly by clients by calling {@link #isValid}. By default, RDF
52  * lists are processed in non-strict mode.
53  * </p>
54  *
55  * @author Ian Dickinson, HP Labs
56  * (<a HREF="mailto:Ian.Dickinson@hp.com" >email</a>)
57  * @version Release ($Id: RDFList.java,v 1.10 2005/02/21 12:14:21 andy_seaborne Exp $)
58  */

59 public interface RDFList
60     extends Resource
61 {
62     // Constants
63
//////////////////////////////////
64

65
66     // External signature methods
67
//////////////////////////////////
68

69     /**
70      * <p>
71      * Answer the number of elements in the list.
72      * </p>
73      *
74      * @return The size of the list as an integer
75      */

76     public int size();
77     
78     
79     /**
80      * <p>
81      * Answer the value that is at the head of the list.
82      * </p>
83      *
84      * @return The value that is associated with the head of the list.
85      * @exception EmptyListException if this list is the empty list
86      */

87     public RDFNode getHead();
88     
89     
90     /**
91      * <p>
92      * Update the head of the list to have the given value, and return the
93      * previous value.
94      * </p>
95      *
96      * @param value The value that will become the value of the list head
97      * @exception EmptyListException if this list is the empty list
98      */

99     public RDFNode setHead( RDFNode value );
100     
101     
102     /**
103      * <p>
104      * Answer the list that is the tail of this list.
105      * </p>
106      *
107      * @return The tail of the list, as a list
108      * @exception EmptyListException if this list is the empty list
109      */

110     public RDFList getTail();
111     
112     
113     /**
114      * <p>
115      * Update the list cell at the front of the list to have the given list as
116      * tail. The old tail is returned, and remains in the model.
117      * </p>
118      *
119      * @param tail The new tail for this list.
120      * @return The old tail.
121      */

122     public RDFList setTail( RDFList tail );
123     
124     
125     /**
126      * Answer true if this list is the empty list.
127      *
128      * @return True if this is the empty (nil) list, otherwise false.
129      */

130     public boolean isEmpty();
131     
132     
133     /**
134      * <p>
135      * Return a reference to a new list cell whose head is <code>value</code>
136      * and whose tail is this list.
137      * </p>
138      *
139      * @param value A new value to add to the head of the list
140      * @return The new list, whose head is <code>value</code>
141      */

142     public RDFList cons( RDFNode value );
143     
144     
145     /**
146      * <p>
147      * Add the given value to the end of the list. This is a side-effecting
148      * operation on the underlying model that is only defined if this is not the
149      * empty list. If this list is the empty (nil) list, we cannot perform a
150      * side-effecting update without changing the URI of this node (from <code>rdf:nil</code)
151      * to a blank-node for the new list cell) without violating a Jena invariant.
152      * Therefore, this update operation will throw an exception if an attempt is
153      * made to add to the nil list. Safe ways to add to an empty list include
154      * {@link #with} and {@link #cons}.
155      * </p>
156      *
157      * @param value A value to add to the end of the list
158      * @exception EmptyListUpdateException if an attempt is made to
159      * <code>add</code> to the empty list.
160      */

161     public void add( RDFNode value );
162     
163     
164     /**
165      * <p>
166      * Answer the list that is this list with the given value added to the end
167      * of the list. This operation differs from {@link #add} in that it will
168      * always work, even on an empty list, but the return value is the updated
169      * list. Specifically, in the case of adding a value to the empty list, the
170      * returned list will not be the same as this list. <strong>Client code should
171      * not assume that this is an in-place update, but should ensure that the resulting
172      * list is asserted back into the graph into the appropriate relationships.</strong>
173      * </p>
174      *
175      * @param value A value to add to the end of the list
176      * @return The list that results from adding a value to the end of this list
177      */

178     public RDFList with( RDFNode value );
179     
180     
181     /**
182      * <p>
183      * Answer the node that is the i'th element of the list, assuming that the
184      * head is item zero. If the list is too short to have an i'th element,
185      * throws a {@link ListIndexException}.
186      * </p>
187      *
188      * @param i The index into the list, from 0
189      * @return The list value at index i, or null
190      * @exception ListIndexException if the list has fewer than (i + 1)
191      * elements.
192      */

193     public RDFNode get( int i );
194     
195     
196     /**
197      * <p>
198      * Replace the value at the i'th position in the list with the given value.
199      * If the list is too short to have an i'th element, throws a {@link
200      * ListIndexException}.
201      * </p>
202      *
203      * @param i The index into the list, from 0
204      * @param value The new value to associate with the i'th list element
205      * @return The value that was previously at position i in the list
206      * @exception ListIndexException if the list has fewer than (i + 1)
207      * elements.
208      */

209     public RDFNode replace( int i, RDFNode value );
210     
211     
212     /**
213      * <p>
214      * Answer true if the given node appears as the value of a value of any
215      * of the cells of this list.
216      * </p>
217      *
218      * @param value A value to test for
219      * @return True if the list contains value.
220      */

221     public boolean contains( RDFNode value );
222     
223     
224     /**
225      * <p>
226      * Answer the index of the first occurrence of the given value in the list,
227      * or -1 if the value is not in the list.
228      * </p>
229      *
230      * @param value The value to search for
231      * @return The index of the first occurrence of value in the list, or
232      * <code>-1</code> if not found.
233      */

234     public int indexOf( RDFNode value );
235     
236     
237     /**
238      * <p>
239      * Answer the index of the first occurrence of the given value in the list
240      * after index <code>start</code>, or -1 if the value is not in the list
241      * after the given start point.
242      * </p>
243      *
244      * @param value The value to search for
245      * @param start The index into the list to start searching from
246      * @return The index of the first occurrence of value in the list not less
247      * than <code>start</code>, or <code>-1</code> if not found.
248      * @exception ListIndexException if <code>start</code> is greater than the
249      * length of the list.
250      */

251     public int indexOf( RDFNode value, int start );
252     
253     
254     /**
255      * <p>
256      * Answer a new list that is formed by adding each element of this list to
257      * the head of the given <code>list</code>. This is a non side-effecting
258      * operation on either this list or the given list, but generates a copy
259      * of this list. For a more storage efficient alternative, see {@link
260      * #concatenate concatenate}.
261      * </p>
262      *
263      * @param list The argument list
264      * @return A new RDFList that contains all of this elements of this list,
265      * followed by all of the elements of the given list.
266      */

267     public RDFList append( RDFList list );
268         
269         
270     /**
271      * <p>
272      * Answer a new list that is formed by adding each element of this list to
273      * the head of the the list formed from the
274      * given <code>nodes</code>. This is a non side-effecting
275      * operation on either this list or the given list, but generates a copy
276      * of this list. For a more storage efficient alternative, see {@link
277      * #concatenate concatenate}.
278      * </p>
279      *
280      * @param nodes An iterator whose range is RDFNode
281      * @return A new RDFList that contains all of this elements of this list,
282      * followed by all of the elements of the given iterator.
283      */

284     public RDFList append( Iterator nodes );
285         
286         
287     /**
288      * <p>
289      * Change the tail of this list to point to the given list, so that this
290      * list becomes the list of the concatenation of the elements of both lists.
291      * This is a side-effecting operation on this list; for a non side-effecting
292      * alternative, see {@link #append}. Due to the problem of maintaining
293      * the URI invariant on a node, this operation will throw an exception if an
294      * attempt is made to concatenate onto an empty list. To avoid this, test for
295      * an empty list: if true replace the empty list with the argument list, otherwise
296      * proceed with the concatenate as usual. An alternative solution is to use
297      * {@link #append} and replace the original list with the return value.
298      * </p>
299      *
300      * @param list The argument list to concatenate to this list
301      * @exception EmptyListUpdateException if this list is the nil list
302      */

303     public void concatenate( RDFList list );
304         
305         
306     /**
307      * <p>
308      * Add the nodes returned by the given iterator to the end of this list.
309      * </p>
310      *
311      * @param nodes An iterator whose range is RDFNode
312      * @exception EmptyListUpdateException if this list is the nil list
313      * @see #concatenate(RDFList) for details on avoiding the empty list update exception.
314      */

315     public void concatenate( Iterator nodes );
316         
317     
318     /**
319      * <p>
320      * Answer a list that contains all of the elements of this list in the same
321      * order, but is a duplicate copy in the underlying model.
322      * </p>
323      *
324      * @return A copy of the current list
325      */

326     public RDFList copy();
327     
328     
329     /**
330      * <p>
331      * Apply a function to each value in the list in turn.
332      * </p>
333      *
334      * @param fn The function to apply to each list node.
335      */

336     public void apply( ApplyFn fn );
337     
338     
339     /**
340      * <p>
341      * Apply a function to each value in the list in turn, accumulating the
342      * results in an accumulator. The final value of the accumulator is returned
343      * as the value of <code>reduce()</code>.
344      * </p>
345      *
346      * @param fn The reduction function to apply
347      * @param initial The initial value for the accumulator
348      * @return The final value of the accumulator.
349      */

350     public Object JavaDoc reduce( ReduceFn fn, Object JavaDoc initial );
351     
352     
353     /**
354      * <p>Answer an iterator of the elements of this list, to each of which
355      * the given map function has been applied.</p>
356      * @param fn A Map function
357      * @return The iterator of the elements of this list mapped with the given map function.
358      */

359     public ExtendedIterator mapWith( Map1 fn );
360     
361     
362     /**
363      * <p>
364      * Remove the value from the head of the list. The tail of the list remains
365      * in the model. Note that no changes are made to list cells that point to
366      * this list cell as their tail. Immediately following a
367      * <code>removeHead</code> operation, such lists will be in a non-valid
368      * state.
369      * </p>
370      *
371      * @return The remainder of the list after the head is removed (i&#046;e&#046; the
372      * pre-removal list tail)
373      */

374     public RDFList removeHead();
375     
376     
377     /**
378      * <p>Deprecated. Since an <code>RDFList</code> does not behave like a Java container, it is not
379      * the case that the contents of the list can be removed and the container filled with values
380      * again. Therefore, this method name has been deprecated in favour of {@link #removeList}</p>
381      * @deprecated Replaced by {@link #removeList}
382      */

383     public void removeAll();
384     
385     
386     /**
387      * <p>Remove all of the components of this list from the model. Once this operation
388      * has completed, the {@link RDFList} resource on which it was called will no
389      * longer be a resource in the model, so further methods calls on the list object
390      * (for example, {@link #size} will fail. Due to restrictions on the encoding
391      * of lists in RDF, it is not possible to perform an operation which empties a list
392      * and then adds further values to that list. Client code wishing to perform
393      * such an operation should do so in two steps: first remove the old list, then
394      * create a new list with the new contents. It is important that RDF statements
395      * that reference the old list (in the object position) be updated to point
396      * to the newly created list.
397      * Note that this
398      * is operation is only removing the list cells themselves, not the resources
399      * referenced by the list - unless being the object of an <code>rdf:first</code>
400      * statement is the only mention of that resource in the model.</p>
401      */

402     public void removeList();
403     
404     
405     /**
406      * <p>Remove the given value from this list. If <code>val</code> does not occur in
407      * the list, no action is taken. Since removing the head of the list will invalidate
408      * the list head cell, in general the list must return the list that results from this
409      * operation. However, in many cases the return value will be the same as the object
410      * that this method is invoked on</p>
411      *
412      * @param val The value to be removed from the list
413      * @return The resulting list, which will be the same as the current list in most
414      * cases, except when <code>val</code> occurs at the head of the list.
415      */

416     public RDFList remove( RDFNode val );
417     
418     
419     /**
420      * <p>
421      * Answer an iterator over the elements of the list. Note that this iterator
422      * does not take a snapshot of the list, so changes to the list statements
423      * in the model while iterating will affect the behaviour of the iterator.
424      * To get an iterator that is not affected by model changes, use {@link
425      * #asJavaList}.
426      * </p>
427      *
428      * @return A closable iterator over the elements of the list.
429      */

430     public ExtendedIterator iterator();
431     
432     
433     /**
434      * <p>
435      * Answer the contents of this RDF list as a Java list of RDFNode values.
436      * </p>
437      *
438      * @return The contents of this list as a Java List.
439      */

440     public List asJavaList();
441     
442     
443     /**
444      * <p>
445      * Answer true if this list has the same elements in the same order as the
446      * given list. Note that the standard <code>equals</code> test just tests
447      * for equality of two given list cells. While such a test is sufficient
448      * for many purposes, this test provides a broader equality definition, but
449      * is correspondingly more expensive to test.
450      * </p>
451      *
452      * @param list The list to test against
453      * @return True if the given list and this list are the same length, and
454      * contain equal elements in the same order.
455      */

456     public boolean sameListAs( RDFList list );
457     
458     
459     /**
460      * <p>
461      * Answer true lists are operating in strict mode, in which the
462      * well- formedness of the list is checked at every operation.
463      * </p>
464      *
465      * @return True lists are being strictly checked.
466      */

467     public boolean getStrict();
468     
469     
470     /**
471      * <p>
472      * Set a flag to indicate whether to strictly check the well-formedness of
473      * lists at each operation. Default false. <strong>Note</strong> that the flag that is
474      * manipulated is actually a static: it applies to all lists. However, RDFList
475      * is a Java interface, and Java does not permit static methods in interfaces.
476      * </p>
477      *
478      * @param strict The <b>static</b> flag for whether lists will be checked strictly.
479      */

480     public void setStrict( boolean strict );
481     
482     
483     /**
484      * <p>
485      * Answer true if the list is well-formed, by checking that each node is
486      * correctly typed, and has a head and tail pointer from the correct
487      * vocabulary. If the list is invalid, the reason is available via {@link
488      * #getValidityErrorMessage}.
489      * </p>
490      *
491      * @return True if the list is well-formed.
492      * @see #getValidityErrorMessage
493      */

494     public boolean isValid();
495     
496     
497     /**
498      * <p>
499      * Answer the error message returned by the last failed validity check,
500      * if any.
501      * </p>
502      *
503      * @return The most recent error message, or null.
504      * @see #isValid
505      */

506     public String JavaDoc getValidityErrorMessage();
507     
508     
509     //==============================================================================
510
// Inner class definitions
511
//==============================================================================
512

513     /**
514      * Interface that encapsulates a function to apply to every element in a
515      * list.
516      */

517     public static interface ApplyFn {
518         /**
519          * <p>
520          * Apply a function to the given RDF node.
521          * </p>
522          *
523          * @param node A node from the list.
524          */

525         public void apply( RDFNode node );
526     }
527     
528     
529     /**
530      * Interface that encapsulates a function to apply to each element of a list
531      * in turn, and passing the result to an accumulator.
532      */

533     public static interface ReduceFn {
534         /**
535          * <p>
536          * Apply a function to the given RDF node.
537          * </p>
538          *
539          * @param node A node from the list.
540          * @param accumulator The accumulator for the reduction, which will
541          * either be an initial value passed to {@link RDFList#reduce}, or the
542          * output from <code>reduce</code> applied to the previous node in the
543          * list.
544          * @return The result of applying the reduction function to the current
545          * node and the accumulator.
546          */

547         public Object JavaDoc reduce( RDFNode node, Object JavaDoc accumulator );
548     }
549 }
550
551
552 /*
553     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
554     All rights reserved.
555
556     Redistribution and use in source and binary forms, with or without
557     modification, are permitted provided that the following conditions
558     are met:
559
560     1. Redistributions of source code must retain the above copyright
561        notice, this list of conditions and the following disclaimer.
562
563     2. Redistributions in binary form must reproduce the above copyright
564        notice, this list of conditions and the following disclaimer in the
565        documentation and/or other materials provided with the distribution.
566
567     3. The name of the author may not be used to endorse or promote products
568        derived from this software without specific prior written permission.
569
570     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
571     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
572     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
573     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
574     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
575     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
576     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
577     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
578     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
579     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
580 */

581
Popular Tags