KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > util > ResourceUtils


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 05-Jun-2003
9  * Filename $RCSfile: ResourceUtils.java,v $
10  * Revision $Revision: 1.12 $
11  * Release status $State: Exp $
12  *
13  * Last modified on $Date: 2005/02/21 12:18:57 $
14  * by $Author: andy_seaborne $
15  *
16  * (c) Copyright 2002, 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.util;
23
24
25
26 // Imports
27
///////////////
28
import java.util.*;
29
30 import com.hp.hpl.jena.rdf.model.*;
31
32
33
34 /**
35  * <p>
36  * General utility methods that operate on RDF resources, but which are not specific
37  * to a given model.
38  * </p>
39  *
40  * @author Ian Dickinson, HP Labs
41  * (<a HREF="mailto:Ian.Dickinson@hp.com" >email</a>)
42  * @version CVS $Id: ResourceUtils.java,v 1.12 2005/02/21 12:18:57 andy_seaborne Exp $
43  */

44 public class ResourceUtils {
45     // Constants
46
//////////////////////////////////
47

48     // Static variables
49
//////////////////////////////////
50

51     // Instance variables
52
//////////////////////////////////
53

54     // Constructors
55
//////////////////////////////////
56

57     // External signature methods
58
//////////////////////////////////
59

60     /**
61      * <p>
62      * Answer the maximal lower elements of the given collection, given the partial
63      * ordering <code>rel</code>. See {@link #maximalLowerElements( Iterator, Property, boolean )}
64      * for details.
65      * </p>
66      *
67      * @param resources A collection of resources
68      * @param rel A property defining a partial-ordering on <code>resources</code>
69      * @param inverse If true, we invert the given property (by reversing the order
70      * of the arguments), which allows us to use eg subClassOf as a partial order
71      * operator for both sub-class and super-class relationships
72      * @return The collection that contains only those <code>resources</code> are not
73      * greater than another resource under the partial order.
74      */

75     public static List maximalLowerElements( Collection resources, Property rel, boolean inverse ) {
76         return maximalLowerElements( resources.iterator(), rel, inverse );
77     }
78     
79     /**
80      * <p>
81      * Given a collection of resources, and a relation defining a partial order over
82      * those resources, answer the sub-collection that contains only those elements
83      * that appear in the maximal generator of the relation. Specifically, a resource
84      * <code>x</code> is excluded from the return value if there is another resource
85      * <code>y</code> in the input collection such that <code>y&nbsp;Rel&nbsp;x</code> holds.
86      * </p>
87      *
88      * @param resources An iterator over a collection of resources
89      * @param rel A property defining a partial-ordering on <code>resources</code>
90      * @param inverse If true, we invert the given property (by reversing the order
91      * of the arguments), which allows us to use eg subClassOf as a partial order
92      * operator for both sub-class and super-class relationships
93      * @return The list that contains only those <code>resources</code> are not
94      * greater than another resource under the partial order.
95      */

96     public static List maximalLowerElements( Iterator resources, Property rel, boolean inverse ) {
97         List in = new ArrayList();
98         List out = new ArrayList();
99         
100         while (resources.hasNext()) {
101             in.add( resources.next() );
102         }
103         
104         while (! in.isEmpty()) {
105             boolean rCovered = false;
106             Resource r = (Resource) in.remove( 0 );
107             
108             // check the remaining input list
109
for (Iterator i = in.iterator(); !rCovered && i.hasNext(); ) {
110                 Resource next = (Resource) i.next();
111                 rCovered = inverse ? r.hasProperty( rel, next ) : next.hasProperty( rel, r );
112             }
113             
114             // check the output list
115
for (Iterator i = out.iterator(); !rCovered && i.hasNext(); ) {
116                 Resource next = (Resource) i.next();
117                 rCovered = inverse ? r.hasProperty( rel, next ) : next.hasProperty( rel, r );
118             }
119             
120             // if r is not covered by another resource, we can add it to the output
121
if (!rCovered) {
122                 out.add( r );
123             }
124         }
125         
126         return out;
127     }
128
129     
130     /**
131      * <p>Remove from the given list l of {@link Resource Resources}, any Resource that is equivalent
132      * to the reference resource <code>ref</code> under the relation <code>p</code>. Typically,
133      * <code>p</code> will be <code>owl:subClassOf</code> or <code>owl:subPropertyOf</code>
134      * or some similar predicate. A resource R is defined to be equivalent to <code>ref</code>
135      * iff <code>R&nbsp;p&nbsp;ref</code> is true <em>and</em> <code>ref&nbsp;p&nbsp;R</code> is true.
136      * </p>
137      * <p>The equivalent resources are removed from list <code>l</code>
138      * </em>in place</em>, the return value is the list of <em>removed</em> resources.</p>
139      * @param l A list of resources from which the resources equivalent to ref will be removed
140      * @param p An equivalence predicate
141      * @param ref A reference resource
142      * @return A list of the resources removed from the parameter list l
143      */

144     public static List removeEquiv( List l, Property p, Resource ref ) {
145         List equiv = new ArrayList();
146         
147         for (Iterator i = l.iterator(); i.hasNext(); ) {
148             Resource r = (Resource) i.next();
149             
150             if (r.hasProperty( p, ref ) && ref.hasProperty( p, r )) {
151                 // resource r is equivalent to the reference resource
152
equiv.add( r );
153             }
154         }
155         
156         l.removeAll( equiv );
157         return equiv;
158     }
159
160     
161     /**
162      * <p>Answer a list of lists, which is a partition of the given
163      * input list of resources. The equivalence relation is the predicate p.
164      * So, two resources <code>a</code> and <code>b</code>
165      * will be in the same partition iff
166      * <code>(a p b) && (b p a)</code>.</p>
167      * @param l A list of resources
168      * @param p An equivalence predicate
169      * @return A list of lists which are the partitions of <code>l</code>
170      * under <code>p</code>
171      */

172     public static List partition( List l, Property p ) {
173         // first copy the input so we can mess with it
174
List source = new ArrayList();
175         source.addAll( l );
176         List parts = new ArrayList();
177         
178         while (!source.isEmpty()) {
179             // each step through the loop we pick a random element, and
180
// create a list of that element and all its equivalent values
181
Resource seed = (Resource) source.remove( 0 );
182             List part = removeEquiv( source, p, seed );
183             part.add( seed );
184             
185             // add to the partition list
186
parts.add( part );
187         }
188         
189         return parts;
190     }
191     
192     
193     /**
194      * <p>Answer a new resource that occupies the same position in the graph as the current
195      * resource <code>old</code>, but that has the given URI. In the process, the existing
196      * statements referring to <code>old</code> are removed. Since Jena does not allow the
197      * identity of a resource to change, this is the closest approximation to a rename operation
198      * that works.
199      * </p>
200      * <p><strong>Notes:</strong> This method does minimal checking, so renaming a resource
201      * to its own URI is unpredictable. Furthermore, it is a general and simple approach, and
202      * in given applications it may be possible to do this operation more efficiently. Finally,
203      * if <code>res</code> is a property, existing statements that use the property will not
204      * be renamed, nor will occurrences of <code>res</code> in other models.
205      * </p>
206      * @param old An existing resource in a given model
207      * @param uri A new URI for resource old, or null to rename old to a bNode
208      * @return A new resource that occupies the same position in the graph as old, but which
209      * has the new given URI.
210      */

211     public static Resource renameResource( Resource old, String JavaDoc uri ) {
212         Model m = old.getModel();
213         List stmts = new ArrayList();
214         
215         // list the statements that mention old as a subject
216
for (Iterator i = old.listProperties(); i.hasNext(); stmts.add( i.next() ) );
217         
218         // list the statements that mention old an an object
219
for (Iterator i = m.listStatements( null, null, old ); i.hasNext(); stmts.add( i.next() ) );
220         
221         // create a new resource to replace old
222
Resource res = (uri == null) ? m.createResource() : m.createResource( uri );
223         
224         // now move the statements to refer to res instead of old
225
for (Iterator i = stmts.iterator(); i.hasNext(); ) {
226             Statement s = (Statement) i.next();
227             
228             s.remove();
229             
230             Resource subj = s.getSubject().equals( old ) ? res : s.getSubject();
231             RDFNode obj = s.getObject().equals( old ) ? res : s.getObject();
232         
233             m.add( subj, s.getPredicate(), obj );
234         }
235         
236         return res;
237     }
238     
239
240     /**
241      * <p>Answer a model that contains all of the resources reachable from a given
242      * resource by any property, transitively. The returned graph is the sub-graph
243      * of the parent graph of root, whose root node is the given root. Cycles are
244      * permitted in the sub-graph.</p>
245      * @param root The root node of the sub-graph to extract
246      * @return A model containing all reachable RDFNodes from root by any property.
247      */

248     public static Model reachableClosure( Resource root ) {
249         Model m = ModelFactory.createDefaultModel();
250         
251         // set of resources we have passed through already (i.e. the occurs check)
252
Set seen = CollectionFactory.createHashedSet();
253         
254         // queue of resources we have not yet visited
255
List queue = new LinkedList();
256         queue.add( root );
257         
258         while (!queue.isEmpty()) {
259             Resource r = (Resource) queue.remove( 0 );
260             
261             // check for multiple paths arriving at this queue node
262
if (!seen.contains( r )) {
263                 seen.add( r );
264
265                 // add the statements to the output model, and queue any new resources
266
for (StmtIterator i = r.listProperties(); i.hasNext(); ) {
267                     Statement s = i.nextStatement();
268                     
269                     // don't do the occurs check now in case of reflexive statements
270
m.add( s );
271
272                     if (s.getObject() instanceof Resource) {
273                         queue.add( s.getObject() );
274                     }
275                 }
276             }
277         }
278         
279         return m;
280     }
281     
282     
283     // Internal implementation methods
284
//////////////////////////////////
285

286     //==============================================================================
287
// Inner class definitions
288
//==============================================================================
289

290 }
291
292
293 /*
294     (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
295     All rights reserved.
296
297     Redistribution and use in source and binary forms, with or without
298     modification, are permitted provided that the following conditions
299     are met:
300
301     1. Redistributions of source code must retain the above copyright
302        notice, this list of conditions and the following disclaimer.
303
304     2. Redistributions in binary form must reproduce the above copyright
305        notice, this list of conditions and the following disclaimer in the
306        documentation and/or other materials provided with the distribution.
307
308     3. The name of the author may not be used to endorse or promote products
309        derived from this software without specific prior written permission.
310
311     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
312     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
313     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
314     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
315     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
316     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
317     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
318     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
319     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
320     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
321 */

322
Popular Tags