KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > ontology > impl > OntModelImpl


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 22 Feb 2003
9  * Filename $RCSfile: OntModelImpl.java,v $
10  * Revision $Revision: 1.82 $
11  * Release status $State: Exp $
12  *
13  * Last modified on $Date: 2005/04/11 16:37:41 $
14  * by $Author: ian_dickinson $
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.ontology.impl;
23
24
25 // Imports
26
///////////////
27
import com.hp.hpl.jena.rdf.listeners.StatementListener;
28 import com.hp.hpl.jena.rdf.model.*;
29 import com.hp.hpl.jena.rdf.model.impl.*;
30 import com.hp.hpl.jena.reasoner.*;
31 import com.hp.hpl.jena.util.iterator.*;
32 import com.hp.hpl.jena.vocabulary.*;
33 import com.hp.hpl.jena.ontology.*;
34 import com.hp.hpl.jena.ontology.event.*;
35 import com.hp.hpl.jena.graph.*;
36 import com.hp.hpl.jena.graph.compose.MultiUnion;
37 import com.hp.hpl.jena.graph.query.*;
38 import com.hp.hpl.jena.enhanced.*;
39 import com.hp.hpl.jena.shared.*;
40
41 import java.io.*;
42 import java.util.*;
43
44 import org.apache.commons.logging.Log;
45 import org.apache.commons.logging.LogFactory;
46
47
48
49 /**
50  * <p>
51  * Implementation of a model that can process general ontologies in OWL,
52  * DAML and similar languages.
53  * </p>
54  *
55  * @author Ian Dickinson, HP Labs
56  * (<a HREF="mailto:Ian.Dickinson@hp.com" >email</a>)
57  * @version CVS $Id: OntModelImpl.java,v 1.82 2005/04/11 16:37:41 ian_dickinson Exp $
58  */

59 public class OntModelImpl
60     extends ModelCom
61     implements OntModel
62 {
63     // Constants
64
//////////////////////////////////
65

66     /**
67      * This variable is how the OntModel knows how to construct
68      * a syntax checker. This part of the design may change.
69      */

70     static public String JavaDoc owlSyntaxCheckerClassName = "com.hp.hpl.jena.ontology.tidy.JenaChecker";
71
72
73     // Static variables
74
//////////////////////////////////
75

76     static private Log s_log = LogFactory.getLog( OntModelImpl.class );
77
78     /** Found from {@link owlSyntaxCheckerClassName}, must implement
79      * {@link OWLSyntaxChecker}. */

80     static private Class JavaDoc owlSyntaxCheckerClass;
81
82     // Instance variables
83
//////////////////////////////////
84

85     /** The model specification this model is using to define its structure */
86     protected OntModelSpec m_spec;
87
88     /** List of URI strings of documents that have been imported into this one */
89     protected Set m_imported = new HashSet();
90
91     /** Query that will access nodes with types whose type is Class */
92     protected BindingQueryPlan m_individualsQueryNoInf0;
93
94     /** Query that will access nodes with types whose type is Restriction */
95     protected BindingQueryPlan m_individualsQueryNoInf1;
96
97     /** Mode switch for strict checking mode */
98     protected boolean m_strictMode = true;
99
100     /** The union graph that contains the imports closure - there is always one of these, which may also be _the_ graph for the model */
101     protected MultiUnion m_union = new MultiUnion();
102
103     /** The listener that detects dynamically added or removed imports statments */
104     protected ImportsListener m_importsListener = null;
105
106     /** The event manager for ontology events on this model */
107     protected OntEventManager m_ontEventMgr = null;
108
109     /** Cached deductions model */
110     private Model m_deductionsModel = null;
111
112
113     // Constructors
114
//////////////////////////////////
115

116
117     /**
118      * <p>
119      * Construct a new ontology model, using the given model as a base. The document manager
120      * given in the specification object
121      * will be used to build the imports closure of the model if its policy permits.
122      * </p>
123      *
124      * @param model The base model that may contain existing statements for the ontology.
125      * if it is null, a fresh model is created as the base.
126      * @param spec A specification object that allows us to specify parameters and structure for the
127      * ontology model to be constructed.
128      */

129     public OntModelImpl( OntModelSpec spec, Model model ) {
130         this( spec, makeBaseModel( spec, model ), false );
131     }
132
133     /**
134      * Construct a new ontology model from the given specification. The base model is
135      * produced using the baseModelMaker.
136     */

137     public OntModelImpl( OntModelSpec spec ) {
138         this( spec, spec.createBaseModel(), false );
139     }
140
141     /**
142      *
143      * @param spec the specification for the OntModel
144      * @param model the base model [must be non-null]
145      * @param overloadingTrick because otherwise this looks like the public
146      * OntModelImpl(spec, model)
147      */

148     private OntModelImpl( OntModelSpec spec, Model model, boolean overloadingTrick ) {
149         // we haven't built the full graph yet, so we pass a vestigial form up to the super constructor
150
super( generateGraph( spec, model.getGraph() ), BuiltinPersonalities.model );
151         m_spec = spec;
152
153         // extract the union graph from whatever generateGraph() created
154
m_union = (getGraph() instanceof MultiUnion) ?
155                         ((MultiUnion) getGraph()) :
156                         (MultiUnion) ((InfGraph) getGraph()).getRawGraph();
157
158         // cache the query plan for individuals
159
m_individualsQueryNoInf0 = queryXTypeOfType( getProfile().CLASS() );
160         m_individualsQueryNoInf1 = queryXTypeOfType( getProfile().RESTRICTION() );
161
162         // add the global prefixes, if required
163
if (getDocumentManager().useDeclaredPrefixes()) {
164             withDefaultMappings( getDocumentManager().getDeclaredPrefixMapping() );
165         }
166
167         // load the imports closure, according to the policies in my document manager
168
getDocumentManager().loadImports( this );
169
170         // force the inference engine, if we have one, to see the new graph data
171
rebind();
172     }
173
174
175
176     // External signature methods
177
//////////////////////////////////
178

179     /**
180      * <p>
181      * Answer a reference to the document manager that this model is using to manage
182      * ontology &lt;-&gt; mappings, and to load the imports closure. <strong>Note</strong>
183      * the default ontology model {@linkplain OntModelSpec specifications} each have
184      * a contained default document manager. Changing the document managers specified by
185      * these default specification may (in fact, probably will)
186      * affect other models built with the same specification
187      * policy. This may or may not be as desired by the programmer!
188      * </p>
189      * @return A reference to this model's document manager, obtained from the specification object
190      */

191     public OntDocumentManager getDocumentManager() {
192         return m_spec.getDocumentManager();
193     }
194
195
196     /**
197      * <p>
198      * Answer an iterator that ranges over the ontology resources in this model, i&#046;e&#046;
199      * the resources with <code>rdf:type Ontology</code> or equivalent. These resources
200      * typically contain metadata about the ontology document that contains them.
201      * </p>
202      * <p>
203      * Specifically, the resources in this iterator will those whose type corresponds
204      * to the value given in the ontology vocabulary associated with this model, see
205      * {@link Profile#ONTOLOGY}.
206      * </p>
207      * <p>
208      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
209      * the completeness of the deductive extension of the underlying graph. See class
210      * overview for more details.
211      * </p>
212      *
213      * @return An iterator over ontology resources.
214      */

215     public ExtendedIterator listOntologies() {
216         checkProfileEntry( getProfile().ONTOLOGY(), "ONTOLOGY" );
217         return UniqueExtendedIterator.create(
218             findByTypeAs( getProfile().ONTOLOGY(), Ontology.class ) );
219     }
220
221
222     /**
223      * <p>
224      * Answer an iterator that ranges over the property resources in this model, i&#046;e&#046;
225      * the resources with <code>rdf:type Property</code> or equivalent. An <code>OntProperty</code>
226      * is equivalent to an <code>rdfs:Property</code> in a normal RDF graph; this type is
227      * provided as a common super-type for the more specific {@link ObjectProperty} and
228      * {@link DatatypeProperty} property types.
229      * </p>
230      * <p>
231      * Specifically, the resources in this iterator will those whose type corresponds
232      * to the value given in the ontology vocabulary associated with this model.
233      * </p>
234      * <p>
235      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
236      * the completeness of the deductive extension of the underlying graph. See class
237      * overview for more details.
238      * </p>
239      *
240      * @return An iterator over property resources.
241      */

242     public ExtendedIterator listOntProperties() {
243         return UniqueExtendedIterator.create(
244             findByTypeAs( RDF.Property, OntProperty.class ) );
245     }
246
247
248     /**
249      * <p>
250      * Answer an iterator that ranges over the object property resources in this model, i&#046;e&#046;
251      * the resources with <code>rdf:type ObjectProperty</code> or equivalent. An object
252      * property is a property that is defined in the ontology language semantics as a
253      * one whose range comprises individuals (rather than datatyped literals).
254      * </p>
255      * <p>
256      * Specifically, the resources in this iterator will those whose type corresponds
257      * to the value given in the ontology vocabulary associated with this model: see
258      * {@link Profile#OBJECT_PROPERTY}.
259      * </p>
260      * <p>
261      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
262      * the completeness of the deductive extension of the underlying graph. See class
263      * overview for more details.
264      * </p>
265      *
266      * @return An iterator over object property resources.
267      */

268     public ExtendedIterator listObjectProperties() {
269         checkProfileEntry( getProfile().OBJECT_PROPERTY(), "OBJECT_PROPERTY" );
270         return UniqueExtendedIterator.create(
271             findByTypeAs( getProfile().OBJECT_PROPERTY(), ObjectProperty.class ) );
272     }
273
274
275     /**
276      * <p>
277      * Answer an iterator that ranges over the datatype property resources in this model, i&#046;e&#046;
278      * the resources with <code>rdf:type DatatypeProperty</code> or equivalent. An datatype
279      * property is a property that is defined in the ontology language semantics as a
280      * one whose range comprises datatyped literals (rather than individuals).
281      * </p>
282      * <p>
283      * Specifically, the resources in this iterator will those whose type corresponds
284      * to the value given in the ontology vocabulary associated with this model: see
285      * {@link Profile#DATATYPE_PROPERTY}.
286      * </p>
287      * <p>
288      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
289      * the completeness of the deductive extension of the underlying graph. See class
290      * overview for more details.
291      * </p>
292      *
293      * @return An iterator over datatype property resources.
294      */

295     public ExtendedIterator listDatatypeProperties() {
296         checkProfileEntry( getProfile().DATATYPE_PROPERTY(), "DATATYPE_PROPERTY" );
297         return UniqueExtendedIterator.create(
298             findByTypeAs( getProfile().DATATYPE_PROPERTY(), DatatypeProperty.class ) );
299     }
300
301
302     /**
303      * <p>
304      * Answer an iterator that ranges over the functional property resources in this model, i&#046;e&#046;
305      * the resources with <code>rdf:type FunctionalProperty</code> or equivalent. A functional
306      * property is a property that is defined in the ontology language semantics as having
307      * a unique domain element for each instance of the relationship.
308      * </p>
309      * <p>
310      * Specifically, the resources in this iterator will those whose type corresponds
311      * to the value given in the ontology vocabulary associated with this model: see
312      * {@link Profile#FUNCTIONAL_PROPERTY}.
313      * </p>
314      *
315      * @return An iterator over functional property resources.
316      */

317     public ExtendedIterator listFunctionalProperties() {
318         checkProfileEntry( getProfile().FUNCTIONAL_PROPERTY(), "FUNCTIONAL_PROPERTY" );
319         return UniqueExtendedIterator.create(
320             findByTypeAs( getProfile().FUNCTIONAL_PROPERTY(), FunctionalProperty.class ) );
321     }
322
323
324     /**
325      * <p>
326      * Answer an iterator that ranges over the transitive property resources in this model, i&#046;e&#046;
327      * the resources with <code>rdf:type TransitiveProperty</code> or equivalent.
328      * </p>
329      * <p>
330      * Specifically, the resources in this iterator will those whose type corresponds
331      * to the value given in the ontology vocabulary associated with this model: see
332      * {@link Profile#TRANSITIVE_PROPERTY}.
333      * </p>
334      *
335      * @return An iterator over transitive property resources.
336      */

337     public ExtendedIterator listTransitiveProperties() {
338         checkProfileEntry( getProfile().TRANSITIVE_PROPERTY(), "TRANSITIVE_PROPERTY" );
339         return UniqueExtendedIterator.create(
340             findByTypeAs( getProfile().TRANSITIVE_PROPERTY(), TransitiveProperty.class ) );
341     }
342
343
344     /**
345      * <p>
346      * Answer an iterator that ranges over the symmetric property resources in this model, i&#046;e&#046;
347      * the resources with <code>rdf:type SymmetricProperty</code> or equivalent.
348      * </p>
349      * <p>
350      * Specifically, the resources in this iterator will those whose type corresponds
351      * to the value given in the ontology vocabulary associated with this model: see
352      * {@link Profile#SYMMETRIC_PROPERTY}.
353      * </p>
354      *
355      * @return An iterator over symmetric property resources.
356      */

357     public ExtendedIterator listSymmetricProperties() {
358         checkProfileEntry( getProfile().SYMMETRIC_PROPERTY(), "SYMMETRIC_PROPERTY" );
359         return UniqueExtendedIterator.create(
360             findByTypeAs( getProfile().SYMMETRIC_PROPERTY(), SymmetricProperty.class ) );
361     }
362
363
364     /**
365      * <p>
366      * Answer an iterator that ranges over the inverse functional property resources in this model, i&#046;e&#046;
367      * the resources with <code>rdf:type InverseFunctionalProperty</code> or equivalent.
368      * </p>
369      * <p>
370      * Specifically, the resources in this iterator will those whose type corresponds
371      * to the value given in the ontology vocabulary associated with this model: see
372      * {@link Profile#INVERSE_FUNCTIONAL_PROPERTY}.
373      * </p>
374      *
375      * @return An iterator over inverse functional property resources.
376      */

377     public ExtendedIterator listInverseFunctionalProperties() {
378         checkProfileEntry( getProfile().INVERSE_FUNCTIONAL_PROPERTY(), "INVERSE_FUNCTIONAL_PROPERTY" );
379         return UniqueExtendedIterator.create(
380             findByTypeAs( getProfile().INVERSE_FUNCTIONAL_PROPERTY(), InverseFunctionalProperty.class ) );
381     }
382
383
384     /**
385      * <p>
386      * Answer an iterator that ranges over the individual resources in this model, i&#046;e&#046;
387      * the resources with <code>rdf:type</code> corresponding to a class defined
388      * in the ontology.
389      * </p>
390      * <p>
391      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
392      * the completeness of the deductive extension of the underlying graph. See class
393      * overview for more details.
394      * </p>
395      *
396      * @return An iterator over Individuals.
397      */

398     public ExtendedIterator listIndividuals() {
399         // since the reasoner implements some OWL full functionality for RDF compatability, we
400
// have to decide which strategy to use for indentifying individuals depending on whether
401
// or not a powerful reasoner (i.e. owl:Thing/daml:Thing aware) is being used with this model
402
boolean supportsIndAsThing = false;
403         if (getGraph() instanceof InfGraph) {
404             supportsIndAsThing = ((InfGraph) getGraph()).getReasoner()
405                                                         .getReasonerCapabilities()
406                                                         .contains( null, ReasonerVocabulary.supportsP, ReasonerVocabulary.individualAsThingP );
407         }
408         if (!supportsIndAsThing || (getProfile().THING() == null) || getProfile().CLASS().equals( RDFS.Class )) {
409             // no inference, or we are in RDFS land, so we pick things that have rdf:type whose rdf:type is Class
410
ExtendedIterator indivI = queryFor( m_individualsQueryNoInf0, null, Individual.class );
411
412             if (m_individualsQueryNoInf1 != null) {
413                 // and things whose rdf:type is Restriction
414
indivI = indivI.andThen( queryFor( m_individualsQueryNoInf1, null, Individual.class ) );
415             }
416
417             // we also must pick resources that simply have rdf:type owl:Thing, since some individuals are asserted that way
418
if (getProfile().THING() != null) {
419                 indivI = indivI.andThen( findByTypeAs( getProfile().THING(), Individual.class ) );
420             }
421
422             return UniqueExtendedIterator.create( indivI );
423         }
424         else {
425             // inference, so we pick the nodes that are of type Thing
426
return UniqueExtendedIterator.create(
427                     findByTypeAs( getProfile().THING(), Individual.class ) );
428         }
429     }
430
431
432     /**
433      * <p>
434      * Answer an iterator that ranges over all of the various forms of class description resource
435      * in this model. Class descriptions include {@link #listEnumeratedClasses enumerated}
436      * classes, {@link #listUnionClasses union} classes, {@link #listComplementClasses complement}
437      * classes, {@link #listIntersectionClasses intersection} classes, {@link #listClasses named}
438      * classes and {@link #listRestrictions property restrictions}.
439      * </p>
440      * <p>
441      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
442      * the completeness of the deductive extension of the underlying graph. See class
443      * overview for more details.
444      * </p>
445      *
446      * @return An iterator over class description resources.
447      */

448     public ExtendedIterator listClasses() {
449         return UniqueExtendedIterator.create(
450             findByTypeAs( getProfile().getClassDescriptionTypes(), OntClass.class ) );
451     }
452
453
454     /**
455      * <p>Answer an iterator over the classes in this ontology model that represent
456      * the uppermost nodes of the class hierarchy. Depending on the underlying
457      * reasoner configuration, if any, these will be calculated as the classes
458      * that have Top (i.e. <code>owl:Thing</code> or <code>daml:Thing</code>)
459      * as a direct super-class, or the classes which have no declared super-class.</p>
460      * @return An iterator of the root classes in the local class hierarchy
461      */

462     public ExtendedIterator listHierarchyRootClasses() {
463         // look for the shortcut of using direct subClass on :Thing
464
if (getReasoner() != null) {
465             Model conf = getReasoner().getReasonerCapabilities();
466             if (conf.contains( null, ReasonerVocabulary.supportsP, ReasonerVocabulary.directSubClassOf ) &&
467                 getProfile().THING() != null)
468             {
469                 // we have have both direct sub-class of and a :Thing class to test against
470
return listStatements( null, ReasonerVocabulary.directSubClassOf, getProfile().THING() )
471                        .mapWith( new OntResourceImpl.SubjectAsMapper( OntClass.class ));
472             }
473         }
474
475         // no easy shortcut, so we use brute force
476
return listClasses()
477                  .filterDrop( new Filter() {
478                      public boolean accept( Object JavaDoc o ) {
479                          return ((OntResource) o).isOntLanguageTerm();
480                      }} )
481                  .filterKeep( new Filter() {
482                      public boolean accept( Object JavaDoc o ) {
483                          return ((OntClass) o).isHierarchyRoot();
484                      }} )
485                     ;
486     }
487
488
489     /**
490      * <p>
491      * Answer an iterator that ranges over the enumerated class class-descriptions
492      * in this model, i&#046;e&#046; the class resources specified to have a property
493      * <code>oneOf</code> (or equivalent) and a list of values.
494      * </p>
495      * <p>
496      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
497      * the completeness of the deductive extension of the underlying graph. See class
498      * overview for more details.
499      * </p>
500      *
501      * @return An iterator over enumerated class resources.
502      * @see Profile#ONE_OF
503      */

504     public ExtendedIterator listEnumeratedClasses() {
505         checkProfileEntry( getProfile().ONE_OF(), "ONE_OF" );
506         return UniqueExtendedIterator.create(
507             findByDefiningPropertyAs( getProfile().ONE_OF(), EnumeratedClass.class ) );
508     }
509
510
511     /**
512      * <p>
513      * Answer an iterator that ranges over the union class-descriptions
514      * in this model, i&#046;e&#046; the class resources specified to have a property
515      * <code>unionOf</code> (or equivalent) and a list of values.
516      * </p>
517      * <p>
518      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
519      * the completeness of the deductive extension of the underlying graph. See class
520      * overview for more details.
521      * </p>
522      *
523      * @return An iterator over union class resources.
524      * @see Profile#UNION_OF
525      */

526     public ExtendedIterator listUnionClasses() {
527         checkProfileEntry( getProfile().UNION_OF(), "UNION_OF" );
528         return UniqueExtendedIterator.create(
529             findByDefiningPropertyAs( getProfile().UNION_OF(), UnionClass.class ) );
530     }
531
532
533     /**
534      * <p>
535      * Answer an iterator that ranges over the complement class-descriptions
536      * in this model, i&#046;e&#046; the class resources specified to have a property
537      * <code>complementOf</code> (or equivalent) and a list of values.
538      * </p>
539      * <p>
540      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
541      * the completeness of the deductive extension of the underlying graph. See class
542      * overview for more details.
543      * </p>
544      *
545      * @return An iterator over complement class resources.
546      * @see Profile#COMPLEMENT_OF
547      */

548     public ExtendedIterator listComplementClasses() {
549         checkProfileEntry( getProfile().COMPLEMENT_OF(), "COMPLEMENT_OF" );
550         return UniqueExtendedIterator.create(
551             findByDefiningPropertyAs( getProfile().COMPLEMENT_OF(), ComplementClass.class ) );
552     }
553
554
555     /**
556      * <p>
557      * Answer an iterator that ranges over the intersection class-descriptions
558      * in this model, i&#046;e&#046; the class resources specified to have a property
559      * <code>intersectionOf</code> (or equivalent) and a list of values.
560      * </p>
561      * <p>
562      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
563      * the completeness of the deductive extension of the underlying graph. See class
564      * overview for more details.
565      * </p>
566      *
567      * @return An iterator over complement class resources.
568      * @see Profile#INTERSECTION_OF
569      */

570     public ExtendedIterator listIntersectionClasses() {
571         checkProfileEntry( getProfile().INTERSECTION_OF(), "INTERSECTION_OF" );
572         return UniqueExtendedIterator.create(
573             findByDefiningPropertyAs( getProfile().INTERSECTION_OF(), IntersectionClass.class ) );
574     }
575
576
577     /**
578      * <p>
579      * Answer an iterator that ranges over the named class-descriptions
580      * in this model, i&#046;e&#046; resources with <code>rdf:type
581      * Class</code> (or equivalent) and a node URI.
582      * </p>
583      * <p>
584      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
585      * the completeness of the deductive extension of the underlying graph. See class
586      * overview for more details.
587      * </p>
588      *
589      * @return An iterator over named class resources.
590      */

591     public ExtendedIterator listNamedClasses() {
592         return listClasses().filterDrop(
593             new Filter() {
594                 public boolean accept( Object JavaDoc x ) {
595                     return ((Resource) x).isAnon();
596                 }
597             }
598         );
599     }
600
601
602     /**
603      * <p>
604      * Answer an iterator that ranges over the property restriction class-descriptions
605      * in this model, i&#046;e&#046; resources with <code>rdf:type
606      * Restriction</code> (or equivalent).
607      * </p>
608      * <p>
609      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
610      * the completeness of the deductive extension of the underlying graph. See class
611      * overview for more details.
612      * </p>
613      *
614      * @return An iterator over restriction class resources.
615      * @see Profile#RESTRICTION
616      */

617     public ExtendedIterator listRestrictions() {
618         checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
619         return UniqueExtendedIterator.create(
620             findByTypeAs( getProfile().RESTRICTION(), Restriction.class ) );
621     }
622
623
624     /**
625      * <p>
626      * Answer an iterator that ranges over the nodes that denote pair-wise disjointness between
627      * sets of classes.
628      * </p>
629      * <p>
630      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
631      * the completeness of the deductive extension of the underlying graph. See class
632      * overview for more details.
633      * </p>
634      *
635      * @return An iterator over AllDifferent nodes.
636      */

637     public ExtendedIterator listAllDifferent() {
638         checkProfileEntry( getProfile().ALL_DIFFERENT(), "ALL_DIFFERENT" );
639         return UniqueExtendedIterator.create(
640             findByTypeAs( getProfile().ALL_DIFFERENT(), AllDifferent.class ) );
641     }
642
643     /**
644      * <p>Answer an iterator over the DataRange objects in this ontology, if there
645      * are any.</p>
646      * @return An iterator, whose values are {@link DataRange} objects.
647      */

648     public ExtendedIterator listDataRanges() {
649         checkProfileEntry( getProfile().DATARANGE(), "DATARANGE" );
650         return UniqueExtendedIterator.create(
651                 findByTypeAs( getProfile().DATARANGE(), DataRange.class ) );
652     }
653
654
655     /**
656      * <p>
657      * Answer an iterator that ranges over the properties in this model that are declared
658      * to be annotation properties. Not all supported languages define annotation properties
659      * (the category of annotation properties is chiefly an OWL innovation).
660      * </p>
661      * <p>
662      * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
663      * the completeness of the deductive extension of the underlying graph. See class
664      * overview for more details.
665      * </p>
666      *
667      * @return An iterator over annotation properties.
668      * @see Profile#getAnnotationProperties()
669      */

670     public ExtendedIterator listAnnotationProperties() {
671         checkProfileEntry( getProfile().ANNOTATION_PROPERTY(), "ANNOTATION_PROPERTY" );
672         Resource r = getProfile().ANNOTATION_PROPERTY();
673
674         if (r == null) {
675             return NullIterator.instance;
676         }
677         else {
678             return UniqueExtendedIterator.create(
679                         findByType( r )
680                           .andThen( WrappedIterator.create( getProfile().getAnnotationProperties() ) )
681                           .mapWith( new SubjectNodeAs( AnnotationProperty.class ) ) );
682         }
683     }
684
685
686     /**
687      * <p>
688      * Answer a resource that represents an ontology description node in this model. If a resource
689      * with the given uri exists in the model, and can be viewed as an Ontology, return the
690      * Ontology facet, otherwise return null.
691      * </p>
692      *
693      * @param uri The uri for the ontology node. Conventionally, this corresponds to the base URI
694      * of the document itself.
695      * @return An Ontology resource or null.
696      */

697     public Ontology getOntology( String JavaDoc uri ) {
698         return (Ontology) findByURIAs( uri, Ontology.class );
699     }
700
701
702     /**
703      * <p>
704      * Answer a resource that represents an Individual node in this model. If a resource
705      * with the given uri exists in the model, and can be viewed as an Individual, return the
706      * Individual facet, otherwise return null.
707      * </p>
708      *
709      * @param uri The URI for the requried individual
710      * @return An Individual resource or null.
711      */

712     public Individual getIndividual( String JavaDoc uri ) {
713         return (Individual) findByURIAs( uri, Individual.class );
714     }
715
716
717     /**
718      * <p>
719      * Answer a resource representing an generic property in this model. If a property
720      * with the given uri exists in the model, return the
721      * OntProperty facet, otherwise return null.
722      * </p>
723      *
724      * @param uri The uri for the property.
725      * @return An OntProperty resource or null.
726      */

727     public OntProperty getOntProperty( String JavaDoc uri ) {
728         return (OntProperty) findByURIAs( uri, OntProperty.class );
729     }
730
731
732     /**
733      * <p>
734      * Answer a resource representing an object property in this model. If a resource
735      * with the given uri exists in the model, and can be viewed as an ObjectProperty, return the
736      * ObjectProperty facet, otherwise return null.
737      * </p>
738      *
739      * @param uri The uri for the object property. May not be null.
740      * @return An ObjectProperty resource or null.
741      */

742     public ObjectProperty getObjectProperty( String JavaDoc uri ) {
743         return (ObjectProperty) findByURIAs( uri, ObjectProperty.class );
744     }
745
746
747     /**
748      * <p>Answer a resource representing a transitive property. If a resource
749      * with the given uri exists in the model, and can be viewed as a TransitiveProperty, return the
750      * TransitiveProperty facet, otherwise return null. </p>
751      * @param uri The uri for the property. May not be null.
752      * @return A TransitiveProperty resource or null
753      */

754     public TransitiveProperty getTransitiveProperty( String JavaDoc uri ) {
755         return (TransitiveProperty) findByURIAs( uri, TransitiveProperty.class );
756     }
757
758
759     /**
760      * <p>Answer a resource representing a symmetric property. If a resource
761      * with the given uri exists in the model, and can be viewed as a SymmetricProperty, return the
762      * SymmetricProperty facet, otherwise return null. </p>
763      * @param uri The uri for the property. May not be null.
764      * @return A SymmetricProperty resource or null
765      */

766     public SymmetricProperty getSymmetricProperty( String JavaDoc uri ) {
767         return (SymmetricProperty) findByURIAs( uri, SymmetricProperty.class );
768     }
769
770
771     /**
772      * <p>Answer a resource representing an inverse functional property. If a resource
773      * with the given uri exists in the model, and can be viewed as a InverseFunctionalProperty, return the
774      * InverseFunctionalProperty facet, otherwise return null. </p>
775      * @param uri The uri for the property. May not be null.
776      * @return An InverseFunctionalProperty resource or null
777      */

778     public InverseFunctionalProperty getInverseFunctionalProperty( String JavaDoc uri ) {
779         return (InverseFunctionalProperty) findByURIAs( uri, InverseFunctionalProperty.class );
780     }
781
782
783     /**
784      * <p>
785      * Answer a resource that represents datatype property in this model. . If a resource
786      * with the given uri exists in the model, and can be viewed as a DatatypeProperty, return the
787      * DatatypeProperty facet, otherwise return null.
788      * </p>
789      *
790      * @param uri The uri for the datatype property. May not be null.
791      * @return A DatatypeProperty resource or null
792      */

793     public DatatypeProperty getDatatypeProperty( String JavaDoc uri ) {
794         return (DatatypeProperty) findByURIAs( uri, DatatypeProperty.class );
795     }
796
797
798     /**
799      * <p>
800      * Answer a resource that represents an annotation property in this model. If a resource
801      * with the given uri exists in the model, and can be viewed as an AnnotationProperty, return the
802      * AnnotationProperty facet, otherwise return null.
803      * </p>
804      *
805      * @param uri The uri for the annotation property. May not be null.
806      * @return An AnnotationProperty resource or null
807      */

808     public AnnotationProperty getAnnotationProperty( String JavaDoc uri ) {
809         return (AnnotationProperty) findByURIAs( uri, AnnotationProperty.class );
810     }
811
812
813     /**
814      * <p>
815      * Answer a resource that represents a class description node in this model. If a resource
816      * with the given uri exists in the model, and can be viewed as an OntClass, return the
817      * OntClass facet, otherwise return null.
818      * </p>
819      *
820      * @param uri The uri for the class node, or null for an anonymous class.
821      * @return An OntClass resource or null.
822      */

823     public OntClass getOntClass( String JavaDoc uri ) {
824         return (OntClass) findByURIAs( uri, OntClass.class );
825     }
826
827
828     /**
829      * <p>Answer a resource representing the class that is the complement of another class. If a resource
830      * with the given uri exists in the model, and can be viewed as a ComplementClass, return the
831      * ComplementClass facet, otherwise return null. </p>
832      * @param uri The URI of the new complement class.
833      * @return A complement class or null
834      */

835     public ComplementClass getComplementClass( String JavaDoc uri ) {
836         return (ComplementClass) findByURIAs( uri, ComplementClass.class );
837     }
838
839
840     /**
841      * <p>Answer a resource representing the class that is the enumeration of a list of individuals. If a resource
842      * with the given uri exists in the model, and can be viewed as an EnumeratedClass, return the
843      * EnumeratedClass facet, otherwise return null. </p>
844      * @param uri The URI of the new enumeration class.
845      * @return An enumeration class or null
846      */

847     public EnumeratedClass getEnumeratedClass( String JavaDoc uri ) {
848         return (EnumeratedClass) findByURIAs( uri, EnumeratedClass.class );
849     }
850
851
852     /**
853      * <p>Answer a resource representing the class that is the union of a list of class desctiptions. If a resource
854      * with the given uri exists in the model, and can be viewed as a UnionClass, return the
855      * UnionClass facet, otherwise return null. </p>
856      * @param uri The URI of the new union class.
857      * @return A union class description or null
858      */

859     public UnionClass getUnionClass( String JavaDoc uri ) {
860         return (UnionClass) findByURIAs( uri, UnionClass.class );
861     }
862
863
864     /**
865      * <p>Answer a resource representing the class that is the intersection of a list of class descriptions. If a resource
866      * with the given uri exists in the model, and can be viewed as a IntersectionClass, return the
867      * IntersectionClass facet, otherwise return null. </p>
868      * @param uri The URI of the new intersection class.
869      * @return An intersection class description or null
870      */

871     public IntersectionClass getIntersectionClass( String JavaDoc uri ) {
872         return (IntersectionClass) findByURIAs( uri, IntersectionClass.class );
873     }
874
875
876     /**
877      * <p>
878      * Answer a resource that represents a property restriction in this model. If a resource
879      * with the given uri exists in the model, and can be viewed as a Restriction, return the
880      * Restriction facet, otherwise return null.
881      * </p>
882      *
883      * @param uri The uri for the restriction node.
884      * @return A Restriction resource or null
885      */

886     public Restriction getRestriction( String JavaDoc uri ) {
887         return (Restriction) findByURIAs( uri, Restriction.class );
888     }
889
890
891     /**
892      * <p>Answer a class description defined as the class of those individuals that have the given
893      * resource as the value of the given property. If a resource
894      * with the given uri exists in the model, and can be viewed as a HasValueRestriction, return the
895      * HasValueRestriction facet, otherwise return null. </p>
896      *
897      * @param uri The URI for the restriction
898      * @return A resource representing a has-value restriction or null
899      */

900     public HasValueRestriction getHasValueRestriction( String JavaDoc uri ) {
901         return (HasValueRestriction) findByURIAs( uri, HasValueRestriction.class );
902     }
903
904
905     /**
906      * <p>Answer a class description defined as the class of those individuals that have at least
907      * one property with a value belonging to the given class. If a resource
908      * with the given uri exists in the model, and can be viewed as a SomeValuesFromRestriction, return the
909      * SomeValuesFromRestriction facet, otherwise return null. </p>
910      *
911      * @param uri The URI for the restriction
912      * @return A resource representing a some-values-from restriction, or null
913      */

914     public SomeValuesFromRestriction getSomeValuesFromRestriction( String JavaDoc uri ) {
915         return (SomeValuesFromRestriction) findByURIAs( uri, SomeValuesFromRestriction.class );
916     }
917
918
919     /**
920      * <p>Answer a class description defined as the class of those individuals for which all values
921      * of the given property belong to the given class. If a resource
922      * with the given uri exists in the model, and can be viewed as an AllValuesFromResriction, return the
923      * AllValuesFromRestriction facet, otherwise return null. </p>
924      *
925      * @param uri The URI for the restriction
926      * @return A resource representing an all-values-from restriction or null
927      */

928     public AllValuesFromRestriction getAllValuesFromRestriction( String JavaDoc uri ) {
929         return (AllValuesFromRestriction) findByURIAs( uri, AllValuesFromRestriction.class );
930     }
931
932
933     /**
934      * <p>Answer a class description defined as the class of those individuals that have exactly
935      * the given number of values for the given property. If a resource
936      * with the given uri exists in the model, and can be viewed as a CardinalityRestriction, return the
937      * CardinalityRestriction facet, otherwise return null. </p>
938      *
939      * @param uri The URI for the restriction
940      * @return A resource representing a has-value restriction, or null
941      */

942     public CardinalityRestriction getCardinalityRestriction( String JavaDoc uri ) {
943         return (CardinalityRestriction) findByURIAs( uri, CardinalityRestriction.class );
944     }
945
946
947     /**
948      * <p>Answer a class description defined as the class of those individuals that have at least
949      * the given number of values for the given property. If a resource
950      * with the given uri exists in the model, and can be viewed as a MinCardinalityRestriction, return the
951      * MinCardinalityRestriction facet, otherwise return null. </p>
952      *
953      * @param uri The URI for the restriction
954      * @return A resource representing a min-cardinality restriction, or null
955      */

956     public MinCardinalityRestriction getMinCardinalityRestriction( String JavaDoc uri ) {
957         return (MinCardinalityRestriction) findByURIAs( uri, MinCardinalityRestriction.class );
958     }
959
960
961     /**
962      * <p>Answer a class description defined as the class of those individuals that have at most
963      * the given number of values for the given property. If a resource
964      * with the given uri exists in the model, and can be viewed as a MaxCardinalityRestriction, return the
965      * MaxCardinalityRestriction facet, otherwise return null.</p>
966      *
967      * @param uri The URI for the restriction
968      * @return A resource representing a mas-cardinality restriction, or null
969      */

970     public MaxCardinalityRestriction getMaxCardinalityRestriction( String JavaDoc uri ) {
971         return (MaxCardinalityRestriction) findByURIAs( uri, MaxCardinalityRestriction.class );
972     }
973
974
975     /**
976      * <p>Answer a class description defined as the class of those individuals that have a property
977      * p, all values of which are members of a given class. Typically used with a cardinality constraint.
978      * If a resource
979      * with the given uri exists in the model, and can be viewed as a QualifiedRestriction, return the
980      * QualifiedRestriction facet, otherwise return null.</p>
981      *
982      * @param uri The URI for the restriction
983      * @return A resource representing a qualified restriction, or null
984      */

985     public QualifiedRestriction getQualifiedRestriction( String JavaDoc uri ) {
986         return (QualifiedRestriction) findByURIAs( uri, QualifiedRestriction.class );
987     }
988
989
990     /**
991      * <p>Answer a class description defined as the class of those individuals that have a property
992      * p, with cardinality N, all values of which are members of a given class.
993      * If a resource
994      * with the given uri exists in the model, and can be viewed as a CardinalityQRestriction, return the
995      * CardinalityQRestriction facet, otherwise return null.</p>
996      *
997      * @param uri The URI for the restriction
998      * @return A resource representing a qualified cardinality restriction, or null
999      */

1000    public CardinalityQRestriction getCardinalityQRestriction( String JavaDoc uri ) {
1001        return (CardinalityQRestriction) findByURIAs( uri, CardinalityQRestriction.class );
1002    }
1003
1004
1005    /**
1006     * <p>Answer a class description defined as the class of those individuals that have a property
1007     * p, with min cardinality N, all values of which are members of a given class.
1008     * If a resource
1009     * with the given uri exists in the model, and can be viewed as a MinCardinalityQRestriction, return the
1010     * MinCardinalityQRestriction facet, otherwise return null.</p>
1011     *
1012     * @param uri The URI for the restriction
1013     * @return A resource representing a qualified min cardinality restriction, or null
1014     */

1015    public MinCardinalityQRestriction getMinCardinalityQRestriction( String JavaDoc uri ) {
1016        return (MinCardinalityQRestriction) findByURIAs( uri, MinCardinalityQRestriction.class );
1017    }
1018
1019
1020    /**
1021     * <p>Answer a class description defined as the class of those individuals that have a property
1022     * p, with max cardinality N, all values of which are members of a given class.
1023     * If a resource
1024     * with the given uri exists in the model, and can be viewed as a MaxCardinalityQRestriction, return the
1025     * MaxCardinalityQRestriction facet, otherwise return null.</p>
1026     *
1027     * @param uri The URI for the restriction
1028     * @return A resource representing a qualified max cardinality restriction, or null
1029     */

1030    public MaxCardinalityQRestriction getMaxCardinalityQRestriction( String JavaDoc uri ) {
1031        return (MaxCardinalityQRestriction) findByURIAs( uri, MaxCardinalityQRestriction.class );
1032    }
1033
1034
1035    /**
1036     * <p>
1037     * Answer a resource that represents an ontology description node in this model. If a resource
1038     * with the given uri exists in the model, it will be re-used. If not, a new one is created in
1039     * the updateable sub-graph of the ontology model.
1040     * </p>
1041     *
1042     * @param uri The uri for the ontology node. Conventionally, this corresponds to the base URI
1043     * of the document itself.
1044     * @return An Ontology resource.
1045     */

1046    public Ontology createOntology( String JavaDoc uri ) {
1047        checkProfileEntry( getProfile().ONTOLOGY(), "ONTOLOGY" );
1048        return (Ontology) createOntResource( Ontology.class, getProfile().ONTOLOGY(), uri );
1049    }
1050
1051
1052    /**
1053     * <p>
1054     * Answer a resource that represents an Indvidual node in this model. A new anonymous resource
1055     * will be created in the updateable sub-graph of the ontology model.
1056     * </p>
1057     *
1058     * @param cls Resource representing the ontology class to which the individual belongs
1059     * @return A new anoymous Individual of the given class.
1060     */

1061    public Individual createIndividual( Resource cls ) {
1062        return (Individual) createOntResource( Individual.class, cls, null );
1063    }
1064
1065
1066    /**
1067     * <p>
1068     * Answer a resource that represents an Individual node in this model. If a resource
1069     * with the given uri exists in the model, it will be re-used. If not, a new one is created in
1070     * the updateable sub-graph of the ontology model.
1071     * </p>
1072     *
1073     * @param cls Resource representing the ontology class to which the individual belongs
1074     * @param uri The uri for the individual, or null for an anonymous individual.
1075     * @return An Individual resource.
1076     */

1077    public Individual createIndividual( String JavaDoc uri, Resource cls ) {
1078        return (Individual) createOntResource( Individual.class, cls, uri );
1079    }
1080
1081
1082    /**
1083     * <p>
1084     * Answer a resource representing an generic property in this model. Effectively
1085     * this method is an alias for {@link #createProperty( String )}, except that
1086     * the return type is {@link OntProperty}, which allow more convenient access to
1087     * a property's position in the property hierarchy, domain, range, etc.
1088     * </p>
1089     *
1090     * @param uri The uri for the property. May not be null.
1091     * @return An OntProperty resource.
1092     */

1093    public OntProperty createOntProperty( String JavaDoc uri ) {
1094        Property p = createProperty( uri );
1095        p.addProperty( RDF.type, getProfile().PROPERTY() );
1096        return (OntProperty) p.as( OntProperty.class );
1097    }
1098
1099
1100    /**
1101     * <p>
1102     * Answer a resource representing an object property in this model,
1103     * and that is not a functional property.
1104     * </p>
1105     *
1106     * @param uri The uri for the object property. May not be null.
1107     * @return An ObjectProperty resource.
1108     * @see #createObjectProperty( String, boolean )
1109     */

1110    public ObjectProperty createObjectProperty( String JavaDoc uri ) {
1111        return createObjectProperty( uri, false );
1112    }
1113
1114
1115    /**
1116     * <p>
1117     * Answer a resource that represents an object property in this model. An object property
1118     * is defined to have a range of individuals, rather than datatypes.
1119     * If a resource
1120     * with the given uri exists in the model, it will be re-used. If not, a new one is created in
1121     * the updateable sub-graph of the ontology model.
1122     * </p>
1123     *
1124     * @param uri The uri for the object property. May not be null.
1125     * @param functional If true, the resource will also be typed as a {@link FunctionalProperty},
1126     * that is, a property that has a unique range value for any given domain value.
1127     * @return An ObjectProperty resource, optionally also functional.
1128     */

1129    public ObjectProperty createObjectProperty( String JavaDoc uri, boolean functional ) {
1130        checkProfileEntry( getProfile().OBJECT_PROPERTY(), "OBJECT_PROPERTY" );
1131        ObjectProperty p = (ObjectProperty) createOntResource( ObjectProperty.class, getProfile().OBJECT_PROPERTY(), uri );
1132
1133        if (functional) {
1134            checkProfileEntry( getProfile().FUNCTIONAL_PROPERTY(), "FUNCTIONAL_PROPERTY" );
1135            p.addProperty( RDF.type, getProfile().FUNCTIONAL_PROPERTY() );
1136        }
1137
1138        return p;
1139    }
1140
1141
1142    /**
1143     * <p>Answer a resource representing a transitive property</p>
1144     * @param uri The uri for the property. May not be null.
1145     * @return An TransitiveProperty resource
1146     * @see #createTransitiveProperty( String, boolean )
1147     */

1148    public TransitiveProperty createTransitiveProperty( String JavaDoc uri ) {
1149        return createTransitiveProperty( uri, false );
1150    }
1151
1152
1153    /**
1154     * <p>Answer a resource representing a transitive property, which is optionally
1155     * also functional. <strong>Note:</strong> although it is permitted in OWL full
1156     * to have functional transitive properties, it makes the language undecideable.
1157     * Functional transitive properties are not permitted in OWL Lite or OWL DL.</p>
1158     * @param uri The uri for the property. May not be null.
1159     * @param functional If true, the property is also functional
1160     * @return An TransitiveProperty resource, optionally also functional.
1161     */

1162    public TransitiveProperty createTransitiveProperty( String JavaDoc uri, boolean functional ) {
1163        checkProfileEntry( getProfile().TRANSITIVE_PROPERTY(), "TRANSITIVE_PROPERTY" );
1164        TransitiveProperty p = (TransitiveProperty) createOntResource( TransitiveProperty.class, getProfile().TRANSITIVE_PROPERTY(), uri );
1165
1166        if (functional) {
1167            checkProfileEntry( getProfile().FUNCTIONAL_PROPERTY(), "FUNCTIONAL_PROPERTY" );
1168            p.addProperty( RDF.type, getProfile().FUNCTIONAL_PROPERTY() );
1169        }
1170
1171        return p;
1172    }
1173
1174
1175    /**
1176     * <p>Answer a resource representing a symmetric property</p>
1177     * @param uri The uri for the property. May not be null.
1178     * @return An SymmetricProperty resource
1179     * @see #createSymmetricProperty( String, boolean )
1180     */

1181    public SymmetricProperty createSymmetricProperty( String JavaDoc uri ) {
1182        return createSymmetricProperty( uri, false );
1183    }
1184
1185
1186    /**
1187     * <p>Answer a resource representing a symmetric property, which is optionally
1188     * also functional.</p>
1189     * @param uri The uri for the property. May not be null.
1190     * @param functional If true, the property is also functional
1191     * @return An SymmetricProperty resource, optionally also functional.
1192     */

1193    public SymmetricProperty createSymmetricProperty( String JavaDoc uri, boolean functional ) {
1194        checkProfileEntry( getProfile().SYMMETRIC_PROPERTY(), "SYMMETRIC_PROPERTY" );
1195        SymmetricProperty p = (SymmetricProperty) createOntResource( SymmetricProperty.class, getProfile().SYMMETRIC_PROPERTY(), uri );
1196
1197        if (functional) {
1198            checkProfileEntry( getProfile().FUNCTIONAL_PROPERTY(), "FUNCTIONAL_PROPERTY" );
1199            p.addProperty( RDF.type, getProfile().FUNCTIONAL_PROPERTY() );
1200        }
1201
1202        return p;
1203    }
1204
1205
1206    /**
1207     * <p>Answer a resource representing an inverse functional property</p>
1208     * @param uri The uri for the property. May not be null.
1209     * @return An InverseFunctionalProperty resource
1210     * @see #createInverseFunctionalProperty( String, boolean )
1211     */

1212    public InverseFunctionalProperty createInverseFunctionalProperty( String JavaDoc uri ) {
1213        return createInverseFunctionalProperty( uri, false );
1214    }
1215
1216
1217    /**
1218     * <p>Answer a resource representing an inverse functional property, which is optionally
1219     * also functional.</p>
1220     * @param uri The uri for the property. May not be null.
1221     * @param functional If true, the property is also functional
1222     * @return An InverseFunctionalProperty resource, optionally also functional.
1223     */

1224    public InverseFunctionalProperty createInverseFunctionalProperty( String JavaDoc uri, boolean functional ) {
1225        checkProfileEntry( getProfile().INVERSE_FUNCTIONAL_PROPERTY(), "INVERSE_FUNCTIONAL_PROPERTY" );
1226        InverseFunctionalProperty p = (InverseFunctionalProperty) createOntResource( InverseFunctionalProperty.class, getProfile().INVERSE_FUNCTIONAL_PROPERTY(), uri );
1227
1228        if (functional) {
1229            checkProfileEntry( getProfile().FUNCTIONAL_PROPERTY(), "FUNCTIONAL_PROPERTY" );
1230            p.addProperty( RDF.type, getProfile().FUNCTIONAL_PROPERTY() );
1231        }
1232
1233        return p;
1234    }
1235
1236
1237    /**
1238     * <p>
1239     * Answer a resource that represents datatype property in this model, and that is
1240     * not a functional property.
1241     * </p>
1242     *
1243     * @param uri The uri for the datatype property. May not be null.
1244     * @return A DatatypeProperty resource.
1245     * @see #createDatatypeProperty( String, boolean )
1246     */

1247    public DatatypeProperty createDatatypeProperty( String JavaDoc uri ) {
1248        return createDatatypeProperty( uri, false );
1249    }
1250
1251
1252    /**
1253     * <p>
1254     * Answer a resource that represents datatype property in this model. A datatype property
1255     * is defined to have a range that is a concrete datatype, rather than an individual.
1256     * If a resource
1257     * with the given uri exists in the model, it will be re-used. If not, a new one is created in
1258     * the updateable sub-graph of the ontology model.
1259     * </p>
1260     *
1261     * @param uri The uri for the datatype property. May not be null.
1262     * @param functional If true, the resource will also be typed as a {@link FunctionalProperty},
1263     * that is, a property that has a unique range value for any given domain value.
1264     * @return A DatatypeProperty resource.
1265     */

1266    public DatatypeProperty createDatatypeProperty( String JavaDoc uri, boolean functional ) {
1267        checkProfileEntry( getProfile().DATATYPE_PROPERTY(), "DATATYPE_PROPERTY" );
1268        DatatypeProperty p = (DatatypeProperty) createOntResource( DatatypeProperty.class, getProfile().DATATYPE_PROPERTY(), uri );
1269
1270        if (functional) {
1271            checkProfileEntry( getProfile().FUNCTIONAL_PROPERTY(), "FUNCTIONAL_PROPERTY" );
1272            p.addProperty( RDF.type, getProfile().FUNCTIONAL_PROPERTY() );
1273        }
1274
1275        return p;
1276    }
1277
1278
1279    /**
1280     * <p>
1281     * Answer a resource that represents an annotation property in this model. If a resource
1282     * with the given uri exists in the model, it will be re-used. If not, a new one is created in
1283     * the updateable sub-graph of the ontology model.
1284     * </p>
1285     *
1286     * @param uri The uri for the annotation property.
1287     * @return An AnnotationProperty resource.
1288     */

1289    public AnnotationProperty createAnnotationProperty( String JavaDoc uri ) {
1290        checkProfileEntry( getProfile().ANNOTATION_PROPERTY(), "ANNOTATION_PROPERTY" );
1291        return (AnnotationProperty) createOntResource( AnnotationProperty.class, getProfile().ANNOTATION_PROPERTY(), uri );
1292    }
1293
1294
1295    /**
1296     * <p>
1297     * Answer a resource that represents an anonymous class description in this model. A new
1298     * anonymous resource of <code>rdf:type C</code>, where C is the class type from the
1299     * language profile.
1300     * </p>
1301     *
1302     * @return An anonymous Class resource.
1303     */

1304    public OntClass createClass() {
1305        checkProfileEntry( getProfile().CLASS(), "CLASS" );
1306        return (OntClass) createOntResource( OntClass.class, getProfile().CLASS(), null );
1307    }
1308
1309
1310    /**
1311     * <p>
1312     * Answer a resource that represents a class description node in this model. If a resource
1313     * with the given uri exists in the model, it will be re-used. If not, a new one is created in
1314     * the updateable sub-graph of the ontology model.
1315     * </p>
1316     *
1317     * @param uri The uri for the class node, or null for an anonymous class.
1318     * @return A Class resource.
1319     */

1320    public OntClass createClass( String JavaDoc uri ) {
1321        checkProfileEntry( getProfile().CLASS(), "CLASS" );
1322        return (OntClass) createOntResource( OntClass.class, getProfile().CLASS(), uri );
1323    }
1324
1325
1326    /**
1327     * <p>Answer a resource representing the class that is the complement of the given argument class</p>
1328     * @param uri The URI of the new complement class, or null for an anonymous class description.
1329     * @param cls Resource denoting the class that the new class is a complement of
1330     * @return A complement class
1331     */

1332    public ComplementClass createComplementClass( String JavaDoc uri, Resource cls ) {
1333        checkProfileEntry( getProfile().CLASS(), "CLASS" );
1334        OntClass c = (OntClass) createOntResource( OntClass.class, getProfile().CLASS(), uri );
1335
1336        checkProfileEntry( getProfile().COMPLEMENT_OF(), "COMPLEMENT_OF" );
1337        // if the class that this class is a complement of is not specified, use owl:nothing or daml:nothing
1338
c.addProperty( getProfile().COMPLEMENT_OF(), (cls == null) ? getProfile().NOTHING() : cls );
1339
1340        return (ComplementClass) c.as( ComplementClass.class );
1341    }
1342
1343
1344    /**
1345     * <p>Answer a resource representing the class that is the enumeration of the given list of individuals</p>
1346     * @param uri The URI of the new enumeration class, or null for an anonymous class description.
1347     * @param members An optional list of resources denoting the individuals in the enumeration
1348     * @return An enumeration class
1349     */

1350    public EnumeratedClass createEnumeratedClass( String JavaDoc uri, RDFList members ) {
1351        checkProfileEntry( getProfile().CLASS(), "CLASS" );
1352        OntClass c = (OntClass) createOntResource( OntClass.class, getProfile().CLASS(), uri );
1353
1354        checkProfileEntry( getProfile().ONE_OF(), "ONE_OF" );
1355        c.addProperty( getProfile().ONE_OF(), (members == null) ? createList() : members );
1356
1357        return (EnumeratedClass) c.as( EnumeratedClass.class );
1358    }
1359
1360
1361    /**
1362     * <p>Answer a resource representing the class that is the union of the given list of class desctiptions</p>
1363     * @param uri The URI of the new union class, or null for an anonymous class description.
1364     * @param members A list of resources denoting the classes that comprise the union
1365     * @return A union class description
1366     */

1367    public UnionClass createUnionClass( String JavaDoc uri, RDFList members ) {
1368        checkProfileEntry( getProfile().CLASS(), "CLASS" );
1369        OntClass c = (OntClass) createOntResource( OntClass.class, getProfile().CLASS(), uri );
1370
1371        checkProfileEntry( getProfile().UNION_OF(), "UNION_OF" );
1372        c.addProperty( getProfile().UNION_OF(), (members == null) ? createList() : members );
1373
1374        return (UnionClass) c.as( UnionClass.class );
1375    }
1376
1377
1378    /**
1379     * <p>Answer a resource representing the class that is the intersection of the given list of class descriptions.</p>
1380     * @param uri The URI of the new intersection class, or null for an anonymous class description.
1381     * @param members A list of resources denoting the classes that comprise the intersection
1382     * @return An intersection class description
1383     */

1384    public IntersectionClass createIntersectionClass( String JavaDoc uri, RDFList members ) {
1385        checkProfileEntry( getProfile().CLASS(), "CLASS" );
1386        OntClass c = (OntClass) createOntResource( OntClass.class, getProfile().CLASS(), uri );
1387
1388        checkProfileEntry( getProfile().INTERSECTION_OF(), "INTERSECTION_OF" );
1389        c.addProperty( getProfile().INTERSECTION_OF(), (members == null) ? createList() : members );
1390
1391        return (IntersectionClass) c.as( IntersectionClass.class );
1392    }
1393
1394
1395    /**
1396     * <p>
1397     * Answer a resource that represents an anonymous property restriction in this model. A new
1398     * anonymous resource of <code>rdf:type R</code>, where R is the restriction type from the
1399     * language profile.
1400     * </p>
1401     *
1402     * @param p The property that is restricted by this restriction
1403     * @return An anonymous Restriction resource.
1404     */

1405    public Restriction createRestriction( Property p ) {
1406        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1407        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), null );
1408        if (p != null) {
1409            r.setOnProperty( p );
1410        }
1411
1412        return r;
1413    }
1414
1415
1416    /**
1417     * <p>
1418     * Answer a resource that represents a property restriction in this model. If a resource
1419     * with the given uri exists in the model, it will be re-used. If not, a new one is created in
1420     * the updateable sub-graph of the ontology model.
1421     * </p>
1422     *
1423     * @param uri The uri for the restriction node, or null for an anonymous restriction.
1424     * @param p The property that is restricted by this restriction
1425     * @return A Restriction resource.
1426     */

1427    public Restriction createRestriction( String JavaDoc uri, Property p ) {
1428        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1429        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1430        if (p != null) {
1431            r.setOnProperty( p );
1432        }
1433
1434        return r;
1435    }
1436
1437
1438    /**
1439     * <p>Answer a class description defined as the class of those individuals that have the given
1440     * resource as the value of the given property</p>
1441     *
1442     * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1443     * should be the normal case)
1444     * @param prop The property the restriction applies to
1445     * @param value The value of the property, as a resource or RDF literal
1446     * @return A new resource representing a has-value restriction
1447     */

1448    public HasValueRestriction createHasValueRestriction( String JavaDoc uri, Property prop, RDFNode value ) {
1449        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1450        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1451
1452        if (prop == null || value == null) {
1453            throw new IllegalArgumentException JavaDoc( "Cannot create hasValueRestriction with a null property or value" );
1454        }
1455
1456        checkProfileEntry( getProfile().HAS_VALUE(), "HAS_VALUE" );
1457        r.addProperty( getProfile().ON_PROPERTY(), prop );
1458        r.addProperty( getProfile().HAS_VALUE(), value );
1459
1460        return (HasValueRestriction) r.as( HasValueRestriction.class );
1461    }
1462
1463
1464    /**
1465     * <p>Answer a class description defined as the class of those individuals that have at least
1466     * one property with a value belonging to the given class</p>
1467     *
1468     * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1469     * should be the normal case)
1470     * @param prop The property the restriction applies to
1471     * @param cls The class to which at least one value of the property belongs
1472     * @return A new resource representing a some-values-from restriction
1473     */

1474    public SomeValuesFromRestriction createSomeValuesFromRestriction( String JavaDoc uri, Property prop, Resource cls ) {
1475        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1476        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1477
1478        if (prop == null || cls == null) {
1479            throw new IllegalArgumentException JavaDoc( "Cannot create someValuesFromRestriction with a null property or class" );
1480        }
1481
1482        checkProfileEntry( getProfile().SOME_VALUES_FROM(), "SOME_VALUES_FROM" );
1483        r.addProperty( getProfile().ON_PROPERTY(), prop );
1484        r.addProperty( getProfile().SOME_VALUES_FROM(), cls );
1485
1486        return (SomeValuesFromRestriction) r.as( SomeValuesFromRestriction.class );
1487    }
1488
1489
1490    /**
1491     * <p>Answer a class description defined as the class of those individuals for which all values
1492     * of the given property belong to the given class</p>
1493     *
1494     * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1495     * should be the normal case)
1496     * @param prop The property the restriction applies to
1497     * @param cls The class to which any value of the property belongs
1498     * @return A new resource representing an all-values-from restriction
1499     */

1500    public AllValuesFromRestriction createAllValuesFromRestriction( String JavaDoc uri, Property prop, Resource cls ) {
1501        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1502        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1503
1504        if (prop == null || cls == null) {
1505            throw new IllegalArgumentException JavaDoc( "Cannot create allValuesFromRestriction with a null property or class" );
1506        }
1507
1508        checkProfileEntry( getProfile().ALL_VALUES_FROM(), "ALL_VALUES_FROM" );
1509        r.addProperty( getProfile().ON_PROPERTY(), prop );
1510        r.addProperty( getProfile().ALL_VALUES_FROM(), cls );
1511
1512        return (AllValuesFromRestriction) r.as( AllValuesFromRestriction.class );
1513    }
1514
1515
1516    /**
1517     * <p>Answer a class description defined as the class of those individuals that have exactly
1518     * the given number of values for the given property.</p>
1519     *
1520     * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1521     * should be the normal case)
1522     * @param prop The property the restriction applies to
1523     * @param cardinality The exact cardinality of the property
1524     * @return A new resource representing a has-value restriction
1525     */

1526    public CardinalityRestriction createCardinalityRestriction( String JavaDoc uri, Property prop, int cardinality ) {
1527        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1528        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1529
1530        if (prop == null) {
1531            throw new IllegalArgumentException JavaDoc( "Cannot create cardinalityRestriction with a null property" );
1532        }
1533
1534        checkProfileEntry( getProfile().CARDINALITY(), "CARDINALITY" );
1535        r.addProperty( getProfile().ON_PROPERTY(), prop );
1536        r.addProperty( getProfile().CARDINALITY(), createTypedLiteral( cardinality ) );
1537
1538        return (CardinalityRestriction) r.as( CardinalityRestriction.class );
1539    }
1540
1541
1542    /**
1543     * <p>Answer a class description defined as the class of those individuals that have at least
1544     * the given number of values for the given property.</p>
1545     *
1546     * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1547     * should be the normal case)
1548     * @param prop The property the restriction applies to
1549     * @param cardinality The minimum cardinality of the property
1550     * @return A new resource representing a min-cardinality restriction
1551     */

1552    public MinCardinalityRestriction createMinCardinalityRestriction( String JavaDoc uri, Property prop, int cardinality ) {
1553        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1554        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1555
1556        if (prop == null) {
1557            throw new IllegalArgumentException JavaDoc( "Cannot create minCardinalityRestriction with a null property" );
1558        }
1559
1560        checkProfileEntry( getProfile().MIN_CARDINALITY(), "MIN_CARDINALITY" );
1561        r.addProperty( getProfile().ON_PROPERTY(), prop );
1562        r.addProperty( getProfile().MIN_CARDINALITY(), createTypedLiteral( cardinality ) );
1563
1564        return (MinCardinalityRestriction) r.as( MinCardinalityRestriction.class );
1565    }
1566
1567
1568    /**
1569     * <p>Answer a class description defined as the class of those individuals that have at most
1570     * the given number of values for the given property.</p>
1571     *
1572     * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1573     * should be the normal case)
1574     * @param prop The property the restriction applies to
1575     * @param cardinality The maximum cardinality of the property
1576     * @return A new resource representing a mas-cardinality restriction
1577     */

1578    public MaxCardinalityRestriction createMaxCardinalityRestriction( String JavaDoc uri, Property prop, int cardinality ) {
1579        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1580        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1581
1582        if (prop == null) {
1583            throw new IllegalArgumentException JavaDoc( "Cannot create maxCardinalityRestriction with a null property" );
1584        }
1585
1586        checkProfileEntry( getProfile().MAX_CARDINALITY(), "MAX_CARDINALITY" );
1587        r.addProperty( getProfile().ON_PROPERTY(), prop );
1588        r.addProperty( getProfile().MAX_CARDINALITY(), createTypedLiteral( cardinality ) );
1589
1590        return (MaxCardinalityRestriction) r.as( MaxCardinalityRestriction.class );
1591    }
1592
1593
1594    /**
1595     * <p>Answer a class description defined as the class of those individuals that have at most
1596     * the given number of values for the given property, all values of which belong to the given
1597     * class.</p>
1598     *
1599     * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1600     * should be the normal case)
1601     * @param prop The property the restriction applies to
1602     * @param cardinality The maximum cardinality of the property
1603     * @param cls The class to which all values of the restricted property should belong
1604     * @return A new resource representing a mas-cardinality restriction
1605     */

1606    public MaxCardinalityQRestriction createMaxCardinalityQRestriction( String JavaDoc uri, Property prop, int cardinality, OntClass cls ) {
1607        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1608        checkProfileEntry( getProfile().ON_PROPERTY(), "ON_PROPERTY" );
1609        checkProfileEntry( getProfile().MAX_CARDINALITY_Q(), "MAX_CARDINALITY_Q" );
1610        checkProfileEntry( getProfile().HAS_CLASS_Q(), "HAS_CLASS_Q" );
1611
1612        if (prop == null) {
1613            throw new IllegalArgumentException JavaDoc( "Cannot create MaxCardinalityQRestriction with a null property" );
1614        }
1615        if (cls == null) {
1616            throw new IllegalArgumentException JavaDoc( "Cannot create MaxCardinalityQRestriction with a null class" );
1617        }
1618
1619        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1620
1621        r.addProperty( getProfile().ON_PROPERTY(), prop );
1622        r.addProperty( getProfile().MAX_CARDINALITY_Q(), createTypedLiteral( cardinality ) );
1623        r.addProperty( getProfile().HAS_CLASS_Q(), cls );
1624
1625        return (MaxCardinalityQRestriction) r.as( MaxCardinalityQRestriction.class );
1626    }
1627
1628
1629    /**
1630     * <p>Answer a class description defined as the class of those individuals that have at least
1631     * the given number of values for the given property, all values of which belong to the given
1632     * class.</p>
1633     *
1634     * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1635     * should be the normal case)
1636     * @param prop The property the restriction applies to
1637     * @param cardinality The minimun cardinality of the property
1638     * @param cls The class to which all values of the restricted property should belong
1639     * @return A new resource representing a mas-cardinality restriction
1640     */

1641    public MinCardinalityQRestriction createMinCardinalityQRestriction( String JavaDoc uri, Property prop, int cardinality, OntClass cls ) {
1642        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1643        checkProfileEntry( getProfile().ON_PROPERTY(), "ON_PROPERTY" );
1644        checkProfileEntry( getProfile().MIN_CARDINALITY_Q(), "MIN_CARDINALITY_Q" );
1645        checkProfileEntry( getProfile().HAS_CLASS_Q(), "HAS_CLASS_Q" );
1646
1647        if (prop == null) {
1648            throw new IllegalArgumentException JavaDoc( "Cannot create MinCardinalityQRestriction with a null property" );
1649        }
1650        if (cls == null) {
1651            throw new IllegalArgumentException JavaDoc( "Cannot create MinCardinalityQRestriction with a null class" );
1652        }
1653
1654        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1655
1656        r.addProperty( getProfile().ON_PROPERTY(), prop );
1657        r.addProperty( getProfile().MIN_CARDINALITY_Q(), createTypedLiteral( cardinality ) );
1658        r.addProperty( getProfile().HAS_CLASS_Q(), cls );
1659
1660        return (MinCardinalityQRestriction) r.as( MinCardinalityQRestriction.class );
1661    }
1662
1663
1664    /**
1665     * <p>Answer a class description defined as the class of those individuals that have exactly
1666     * the given number of values for the given property, all values of which belong to the given
1667     * class.</p>
1668     *
1669     * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1670     * should be the normal case)
1671     * @param prop The property the restriction applies to
1672     * @param cardinality The cardinality of the property
1673     * @param cls The class to which all values of the restricted property should belong
1674     * @return A new resource representing a mas-cardinality restriction
1675     */

1676    public CardinalityQRestriction createCardinalityQRestriction( String JavaDoc uri, Property prop, int cardinality, OntClass cls ) {
1677        checkProfileEntry( getProfile().RESTRICTION(), "RESTRICTION" );
1678        checkProfileEntry( getProfile().ON_PROPERTY(), "ON_PROPERTY" );
1679        checkProfileEntry( getProfile().CARDINALITY_Q(), "CARDINALITY_Q" );
1680        checkProfileEntry( getProfile().HAS_CLASS_Q(), "HAS_CLASS_Q" );
1681
1682        if (prop == null) {
1683            throw new IllegalArgumentException JavaDoc( "Cannot create CardinalityQRestriction with a null property" );
1684        }
1685        if (cls == null) {
1686            throw new IllegalArgumentException JavaDoc( "Cannot create CardinalityQRestriction with a null class" );
1687        }
1688
1689        Restriction r = (Restriction) createOntResource( Restriction.class, getProfile().RESTRICTION(), uri );
1690
1691        r.addProperty( getProfile().ON_PROPERTY(), prop );
1692        r.addProperty( getProfile().CARDINALITY_Q(), createTypedLiteral( cardinality ) );
1693        r.addProperty( getProfile().HAS_CLASS_Q(), cls );
1694
1695        return (CardinalityQRestriction) r.as( CardinalityQRestriction.class );
1696    }
1697
1698
1699    /**
1700     * <p>Answer a data range defined as the given set of concrete data values. DataRange resources
1701     * are necessarily bNodes.</p>
1702     *
1703     * @param literals An iterator over a set of literals that will be the members of the data range,
1704     * or null to define an empty data range
1705     * @return A new data range containing the given literals as permissible values
1706     */

1707    public DataRange createDataRange( RDFList literals ) {
1708        checkProfileEntry( getProfile().DATARANGE(), "DATARANGE" );
1709        DataRange d = (DataRange) createOntResource( DataRange.class, getProfile().DATARANGE(), null );
1710
1711        checkProfileEntry( getProfile().ONE_OF(), "ONE_OF" );
1712        d.addProperty( getProfile().ONE_OF(), (literals == null) ? createList() : literals );
1713
1714        return d;
1715    }
1716
1717
1718    /**
1719     * <p>
1720     * Answer a new, anonymous node representing the fact that a given set of classes are all
1721     * pair-wise distinct. <code>AllDifferent</code> is a feature of OWL only, and is something
1722     * of an anomoly in that it exists only to give a place to anchor the <code>distinctMembers</code>
1723     * property, which is the actual expression of the fact.
1724     * </p>
1725     *
1726     * @return A new AllDifferent resource
1727     */

1728    public AllDifferent createAllDifferent() {
1729        return createAllDifferent( null );
1730    }
1731
1732
1733    /**
1734     * <p>
1735     * Answer a new, anonymous node representing the fact that a given set of classes are all
1736     * pair-wise distinct. <code>AllDifferent</code> is a feature of OWL only, and is something
1737     * of an anomoly in that it exists only to give a place to anchor the <code>distinctMembers</code>
1738     * property, which is the actual expression of the fact.
1739     * </p>
1740     * @param differentMembers A list of the class expressions that denote a set of mutually disjoint classes
1741     * @return A new AllDifferent resource
1742     */

1743    public AllDifferent createAllDifferent( RDFList differentMembers ) {
1744        checkProfileEntry( getProfile().ALL_DIFFERENT(), "ALL_DIFFERENT" );
1745        AllDifferent ad = (AllDifferent) createOntResource( AllDifferent.class, getProfile().ALL_DIFFERENT(), null );
1746
1747        ad.setDistinctMembers( (differentMembers == null) ? createList() : differentMembers );
1748
1749        return ad;
1750    }
1751
1752
1753    /**
1754     * <p>
1755     * Answer a resource that represents a generic ontology node in this model. If a resource
1756     * with the given uri exists in the model, it will be re-used. If not, a new one is created in
1757     * the updateable sub-graph of the ontology model.
1758     * </p>
1759     * <p>
1760     * This is a generic method for creating any known ontology value. The selector that determines
1761     * which resource to create is the same as as the argument to the {@link RDFNode#as as()}
1762     * method: the Java class object of the desired abstraction. For example, to create an
1763     * ontology class via this mechanism, use:
1764     * <code><pre>
1765     * OntClass c = (OntClass) myModel.createOntResource( OntClass.class, null,
1766     * "http://example.org/ex#Parrot" );
1767     * </pre></code>
1768     * </p>
1769     *
1770     * @param javaClass The Java class object that represents the ontology abstraction to create
1771     * @param rdfType Optional resource denoting the ontology class to which an individual or
1772     * axiom belongs, if that is the type of resource being created.
1773     * @param uri The uri for the ontology resource, or null for an anonymous resource.
1774     * @return An ontology resource, of the type specified by the <code>javaClass</code>
1775     */

1776    public OntResource createOntResource( Class JavaDoc javaClass, Resource rdfType, String JavaDoc uri ) {
1777        return (OntResource) getResourceWithType( uri, rdfType ).as( javaClass );
1778    }
1779
1780    /**
1781     * <p>Answer a resource presenting the {@link OntResource} facet, which has the
1782     * given URI.</p>
1783     * @param uri The URI of the resource, or null for an anonymous resource (aka bNode)
1784     * @return An OntResource with the given URI
1785     */

1786    public OntResource createOntResource( String JavaDoc uri ) {
1787        return (OntResource) getResource( uri ).as( OntResource.class );
1788    }
1789
1790
1791    /**
1792     * <p>Answer a new empty list. This method overrides the list create method in ModelCom,
1793     * to allow both DAML and RDFS lists to be created.</p>
1794     * @return An RDF-encoded list of no elements, using the current language profile
1795     */

1796    public RDFList createList() {
1797        Resource list = getResource( getProfile().NIL().getURI() );
1798
1799        return (RDFList) list.as( RDFList.class );
1800    }
1801
1802
1803    /**
1804     * <p>
1805     * Answer the language profile (for example, OWL or DAML+OIL) that this model is
1806     * working to.
1807     * </p>
1808     *
1809     * @return A language profile
1810     */

1811    public Profile getProfile() {
1812        return m_spec.getProfile();
1813    }
1814
1815
1816    /**
1817     * <p>
1818     * Answer true if this model has had the given URI document imported into it. This is
1819     * important to know since an import only occurs once, and we also want to be able to
1820     * detect cycles of imports.
1821     * </p>
1822     *
1823     * @param uri An ontology URI
1824     * @return True if the document corresponding to the URI has been successfully loaded
1825     * into this model
1826     */

1827    public boolean hasLoadedImport( String JavaDoc uri ) {
1828        return m_imported.contains( uri );
1829    }
1830
1831
1832    /**
1833     * <p>
1834     * Record that this model has now imported the document with the given
1835     * URI, so that it will not be re-imported in the future.
1836     * </p>
1837     *
1838     * @param uri A document URI that has now been imported into the model.
1839     */

1840    public void addLoadedImport( String JavaDoc uri ) {
1841        m_imported.add( uri );
1842    }
1843
1844
1845    /**
1846     * <p>
1847     * Record that this model no longer imports the document with the given
1848     * URI.
1849     * </p>
1850     *
1851     * @param uri A document URI that is no longer imported into the model.
1852     */

1853    public void removeLoadedImport( String JavaDoc uri ) {
1854        m_imported.remove( uri );
1855    }
1856
1857
1858    /**
1859     * <p>
1860     * Answer a list of the imported URI's in this ontology model. Detection of <code>imports</code>
1861     * statments will be according to the local language profile
1862     * </p>
1863     *
1864     * @return The imported ontology URI's as a set. Note that since the underlying graph is
1865     * not ordered, the order of values in the list in successive calls to this method is
1866     * not guaranteed to be preserved.
1867     */

1868    public Set listImportedOntologyURIs() {
1869        return listImportedOntologyURIs( false );
1870    }
1871
1872
1873    /**
1874     * <p>
1875     * Answer a list of the imported URI's in this ontology model, and optionally in the closure
1876     * of this model's imports. Detection of <code>imports</code>
1877     * statments will be according to the local language profile. Note that, in order to allow this
1878     * method to be called during the imports closure process, we <b>only query the base model</b>,
1879     * thus side-stepping the any attached reasoner.
1880     * </p>
1881     * @param closure If true, the set of uri's returned will include not only those directly
1882     * imported by this model, but those imported by the model's imports transitively.
1883     * @return The imported ontology URI's as a list. Note that since the underlying graph is
1884     * not ordered, the order of values in the list in successive calls to this method is
1885     * not guaranteed to be preserved.
1886     */

1887    public Set listImportedOntologyURIs( boolean closure ) {
1888        Set results = new HashSet();
1889        List queue = new ArrayList();
1890        queue.add( getBaseModel() );
1891
1892        while (!queue.isEmpty()) {
1893            Model m = (Model) queue.remove( 0 );
1894
1895            // list the ontology nodes
1896
if (getProfile().ONTOLOGY() != null && getProfile().IMPORTS() != null) {
1897                StmtIterator i = m.listStatements(null, getProfile().IMPORTS(), (RDFNode)null);
1898                while (i.hasNext()) {
1899                    Statement s = i.nextStatement();
1900                    String JavaDoc uri = s.getResource().getURI();
1901
1902                    if (!results.contains( uri )) {
1903                        // this is a new uri, so we add it
1904
results.add( uri );
1905
1906                        // and push the model on the stack if we know it
1907
Model mi = getDocumentManager().getModel( uri );
1908                        if (closure && mi != null && !queue.contains( mi )) {
1909                            queue.add( mi );
1910                        }
1911                    }
1912                }
1913            }
1914        }
1915
1916        return results;
1917    }
1918
1919
1920    /**
1921     * <p>
1922     * Answer the model maker associated with this model (used for constructing the
1923     * constituent models of the imports closure).
1924     * </p>
1925     *
1926     * @return The local graph factory
1927     */

1928    public ModelMaker getImportModelMaker() {
1929        return m_spec.getImportModelMaker();
1930    }
1931
1932    /**
1933        @deprecated use getImportModelMaker instead.
1934    */

1935    public ModelMaker getModelMaker() {
1936        return getImportModelMaker();
1937    }
1938
1939    /**
1940     * <p>If this OntModel is presenting an OWL model, answer the minimum OWL language
1941     * level that the constructs
1942     * used in this model lie entirely within. The three possible return values are
1943     * {@link OWL#FULL_LANG} for OWL-full,
1944     * {@link OWL#DL_LANG} for OWL-DL or
1945     * {@link OWL#LITE_LANG} for OWL-lite.
1946     * Note that these URI's are <strong>not</strong> officially sanctioned by the WebOnt
1947     * working group. For unknown reasons, the working group chose not to assign official
1948     * URI's to represent the different OWL language levels. There is a slim chance that this
1949     * may change in future, in which case these return values will change apropriately.
1950     * In addition, the given <code>problems</problems> list, if non-null, will be filled with the syntax
1951     * problems detected by the {@link com.hp.hpl.jena.ontology.tidy.Checker syntax checker}.
1952     * </p>
1953     * <p>
1954     * The Jena OWL syntax checker will normally list as problems those constructs used in
1955     * this model that are in OWL Full but not permitted in OWL DL. The exception to this
1956     * is if the {@linkplain #getProfile() language profile} for this model is
1957     * {@linkplain OWLLiteProfile OWL Lite}, then the syntax checker will
1958     * test for constructs that lie in OWL-DL or OWL-Full and hence outside in OWL-Lite.
1959     * </p>
1960     *
1961     * @param problems A list that, if non-null, will have the various problems discovered by the OWL syntax
1962     * checker added to it.
1963     * @return A resource denoting the minimum OWL language level for this model
1964     * @exception OntologyException if this model is not an OWL model
1965     */

1966    public Resource getOWLLanguageLevel( List problems ) {
1967        initSyntaxCheckerClass();
1968        try {
1969          return
1970            ((OWLSyntaxChecker)owlSyntaxCheckerClass.newInstance()).
1971            getOWLLanguageLevel(this, problems);
1972        }
1973        catch (InstantiationException JavaDoc e){
1974            throw new BrokenException("Syntax Checker misconfigured: ",e);
1975        }
1976        catch (IllegalAccessException JavaDoc e){
1977            throw new BrokenException("Syntax Checker misconfigured: ",e);
1978        }
1979    }
1980
1981
1982    /**
1983     * <p>Read statements into the model from the given source, and then load
1984     * imported ontologies (according to the document manager policy).</p>
1985     * @param uri URI to read from, may be mapped to a local source by the document manager
1986     */

1987    public Model read( String JavaDoc uri ) {
1988        return read( uri, null );
1989    }
1990
1991    /**
1992     * <p>Read statements into the model from the given source, and then load
1993     * imported ontologies (according to the document manager policy).</p>
1994     * @param reader An input reader
1995     * @param base The base URI
1996     */

1997    public Model read( Reader reader, String JavaDoc base ) {
1998        super.read( reader, base );
1999
2000        getDocumentManager().loadImports( this );
2001        rebind();
2002        return this;
2003    }
2004
2005    /**
2006     * <p>Read statements into the model from the given source, and then load
2007     * imported ontologies (according to the document manager policy).</p>
2008     * @param reader An input stream
2009     * @param base The base URI
2010     */

2011    public Model read(InputStream reader, String JavaDoc base) {
2012        super.read( reader, base );
2013
2014        getDocumentManager().loadImports( this );
2015        rebind();
2016        return this;
2017    }
2018
2019    /**
2020     * <p>Read statements into the model from the given source, and then load
2021     * imported ontologies (according to the document manager policy).</p>
2022     * @param uri URI to read from, may be mapped to a local source by the document manager
2023     * @param syntax The source syntax
2024     * @return This model, to allow chaining calls
2025     */

2026    public Model read( String JavaDoc uri, String JavaDoc syntax ) {
2027        return read( uri, uri, syntax );
2028    }
2029
2030    /**
2031     * <p>Read statements into the model from the given source, and then load
2032     * imported ontologies (according to the document manager policy).</p>
2033     * @param uri URI to read from, may be mapped to a local source by the document manager
2034     * @param base The base URI for this model
2035     * @param syntax The source syntax
2036     * @return This model, to allow chaining calls
2037     */

2038    public Model read( String JavaDoc uri, String JavaDoc base, String JavaDoc syntax ) {
2039        // we don't want to load this document again if imported by one of the imports
2040
if (s_log.isDebugEnabled()) {
2041            s_log.debug( "Noting already loaded import URI " + uri );
2042        }
2043        addLoadedImport( uri );
2044
2045        String JavaDoc sourceURL = getDocumentManager().doAltURLMapping( uri );
2046        super.read( sourceURL, base, syntax );
2047
2048        // cache this model against the public uri (if caching enabled)
2049
getDocumentManager().addModel( uri, this );
2050
2051        // now load the imported documents
2052
getDocumentManager().loadImports( this );
2053        rebind();
2054        return this;
2055    }
2056
2057    /**
2058     * <p>Read statements into the model from the given source, and then load
2059     * imported ontologies (according to the document manager policy).</p>
2060     * @param reader An input reader
2061     * @param base The base URI
2062     * @param syntax The source syntax
2063     * @return This model, to allow chaining calls
2064     */

2065    public Model read(Reader reader, String JavaDoc base, String JavaDoc syntax) {
2066        super.read( reader, base, syntax );
2067
2068        getDocumentManager().loadImports( this );
2069        rebind();
2070        return this;
2071    }
2072
2073    /**
2074     * <p>Read statements into the model from the given source, and then load
2075     * imported ontologies (according to the document manager policy).</p>
2076     * @param reader An input stream
2077     * @param base The base URI
2078     * @param syntax The source syntax
2079     * @return This model, to allow chaining calls
2080     */

2081    public Model read(InputStream reader, String JavaDoc base, String JavaDoc syntax) {
2082        super.read( reader, base, syntax );
2083
2084        getDocumentManager().loadImports( this );
2085        rebind();
2086        return this;
2087    }
2088
2089
2090    /**
2091     * <p>
2092     * Answer the sub-graphs of this model. A sub-graph is defined as a graph that
2093     * is used to contain the triples from an imported document.
2094     * </p>
2095     *
2096     * @return A list of sub graphs for this ontology model
2097     */

2098    public List getSubGraphs() {
2099        return getUnionGraph().getSubGraphs();
2100    }
2101
2102
2103    /**
2104     * <p>Answer an iterator over the ontologies that this ontology imports,
2105     * each of which will have been wrapped as an ontology model using the same
2106     * {@link OntModelSpec} as this model. If this model has no imports,
2107     * the iterator will be non-null but will not have any values.</p>
2108     * @return An iterator, each value of which will be an <code>OntModel</code>
2109     * representing an imported ontology.
2110     */

2111    public ExtendedIterator listImportedModels() {
2112        ExtendedIterator i = WrappedIterator.create( getSubGraphs().iterator() );
2113
2114        return i.mapWith( new Map1() {
2115                    public Object JavaDoc map1(Object JavaDoc o) {
2116                        Graph g = (Graph) o;
2117                        Model temp = ModelFactory.createModelForGraph( g );
2118                        return ModelFactory.createOntologyModel( m_spec, temp );
2119                    }} );
2120    }
2121
2122
2123    /**
2124     * <p>Answer an <code>OntModel</code> representing the imported ontology
2125     * with the given URI. If an ontology with that URI has not been imported,
2126     * answer null.</p>
2127     * @param uri The URI of an ontology that may have been imported into the
2128     * ontology represented by this model
2129     * @return A model representing the imported ontology with the given URI, or
2130     * null.
2131     */

2132    public OntModel getImportedModel( String JavaDoc uri ) {
2133        if (listImportedOntologyURIs( true ).contains( uri )) {
2134            Model mi = getDocumentManager().getModel( uri );
2135
2136            if (mi != null) {
2137                if (mi instanceof OntModel) {
2138                    // already a suitable ont model
2139
return (OntModel) mi;
2140                }
2141                else {
2142                    // not in ont-model clothing yet, so re-wrap
2143
return ModelFactory.createOntologyModel( m_spec, mi );
2144                }
2145            }
2146        }
2147
2148        return null;
2149    }
2150
2151
2152    /**
2153     * <p>
2154     * Answer the base-graph of this model. The base-graph is the graph that
2155     * contains the triples read from the source document for this ontology.
2156     * </p>
2157     *
2158     * @return The base-graph for this ontology model
2159     */

2160    public Graph getBaseGraph() {
2161        return getUnionGraph().getBaseGraph();
2162    }
2163
2164
2165    /**
2166     * <p>
2167     * Answer the base model of this model. The base model is the model wrapping
2168     * the graph that contains the triples read from the source document for this
2169     * ontology. It is therefore the model that will be updated if statements are
2170     * added to a model that is built from a union of documents (via the
2171     * <code>imports</code> statements in the source document).
2172     * </p>
2173     *
2174     * @return The base model for this ontology model
2175     */

2176    public Model getBaseModel() {
2177        Model result = ModelFactory.createModelForGraph( getBaseGraph() );
2178        result.setNsPrefixes( this );
2179        return result;
2180    }
2181
2182
2183    /**
2184     * <p>
2185     * Add the given model as one of the sub-models of this ontology union. Will
2186     * cause the associated infererence engine (if any) to update, so this may be
2187     * an expensive operation in some cases.
2188     * </p>
2189     *
2190     * @param model A sub-model to add
2191     */

2192    public void addSubModel( Model model) {
2193        addSubModel( model, true );
2194    }
2195
2196
2197    /**
2198     * <p>
2199     * Add the given model as one of the sub-models of the enclosed ontology union model.
2200     * </p>
2201     *
2202     * @param model A sub-model to add
2203     * @param rebind If true, rebind any associated inferencing engine to the new data (which
2204     * may be an expensive operation)
2205     */

2206    public void addSubModel( Model model, boolean rebind ) {
2207        getUnionGraph().addGraph( model.getGraph() );
2208        if (rebind) {
2209            rebind();
2210        }
2211    }
2212
2213
2214    /**
2215     * <p>
2216     * Remove the given model as one of the sub-models of the enclosed ontology union model. Will
2217     * cause the associated infererence engine (if any) to update, so this may be
2218     * an expensive operation in some cases.
2219     * </p>
2220     *
2221     * @param model A sub-model to remove
2222     * @see #addSubModel( Model, boolean )
2223     */

2224    public void removeSubModel( Model model ) {
2225        removeSubModel( model, true );
2226    }
2227
2228
2229    /**
2230     * <p>
2231     * Remove the given model as one of the sub-models of the enclosed ontology union model.
2232     * </p>
2233     *
2234     * @param model A sub-model to remove
2235     * @param rebind If true, rebind any associated inferencing engine to the new data (which
2236     * may be an expensive operation)
2237     */

2238    public void removeSubModel( Model model, boolean rebind ) {
2239        Graph subG = model.getGraph();
2240
2241        if (subG instanceof MultiUnion) {
2242            // we need to get the base graph when removing a ontmodel
2243
subG = ((MultiUnion) subG).getBaseGraph();
2244        }
2245
2246        getUnionGraph().removeGraph( subG );
2247        if (rebind) {
2248            rebind();
2249        }
2250    }
2251
2252
2253    /**
2254     * <p>Answer true if the given node is a member of the base model of this ontology model.
2255     * This is an important distiction, because only the base model receives updates when the
2256     * ontology model is updated. Thus, removing properties of a resource that is not in the base
2257     * model will not actually side-effect the overall model.</p>
2258     * @param node An RDF node (Resource, Property or Literal) to test
2259     * @return True if the given node is from the base model
2260     */

2261    public boolean isInBaseModel( RDFNode node ) {
2262        Node n = node.asNode();
2263        Graph b = getBaseGraph();
2264        return b.contains( n, Node.ANY, Node.ANY ) ||
2265               b.contains( Node.ANY, n, Node.ANY ) ||
2266               b.contains( Node.ANY, Node.ANY, n );
2267    }
2268
2269
2270    /**
2271     * <p>Answer true if the given statement is defined in the base model of this ontology model.
2272     * This is an important distiction, because only the base model receives updates when the
2273     * ontology model is updated. Thus, removing a statement that is not in the base
2274     * model will not actually side-effect the overall model.</p>
2275     * @param stmt A statement to test
2276     * @return True if the given statement is from the base model
2277     */

2278    public boolean isInBaseModel( Statement stmt ) {
2279        Node s = stmt.getSubject().asNode();
2280        Node p = stmt.getPredicate().asNode();
2281        Node o = stmt.getObject().asNode();
2282        Graph b = getBaseGraph();
2283        return b.contains( s, p, o );
2284    }
2285
2286
2287    /**
2288     * <p>
2289     * Answer true if this model is currently in <i>strict checking mode</i>. Strict
2290     * mode means
2291     * that converting a common resource to a particular language element, such as
2292     * an ontology class, will be subject to some simple syntactic-level checks for
2293     * appropriateness.
2294     * </p>
2295     *
2296     * @return True if in strict checking mode
2297     */

2298    public boolean strictMode() {
2299        return m_strictMode;
2300    }
2301
2302
2303    /**
2304     * <p>
2305     * Set the checking mode to strict or non-strict.
2306     * </p>
2307     *
2308     * @param strict
2309     * @see #strictMode()
2310     */

2311    public void setStrictMode( boolean strict ) {
2312        m_strictMode = strict;
2313    }
2314
2315
2316    /**
2317     * <p>Set the flag that controls whether adding or removing <i>imports</i>
2318     * statements into the
2319     * model will result in the imports closure changing dynamically.</p>
2320     * @param dynamic If true, adding or removing an imports statement to the
2321     * model will result in a change in the imports closure. If false, changes
2322     * to the imports are not monitored dynamically. Default false.
2323     */

2324    public void setDynamicImports( boolean dynamic ) {
2325        if (dynamic) {
2326            if (m_importsListener == null) {
2327                // turn on dynamic processing
2328
m_importsListener = new ImportsListener();
2329                register( m_importsListener );
2330            }
2331        }
2332        else {
2333            if (m_importsListener != null) {
2334                // turn off dynamic processing
2335
unregister( m_importsListener );
2336                m_importsListener = null;
2337            }
2338        }
2339    }
2340
2341
2342    /**
2343     * <p>Answer true if the imports closure of the model will be dynamically
2344     * updated as imports statements are added and removed.</p>
2345     * @return True if the imports closure is updated dynamically.
2346     */

2347    public boolean getDynamicImports() {
2348        return m_importsListener != null;
2349    }
2350
2351
2352    /**
2353     * <p>Answer the ontology model specification that was used to construct this model</p>
2354     * @return An ont model spec instance.
2355     */

2356    public OntModelSpec getSpecification() {
2357        return m_spec;
2358    }
2359
2360
2361    /**
2362     * <p>Answer the ontology event manager attached to this model. If there is no event
2363     * manager currently attached, a new one will be created.</p>
2364     * @return The current, or a new, ontology event mananger
2365     */

2366    public OntEventManager getEventManager() {
2367        if (m_ontEventMgr == null) {
2368            m_ontEventMgr = new OntEventManager( this );
2369        }
2370
2371        return m_ontEventMgr;
2372    }
2373
2374
2375    /**
2376     * <p>
2377     * Answer the iterator over the resources from the graph that satisfy the given
2378     * query, followed by the answers to the alternative queries (if specified). A
2379     * typical scenario is that the main query gets resources of a given class (say,
2380     * <code>rdfs:Class</code>), while the altQueries query for aliases for that
2381     * type (such as <code>daml:Class</code>).
2382     * </p>
2383     *
2384     * @param query A query to run against the model
2385     * @param altQueries An optional list of subsidiary queries to chain on to the first
2386     * @return ExtendedIterator An iterator over the (assumed single) results of
2387     * executing the queries.
2388     */

2389    public ExtendedIterator queryFor( BindingQueryPlan query, List altQueries, Class JavaDoc asKey ) {
2390        GetBinding firstBinding = new GetBinding( 0 );
2391
2392        // get the results from the main query
2393
ExtendedIterator mainQuery = query.executeBindings().mapWith( firstBinding );
2394
2395        // now add the alternate queries, if defined
2396
if (altQueries != null) {
2397            for (Iterator i = altQueries.iterator(); i.hasNext(); ) {
2398                ExtendedIterator altQuery = ((BindingQueryPlan) i.next()).executeBindings().mapWith( firstBinding );
2399                mainQuery = mainQuery.andThen( altQuery );
2400            }
2401        }
2402
2403        // map each answer value to the appropriate ehnanced node
2404
return mainQuery.filterKeep( new SubjectNodeCanAs( asKey ) )
2405                        .mapWith( new SubjectNodeAs( asKey ) );
2406    }
2407
2408    // output operations - delegate to base model
2409

2410    public Model write( Writer writer ) { return getBaseModel().write( writer ); }
2411    public Model write( Writer writer, String JavaDoc lang ) { return getBaseModel().write( writer, lang ); }
2412    public Model write( Writer writer, String JavaDoc lang, String JavaDoc base ) { return getBaseModel().write( writer, lang, base ); }
2413    public Model write( OutputStream out ) { return getBaseModel().write( out ); }
2414    public Model write( OutputStream out, String JavaDoc lang ) { return getBaseModel().write( out, lang ); }
2415    public Model write( OutputStream out, String JavaDoc lang, String JavaDoc base) { return getBaseModel().write( out, lang, base ); }
2416
2417    public Model writeAll( Writer writer, String JavaDoc lang, String JavaDoc base ) {
2418        return super.write( writer, lang, base );
2419    }
2420
2421    public Model writeAll( OutputStream out, String JavaDoc lang, String JavaDoc base ) {
2422        return super.write( out, lang, base );
2423    }
2424
2425
2426    // Implementation of inf model interface methods
2427

2428    /**
2429     * Return the raw RDF model being processed (i.e. the argument
2430     * to the Reasonder.bind call that created this InfModel).
2431     */

2432    public Model getRawModel() {
2433        return getBaseModel();
2434    }
2435
2436    /**
2437     * Return the Reasoner which is being used to answer queries to this graph.
2438     */

2439    public Reasoner getReasoner() {
2440        return (getGraph() instanceof InfGraph) ? ((InfGraph) getGraph()).getReasoner() : null;
2441    }
2442
2443    /**
2444     * Cause the inference model to reconsult the underlying data to take
2445     * into account changes. Normally changes are made through the InfModel's add and
2446     * remove calls are will be handled appropriately. However, in some cases changes
2447     * are made "behind the InfModels's back" and this forces a full reconsult of
2448     * the changed data.
2449     */

2450    public void rebind() {
2451        if (getGraph() instanceof InfGraph) {
2452            ((InfGraph) getGraph()).rebind();
2453        }
2454    }
2455
2456    /**
2457     * Perform any initial processing and caching. This call is optional. Most
2458     * engines either have negligable set up work or will perform an implicit
2459     * "prepare" if necessary. The call is provided for those occasions where
2460     * substantial preparation work is possible (e.g. running a forward chaining
2461     * rule system) and where an application might wish greater control over when
2462     * this prepration is done rather than just leaving to be done at first query time.
2463     */

2464    public void prepare() {
2465        if (getGraph() instanceof InfGraph) {
2466            ((InfGraph) getGraph()).prepare();
2467        }
2468    }
2469
2470    /**
2471     * Reset any internal caches. Some systems, such as the tabled backchainer,
2472     * retain information after each query. A reset will wipe this information preventing
2473     * unbounded memory use at the expense of more expensive future queries. A reset
2474     * does not cause the raw data to be reconsulted and so is less expensive than a rebind.
2475     */

2476    public void reset() {
2477        if (getGraph() instanceof InfGraph) {
2478            ((InfGraph) getGraph()).reset();
2479        }
2480    }
2481
2482    /**
2483     * <p>Returns a derivations model. The rule reasoners typically create a
2484     * graph containing those triples added to the base graph due to rule firings.
2485     * In some applications it can useful to be able to access those deductions
2486     * directly, without seeing the raw data which triggered them. In particular,
2487     * this allows the forward rules to be used as if they were rewrite transformation
2488     * rules.</p>
2489     *
2490     * @return The derivations model, if one is defined, or else null
2491     */

2492    public Model getDeductionsModel() {
2493        if (m_deductionsModel == null) {
2494            InfGraph infGraph = getInfGraph();
2495            if (infGraph != null) {
2496                Graph deductionsGraph = infGraph.getDeductionsGraph();
2497                if (deductionsGraph != null) {
2498                    m_deductionsModel = ModelFactory.createModelForGraph( deductionsGraph );
2499                }
2500            }
2501        }
2502        return m_deductionsModel;
2503    }
2504
2505
2506    /**
2507     * Test the consistency of the underlying data. This normally tests
2508     * the validity of the bound instance data against the bound
2509     * schema data.
2510     * @return a ValidityReport structure
2511     */

2512    public ValidityReport validate() {
2513        return (getGraph() instanceof InfGraph) ? ((InfGraph) getGraph()).validate() : null;
2514    }
2515
2516    /** Find all the statements matching a pattern.
2517     * <p>Return an iterator over all the statements in a model
2518     * that match a pattern. The statements selected are those
2519     * whose subject matches the <code>subject</code> argument,
2520     * whose predicate matches the <code>predicate</code> argument
2521     * and whose object matchesthe <code>object</code> argument.
2522     * If an argument is <code>null</code> it matches anything.</p>
2523     * <p>
2524     * The s/p/o terms may refer to resources which are temporarily defined in the "posit" model.
2525     * This allows one, for example, to query what resources are of type CE where CE is a
2526     * class expression rather than a named class - put CE in the posit arg.</p>
2527     *
2528     * @return an iterator over the subjects
2529     * @param subject The subject sought
2530     * @param predicate The predicate sought
2531     * @param object The value sought
2532     */

2533    public StmtIterator listStatements( Resource subject, Property predicate, RDFNode object, Model posit ) {
2534        if (getGraph() instanceof InfGraph) {
2535            Iterator iter = ((InfGraph) getGraph()).find(subject.asNode(), predicate.asNode(), object.asNode(), posit.getGraph());
2536            return IteratorFactory.asStmtIterator(iter,this);
2537        }
2538        else {
2539            return null;
2540        }
2541    }
2542
2543    /**
2544     * Switch on/off drivation logging. If this is switched on then every time an inference
2545     * is a made that fact is recorded and the resulting record can be access through a later
2546     * getDerivation call. This may consume a lot of space!
2547     */

2548    public void setDerivationLogging(boolean logOn) {
2549        if (getGraph() instanceof InfGraph) {
2550            ((InfGraph) getGraph()).setDerivationLogging( logOn );
2551        }
2552    }
2553
2554    /**
2555     * Return the derivation of the given statement (which should be the result of
2556     * some previous list operation).
2557     * Not all reasoneers will support derivations.
2558     * @return an iterator over Derivation records or null if there is no derivation information
2559     * available for this triple.
2560     */

2561    public Iterator getDerivation(Statement statement) {
2562        return (getGraph() instanceof InfGraph) ? ((InfGraph) getGraph()).getDerivation( statement.asTriple() ) : null;
2563    }
2564
2565
2566
2567    // Internal implementation methods
2568
//////////////////////////////////
2569

2570
2571    private static void initSyntaxCheckerClass() {
2572        if (owlSyntaxCheckerClass == null ) {
2573            try {
2574              owlSyntaxCheckerClass = Class.forName(owlSyntaxCheckerClassName);
2575              OWLSyntaxChecker chk = (OWLSyntaxChecker)owlSyntaxCheckerClass.newInstance();
2576            }
2577            catch (Exception JavaDoc e){
2578                throw new ConfigException("owlsyntax.jar must be on the classpath.",e);
2579            }
2580        }
2581    }
2582
2583    /**
2584     * <p>Helper method to the constructor, which interprets the spec and generates an appropriate
2585     * graph for this model</p>
2586     * @param spec The model spec to interpret
2587     * @param base The base model, or null
2588     */

2589    private static Graph generateGraph( OntModelSpec spec, Graph base ) {
2590        // create a empty union graph
2591
MultiUnion u = new MultiUnion();
2592        u.addGraph( base );
2593        u.setBaseGraph( base );
2594
2595        Reasoner r = spec.getReasoner();
2596        // if we have a reasoner in the spec, bind to the union graph and return
2597
return r == null ? (Graph) u : r.bind( u );
2598    }
2599
2600
2601    /**
2602     * <p>Answer the union graph that contains the imports closure for this ontology</p>
2603     * @return The union graph
2604     */

2605    protected MultiUnion getUnionGraph() {
2606        return m_union;
2607    }
2608
2609
2610    /** Answer the resource with the given URI, if present, as the given facet */
2611    protected Resource findByURIAs( String JavaDoc uri, Class JavaDoc asKey ) {
2612        if (uri == null) {
2613            throw new IllegalArgumentException JavaDoc( "Cannot get() ontology value with a null URI" );
2614        }
2615
2616        Node n = Node.createURI( uri );
2617
2618        if (getGraph().contains( n, Node.ANY, Node.ANY )) {
2619            // this resource is a subject in the graph
2620
try {
2621                return (Resource) getNodeAs( n, asKey );
2622            }
2623            catch (ConversionException ignore) {}
2624        }
2625
2626        // not present, or cannot be as'ed to the desired facet
2627
return null;
2628    }
2629
2630    /**
2631     * <p>
2632     * Answer an iterator over all of the resources that have
2633     * <code>rdf:type</code> type.
2634     * </p>
2635     *
2636     * @param type The resource that is the value of <code>rdf:type</code> we
2637     * want to match
2638     * @return An iterator over all triples <code>_x rdf:type type</code>
2639     */

2640    protected ExtendedIterator findByType( Resource type ) {
2641        return getGraph().find( null, RDF.type.asNode(), type.asNode() );
2642    }
2643
2644
2645    /**
2646     * <p>
2647     * Answer an iterator over all of the resources that have
2648     * <code>rdf:type type</code>, or optionally, one of the alternative types.
2649     * </p>
2650     *
2651     * @param type The resource that is the value of <code>rdf:type</code> we
2652     * want to match
2653     * @param alternates An iterator over alternative types to search for, or null
2654     * @return An iterator over all triples <code>_x rdf:type t</code> where t
2655     * is <code>type</code> or one of the values from <code>types</code>.
2656     */

2657    protected ExtendedIterator findByType( Resource type, Iterator alternates ) {
2658        ExtendedIterator i = findByType( type );
2659
2660        // compose onto i the find iterators for the alternate types
2661
if (alternates != null) {
2662            while (alternates.hasNext()) {
2663                i = i.andThen( findByType( (Resource) alternates.next() ) );
2664            }
2665        }
2666
2667        return UniqueExtendedIterator.create( i );
2668    }
2669
2670
2671    /**
2672     * <p>
2673     * Answer an iterator over all of the resources that have
2674     * <code>rdf:type type</code>, or optionally, one of the alternative types,
2675     * and present the results <code>as()</code> the given class.
2676     * </p>
2677     *
2678     * @param type The resource that is the value of <code>rdf:type</code> we
2679     * want to match
2680     * @param types An iterator over alternative types to search for, or null
2681     * @param asKey The value to use to present the polymorphic results
2682     * @return An iterator over all triples <code>_x rdf:type type</code>
2683     */

2684    protected ExtendedIterator findByTypeAs( Resource type, Iterator types, Class JavaDoc asKey ) {
2685        return findByType( type, types ).mapWith( new SubjectNodeAs( asKey ) );
2686    }
2687
2688
2689    /**
2690     * <p>
2691     * Answer an iterator over all of the resources that has an
2692     * <code>rdf:type</code> from the types iterator,
2693     * and present the results <code>as()</code> the given class.
2694     * </p>
2695     *
2696     * @param types An iterator over types to search for. An exception will
2697     * be raised if this iterator does not have at least one next() element.
2698     * @param asKey The value to use to present the polymorphic results
2699     * @return An iterator over all triples <code>_x rdf:type type</code>
2700     */

2701    protected ExtendedIterator findByTypeAs( Iterator types, Class JavaDoc asKey ) {
2702        return findByTypeAs( (Resource) types.next(), types, asKey );
2703    }
2704
2705
2706    /**
2707     * <p>
2708     * Answer an iterator over resources with the given rdf:type; for each value
2709     * in the iterator, ensure that is is presented <code>as()</code> the
2710     * polymorphic object denoted by the given class key.
2711     * </p>
2712     *
2713     * @param type The rdf:type to search for
2714     * @param asKey The key to pass to as() on the subject nodes
2715     * @return An iterator over subjects with the given type, presenting as
2716     * the given polymorphic class.
2717     */

2718    protected ExtendedIterator findByTypeAs( Resource type, Class JavaDoc asKey ) {
2719        return findByType( type ).mapWith( new SubjectNodeAs( asKey ) );
2720    }
2721
2722
2723    /**
2724     * <p>
2725     * Answer a binding query that will search for 'an X that has an
2726     * rdf:type whose rdf:type is C' for some given resource C.
2727     * </p>
2728     *
2729     * @param type The type of the type of the resources we're searching for
2730     * @return BindingQueryPlan A binding query for the X resources.
2731     */

2732    protected BindingQueryPlan queryXTypeOfType( Resource type ) {
2733        if (type != null) {
2734            Query q = new Query();
2735            // kers: this non-intuitive order should improve search performance
2736
q.addMatch( Query.Y, RDF.type.asNode(), type.asNode() );
2737            q.addMatch( Query.X, RDF.type.asNode(), Query.Y );
2738
2739            return queryHandler().prepareBindings( q, new Node[] {Query.X} );
2740        }
2741        else {
2742            return null;
2743        }
2744    }
2745
2746
2747    /**
2748     * <p>
2749     * Answer an iterator over nodes that have p as a subject
2750     * </p>
2751     *
2752     * @param p A property
2753     * @return ExtendedIterator over subjects of p.
2754     */

2755    protected ExtendedIterator findByDefiningProperty( Property p ) {
2756        return getGraph().find( null, p.getNode(), null );
2757    }
2758
2759
2760    /**
2761     * <p>
2762     * Answer an iterator over nodes that have p as a subject, presented as
2763     * polymorphic enh resources of the given facet.
2764     * </p>
2765     *
2766     * @param p A property
2767     * @param asKey A facet type
2768     * @return ExtendedIterator over subjects of p, presented as the facet.
2769     */

2770    protected ExtendedIterator findByDefiningPropertyAs( Property p, Class JavaDoc asKey ) {
2771        return findByDefiningProperty( p ).mapWith( new SubjectNodeAs( asKey ) );
2772    }
2773
2774
2775    /**
2776     * <p>
2777     * Answer the resource with the given uri and that optionally has the given <code>rdf:type</code>,
2778     * creating the resource if necessary.
2779     * </p>
2780     *
2781     * @param uri The uri to use, or null for an anonymous resource
2782     * @param rdfType The resource to assert as the <code>rdf:type</code>, or null to leave untyped
2783     * @return A new or existing Resource
2784     */

2785    protected Resource getResourceWithType( String JavaDoc uri, Resource rdfType ) {
2786        Resource r = getResource( uri );
2787        if (rdfType != null) {
2788            r.addProperty( RDF.type, rdfType );
2789        }
2790        return r;
2791    }
2792
2793
2794    /**
2795     * <p>Answer a resource presenting the {@link OntResource} facet, which has the given
2796     * URI. If no such resource is currently present in the model, return null.</p>
2797     * @param uri The URI of a resource
2798     * @return An OntResource with the given URI, or null
2799     */

2800    public OntResource getOntResource( String JavaDoc uri ) {
2801        Resource r = getResource( uri );
2802        if (containsResource( r )) {
2803            return (OntResource) r.as( OntResource.class );
2804        }
2805        return null;
2806    }
2807
2808    /**
2809     * <p>Answer a resource presenting the {@link OntResource} facet, which
2810     * corresponds to the given resource but attached to this model.</p>
2811     * @param resource An existing resource
2812     * @return An OntResource attached to this model that has the same URI
2813     * or anonID as the given resource
2814     */

2815    public OntResource getOntResource( Resource res ) {
2816        return (OntResource) res.inModel( this ).as( OntResource.class );
2817    }
2818
2819    /**
2820     * <p>Throw an OntologyException if the term is not in language profile</p>
2821     *
2822     * @param profileTerm The entry from the profile
2823     * @param desc A label for the profile term
2824     * @exception OntologyException if profileTerm is null.
2825     */

2826    protected void checkProfileEntry( Object JavaDoc profileTerm, String JavaDoc desc ) {
2827        if (profileTerm == null) {
2828            // not in the profile
2829
throw new ProfileException( desc, getProfile() );
2830        }
2831    }
2832
2833
2834    /**
2835     * <p>Check that every member of the given list has the given rdf:type, and throw an exception if not.</p>
2836     * @param list The list to be checked
2837     * @param rdfType The rdf:type value to check for
2838     * @exception LanguageConsistencyException if any member of the list does not have <code>rdf:type <i>rdfType</i></code>
2839     */

2840    protected void checkListMembersRdfType( RDFList list, Resource rdfType ) {
2841        if (strictMode() && ! ((Boolean JavaDoc) list.reduce( new RdfTypeTestFn( rdfType), Boolean.TRUE )).booleanValue()) {
2842            // not all of the members of the list are of the given type
2843
throw new LanguageConsistencyException( "The members of the given list are expected to be of rdf:type " + rdfType.toString() );
2844        }
2845    }
2846
2847    /**
2848        Answer the supplied model, unless it's null, in which case answer a new model
2849        constructed as per spec.
2850    */

2851    private static Model makeBaseModel( OntModelSpec spec, Model model ) {
2852        return model == null ? spec.createBaseModel() : model;
2853    }
2854
2855
2856    /**
2857     * <p>Answer the InfGraph that this model is wrapping, or null if this ontology
2858     * model is not wrapping an inf graph.</p>
2859     * @return The model's graph as an InfGraph, or null
2860     */

2861    private InfGraph getInfGraph() {
2862        return (getGraph() instanceof InfGraph) ? ((InfGraph) getGraph()) : null;
2863    }
2864
2865
2866    //==============================================================================
2867
// Inner class definitions
2868
//==============================================================================
2869

2870    /** Map triple subjects or single nodes to subject enh nodes, presented as() the given class */
2871    protected class SubjectNodeAs implements Map1
2872    {
2873        protected Class JavaDoc m_asKey;
2874
2875        protected SubjectNodeAs( Class JavaDoc asKey ) { m_asKey = asKey; }
2876
2877        public Object JavaDoc map1( Object JavaDoc x ) {
2878            Node n = (x instanceof Triple)
2879                         ? ((Triple) x).getSubject()
2880                         : ((x instanceof EnhNode) ? ((EnhNode) x).asNode() : (Node) x);
2881            return getNodeAs( n, m_asKey );
2882        }
2883
2884    }
2885
2886    /** Filter that accepts nodes that can be mapped to the given facet */
2887    protected class SubjectNodeCanAs implements Filter
2888    {
2889        protected Class JavaDoc m_asKey;
2890        protected SubjectNodeCanAs( Class JavaDoc asKey ) { m_asKey = asKey; }
2891
2892        public boolean accept( Object JavaDoc x ) {
2893            Node n = (x instanceof Triple)
2894                    ? ((Triple) x).getSubject()
2895                    : ((x instanceof EnhNode) ? ((EnhNode) x).asNode() : (Node) x);
2896            try {
2897                getNodeAs( n, m_asKey );
2898            }
2899            catch (Exception JavaDoc ignore) {
2900                return false;
2901            }
2902
2903            return true;
2904        }
2905
2906    }
2907
2908    /** Project out the first element of a list of bindings */
2909    protected class GetBinding implements Map1
2910    {
2911        protected int m_index;
2912        protected GetBinding( int index ) { m_index = index; }
2913        public Object JavaDoc map1( Object JavaDoc x ) { return ((List) x).get( m_index ); }
2914    }
2915
2916    /** Function to test the rdf type of a list */
2917    protected class RdfTypeTestFn implements RDFList.ReduceFn
2918    {
2919        protected Resource m_type;
2920        protected RdfTypeTestFn( Resource type ) { m_type = type; }
2921        public Object JavaDoc reduce( RDFNode node, Object JavaDoc accumulator ) {
2922            Boolean JavaDoc acc = (Boolean JavaDoc) accumulator;
2923            if (acc.booleanValue()) {
2924                // true so far
2925
Resource r = (Resource) node;
2926                return new Boolean JavaDoc( r.hasProperty( RDF.type, m_type ) );
2927            }
2928            else {
2929                return acc;
2930            }
2931        }
2932    }
2933
2934    /** Listener for model changes that indicate a change in the imports to the model */
2935    protected class ImportsListener
2936        extends StatementListener
2937    {
2938        public void addedStatement( Statement added ) {
2939            if (added.getPredicate().equals( getProfile().IMPORTS() )) {
2940                getDocumentManager().loadImport( OntModelImpl.this, added.getResource().getURI() );
2941            }
2942        }
2943
2944        public void removedStatement( Statement removed ) {
2945            if (removed.getPredicate().equals( getProfile().IMPORTS() )) {
2946                getDocumentManager().unloadImport( OntModelImpl.this, removed.getResource().getURI() );
2947            }
2948        }
2949    }
2950}
2951
2952
2953/*
2954    (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
2955    All rights reserved.
2956
2957    Redistribution and use in source and binary forms, with or without
2958    modification, are permitted provided that the following conditions
2959    are met:
2960
2961    1. Redistributions of source code must retain the above copyright
2962       notice, this list of conditions and the following disclaimer.
2963
2964    2. Redistributions in binary form must reproduce the above copyright
2965       notice, this list of conditions and the following disclaimer in the
2966       documentation and/or other materials provided with the distribution.
2967
2968    3. The name of the author may not be used to endorse or promote products
2969       derived from this software without specific prior written permission.
2970
2971    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2972    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2973    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2974    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2975    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2976    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2977    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2978    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2979    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2980    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2981*/

2982
Popular Tags