Source Code Cross Referenced for OntModelImpl.java in  » RSS-RDF » Jena-2.5.5 » com » hp » hpl » jena » ontology » impl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » RSS RDF » Jena 2.5.5 » com.hp.hpl.jena.ontology.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*****************************************************************************
0002:         * Source code information
0003:         * -----------------------
0004:         * Original author    Ian Dickinson, HP Labs Bristol
0005:         * Author email       Ian.Dickinson@hp.com
0006:         * Package            Jena 2
0007:         * Web                http://sourceforge.net/projects/jena/
0008:         * Created            22 Feb 2003
0009:         * Filename           $RCSfile: OntModelImpl.java,v $
0010:         * Revision           $Revision: 1.106 $
0011:         * Release status     $State: Exp $
0012:         *
0013:         * Last modified on   $Date: 2008/01/28 15:51:48 $
0014:         *               by   $Author: chris-dollin $
0015:         *
0016:         * (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
0017:         * (see footer for full conditions)
0018:         *****************************************************************************/package com.hp.hpl.jena.ontology.impl;
0019:
0020:        // Imports
0021:        ///////////////
0022:        import com.hp.hpl.jena.rdf.listeners.StatementListener;
0023:        import com.hp.hpl.jena.rdf.model.*;
0024:        import com.hp.hpl.jena.rdf.model.impl.*;
0025:        import com.hp.hpl.jena.reasoner.*;
0026:        import com.hp.hpl.jena.util.iterator.*;
0027:        import com.hp.hpl.jena.vocabulary.*;
0028:        import com.hp.hpl.jena.ontology.*;
0029:        import com.hp.hpl.jena.ontology.event.*;
0030:        import com.hp.hpl.jena.graph.*;
0031:        import com.hp.hpl.jena.graph.compose.MultiUnion;
0032:        import com.hp.hpl.jena.graph.query.*;
0033:        import com.hp.hpl.jena.enhanced.*;
0034:        import com.hp.hpl.jena.shared.*;
0035:
0036:        import java.io.*;
0037:        import java.util.*;
0038:
0039:        import org.apache.commons.logging.Log;
0040:        import org.apache.commons.logging.LogFactory;
0041:
0042:        /**
0043:         * <p>
0044:         * Implementation of a model that can process general ontologies in OWL,
0045:         * DAML and similar languages.
0046:         * </p>
0047:         *
0048:         * @author Ian Dickinson, HP Labs
0049:         *         (<a  href="mailto:Ian.Dickinson@hp.com" >email</a>)
0050:         * @version CVS $Id: OntModelImpl.java,v 1.106 2008/01/28 15:51:48 chris-dollin Exp $
0051:         */
0052:        public class OntModelImpl extends ModelCom implements  OntModel {
0053:            // Constants
0054:            //////////////////////////////////
0055:
0056:            /**
0057:             * This variable is how the OntModel knows how to construct
0058:             * a syntax checker. This part of the design may change.
0059:             */
0060:            static public String owlSyntaxCheckerClassName = "com.hp.hpl.jena.ontology.tidy.JenaChecker";
0061:
0062:            // Static variables
0063:            //////////////////////////////////
0064:
0065:            static private Log s_log = LogFactory.getLog(OntModelImpl.class);
0066:
0067:            /** Found from {@link owlSyntaxCheckerClassName}, must implement
0068:             * {@link OWLSyntaxChecker}. */
0069:            static private Class owlSyntaxCheckerClass;
0070:
0071:            // Instance variables
0072:            //////////////////////////////////
0073:
0074:            /** The model specification this model is using to define its structure */
0075:            protected OntModelSpec m_spec;
0076:
0077:            /** List of URI strings of documents that have been imported into this one */
0078:            protected Set m_imported = new HashSet();
0079:
0080:            /** Mode switch for strict checking mode */
0081:            protected boolean m_strictMode = true;
0082:
0083:            /** The union graph that contains the imports closure - there is always one of these, which may also be _the_ graph for the model */
0084:            protected MultiUnion m_union = new MultiUnion();
0085:
0086:            /** The listener that detects dynamically added or removed imports statements */
0087:            protected ImportsListener m_importsListener = null;
0088:
0089:            /** The event manager for ontology events on this model */
0090:            protected OntEventManager m_ontEventMgr = null;
0091:
0092:            /** Cached deductions model */
0093:            private Model m_deductionsModel = null;
0094:
0095:            // Constructors
0096:            //////////////////////////////////
0097:
0098:            /**
0099:             * <p>
0100:             * Construct a new ontology model, using the given model as a base.  The document manager
0101:             * given in the specification object
0102:             * will be used to build the imports closure of the model if its policy permits.
0103:             * </p>
0104:             *
0105:             * @param model The base model that may contain existing statements for the ontology.
0106:             *  if it is null, a fresh model is created as the base.
0107:             * @param spec A specification object that allows us to specify parameters and structure for the
0108:             *              ontology model to be constructed.
0109:             */
0110:            public OntModelImpl(OntModelSpec spec, Model model) {
0111:                this (spec, makeBaseModel(spec, model), true);
0112:            }
0113:
0114:            /**
0115:             * Construct a new ontology model from the given specification. The base model is
0116:             * produced using the baseModelMaker.
0117:             */
0118:            public OntModelImpl(OntModelSpec spec) {
0119:                this (spec, spec.createBaseModel(), true);
0120:            }
0121:
0122:            /**
0123:             *
0124:             * @param spec the specification for the OntModel
0125:             * @param model the base model [must be non-null]
0126:             * @param withImports If true, we load the imports as sub-models
0127:             */
0128:            private OntModelImpl(OntModelSpec spec, Model model,
0129:                    boolean withImports) {
0130:                // we haven't built the full graph yet, so we pass a vestigial form up to the super constructor
0131:                super (generateGraph(spec, model.getGraph()),
0132:                        BuiltinPersonalities.model);
0133:                m_spec = spec;
0134:
0135:                // extract the union graph from whatever generateGraph() created
0136:                m_union = (getGraph() instanceof  MultiUnion) ? ((MultiUnion) getGraph())
0137:                        : (MultiUnion) ((InfGraph) getGraph()).getRawGraph();
0138:
0139:                // add the global prefixes, if required
0140:                if (getDocumentManager().useDeclaredPrefixes()) {
0141:                    withDefaultMappings(getDocumentManager()
0142:                            .getDeclaredPrefixMapping());
0143:                }
0144:
0145:                if (withImports) {
0146:                    loadImports();
0147:                }
0148:
0149:                // force the inference engine, if we have one, to see the new graph data
0150:                rebind();
0151:            }
0152:
0153:            // External signature methods
0154:            //////////////////////////////////
0155:
0156:            /**
0157:             * <p>
0158:             * Answer a reference to the document manager that this model is using to manage
0159:             * ontology &lt;-&gt; mappings, and to load the imports closure. <strong>Note</strong>
0160:             * the default ontology model {@linkplain OntModelSpec specifications} each have
0161:             * a contained default document manager. Changing the document managers specified by
0162:             * these default specification may (in fact, probably will)
0163:             * affect other models built with the same specification
0164:             * policy. This may or may not be as desired by the programmer!
0165:             * </p>
0166:             * @return A reference to this model's document manager, obtained from the specification object
0167:             */
0168:            public OntDocumentManager getDocumentManager() {
0169:                return m_spec.getDocumentManager();
0170:            }
0171:
0172:            /**
0173:             * <p>
0174:             * Answer an iterator that ranges over the ontology resources in this model, i&#046;e&#046;
0175:             * the resources with <code>rdf:type Ontology</code> or equivalent. These resources
0176:             * typically contain metadata about the ontology document that contains them.
0177:             * </p>
0178:             * <p>
0179:             * Specifically, the resources in this iterator will those whose type corresponds
0180:             * to the value given in the ontology vocabulary associated with this model, see
0181:             * {@link Profile#ONTOLOGY}.
0182:             * </p>
0183:             * <p>
0184:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0185:             * the completeness of the deductive extension of the underlying graph.  See class
0186:             * overview for more details.
0187:             * </p>
0188:             *
0189:             * @return An iterator over ontology resources.
0190:             */
0191:            public ExtendedIterator listOntologies() {
0192:                checkProfileEntry(getProfile().ONTOLOGY(), "ONTOLOGY");
0193:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0194:                        .ONTOLOGY(), Ontology.class));
0195:            }
0196:
0197:            /**
0198:             * <p>
0199:             * Answer an iterator that ranges over the property resources in this model, i&#046;e&#046;
0200:             * the resources with <code>rdf:type Property</code> or equivalent.  An <code>OntProperty</code>
0201:             * is equivalent to an <code>rdfs:Property</code> in a normal RDF graph; this type is
0202:             * provided as a common super-type for the more specific {@link ObjectProperty} and
0203:             * {@link DatatypeProperty} property types.
0204:             * </p>
0205:             * <p><strong>Note</strong> This method searches for nodes in the underlying model whose
0206:             * <code>rdf:type</code> is <code>rdf:Property</code>. This type is <em>entailed</em> by
0207:             * specific property sub-types, such as <code>owl:ObjectProperty</code>. An important
0208:             * consequence of this is that in <em>models without an attached reasoner</em> (e.g. in the
0209:             * <code>OWL_MEM</code> {@link OntModelSpec}), the entailed type will not be present
0210:             * and this method will omit such properties from the returned iterator. <br />
0211:             * <strong>Solution</strong> There are two
0212:             * ways to address to this issue: either use a reasoning engine to ensure that type entailments
0213:             * are taking place correctly, or call {@link #listAllOntProperties()}. Note
0214:             * that <code>listAllOntProperties</code> is potentially less efficient than this method.</p>
0215:             * <p>
0216:             * The resources returned by this iterator will those whose type corresponds
0217:             * to the value given in the ontology vocabulary associated with this model.
0218:             * </p>
0219:             *
0220:             * @return An iterator over property resources.
0221:             */
0222:            public ExtendedIterator listOntProperties() {
0223:                ExtendedIterator i = UniqueExtendedIterator
0224:                        .create(findByTypeAs(RDF.Property, OntProperty.class));
0225:
0226:                // if we are in OWL_FULL, the properties should also include the annotation properties
0227:                if (getReasoner() != null
0228:                        && getProfile().equals(
0229:                                ProfileRegistry.getInstance().getProfile(
0230:                                        ProfileRegistry.OWL_LANG))) {
0231:                    // we are using a reasoner, and in OWL Full
0232:                    // so add the annotation properties too
0233:                    i = i.andThen(listAnnotationProperties());
0234:                }
0235:
0236:                return i;
0237:            }
0238:
0239:            /**
0240:             * <p>Answer an iterator over all of the ontology properties in this model, including
0241:             * object properties, datatype properties, annotation properties, etc. This method
0242:             * takes a different approach to calculating the set of property resources to return,
0243:             * and is robust against the absence of a reasoner attached to the model (see note
0244:             * in {@link #listOntProperties()} for explanation). However, the calculation used by
0245:             * this method is potentially less efficient than the alternative <code>listOntProperties()</code>.
0246:             * Users whose models have an attached reasoner are recommended to use
0247:             * {@link #listOntProperties()}.</p>
0248:             * @return An iterator over all available properties in a model, irrespective of
0249:             * whether a reasoner is available to perform <code>rdf:type</code> entailments.
0250:             * Each property will appear exactly once in the iterator.
0251:             */
0252:            public ExtendedIterator listAllOntProperties() {
0253:                ExtendedIterator i = findByTypeAs(RDF.Property,
0254:                        OntProperty.class).andThen(listObjectProperties())
0255:                        .andThen(listDatatypeProperties()).andThen(
0256:                                listAnnotationProperties()).andThen(
0257:                                listFunctionalProperties()).andThen(
0258:                                listTransitiveProperties()).andThen(
0259:                                listSymmetricProperties());
0260:
0261:                // we must filter for uniqueness
0262:                return UniqueExtendedIterator.create(i);
0263:            }
0264:
0265:            /**
0266:             * <p>
0267:             * Answer an iterator that ranges over the object property resources in this model, i&#046;e&#046;
0268:             * the resources with <code>rdf:type ObjectProperty</code> or equivalent.  An object
0269:             * property is a property that is defined in the ontology language semantics as a
0270:             * one whose range comprises individuals (rather than datatyped literals).
0271:             * </p>
0272:             * <p>
0273:             * Specifically, the resources in this iterator will those whose type corresponds
0274:             * to the value given in the ontology vocabulary associated with this model: see
0275:             * {@link Profile#OBJECT_PROPERTY}.
0276:             * </p>
0277:             * <p>
0278:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0279:             * the completeness of the deductive extension of the underlying graph.  See class
0280:             * overview for more details.
0281:             * </p>
0282:             *
0283:             * @return An iterator over object property resources.
0284:             */
0285:            public ExtendedIterator listObjectProperties() {
0286:                checkProfileEntry(getProfile().OBJECT_PROPERTY(),
0287:                        "OBJECT_PROPERTY");
0288:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0289:                        .OBJECT_PROPERTY(), ObjectProperty.class));
0290:            }
0291:
0292:            /**
0293:             * <p>
0294:             * Answer an iterator that ranges over the datatype property resources in this model, i&#046;e&#046;
0295:             * the resources with <code>rdf:type DatatypeProperty</code> or equivalent.  An datatype
0296:             * property is a property that is defined in the ontology language semantics as a
0297:             * one whose range comprises datatyped literals (rather than individuals).
0298:             * </p>
0299:             * <p>
0300:             * Specifically, the resources in this iterator will those whose type corresponds
0301:             * to the value given in the ontology vocabulary associated with this model: see
0302:             * {@link Profile#DATATYPE_PROPERTY}.
0303:             * </p>
0304:             * <p>
0305:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0306:             * the completeness of the deductive extension of the underlying graph.  See class
0307:             * overview for more details.
0308:             * </p>
0309:             *
0310:             * @return An iterator over datatype property resources.
0311:             */
0312:            public ExtendedIterator listDatatypeProperties() {
0313:                checkProfileEntry(getProfile().DATATYPE_PROPERTY(),
0314:                        "DATATYPE_PROPERTY");
0315:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0316:                        .DATATYPE_PROPERTY(), DatatypeProperty.class));
0317:            }
0318:
0319:            /**
0320:             * <p>
0321:             * Answer an iterator that ranges over the functional property resources in this model, i&#046;e&#046;
0322:             * the resources with <code>rdf:type FunctionalProperty</code> or equivalent.  A functional
0323:             * property is a property that is defined in the ontology language semantics as having
0324:             * a unique domain element for each instance of the relationship.
0325:             * </p>
0326:             * <p>
0327:             * Specifically, the resources in this iterator will those whose type corresponds
0328:             * to the value given in the ontology vocabulary associated with this model: see
0329:             * {@link Profile#FUNCTIONAL_PROPERTY}.
0330:             * </p>
0331:             *
0332:             * @return An iterator over functional property resources.
0333:             */
0334:            public ExtendedIterator listFunctionalProperties() {
0335:                checkProfileEntry(getProfile().FUNCTIONAL_PROPERTY(),
0336:                        "FUNCTIONAL_PROPERTY");
0337:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0338:                        .FUNCTIONAL_PROPERTY(), FunctionalProperty.class));
0339:            }
0340:
0341:            /**
0342:             * <p>
0343:             * Answer an iterator that ranges over the transitive property resources in this model, i&#046;e&#046;
0344:             * the resources with <code>rdf:type TransitiveProperty</code> or equivalent.
0345:             * </p>
0346:             * <p>
0347:             * Specifically, the resources in this iterator will those whose type corresponds
0348:             * to the value given in the ontology vocabulary associated with this model: see
0349:             * {@link Profile#TRANSITIVE_PROPERTY}.
0350:             * </p>
0351:             *
0352:             * @return An iterator over transitive property resources.
0353:             */
0354:            public ExtendedIterator listTransitiveProperties() {
0355:                checkProfileEntry(getProfile().TRANSITIVE_PROPERTY(),
0356:                        "TRANSITIVE_PROPERTY");
0357:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0358:                        .TRANSITIVE_PROPERTY(), TransitiveProperty.class));
0359:            }
0360:
0361:            /**
0362:             * <p>
0363:             * Answer an iterator that ranges over the symmetric property resources in this model, i&#046;e&#046;
0364:             * the resources with <code>rdf:type SymmetricProperty</code> or equivalent.
0365:             * </p>
0366:             * <p>
0367:             * Specifically, the resources in this iterator will those whose type corresponds
0368:             * to the value given in the ontology vocabulary associated with this model: see
0369:             * {@link Profile#SYMMETRIC_PROPERTY}.
0370:             * </p>
0371:             *
0372:             * @return An iterator over symmetric property resources.
0373:             */
0374:            public ExtendedIterator listSymmetricProperties() {
0375:                checkProfileEntry(getProfile().SYMMETRIC_PROPERTY(),
0376:                        "SYMMETRIC_PROPERTY");
0377:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0378:                        .SYMMETRIC_PROPERTY(), SymmetricProperty.class));
0379:            }
0380:
0381:            /**
0382:             * <p>
0383:             * Answer an iterator that ranges over the inverse functional property resources in this model, i&#046;e&#046;
0384:             * the resources with <code>rdf:type InverseFunctionalProperty</code> or equivalent.
0385:             * </p>
0386:             * <p>
0387:             * Specifically, the resources in this iterator will those whose type corresponds
0388:             * to the value given in the ontology vocabulary associated with this model: see
0389:             * {@link Profile#INVERSE_FUNCTIONAL_PROPERTY}.
0390:             * </p>
0391:             *
0392:             * @return An iterator over inverse functional property resources.
0393:             */
0394:            public ExtendedIterator listInverseFunctionalProperties() {
0395:                checkProfileEntry(getProfile().INVERSE_FUNCTIONAL_PROPERTY(),
0396:                        "INVERSE_FUNCTIONAL_PROPERTY");
0397:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0398:                        .INVERSE_FUNCTIONAL_PROPERTY(),
0399:                        InverseFunctionalProperty.class));
0400:            }
0401:
0402:            /**
0403:             * <p>
0404:             * Answer an iterator that ranges over the individual resources in this model, i&#046;e&#046;
0405:             * the resources with <code>rdf:type</code> corresponding to a class defined
0406:             * in the ontology.
0407:             * </p>
0408:             * <p>
0409:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0410:             * the completeness of the deductive extension of the underlying graph.  See class
0411:             * overview for more details.
0412:             * </p>
0413:             *
0414:             * @return An iterator over Individuals.
0415:             */
0416:            public ExtendedIterator listIndividuals() {
0417:                // since the reasoner implements some OWL full functionality for RDF compatability, we
0418:                // have to decide which strategy to use for indentifying individuals depending on whether
0419:                // or not a powerful reasoner (i.e. owl:Thing/daml:Thing aware) is being used with this model
0420:                boolean supportsIndAsThing = false;
0421:                if (getGraph() instanceof  InfGraph) {
0422:                    supportsIndAsThing = ((InfGraph) getGraph()).getReasoner()
0423:                            .getReasonerCapabilities().contains(null,
0424:                                    ReasonerVocabulary.supportsP,
0425:                                    ReasonerVocabulary.individualAsThingP);
0426:                }
0427:                if (!supportsIndAsThing || (getProfile().THING() == null)
0428:                        || getProfile().CLASS().equals(RDFS.Class)) {
0429:                    // no inference, or we are in RDFS land, so we pick things that have rdf:type whose rdf:type is Class
0430:
0431:                    // we have to build the query plans dynamically - these were done once-only in pre-Jena-2.5,
0432:                    // but this can interfere with some opimisations
0433:                    ExtendedIterator indivI = queryFor(
0434:                            queryXTypeOfType(getProfile().CLASS()), null,
0435:                            Individual.class);
0436:
0437:                    if (getProfile().RESTRICTION() != null) {
0438:                        // and things whose rdf:type is Restriction
0439:                        indivI = indivI.andThen(queryFor(
0440:                                queryXTypeOfType(getProfile().RESTRICTION()),
0441:                                null, Individual.class));
0442:                    }
0443:
0444:                    // we also must pick resources that simply have rdf:type owl:Thing, since some individuals are asserted that way
0445:                    if (getProfile().THING() != null) {
0446:                        indivI = indivI.andThen(findByTypeAs(getProfile()
0447:                                .THING(), Individual.class));
0448:                    }
0449:
0450:                    return UniqueExtendedIterator.create(indivI);
0451:                } else {
0452:                    // we have inference, so we pick the nodes that are of type Thing
0453:                    return UniqueExtendedIterator.create(findByTypeAs(
0454:                            getProfile().THING(), Individual.class));
0455:                }
0456:            }
0457:
0458:            /**
0459:             * <p>
0460:             * Answer an iterator that ranges over the resources in this model that are
0461:             * instances of the given class.
0462:             * </p>
0463:             *
0464:             * @return An iterator over individual resources whose <code>rdf:type</code>
0465:             * is <code>cls</code>.
0466:             */
0467:            public ExtendedIterator listIndividuals(Resource cls) {
0468:                return UniqueExtendedIterator.create(findByTypeAs(cls,
0469:                        Individual.class));
0470:            }
0471:
0472:            /**
0473:             * <p>
0474:             * Answer an iterator that ranges over all of the various forms of class description resource
0475:             * in this model.  Class descriptions include {@link #listEnumeratedClasses enumerated}
0476:             * classes, {@link #listUnionClasses union} classes, {@link #listComplementClasses complement}
0477:             * classes, {@link #listIntersectionClasses intersection} classes, {@link #listClasses named}
0478:             * classes and {@link #listRestrictions property restrictions}.
0479:             * </p>
0480:             * <p>
0481:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0482:             * the completeness of the deductive extension of the underlying graph.  See class
0483:             * overview for more details.
0484:             * </p>
0485:             *
0486:             * @return An iterator over class description resources.
0487:             */
0488:            public ExtendedIterator listClasses() {
0489:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0490:                        .getClassDescriptionTypes(), OntClass.class));
0491:            }
0492:
0493:            /**
0494:             * <p>Answer an iterator over the classes in this ontology model that represent
0495:             * the uppermost nodes of the class hierarchy.  Depending on the underlying
0496:             * reasoner configuration, if any, these will be calculated as the classes
0497:             * that have Top (i.e. <code>owl:Thing</code> or <code>daml:Thing</code>)
0498:             * as a direct super-class, or the classes which have no declared super-class.</p>
0499:             * @return An iterator of the root classes in the local class hierarchy
0500:             */
0501:            public ExtendedIterator listHierarchyRootClasses() {
0502:                // look for the shortcut of using direct subClass on :Thing
0503:                if (getReasoner() != null) {
0504:                    Model conf = getReasoner().getReasonerCapabilities();
0505:                    if (conf != null
0506:                            && conf.contains(null,
0507:                                    ReasonerVocabulary.supportsP,
0508:                                    ReasonerVocabulary.directSubClassOf)
0509:                            && getProfile().THING() != null) {
0510:                        // we have have both direct sub-class of and a :Thing class to test against
0511:                        return listStatements(null,
0512:                                ReasonerVocabulary.directSubClassOf,
0513:                                getProfile().THING()).mapWith(
0514:                                new OntResourceImpl.SubjectAsMapper(
0515:                                        OntClass.class));
0516:                    }
0517:                }
0518:
0519:                // no easy shortcut, so we use brute force
0520:                return listClasses().filterDrop(new Filter() {
0521:                    public boolean accept(Object o) {
0522:                        return ((OntResource) o).isOntLanguageTerm();
0523:                    }
0524:                }).filterKeep(new Filter() {
0525:                    public boolean accept(Object o) {
0526:                        return ((OntClass) o).isHierarchyRoot();
0527:                    }
0528:                });
0529:            }
0530:
0531:            /**
0532:             * <p>
0533:             * Answer an iterator that ranges over the enumerated class class-descriptions
0534:             * in this model, i&#046;e&#046; the class resources specified to have a property
0535:             * <code>oneOf</code> (or equivalent) and a list of values.
0536:             * </p>
0537:             * <p>
0538:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0539:             * the completeness of the deductive extension of the underlying graph.  See class
0540:             * overview for more details.
0541:             * </p>
0542:             *
0543:             * @return An iterator over enumerated class resources.
0544:             * @see Profile#ONE_OF
0545:             */
0546:            public ExtendedIterator listEnumeratedClasses() {
0547:                checkProfileEntry(getProfile().ONE_OF(), "ONE_OF");
0548:                return UniqueExtendedIterator.create(findByDefiningPropertyAs(
0549:                        getProfile().ONE_OF(), EnumeratedClass.class));
0550:            }
0551:
0552:            /**
0553:             * <p>
0554:             * Answer an iterator that ranges over the union class-descriptions
0555:             * in this model, i&#046;e&#046; the class resources specified to have a property
0556:             * <code>unionOf</code> (or equivalent) and a list of values.
0557:             * </p>
0558:             * <p>
0559:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0560:             * the completeness of the deductive extension of the underlying graph.  See class
0561:             * overview for more details.
0562:             * </p>
0563:             *
0564:             * @return An iterator over union class resources.
0565:             * @see Profile#UNION_OF
0566:             */
0567:            public ExtendedIterator listUnionClasses() {
0568:                checkProfileEntry(getProfile().UNION_OF(), "UNION_OF");
0569:                return UniqueExtendedIterator.create(findByDefiningPropertyAs(
0570:                        getProfile().UNION_OF(), UnionClass.class));
0571:            }
0572:
0573:            /**
0574:             * <p>
0575:             * Answer an iterator that ranges over the complement class-descriptions
0576:             * in this model, i&#046;e&#046; the class resources specified to have a property
0577:             * <code>complementOf</code> (or equivalent) and a list of values.
0578:             * </p>
0579:             * <p>
0580:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0581:             * the completeness of the deductive extension of the underlying graph.  See class
0582:             * overview for more details.
0583:             * </p>
0584:             *
0585:             * @return An iterator over complement class resources.
0586:             * @see Profile#COMPLEMENT_OF
0587:             */
0588:            public ExtendedIterator listComplementClasses() {
0589:                checkProfileEntry(getProfile().COMPLEMENT_OF(), "COMPLEMENT_OF");
0590:                return UniqueExtendedIterator.create(findByDefiningPropertyAs(
0591:                        getProfile().COMPLEMENT_OF(), ComplementClass.class));
0592:            }
0593:
0594:            /**
0595:             * <p>
0596:             * Answer an iterator that ranges over the intersection class-descriptions
0597:             * in this model, i&#046;e&#046; the class resources specified to have a property
0598:             * <code>intersectionOf</code> (or equivalent) and a list of values.
0599:             * </p>
0600:             * <p>
0601:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0602:             * the completeness of the deductive extension of the underlying graph.  See class
0603:             * overview for more details.
0604:             * </p>
0605:             *
0606:             * @return An iterator over complement class resources.
0607:             * @see Profile#INTERSECTION_OF
0608:             */
0609:            public ExtendedIterator listIntersectionClasses() {
0610:                checkProfileEntry(getProfile().INTERSECTION_OF(),
0611:                        "INTERSECTION_OF");
0612:                return UniqueExtendedIterator
0613:                        .create(findByDefiningPropertyAs(getProfile()
0614:                                .INTERSECTION_OF(), IntersectionClass.class));
0615:            }
0616:
0617:            /**
0618:             * <p>
0619:             * Answer an iterator that ranges over the named class-descriptions
0620:             * in this model, i&#046;e&#046; resources with <code>rdf:type
0621:             * Class</code> (or equivalent) and a node URI.
0622:             * </p>
0623:             * <p>
0624:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0625:             * the completeness of the deductive extension of the underlying graph.  See class
0626:             * overview for more details.
0627:             * </p>
0628:             *
0629:             * @return An iterator over named class resources.
0630:             */
0631:            public ExtendedIterator listNamedClasses() {
0632:                return listClasses().filterDrop(new Filter() {
0633:                    public boolean accept(Object x) {
0634:                        return ((Resource) x).isAnon();
0635:                    }
0636:                });
0637:            }
0638:
0639:            /**
0640:             * <p>
0641:             * Answer an iterator that ranges over the property restriction class-descriptions
0642:             * in this model, i&#046;e&#046; resources with <code>rdf:type
0643:             * Restriction</code> (or equivalent).
0644:             * </p>
0645:             * <p>
0646:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0647:             * the completeness of the deductive extension of the underlying graph.  See class
0648:             * overview for more details.
0649:             * </p>
0650:             *
0651:             * @return An iterator over restriction class resources.
0652:             * @see Profile#RESTRICTION
0653:             */
0654:            public ExtendedIterator listRestrictions() {
0655:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
0656:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0657:                        .RESTRICTION(), Restriction.class));
0658:            }
0659:
0660:            /**
0661:             * <p>
0662:             * Answer an iterator that ranges over the nodes that denote pair-wise disjointness between
0663:             * sets of classes.
0664:             * </p>
0665:             * <p>
0666:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0667:             * the completeness of the deductive extension of the underlying graph.  See class
0668:             * overview for more details.
0669:             * </p>
0670:             *
0671:             * @return An iterator over AllDifferent nodes.
0672:             */
0673:            public ExtendedIterator listAllDifferent() {
0674:                checkProfileEntry(getProfile().ALL_DIFFERENT(), "ALL_DIFFERENT");
0675:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0676:                        .ALL_DIFFERENT(), AllDifferent.class));
0677:            }
0678:
0679:            /**
0680:             * <p>Answer an iterator over the DataRange objects in this ontology, if there
0681:             * are any.</p>
0682:             * @return An iterator, whose values are {@link DataRange} objects.
0683:             */
0684:            public ExtendedIterator listDataRanges() {
0685:                checkProfileEntry(getProfile().DATARANGE(), "DATARANGE");
0686:                return UniqueExtendedIterator.create(findByTypeAs(getProfile()
0687:                        .DATARANGE(), DataRange.class));
0688:            }
0689:
0690:            /**
0691:             * <p>
0692:             * Answer an iterator that ranges over the properties in this model that are declared
0693:             * to be annotation properties. Not all supported languages define annotation properties
0694:             * (the category of annotation properties is chiefly an OWL innovation).
0695:             * </p>
0696:             * <p>
0697:             * <strong>Note:</strong> the number of nodes returned by this iterator will vary according to
0698:             * the completeness of the deductive extension of the underlying graph.  See class
0699:             * overview for more details.
0700:             * </p>
0701:             *
0702:             * @return An iterator over annotation properties.
0703:             * @see Profile#getAnnotationProperties()
0704:             */
0705:            public ExtendedIterator listAnnotationProperties() {
0706:                checkProfileEntry(getProfile().ANNOTATION_PROPERTY(),
0707:                        "ANNOTATION_PROPERTY");
0708:                Resource r = getProfile().ANNOTATION_PROPERTY();
0709:
0710:                if (r == null) {
0711:                    return NullIterator.instance;
0712:                } else {
0713:                    return UniqueExtendedIterator.create(findByType(r).andThen(
0714:                            WrappedIterator.create(getProfile()
0715:                                    .getAnnotationProperties())).mapWith(
0716:                            new SubjectNodeAs(AnnotationProperty.class)));
0717:                }
0718:            }
0719:
0720:            /**
0721:             * <p>
0722:             * Answer a resource that represents an ontology description node in this model. If a resource
0723:             * with the given uri exists in the model, and can be viewed as an Ontology, return the
0724:             * Ontology facet, otherwise return null.
0725:             * </p>
0726:             *
0727:             * @param uri The uri for the ontology node. Conventionally, this corresponds to the base URI
0728:             * of the document itself.
0729:             * @return An Ontology resource or null.
0730:             */
0731:            public Ontology getOntology(String uri) {
0732:                return (Ontology) findByURIAs(uri, Ontology.class);
0733:            }
0734:
0735:            /**
0736:             * <p>
0737:             * Answer a resource that represents an Individual node in this model. If a resource
0738:             * with the given uri exists in the model, and can be viewed as an Individual, return the
0739:             * Individual facet, otherwise return null.
0740:             * </p>
0741:             *
0742:             * @param uri The URI for the requried individual
0743:             * @return An Individual resource or null.
0744:             */
0745:            public Individual getIndividual(String uri) {
0746:                return (Individual) findByURIAs(uri, Individual.class);
0747:            }
0748:
0749:            /**
0750:             * <p>
0751:             * Answer a resource representing an generic property in this model. If a property
0752:             * with the given uri exists in the model, return the
0753:             * OntProperty facet, otherwise return null.
0754:             * </p>
0755:             *
0756:             * @param uri The uri for the property.
0757:             * @return An OntProperty resource or null.
0758:             */
0759:            public OntProperty getOntProperty(String uri) {
0760:                return (OntProperty) findByURIAs(uri, OntProperty.class);
0761:            }
0762:
0763:            /**
0764:             * <p>
0765:             * Answer a resource representing an object property in this model. If a resource
0766:             * with the given uri exists in the model, and can be viewed as an ObjectProperty, return the
0767:             * ObjectProperty facet, otherwise return null.
0768:             * </p>
0769:             *
0770:             * @param uri The uri for the object property. May not be null.
0771:             * @return An ObjectProperty resource or null.
0772:             */
0773:            public ObjectProperty getObjectProperty(String uri) {
0774:                return (ObjectProperty) findByURIAs(uri, ObjectProperty.class);
0775:            }
0776:
0777:            /**
0778:             * <p>Answer a resource representing a transitive property. If a resource
0779:             * with the given uri exists in the model, and can be viewed as a TransitiveProperty, return the
0780:             * TransitiveProperty facet, otherwise return null. </p>
0781:             * @param uri The uri for the property. May not be null.
0782:             * @return A TransitiveProperty resource or null
0783:             */
0784:            public TransitiveProperty getTransitiveProperty(String uri) {
0785:                return (TransitiveProperty) findByURIAs(uri,
0786:                        TransitiveProperty.class);
0787:            }
0788:
0789:            /**
0790:             * <p>Answer a resource representing a symmetric property. If a resource
0791:             * with the given uri exists in the model, and can be viewed as a SymmetricProperty, return the
0792:             * SymmetricProperty facet, otherwise return null. </p>
0793:             * @param uri The uri for the property. May not be null.
0794:             * @return A SymmetricProperty resource or null
0795:             */
0796:            public SymmetricProperty getSymmetricProperty(String uri) {
0797:                return (SymmetricProperty) findByURIAs(uri,
0798:                        SymmetricProperty.class);
0799:            }
0800:
0801:            /**
0802:             * <p>Answer a resource representing an inverse functional property. If a resource
0803:             * with the given uri exists in the model, and can be viewed as a InverseFunctionalProperty, return the
0804:             * InverseFunctionalProperty facet, otherwise return null. </p>
0805:             * @param uri The uri for the property. May not be null.
0806:             * @return An InverseFunctionalProperty resource or null
0807:             */
0808:            public InverseFunctionalProperty getInverseFunctionalProperty(
0809:                    String uri) {
0810:                return (InverseFunctionalProperty) findByURIAs(uri,
0811:                        InverseFunctionalProperty.class);
0812:            }
0813:
0814:            /**
0815:             * <p>
0816:             * Answer a resource that represents datatype property in this model. . If a resource
0817:             * with the given uri exists in the model, and can be viewed as a DatatypeProperty, return the
0818:             * DatatypeProperty facet, otherwise return null.
0819:             * </p>
0820:             *
0821:             * @param uri The uri for the datatype property. May not be null.
0822:             * @return A DatatypeProperty resource or null
0823:             */
0824:            public DatatypeProperty getDatatypeProperty(String uri) {
0825:                return (DatatypeProperty) findByURIAs(uri,
0826:                        DatatypeProperty.class);
0827:            }
0828:
0829:            /**
0830:             * <p>
0831:             * Answer a resource that represents an annotation property in this model. If a resource
0832:             * with the given uri exists in the model, and can be viewed as an AnnotationProperty, return the
0833:             * AnnotationProperty facet, otherwise return null.
0834:             * </p>
0835:             *
0836:             * @param uri The uri for the annotation property. May not be null.
0837:             * @return An AnnotationProperty resource or null
0838:             */
0839:            public AnnotationProperty getAnnotationProperty(String uri) {
0840:                return (AnnotationProperty) findByURIAs(uri,
0841:                        AnnotationProperty.class);
0842:            }
0843:
0844:            /**
0845:             * <p>
0846:             * Answer a resource that represents a class description node in this model. If a resource
0847:             * with the given uri exists in the model, and can be viewed as an OntClass, return the
0848:             * OntClass facet, otherwise return null.
0849:             * </p>
0850:             *
0851:             * @param uri The uri for the class node, or null for an anonymous class.
0852:             * @return An OntClass resource or null.
0853:             */
0854:            public OntClass getOntClass(String uri) {
0855:                OntClass c = (OntClass) findByURIAs(uri, OntClass.class);
0856:
0857:                // special case for nothing and thing
0858:                if (c == null) {
0859:                    Resource thing = getProfile().THING();
0860:                    if (thing != null && thing.getURI().equals(uri)) {
0861:                        c = (OntClass) thing.inModel(this ).as(OntClass.class);
0862:                    }
0863:
0864:                    Resource nothing = getProfile().NOTHING();
0865:                    if (nothing != null && nothing.getURI().equals(uri)) {
0866:                        c = (OntClass) nothing.inModel(this ).as(OntClass.class);
0867:                    }
0868:                }
0869:
0870:                return c;
0871:            }
0872:
0873:            /**
0874:             * <p>Answer a resource representing the class that is the complement of another class. If a resource
0875:             * with the given uri exists in the model, and can be viewed as a ComplementClass, return the
0876:             * ComplementClass facet, otherwise return null. </p>
0877:             * @param uri The URI of the new complement class.
0878:             * @return A complement class or null
0879:             */
0880:            public ComplementClass getComplementClass(String uri) {
0881:                return (ComplementClass) findByURIAs(uri, ComplementClass.class);
0882:            }
0883:
0884:            /**
0885:             * <p>Answer a resource representing the class that is the enumeration of a list of individuals. If a resource
0886:             * with the given uri exists in the model, and can be viewed as an EnumeratedClass, return the
0887:             * EnumeratedClass facet, otherwise return null. </p>
0888:             * @param uri The URI of the new enumeration class.
0889:             * @return An enumeration class or null
0890:             */
0891:            public EnumeratedClass getEnumeratedClass(String uri) {
0892:                return (EnumeratedClass) findByURIAs(uri, EnumeratedClass.class);
0893:            }
0894:
0895:            /**
0896:             * <p>Answer a resource representing the class that is the union of a list of class desctiptions. If a resource
0897:             * with the given uri exists in the model, and can be viewed as a UnionClass, return the
0898:             * UnionClass facet, otherwise return null. </p>
0899:             * @param uri The URI of the new union class.
0900:             * @return A union class description or null
0901:             */
0902:            public UnionClass getUnionClass(String uri) {
0903:                return (UnionClass) findByURIAs(uri, UnionClass.class);
0904:            }
0905:
0906:            /**
0907:             * <p>Answer a resource representing the class that is the intersection of a list of class descriptions. If a resource
0908:             * with the given uri exists in the model, and can be viewed as a IntersectionClass, return the
0909:             * IntersectionClass facet, otherwise return null. </p>
0910:             * @param uri The URI of the new intersection class.
0911:             * @return An intersection class description or null
0912:             */
0913:            public IntersectionClass getIntersectionClass(String uri) {
0914:                return (IntersectionClass) findByURIAs(uri,
0915:                        IntersectionClass.class);
0916:            }
0917:
0918:            /**
0919:             * <p>
0920:             * Answer a resource that represents a property restriction in this model. If a resource
0921:             * with the given uri exists in the model, and can be viewed as a Restriction, return the
0922:             * Restriction facet, otherwise return null.
0923:             * </p>
0924:             *
0925:             * @param uri The uri for the restriction node.
0926:             * @return A Restriction resource or null
0927:             */
0928:            public Restriction getRestriction(String uri) {
0929:                return (Restriction) findByURIAs(uri, Restriction.class);
0930:            }
0931:
0932:            /**
0933:             * <p>Answer a class description defined as the class of those individuals that have the given
0934:             * resource as the value of the given property. If a resource
0935:             * with the given uri exists in the model, and can be viewed as a HasValueRestriction, return the
0936:             * HasValueRestriction facet, otherwise return null. </p>
0937:             *
0938:             * @param uri The URI for the restriction
0939:             * @return A resource representing a has-value restriction or null
0940:             */
0941:            public HasValueRestriction getHasValueRestriction(String uri) {
0942:                return (HasValueRestriction) findByURIAs(uri,
0943:                        HasValueRestriction.class);
0944:            }
0945:
0946:            /**
0947:             * <p>Answer a class description defined as the class of those individuals that have at least
0948:             * one property with a value belonging to the given class. If a resource
0949:             * with the given uri exists in the model, and can be viewed as a SomeValuesFromRestriction, return the
0950:             * SomeValuesFromRestriction facet, otherwise return null. </p>
0951:             *
0952:             * @param uri The URI for the restriction
0953:             * @return A resource representing a some-values-from restriction, or null
0954:             */
0955:            public SomeValuesFromRestriction getSomeValuesFromRestriction(
0956:                    String uri) {
0957:                return (SomeValuesFromRestriction) findByURIAs(uri,
0958:                        SomeValuesFromRestriction.class);
0959:            }
0960:
0961:            /**
0962:             * <p>Answer a class description defined as the class of those individuals for which all values
0963:             * of the given property belong to the given class. If a resource
0964:             * with the given uri exists in the model, and can be viewed as an AllValuesFromResriction, return the
0965:             * AllValuesFromRestriction facet, otherwise return null. </p>
0966:             *
0967:             * @param uri The URI for the restriction
0968:             * @return A resource representing an all-values-from restriction or null
0969:             */
0970:            public AllValuesFromRestriction getAllValuesFromRestriction(
0971:                    String uri) {
0972:                return (AllValuesFromRestriction) findByURIAs(uri,
0973:                        AllValuesFromRestriction.class);
0974:            }
0975:
0976:            /**
0977:             * <p>Answer a class description defined as the class of those individuals that have exactly
0978:             * the given number of values for the given property. If a resource
0979:             * with the given uri exists in the model, and can be viewed as a CardinalityRestriction, return the
0980:             * CardinalityRestriction facet, otherwise return null. </p>
0981:             *
0982:             * @param uri The URI for the restriction
0983:             * @return A resource representing a has-value restriction, or null
0984:             */
0985:            public CardinalityRestriction getCardinalityRestriction(String uri) {
0986:                return (CardinalityRestriction) findByURIAs(uri,
0987:                        CardinalityRestriction.class);
0988:            }
0989:
0990:            /**
0991:             * <p>Answer a class description defined as the class of those individuals that have at least
0992:             * the given number of values for the given property. If a resource
0993:             * with the given uri exists in the model, and can be viewed as a MinCardinalityRestriction, return the
0994:             * MinCardinalityRestriction facet, otherwise return null. </p>
0995:             *
0996:             * @param uri The URI for the restriction
0997:             * @return A resource representing a min-cardinality restriction, or null
0998:             */
0999:            public MinCardinalityRestriction getMinCardinalityRestriction(
1000:                    String uri) {
1001:                return (MinCardinalityRestriction) findByURIAs(uri,
1002:                        MinCardinalityRestriction.class);
1003:            }
1004:
1005:            /**
1006:             * <p>Answer a class description defined as the class of those individuals that have at most
1007:             * the given number of values for the given property. If a resource
1008:             * with the given uri exists in the model, and can be viewed as a MaxCardinalityRestriction, return the
1009:             * MaxCardinalityRestriction facet, otherwise return null.</p>
1010:             *
1011:             * @param uri The URI for the restriction
1012:             * @return A resource representing a mas-cardinality restriction, or null
1013:             */
1014:            public MaxCardinalityRestriction getMaxCardinalityRestriction(
1015:                    String uri) {
1016:                return (MaxCardinalityRestriction) findByURIAs(uri,
1017:                        MaxCardinalityRestriction.class);
1018:            }
1019:
1020:            /**
1021:             * <p>Answer a class description defined as the class of those individuals that have a property
1022:             * p, all values of which are members of a given class. Typically used with a cardinality constraint.
1023:             * If a resource
1024:             * with the given uri exists in the model, and can be viewed as a QualifiedRestriction, return the
1025:             * QualifiedRestriction facet, otherwise return null.</p>
1026:             *
1027:             * @param uri The URI for the restriction
1028:             * @return A resource representing a qualified restriction, or null
1029:             */
1030:            public QualifiedRestriction getQualifiedRestriction(String uri) {
1031:                return (QualifiedRestriction) findByURIAs(uri,
1032:                        QualifiedRestriction.class);
1033:            }
1034:
1035:            /**
1036:             * <p>Answer a class description defined as the class of those individuals that have a property
1037:             * p, with cardinality N, all values of which are members of a given class.
1038:             * If a resource
1039:             * with the given uri exists in the model, and can be viewed as a CardinalityQRestriction, return the
1040:             * CardinalityQRestriction facet, otherwise return null.</p>
1041:             *
1042:             * @param uri The URI for the restriction
1043:             * @return A resource representing a qualified cardinality restriction, or null
1044:             */
1045:            public CardinalityQRestriction getCardinalityQRestriction(String uri) {
1046:                return (CardinalityQRestriction) findByURIAs(uri,
1047:                        CardinalityQRestriction.class);
1048:            }
1049:
1050:            /**
1051:             * <p>Answer a class description defined as the class of those individuals that have a property
1052:             * p, with min cardinality N, all values of which are members of a given class.
1053:             * If a resource
1054:             * with the given uri exists in the model, and can be viewed as a MinCardinalityQRestriction, return the
1055:             * MinCardinalityQRestriction facet, otherwise return null.</p>
1056:             *
1057:             * @param uri The URI for the restriction
1058:             * @return A resource representing a qualified min cardinality restriction, or null
1059:             */
1060:            public MinCardinalityQRestriction getMinCardinalityQRestriction(
1061:                    String uri) {
1062:                return (MinCardinalityQRestriction) findByURIAs(uri,
1063:                        MinCardinalityQRestriction.class);
1064:            }
1065:
1066:            /**
1067:             * <p>Answer a class description defined as the class of those individuals that have a property
1068:             * p, with max cardinality N, all values of which are members of a given class.
1069:             * If a resource
1070:             * with the given uri exists in the model, and can be viewed as a MaxCardinalityQRestriction, return the
1071:             * MaxCardinalityQRestriction facet, otherwise return null.</p>
1072:             *
1073:             * @param uri The URI for the restriction
1074:             * @return A resource representing a qualified max cardinality restriction, or null
1075:             */
1076:            public MaxCardinalityQRestriction getMaxCardinalityQRestriction(
1077:                    String uri) {
1078:                return (MaxCardinalityQRestriction) findByURIAs(uri,
1079:                        MaxCardinalityQRestriction.class);
1080:            }
1081:
1082:            /**
1083:             * <p>
1084:             * Answer a resource that represents an ontology description node in this model. If a resource
1085:             * with the given uri exists in the model, it will be re-used.  If not, a new one is created in
1086:             * the updateable sub-graph of the ontology model.
1087:             * </p>
1088:             *
1089:             * @param uri The uri for the ontology node. Conventionally, this corresponds to the base URI
1090:             * of the document itself.
1091:             * @return An Ontology resource.
1092:             */
1093:            public Ontology createOntology(String uri) {
1094:                checkProfileEntry(getProfile().ONTOLOGY(), "ONTOLOGY");
1095:                return (Ontology) createOntResource(Ontology.class,
1096:                        getProfile().ONTOLOGY(), uri);
1097:            }
1098:
1099:            /**
1100:             * <p>
1101:             * Answer a resource that represents an Indvidual node in this model. A new anonymous resource
1102:             * will be created in the updateable sub-graph of the ontology model.
1103:             * </p>
1104:             *
1105:             * @param cls Resource representing the ontology class to which the individual belongs
1106:             * @return A new anoymous Individual of the given class.
1107:             */
1108:            public Individual createIndividual(Resource cls) {
1109:                return (Individual) createOntResource(Individual.class, cls,
1110:                        null);
1111:            }
1112:
1113:            /**
1114:             * <p>
1115:             * Answer a resource that represents an Individual node in this model. If a resource
1116:             * with the given uri exists in the model, it will be re-used.  If not, a new one is created in
1117:             * the updateable sub-graph of the ontology model.
1118:             * </p>
1119:             *
1120:             * @param cls Resource representing the ontology class to which the individual belongs
1121:             * @param uri The uri for the individual, or null for an anonymous individual.
1122:             * @return An Individual resource.
1123:             */
1124:            public Individual createIndividual(String uri, Resource cls) {
1125:                return (Individual) createOntResource(Individual.class, cls,
1126:                        uri);
1127:            }
1128:
1129:            /**
1130:             * <p>
1131:             * Answer a resource representing an generic property in this model.  Effectively
1132:             * this method is an alias for {@link #createProperty( String )}, except that
1133:             * the return type is {@link OntProperty}, which allow more convenient access to
1134:             * a property's position in the property hierarchy, domain, range, etc.
1135:             * </p>
1136:             *
1137:             * @param uri The uri for the property. May not be null.
1138:             * @return An OntProperty resource.
1139:             */
1140:            public OntProperty createOntProperty(String uri) {
1141:                Property p = createProperty(uri);
1142:                p.addProperty(RDF.type, getProfile().PROPERTY());
1143:                return (OntProperty) p.as(OntProperty.class);
1144:            }
1145:
1146:            /**
1147:             * <p>
1148:             * Answer a resource representing an object property in this model,
1149:             * and that is not a functional property.
1150:             * </p>
1151:             *
1152:             * @param uri The uri for the object property. May not be null.
1153:             * @return An ObjectProperty resource.
1154:             * @see #createObjectProperty( String, boolean )
1155:             */
1156:            public ObjectProperty createObjectProperty(String uri) {
1157:                return createObjectProperty(uri, false);
1158:            }
1159:
1160:            /**
1161:             * <p>
1162:             * Answer a resource that represents an object property in this model.  An object property
1163:             * is defined to have a range of individuals, rather than datatypes.
1164:             * If a resource
1165:             * with the given uri exists in the model, it will be re-used.  If not, a new one is created in
1166:             * the updateable sub-graph of the ontology model.
1167:             * </p>
1168:             *
1169:             * @param uri The uri for the object property. May not be null.
1170:             * @param functional If true, the resource will also be typed as a {@link FunctionalProperty},
1171:             * that is, a property that has a unique range value for any given domain value.
1172:             * @return An ObjectProperty resource, optionally also functional.
1173:             */
1174:            public ObjectProperty createObjectProperty(String uri,
1175:                    boolean functional) {
1176:                checkProfileEntry(getProfile().OBJECT_PROPERTY(),
1177:                        "OBJECT_PROPERTY");
1178:                ObjectProperty p = (ObjectProperty) createOntResource(
1179:                        ObjectProperty.class, getProfile().OBJECT_PROPERTY(),
1180:                        uri);
1181:
1182:                if (functional) {
1183:                    checkProfileEntry(getProfile().FUNCTIONAL_PROPERTY(),
1184:                            "FUNCTIONAL_PROPERTY");
1185:                    p.addProperty(RDF.type, getProfile().FUNCTIONAL_PROPERTY());
1186:                }
1187:
1188:                return p;
1189:            }
1190:
1191:            /**
1192:             * <p>Answer a resource representing a transitive property</p>
1193:             * @param uri The uri for the property. May not be null.
1194:             * @return An TransitiveProperty resource
1195:             * @see #createTransitiveProperty( String, boolean )
1196:             */
1197:            public TransitiveProperty createTransitiveProperty(String uri) {
1198:                return createTransitiveProperty(uri, false);
1199:            }
1200:
1201:            /**
1202:             * <p>Answer a resource representing a transitive property, which is optionally
1203:             * also functional. <strong>Note:</strong> although it is permitted in OWL full
1204:             * to have functional transitive properties, it makes the language undecideable.
1205:             * Functional transitive properties are not permitted in OWL Lite or OWL DL.</p>
1206:             * @param uri The uri for the property. May not be null.
1207:             * @param functional If true, the property is also functional
1208:             * @return An TransitiveProperty resource, optionally also functional.
1209:             */
1210:            public TransitiveProperty createTransitiveProperty(String uri,
1211:                    boolean functional) {
1212:                checkProfileEntry(getProfile().TRANSITIVE_PROPERTY(),
1213:                        "TRANSITIVE_PROPERTY");
1214:                TransitiveProperty p = (TransitiveProperty) createOntResource(
1215:                        TransitiveProperty.class, getProfile()
1216:                                .TRANSITIVE_PROPERTY(), uri);
1217:
1218:                if (functional) {
1219:                    checkProfileEntry(getProfile().FUNCTIONAL_PROPERTY(),
1220:                            "FUNCTIONAL_PROPERTY");
1221:                    p.addProperty(RDF.type, getProfile().FUNCTIONAL_PROPERTY());
1222:                }
1223:
1224:                return p;
1225:            }
1226:
1227:            /**
1228:             * <p>Answer a resource representing a symmetric property</p>
1229:             * @param uri The uri for the property. May not be null.
1230:             * @return An SymmetricProperty resource
1231:             * @see #createSymmetricProperty( String, boolean )
1232:             */
1233:            public SymmetricProperty createSymmetricProperty(String uri) {
1234:                return createSymmetricProperty(uri, false);
1235:            }
1236:
1237:            /**
1238:             * <p>Answer a resource representing a symmetric property, which is optionally
1239:             * also functional.</p>
1240:             * @param uri The uri for the property. May not be null.
1241:             * @param functional If true, the property is also functional
1242:             * @return An SymmetricProperty resource, optionally also functional.
1243:             */
1244:            public SymmetricProperty createSymmetricProperty(String uri,
1245:                    boolean functional) {
1246:                checkProfileEntry(getProfile().SYMMETRIC_PROPERTY(),
1247:                        "SYMMETRIC_PROPERTY");
1248:                SymmetricProperty p = (SymmetricProperty) createOntResource(
1249:                        SymmetricProperty.class, getProfile()
1250:                                .SYMMETRIC_PROPERTY(), uri);
1251:
1252:                if (functional) {
1253:                    checkProfileEntry(getProfile().FUNCTIONAL_PROPERTY(),
1254:                            "FUNCTIONAL_PROPERTY");
1255:                    p.addProperty(RDF.type, getProfile().FUNCTIONAL_PROPERTY());
1256:                }
1257:
1258:                return p;
1259:            }
1260:
1261:            /**
1262:             * <p>Answer a resource representing an inverse functional property</p>
1263:             * @param uri The uri for the property. May not be null.
1264:             * @return An InverseFunctionalProperty resource
1265:             * @see #createInverseFunctionalProperty( String, boolean )
1266:             */
1267:            public InverseFunctionalProperty createInverseFunctionalProperty(
1268:                    String uri) {
1269:                return createInverseFunctionalProperty(uri, false);
1270:            }
1271:
1272:            /**
1273:             * <p>Answer a resource representing an inverse functional property, which is optionally
1274:             * also functional.</p>
1275:             * @param uri The uri for the property. May not be null.
1276:             * @param functional If true, the property is also functional
1277:             * @return An InverseFunctionalProperty resource, optionally also functional.
1278:             */
1279:            public InverseFunctionalProperty createInverseFunctionalProperty(
1280:                    String uri, boolean functional) {
1281:                checkProfileEntry(getProfile().INVERSE_FUNCTIONAL_PROPERTY(),
1282:                        "INVERSE_FUNCTIONAL_PROPERTY");
1283:                InverseFunctionalProperty p = (InverseFunctionalProperty) createOntResource(
1284:                        InverseFunctionalProperty.class, getProfile()
1285:                                .INVERSE_FUNCTIONAL_PROPERTY(), uri);
1286:
1287:                if (functional) {
1288:                    checkProfileEntry(getProfile().FUNCTIONAL_PROPERTY(),
1289:                            "FUNCTIONAL_PROPERTY");
1290:                    p.addProperty(RDF.type, getProfile().FUNCTIONAL_PROPERTY());
1291:                }
1292:
1293:                return p;
1294:            }
1295:
1296:            /**
1297:             * <p>
1298:             * Answer a resource that represents datatype property in this model, and that is
1299:             * not a functional property.
1300:             * </p>
1301:             *
1302:             * @param uri The uri for the datatype property. May not be null.
1303:             * @return A DatatypeProperty resource.
1304:             * @see #createDatatypeProperty( String, boolean )
1305:             */
1306:            public DatatypeProperty createDatatypeProperty(String uri) {
1307:                return createDatatypeProperty(uri, false);
1308:            }
1309:
1310:            /**
1311:             * <p>
1312:             * Answer a resource that represents datatype property in this model. A datatype property
1313:             * is defined to have a range that is a concrete datatype, rather than an individual.
1314:             * If a resource
1315:             * with the given uri exists in the model, it will be re-used.  If not, a new one is created in
1316:             * the updateable sub-graph of the ontology model.
1317:             * </p>
1318:             *
1319:             * @param uri The uri for the datatype property. May not be null.
1320:             * @param functional If true, the resource will also be typed as a {@link FunctionalProperty},
1321:             * that is, a property that has a unique range value for any given domain value.
1322:             * @return A DatatypeProperty resource.
1323:             */
1324:            public DatatypeProperty createDatatypeProperty(String uri,
1325:                    boolean functional) {
1326:                checkProfileEntry(getProfile().DATATYPE_PROPERTY(),
1327:                        "DATATYPE_PROPERTY");
1328:                DatatypeProperty p = (DatatypeProperty) createOntResource(
1329:                        DatatypeProperty.class, getProfile()
1330:                                .DATATYPE_PROPERTY(), uri);
1331:
1332:                if (functional) {
1333:                    checkProfileEntry(getProfile().FUNCTIONAL_PROPERTY(),
1334:                            "FUNCTIONAL_PROPERTY");
1335:                    p.addProperty(RDF.type, getProfile().FUNCTIONAL_PROPERTY());
1336:                }
1337:
1338:                return p;
1339:            }
1340:
1341:            /**
1342:             * <p>
1343:             * Answer a resource that represents an annotation property in this model. If a resource
1344:             * with the given uri exists in the model, it will be re-used.  If not, a new one is created in
1345:             * the updateable sub-graph of the ontology model.
1346:             * </p>
1347:             *
1348:             * @param uri The uri for the annotation property.
1349:             * @return An AnnotationProperty resource.
1350:             */
1351:            public AnnotationProperty createAnnotationProperty(String uri) {
1352:                checkProfileEntry(getProfile().ANNOTATION_PROPERTY(),
1353:                        "ANNOTATION_PROPERTY");
1354:                return (AnnotationProperty) createOntResource(
1355:                        AnnotationProperty.class, getProfile()
1356:                                .ANNOTATION_PROPERTY(), uri);
1357:            }
1358:
1359:            /**
1360:             * <p>
1361:             * Answer a resource that represents an anonymous class description in this model. A new
1362:             * anonymous resource of <code>rdf:type C</code>, where C is the class type from the
1363:             * language profile.
1364:             * </p>
1365:             *
1366:             * @return An anonymous Class resource.
1367:             */
1368:            public OntClass createClass() {
1369:                checkProfileEntry(getProfile().CLASS(), "CLASS");
1370:                return (OntClass) createOntResource(OntClass.class,
1371:                        getProfile().CLASS(), null);
1372:            }
1373:
1374:            /**
1375:             * <p>
1376:             * Answer a resource that represents a class description node in this model. If a resource
1377:             * with the given uri exists in the model, it will be re-used.  If not, a new one is created in
1378:             * the updateable sub-graph of the ontology model.
1379:             * </p>
1380:             *
1381:             * @param uri The uri for the class node, or null for an anonymous class.
1382:             * @return A Class resource.
1383:             */
1384:            public OntClass createClass(String uri) {
1385:                checkProfileEntry(getProfile().CLASS(), "CLASS");
1386:                return (OntClass) createOntResource(OntClass.class,
1387:                        getProfile().CLASS(), uri);
1388:            }
1389:
1390:            /**
1391:             * <p>Answer a resource representing the class that is the complement of the given argument class</p>
1392:             * @param uri The URI of the new complement class, or null for an anonymous class description.
1393:             * @param cls Resource denoting the class that the new class is a complement of
1394:             * @return A complement class
1395:             */
1396:            public ComplementClass createComplementClass(String uri,
1397:                    Resource cls) {
1398:                checkProfileEntry(getProfile().CLASS(), "CLASS");
1399:                OntClass c = (OntClass) createOntResource(OntClass.class,
1400:                        getProfile().CLASS(), uri);
1401:
1402:                checkProfileEntry(getProfile().COMPLEMENT_OF(), "COMPLEMENT_OF");
1403:                // if the class that this class is a complement of is not specified, use owl:nothing or daml:nothing
1404:                c.addProperty(getProfile().COMPLEMENT_OF(),
1405:                        (cls == null) ? getProfile().NOTHING() : cls);
1406:
1407:                return (ComplementClass) c.as(ComplementClass.class);
1408:            }
1409:
1410:            /**
1411:             * <p>Answer a resource representing the class that is the enumeration of the given list of individuals</p>
1412:             * @param uri The URI of the new enumeration class, or null for an anonymous class description.
1413:             * @param members An optional list of resources denoting the individuals in the enumeration
1414:             * @return An enumeration class
1415:             */
1416:            public EnumeratedClass createEnumeratedClass(String uri,
1417:                    RDFList members) {
1418:                checkProfileEntry(getProfile().CLASS(), "CLASS");
1419:                OntClass c = (OntClass) createOntResource(OntClass.class,
1420:                        getProfile().CLASS(), uri);
1421:
1422:                checkProfileEntry(getProfile().ONE_OF(), "ONE_OF");
1423:                c.addProperty(getProfile().ONE_OF(),
1424:                        (members == null) ? createList() : members);
1425:
1426:                return (EnumeratedClass) c.as(EnumeratedClass.class);
1427:            }
1428:
1429:            /**
1430:             * <p>Answer a resource representing the class that is the union of the given list of class desctiptions</p>
1431:             * @param uri The URI of the new union class, or null for an anonymous class description.
1432:             * @param members A list of resources denoting the classes that comprise the union
1433:             * @return A union class description
1434:             */
1435:            public UnionClass createUnionClass(String uri, RDFList members) {
1436:                checkProfileEntry(getProfile().CLASS(), "CLASS");
1437:                OntClass c = (OntClass) createOntResource(OntClass.class,
1438:                        getProfile().CLASS(), uri);
1439:
1440:                checkProfileEntry(getProfile().UNION_OF(), "UNION_OF");
1441:                c.addProperty(getProfile().UNION_OF(),
1442:                        (members == null) ? createList() : members);
1443:
1444:                return (UnionClass) c.as(UnionClass.class);
1445:            }
1446:
1447:            /**
1448:             * <p>Answer a resource representing the class that is the intersection of the given list of class descriptions.</p>
1449:             * @param uri The URI of the new intersection class, or null for an anonymous class description.
1450:             * @param members A list of resources denoting the classes that comprise the intersection
1451:             * @return An intersection class description
1452:             */
1453:            public IntersectionClass createIntersectionClass(String uri,
1454:                    RDFList members) {
1455:                checkProfileEntry(getProfile().CLASS(), "CLASS");
1456:                OntClass c = (OntClass) createOntResource(OntClass.class,
1457:                        getProfile().CLASS(), uri);
1458:
1459:                checkProfileEntry(getProfile().INTERSECTION_OF(),
1460:                        "INTERSECTION_OF");
1461:                c.addProperty(getProfile().INTERSECTION_OF(),
1462:                        (members == null) ? createList() : members);
1463:
1464:                return (IntersectionClass) c.as(IntersectionClass.class);
1465:            }
1466:
1467:            /**
1468:             * <p>
1469:             * Answer a resource that represents an anonymous property restriction in this model. A new
1470:             * anonymous resource of <code>rdf:type R</code>, where R is the restriction type from the
1471:             * language profile.
1472:             * </p>
1473:             *
1474:             * @param p The property that is restricted by this restriction
1475:             * @return An anonymous Restriction resource.
1476:             */
1477:            public Restriction createRestriction(Property p) {
1478:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1479:                Restriction r = (Restriction) createOntResource(
1480:                        Restriction.class, getProfile().RESTRICTION(), null);
1481:                if (p != null) {
1482:                    r.setOnProperty(p);
1483:                }
1484:
1485:                return r;
1486:            }
1487:
1488:            /**
1489:             * <p>
1490:             * Answer a resource that represents a property restriction in this model. If a resource
1491:             * with the given uri exists in the model, it will be re-used.  If not, a new one is created in
1492:             * the updateable sub-graph of the ontology model.
1493:             * </p>
1494:             *
1495:             * @param uri The uri for the restriction node, or null for an anonymous restriction.
1496:             * @param p The property that is restricted by this restriction
1497:             * @return A Restriction resource.
1498:             */
1499:            public Restriction createRestriction(String uri, Property p) {
1500:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1501:                Restriction r = (Restriction) createOntResource(
1502:                        Restriction.class, getProfile().RESTRICTION(), uri);
1503:                if (p != null) {
1504:                    r.setOnProperty(p);
1505:                }
1506:
1507:                return r;
1508:            }
1509:
1510:            /**
1511:             * <p>Answer a class description defined as the class of those individuals that have the given
1512:             * resource as the value of the given property</p>
1513:             *
1514:             * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1515:             * should be the normal case)
1516:             * @param prop The property the restriction applies to
1517:             * @param value The value of the property, as a resource or RDF literal
1518:             * @return A new resource representing a has-value restriction
1519:             */
1520:            public HasValueRestriction createHasValueRestriction(String uri,
1521:                    Property prop, RDFNode value) {
1522:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1523:                Restriction r = (Restriction) createOntResource(
1524:                        Restriction.class, getProfile().RESTRICTION(), uri);
1525:
1526:                if (prop == null || value == null) {
1527:                    throw new IllegalArgumentException(
1528:                            "Cannot create hasValueRestriction with a null property or value");
1529:                }
1530:
1531:                checkProfileEntry(getProfile().HAS_VALUE(), "HAS_VALUE");
1532:                r.addProperty(getProfile().ON_PROPERTY(), prop);
1533:                r.addProperty(getProfile().HAS_VALUE(), value);
1534:
1535:                return (HasValueRestriction) r.as(HasValueRestriction.class);
1536:            }
1537:
1538:            /**
1539:             * <p>Answer a class description defined as the class of those individuals that have at least
1540:             * one property with a value belonging to the given class</p>
1541:             *
1542:             * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1543:             * should be the normal case)
1544:             * @param prop The property the restriction applies to
1545:             * @param cls The class to which at least one value of the property belongs
1546:             * @return A new resource representing a some-values-from restriction
1547:             */
1548:            public SomeValuesFromRestriction createSomeValuesFromRestriction(
1549:                    String uri, Property prop, Resource cls) {
1550:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1551:                Restriction r = (Restriction) createOntResource(
1552:                        Restriction.class, getProfile().RESTRICTION(), uri);
1553:
1554:                if (prop == null || cls == null) {
1555:                    throw new IllegalArgumentException(
1556:                            "Cannot create someValuesFromRestriction with a null property or class");
1557:                }
1558:
1559:                checkProfileEntry(getProfile().SOME_VALUES_FROM(),
1560:                        "SOME_VALUES_FROM");
1561:                r.addProperty(getProfile().ON_PROPERTY(), prop);
1562:                r.addProperty(getProfile().SOME_VALUES_FROM(), cls);
1563:
1564:                return (SomeValuesFromRestriction) r
1565:                        .as(SomeValuesFromRestriction.class);
1566:            }
1567:
1568:            /**
1569:             * <p>Answer a class description defined as the class of those individuals for which all values
1570:             * of the given property belong to the given class</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 cls The class to which any value of the property belongs
1576:             * @return A new resource representing an all-values-from restriction
1577:             */
1578:            public AllValuesFromRestriction createAllValuesFromRestriction(
1579:                    String uri, Property prop, Resource cls) {
1580:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1581:                Restriction r = (Restriction) createOntResource(
1582:                        Restriction.class, getProfile().RESTRICTION(), uri);
1583:
1584:                if (prop == null || cls == null) {
1585:                    throw new IllegalArgumentException(
1586:                            "Cannot create allValuesFromRestriction with a null property or class");
1587:                }
1588:
1589:                checkProfileEntry(getProfile().ALL_VALUES_FROM(),
1590:                        "ALL_VALUES_FROM");
1591:                r.addProperty(getProfile().ON_PROPERTY(), prop);
1592:                r.addProperty(getProfile().ALL_VALUES_FROM(), cls);
1593:
1594:                return (AllValuesFromRestriction) r
1595:                        .as(AllValuesFromRestriction.class);
1596:            }
1597:
1598:            /**
1599:             * <p>Answer a class description defined as the class of those individuals that have exactly
1600:             * the given number of values for the given property.</p>
1601:             *
1602:             * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1603:             * should be the normal case)
1604:             * @param prop The property the restriction applies to
1605:             * @param cardinality The exact cardinality of the property
1606:             * @return A new resource representing a has-value restriction
1607:             */
1608:            public CardinalityRestriction createCardinalityRestriction(
1609:                    String uri, Property prop, int cardinality) {
1610:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1611:                Restriction r = (Restriction) createOntResource(
1612:                        Restriction.class, getProfile().RESTRICTION(), uri);
1613:
1614:                if (prop == null) {
1615:                    throw new IllegalArgumentException(
1616:                            "Cannot create cardinalityRestriction with a null property");
1617:                }
1618:
1619:                checkProfileEntry(getProfile().CARDINALITY(), "CARDINALITY");
1620:                r.addProperty(getProfile().ON_PROPERTY(), prop);
1621:                r.addProperty(getProfile().CARDINALITY(),
1622:                        createTypedLiteral(cardinality));
1623:
1624:                return (CardinalityRestriction) r
1625:                        .as(CardinalityRestriction.class);
1626:            }
1627:
1628:            /**
1629:             * <p>Answer a class description defined as the class of those individuals that have at least
1630:             * the given number of values for the given property.</p>
1631:             *
1632:             * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1633:             * should be the normal case)
1634:             * @param prop The property the restriction applies to
1635:             * @param cardinality The minimum cardinality of the property
1636:             * @return A new resource representing a min-cardinality restriction
1637:             */
1638:            public MinCardinalityRestriction createMinCardinalityRestriction(
1639:                    String uri, Property prop, int cardinality) {
1640:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1641:                Restriction r = (Restriction) createOntResource(
1642:                        Restriction.class, getProfile().RESTRICTION(), uri);
1643:
1644:                if (prop == null) {
1645:                    throw new IllegalArgumentException(
1646:                            "Cannot create minCardinalityRestriction with a null property");
1647:                }
1648:
1649:                checkProfileEntry(getProfile().MIN_CARDINALITY(),
1650:                        "MIN_CARDINALITY");
1651:                r.addProperty(getProfile().ON_PROPERTY(), prop);
1652:                r.addProperty(getProfile().MIN_CARDINALITY(),
1653:                        createTypedLiteral(cardinality));
1654:
1655:                return (MinCardinalityRestriction) r
1656:                        .as(MinCardinalityRestriction.class);
1657:            }
1658:
1659:            /**
1660:             * <p>Answer a class description defined as the class of those individuals that have at most
1661:             * the given number of values for the given property.</p>
1662:             *
1663:             * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1664:             * should be the normal case)
1665:             * @param prop The property the restriction applies to
1666:             * @param cardinality The maximum cardinality of the property
1667:             * @return A new resource representing a mas-cardinality restriction
1668:             */
1669:            public MaxCardinalityRestriction createMaxCardinalityRestriction(
1670:                    String uri, Property prop, int cardinality) {
1671:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1672:                Restriction r = (Restriction) createOntResource(
1673:                        Restriction.class, getProfile().RESTRICTION(), uri);
1674:
1675:                if (prop == null) {
1676:                    throw new IllegalArgumentException(
1677:                            "Cannot create maxCardinalityRestriction with a null property");
1678:                }
1679:
1680:                checkProfileEntry(getProfile().MAX_CARDINALITY(),
1681:                        "MAX_CARDINALITY");
1682:                r.addProperty(getProfile().ON_PROPERTY(), prop);
1683:                r.addProperty(getProfile().MAX_CARDINALITY(),
1684:                        createTypedLiteral(cardinality));
1685:
1686:                return (MaxCardinalityRestriction) r
1687:                        .as(MaxCardinalityRestriction.class);
1688:            }
1689:
1690:            /**
1691:             * <p>Answer a class description defined as the class of those individuals that have at most
1692:             * the given number of values for the given property, all values of which belong to the given
1693:             * class.</p>
1694:             *
1695:             * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1696:             * should be the normal case)
1697:             * @param prop The property the restriction applies to
1698:             * @param cardinality The maximum cardinality of the property
1699:             * @param cls The class to which all values of the restricted property should belong
1700:             * @return A new resource representing a mas-cardinality restriction
1701:             */
1702:            public MaxCardinalityQRestriction createMaxCardinalityQRestriction(
1703:                    String uri, Property prop, int cardinality, OntClass cls) {
1704:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1705:                checkProfileEntry(getProfile().ON_PROPERTY(), "ON_PROPERTY");
1706:                checkProfileEntry(getProfile().MAX_CARDINALITY_Q(),
1707:                        "MAX_CARDINALITY_Q");
1708:                checkProfileEntry(getProfile().HAS_CLASS_Q(), "HAS_CLASS_Q");
1709:
1710:                if (prop == null) {
1711:                    throw new IllegalArgumentException(
1712:                            "Cannot create MaxCardinalityQRestriction with a null property");
1713:                }
1714:                if (cls == null) {
1715:                    throw new IllegalArgumentException(
1716:                            "Cannot create MaxCardinalityQRestriction with a null class");
1717:                }
1718:
1719:                Restriction r = (Restriction) createOntResource(
1720:                        Restriction.class, getProfile().RESTRICTION(), uri);
1721:
1722:                r.addProperty(getProfile().ON_PROPERTY(), prop);
1723:                r.addProperty(getProfile().MAX_CARDINALITY_Q(),
1724:                        createTypedLiteral(cardinality));
1725:                r.addProperty(getProfile().HAS_CLASS_Q(), cls);
1726:
1727:                return (MaxCardinalityQRestriction) r
1728:                        .as(MaxCardinalityQRestriction.class);
1729:            }
1730:
1731:            /**
1732:             * <p>Answer a class description defined as the class of those individuals that have at least
1733:             * the given number of values for the given property, all values of which belong to the given
1734:             * class.</p>
1735:             *
1736:             * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1737:             * should be the normal case)
1738:             * @param prop The property the restriction applies to
1739:             * @param cardinality The minimun cardinality of the property
1740:             * @param cls The class to which all values of the restricted property should belong
1741:             * @return A new resource representing a mas-cardinality restriction
1742:             */
1743:            public MinCardinalityQRestriction createMinCardinalityQRestriction(
1744:                    String uri, Property prop, int cardinality, OntClass cls) {
1745:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1746:                checkProfileEntry(getProfile().ON_PROPERTY(), "ON_PROPERTY");
1747:                checkProfileEntry(getProfile().MIN_CARDINALITY_Q(),
1748:                        "MIN_CARDINALITY_Q");
1749:                checkProfileEntry(getProfile().HAS_CLASS_Q(), "HAS_CLASS_Q");
1750:
1751:                if (prop == null) {
1752:                    throw new IllegalArgumentException(
1753:                            "Cannot create MinCardinalityQRestriction with a null property");
1754:                }
1755:                if (cls == null) {
1756:                    throw new IllegalArgumentException(
1757:                            "Cannot create MinCardinalityQRestriction with a null class");
1758:                }
1759:
1760:                Restriction r = (Restriction) createOntResource(
1761:                        Restriction.class, getProfile().RESTRICTION(), uri);
1762:
1763:                r.addProperty(getProfile().ON_PROPERTY(), prop);
1764:                r.addProperty(getProfile().MIN_CARDINALITY_Q(),
1765:                        createTypedLiteral(cardinality));
1766:                r.addProperty(getProfile().HAS_CLASS_Q(), cls);
1767:
1768:                return (MinCardinalityQRestriction) r
1769:                        .as(MinCardinalityQRestriction.class);
1770:            }
1771:
1772:            /**
1773:             * <p>Answer a class description defined as the class of those individuals that have exactly
1774:             * the given number of values for the given property, all values of which belong to the given
1775:             * class.</p>
1776:             *
1777:             * @param uri The optional URI for the restriction, or null for an anonymous restriction (which
1778:             * should be the normal case)
1779:             * @param prop The property the restriction applies to
1780:             * @param cardinality The cardinality of the property
1781:             * @param cls The class to which all values of the restricted property should belong
1782:             * @return A new resource representing a mas-cardinality restriction
1783:             */
1784:            public CardinalityQRestriction createCardinalityQRestriction(
1785:                    String uri, Property prop, int cardinality, OntClass cls) {
1786:                checkProfileEntry(getProfile().RESTRICTION(), "RESTRICTION");
1787:                checkProfileEntry(getProfile().ON_PROPERTY(), "ON_PROPERTY");
1788:                checkProfileEntry(getProfile().CARDINALITY_Q(), "CARDINALITY_Q");
1789:                checkProfileEntry(getProfile().HAS_CLASS_Q(), "HAS_CLASS_Q");
1790:
1791:                if (prop == null) {
1792:                    throw new IllegalArgumentException(
1793:                            "Cannot create CardinalityQRestriction with a null property");
1794:                }
1795:                if (cls == null) {
1796:                    throw new IllegalArgumentException(
1797:                            "Cannot create CardinalityQRestriction with a null class");
1798:                }
1799:
1800:                Restriction r = (Restriction) createOntResource(
1801:                        Restriction.class, getProfile().RESTRICTION(), uri);
1802:
1803:                r.addProperty(getProfile().ON_PROPERTY(), prop);
1804:                r.addProperty(getProfile().CARDINALITY_Q(),
1805:                        createTypedLiteral(cardinality));
1806:                r.addProperty(getProfile().HAS_CLASS_Q(), cls);
1807:
1808:                return (CardinalityQRestriction) r
1809:                        .as(CardinalityQRestriction.class);
1810:            }
1811:
1812:            /**
1813:             * <p>Answer a data range defined as the given set of concrete data values.  DataRange resources
1814:             * are necessarily bNodes.</p>
1815:             *
1816:             * @param literals An iterator over a set of literals that will be the members of the data range,
1817:             *                 or null to define an empty data range
1818:             * @return A new data range containing the given literals as permissible values
1819:             */
1820:            public DataRange createDataRange(RDFList literals) {
1821:                checkProfileEntry(getProfile().DATARANGE(), "DATARANGE");
1822:                DataRange d = (DataRange) createOntResource(DataRange.class,
1823:                        getProfile().DATARANGE(), null);
1824:
1825:                checkProfileEntry(getProfile().ONE_OF(), "ONE_OF");
1826:                d.addProperty(getProfile().ONE_OF(),
1827:                        (literals == null) ? createList() : literals);
1828:
1829:                return d;
1830:            }
1831:
1832:            /**
1833:             * <p>
1834:             * Answer a new, anonymous node representing the fact that a given set of classes are all
1835:             * pair-wise distinct.  <code>AllDifferent</code> is a feature of OWL only, and is something
1836:             * of an anomoly in that it exists only to give a place to anchor the <code>distinctMembers</code>
1837:             * property, which is the actual expression of the fact.
1838:             * </p>
1839:             *
1840:             * @return A new AllDifferent resource
1841:             */
1842:            public AllDifferent createAllDifferent() {
1843:                return createAllDifferent(null);
1844:            }
1845:
1846:            /**
1847:             * <p>
1848:             * Answer a new, anonymous node representing the fact that a given set of classes are all
1849:             * pair-wise distinct.  <code>AllDifferent</code> is a feature of OWL only, and is something
1850:             * of an anomoly in that it exists only to give a place to anchor the <code>distinctMembers</code>
1851:             * property, which is the actual expression of the fact.
1852:             * </p>
1853:             * @param differentMembers A list of the class expressions that denote a set of mutually disjoint classes
1854:             * @return A new AllDifferent resource
1855:             */
1856:            public AllDifferent createAllDifferent(RDFList differentMembers) {
1857:                checkProfileEntry(getProfile().ALL_DIFFERENT(), "ALL_DIFFERENT");
1858:                AllDifferent ad = (AllDifferent) createOntResource(
1859:                        AllDifferent.class, getProfile().ALL_DIFFERENT(), null);
1860:
1861:                ad.setDistinctMembers((differentMembers == null) ? createList()
1862:                        : differentMembers);
1863:
1864:                return ad;
1865:            }
1866:
1867:            /**
1868:             * <p>
1869:             * Answer a resource that represents a generic ontology node in this model. If a resource
1870:             * with the given uri exists in the model, it will be re-used.  If not, a new one is created in
1871:             * the updateable sub-graph of the ontology model.
1872:             * </p>
1873:             * <p>
1874:             * This is a generic method for creating any known ontology value.  The selector that determines
1875:             * which resource to create is the same as as the argument to the {@link RDFNode#as as()}
1876:             * method: the Java class object of the desired abstraction.  For example, to create an
1877:             * ontology class via this mechanism, use:
1878:             * <code><pre>
1879:             *     OntClass c = (OntClass) myModel.createOntResource( OntClass.class, null,
1880:             *                                                        "http://example.org/ex#Parrot" );
1881:             * </pre></code>
1882:             * </p>
1883:             *
1884:             * @param javaClass The Java class object that represents the ontology abstraction to create
1885:             * @param rdfType Optional resource denoting the ontology class to which an individual or
1886:             * axiom belongs, if that is the type of resource being created.
1887:             * @param uri The uri for the ontology resource, or null for an anonymous resource.
1888:             * @return An ontology resource, of the type specified by the <code>javaClass</code>
1889:             */
1890:            public OntResource createOntResource(Class javaClass,
1891:                    Resource rdfType, String uri) {
1892:                return (OntResource) getResourceWithType(uri, rdfType).as(
1893:                        javaClass);
1894:            }
1895:
1896:            /**
1897:             * <p>Answer a resource presenting the {@link OntResource} facet, which has the
1898:             * given URI.</p>
1899:             * @param uri The URI of the resource, or null for an anonymous resource (aka bNode)
1900:             * @return An OntResource with the given URI
1901:             */
1902:            public OntResource createOntResource(String uri) {
1903:                return (OntResource) getResource(uri).as(OntResource.class);
1904:            }
1905:
1906:            /**
1907:             * <p>Answer a new empty list.  This method overrides the list create method in ModelCom,
1908:             * to allow both DAML and RDFS lists to be created.</p>
1909:             * @return An RDF-encoded list of no elements, using the current language profile
1910:             */
1911:            public RDFList createList() {
1912:                Resource list = getResource(getProfile().NIL().getURI());
1913:
1914:                return (RDFList) list.as(RDFList.class);
1915:            }
1916:
1917:            /**
1918:             * <p>
1919:             * Answer the language profile (for example, OWL or DAML+OIL) that this model is
1920:             * working to.
1921:             * </p>
1922:             *
1923:             * @return A language profile
1924:             */
1925:            public Profile getProfile() {
1926:                return m_spec.getProfile();
1927:            }
1928:
1929:            /**
1930:             * <p>Determine which models this model imports (by looking for, for example,
1931:             * <code>owl:imports</code> statements, and load each of those models as an
1932:             * import. A check is made to determine if a model has already been imported,
1933:             * if so, the import is ignored. Thus this method is safe against circular
1934:             * sets of import statements. Note that actual implementation is delegated to
1935:             * the associated {@link OntDocumentManager}.
1936:             */
1937:            public void loadImports() {
1938:                // load the imports closure, according to the policies in my document manager
1939:                getDocumentManager().loadImports(this );
1940:            }
1941:
1942:            /**
1943:             * <p>
1944:             * Answer true if this model has had the given URI document imported into it. This is
1945:             * important to know since an import only occurs once, and we also want to be able to
1946:             * detect cycles of imports.
1947:             * </p>
1948:             *
1949:             * @param uri An ontology URI
1950:             * @return True if the document corresponding to the URI has been successfully loaded
1951:             * into this model
1952:             */
1953:            public boolean hasLoadedImport(String uri) {
1954:                return m_imported.contains(uri);
1955:            }
1956:
1957:            /**
1958:             * <p>
1959:             * Record that this model has now imported the document with the given
1960:             * URI, so that it will not be re-imported in the future.
1961:             * </p>
1962:             *
1963:             * @param uri A document URI that has now been imported into the model.
1964:             */
1965:            public void addLoadedImport(String uri) {
1966:                m_imported.add(uri);
1967:            }
1968:
1969:            /**
1970:             * <p>
1971:             * Record that this model no longer imports the document with the given
1972:             * URI.
1973:             * </p>
1974:             *
1975:             * @param uri A document URI that is no longer imported into the model.
1976:             */
1977:            public void removeLoadedImport(String uri) {
1978:                m_imported.remove(uri);
1979:            }
1980:
1981:            /**
1982:             * <p>
1983:             * Answer a list of the imported URI's in this ontology model. Detection of <code>imports</code>
1984:             * statments will be according to the local language profile
1985:             * </p>
1986:             *
1987:             * @return The imported ontology URI's as a set. Note that since the underlying graph is
1988:             * not ordered, the order of values in the list in successive calls to this method is
1989:             * not guaranteed to be preserved.
1990:             */
1991:            public Set listImportedOntologyURIs() {
1992:                return listImportedOntologyURIs(false);
1993:            }
1994:
1995:            /**
1996:             * <p>
1997:             * Answer a list of the imported URI's in this ontology model, and optionally in the closure
1998:             * of this model's imports. Detection of <code>imports</code>
1999:             * statments will be according to the local language profile.  Note that, in order to allow this
2000:             * method to be called during the imports closure process, we <b>only query the base model</b>,
2001:             * thus side-stepping the any attached reasoner.
2002:             * </p>
2003:             * @param closure If true, the set of uri's returned will include not only those directly
2004:             * imported by this model, but those imported by the model's imports transitively.
2005:             * @return The imported ontology URI's as a list. Note that since the underlying graph is
2006:             * not ordered, the order of values in the list in successive calls to this method is
2007:             * not guaranteed to be preserved.
2008:             */
2009:            public Set listImportedOntologyURIs(boolean closure) {
2010:                Set results = new HashSet();
2011:                List queue = new ArrayList();
2012:                queue.add(getBaseModel());
2013:
2014:                while (!queue.isEmpty()) {
2015:                    Model m = (Model) queue.remove(0);
2016:
2017:                    // list the ontology nodes
2018:                    if (getProfile().ONTOLOGY() != null
2019:                            && getProfile().IMPORTS() != null) {
2020:                        StmtIterator i = m.listStatements(null, getProfile()
2021:                                .IMPORTS(), (RDFNode) null);
2022:                        while (i.hasNext()) {
2023:                            Statement s = i.nextStatement();
2024:                            String uri = s.getResource().getURI();
2025:
2026:                            if (!results.contains(uri)) {
2027:                                // this is a new uri, so we add it
2028:                                results.add(uri);
2029:
2030:                                // and push the model on the stack if we know it
2031:                                Model mi = getDocumentManager().getModel(uri);
2032:                                if (closure && mi != null
2033:                                        && !queue.contains(mi)) {
2034:                                    queue.add(mi);
2035:                                }
2036:                            }
2037:                        }
2038:                    }
2039:                }
2040:
2041:                return results;
2042:            }
2043:
2044:            /**
2045:             * <p>
2046:             * Answer the model maker associated with this model (used for constructing the
2047:             * constituent models of the imports closure).
2048:             * </p>
2049:             *
2050:             * @return The local graph factory
2051:             */
2052:            public ModelMaker getImportModelMaker() {
2053:                return m_spec.getImportModelMaker();
2054:            }
2055:
2056:            /**
2057:                 @deprecated use getImportModelMaker instead.
2058:             */
2059:            public ModelMaker getModelMaker() {
2060:                return getImportModelMaker();
2061:            }
2062:
2063:            /**
2064:             * <p>If this OntModel is presenting an OWL model, answer the minimum OWL language
2065:             * level that the constructs
2066:             * used in this model lie entirely within.  The three possible return values are
2067:             * {@link OWL#FULL_LANG} for OWL-full,
2068:             * {@link OWL#DL_LANG} for OWL-DL or
2069:             * {@link OWL#LITE_LANG} for OWL-lite.
2070:             * Note that these URI's are <strong>not</strong> officially sanctioned by the WebOnt
2071:             * working group.  For unknown reasons, the working group chose not to assign official
2072:             * URI's to represent the different OWL language levels. There is a slim chance that this
2073:             * may change in future, in which case these return values will change apropriately.
2074:             * In addition, the given <code>problems</problems> list, if non-null, will be filled with the syntax
2075:             * problems detected by the syntax checker (<code> com.hp.hpl.jena.ontology.tidy.Checker</code>).
2076:             * </p>
2077:             * <p>
2078:             * The Jena OWL syntax checker will normally list as problems those constructs used in
2079:             * this model that are in OWL Full but not permitted in OWL DL.  The exception to this
2080:             * is if the {@linkplain #getProfile() language profile} for this model is
2081:             * {@linkplain OWLLiteProfile OWL Lite}, then the syntax checker will
2082:             * test for constructs that lie in OWL-DL or OWL-Full and hence outside in OWL-Lite.
2083:             * </p>
2084:             *
2085:             * @param problems A list that, if non-null, will have the various problems discovered by the OWL syntax
2086:             * checker added to it.
2087:             * @return A resource denoting the minimum OWL language level for this model
2088:             * @exception OntologyException if this model is not an OWL model
2089:             */
2090:            public Resource getOWLLanguageLevel(List problems) {
2091:                initSyntaxCheckerClass();
2092:                try {
2093:                    return ((OWLSyntaxChecker) owlSyntaxCheckerClass
2094:                            .newInstance()).getOWLLanguageLevel(this , problems);
2095:                } catch (InstantiationException e) {
2096:                    throw new BrokenException("Syntax Checker misconfigured: ",
2097:                            e);
2098:                } catch (IllegalAccessException e) {
2099:                    throw new BrokenException("Syntax Checker misconfigured: ",
2100:                            e);
2101:                }
2102:            }
2103:
2104:            /**
2105:             * <p>Read statements into the model from the given source, and then load
2106:             * imported ontologies (according to the document manager policy).</p>
2107:             * @param uri URI to read from, may be mapped to a local source by the document manager
2108:             */
2109:            public Model read(String uri) {
2110:                return read(uri, null);
2111:            }
2112:
2113:            /**
2114:             * <p>Read statements into the model from the given source, and then load
2115:             * imported ontologies (according to the document manager policy).</p>
2116:             * @param reader An input reader
2117:             * @param base The base URI
2118:             */
2119:            public Model read(Reader reader, String base) {
2120:                super .read(reader, base);
2121:
2122:                loadImports();
2123:                rebind();
2124:                return this ;
2125:            }
2126:
2127:            /**
2128:             * <p>Read statements into the model from the given source, and then load
2129:             * imported ontologies (according to the document manager policy).</p>
2130:             * @param reader An input stream
2131:             * @param base The base URI
2132:             */
2133:            public Model read(InputStream reader, String base) {
2134:                super .read(reader, base);
2135:
2136:                loadImports();
2137:                rebind();
2138:                return this ;
2139:            }
2140:
2141:            /**
2142:             * <p>Read statements into the model from the given source, and then load
2143:             * imported ontologies (according to the document manager policy).</p>
2144:             * @param uri URI to read from, may be mapped to a local source by the document manager
2145:             * @param syntax The source syntax
2146:             * @return This model, to allow chaining calls
2147:             */
2148:            public Model read(String uri, String syntax) {
2149:                return read(uri, uri, syntax);
2150:            }
2151:
2152:            /**
2153:             * <p>Read statements into the model from the given source, and then load
2154:             * imported ontologies (according to the document manager policy).</p>
2155:             * @param uri URI to read from, may be mapped to a local source by the document manager
2156:             * @param base The base URI for this model
2157:             * @param syntax The source syntax
2158:             * @return This model, to allow chaining calls
2159:             */
2160:            public Model read(String uri, String base, String syntax) {
2161:                // we don't want to load this document again if imported by one of the imports
2162:                if (s_log.isDebugEnabled()) {
2163:                    s_log.debug("Noting already loaded import URI " + uri);
2164:                }
2165:                addLoadedImport(uri);
2166:
2167:                OntDocumentManager odm = getDocumentManager();
2168:
2169:                String sourceURL = odm.doAltURLMapping(uri);
2170:
2171:                // invoke the read hook from the ODM
2172:                String source = odm.getReadHook().beforeRead(this , sourceURL,
2173:                        odm);
2174:                if (source == null) {
2175:                    s_log
2176:                            .warn("ReadHook returned null, so skipping assuming previous value: "
2177:                                    + sourceURL);
2178:                    source = sourceURL;
2179:                } else {
2180:                    // now we can actually do the read
2181:                    super .read(source, base, syntax);
2182:                }
2183:
2184:                // the post read hook
2185:                odm.getReadHook().afterRead(this , source, odm);
2186:
2187:                // cache this model against the public uri (if caching enabled)
2188:                getDocumentManager().addModel(uri, this );
2189:
2190:                loadImports();
2191:                rebind();
2192:                return this ;
2193:            }
2194:
2195:            /**
2196:             * <p>Read statements into the model from the given source, and then load
2197:             * imported ontologies (according to the document manager policy).</p>
2198:             * @param reader An input reader
2199:             * @param base The base URI
2200:             * @param syntax The source syntax
2201:             * @return This model, to allow chaining calls
2202:             */
2203:            public Model read(Reader reader, String base, String syntax) {
2204:                super .read(reader, base, syntax);
2205:
2206:                loadImports();
2207:                rebind();
2208:                return this ;
2209:            }
2210:
2211:            /**
2212:             * <p>Read statements into the model from the given source, and then load
2213:             * imported ontologies (according to the document manager policy).</p>
2214:             * @param reader An input stream
2215:             * @param base The base URI
2216:             * @param syntax The source syntax
2217:             * @return This model, to allow chaining calls
2218:             */
2219:            public Model read(InputStream reader, String base, String syntax) {
2220:                super .read(reader, base, syntax);
2221:
2222:                loadImports();
2223:                rebind();
2224:                return this ;
2225:            }
2226:
2227:            /**
2228:             * <p>
2229:             * Answer the sub-graphs of this model. A sub-graph is defined as a graph that
2230:             * is used to contain the triples from an imported document.
2231:             * </p>
2232:             *
2233:             * @return A list of sub graphs for this ontology model
2234:             */
2235:            public List getSubGraphs() {
2236:                return getUnionGraph().getSubGraphs();
2237:            }
2238:
2239:            /**
2240:             * <p>Answer an iterator over the ontologies that this ontology imports,
2241:             * each of which will have been wrapped as an ontology model using the same
2242:             * {@link OntModelSpec} as this model.  If this model has no imports,
2243:             * the iterator will be non-null but will not have any values.</p>
2244:             * @return An iterator, each value of which will be an <code>OntModel</code>
2245:             * representing an imported ontology.
2246:             * @deprecated This method has been re-named to <code>listSubModels</code>,
2247:             * but note that to obtain the same behaviour as <code>listImportedModels</code>
2248:             * from Jena 2.4 and earlier, callers should invoke {@link #listSubModels(boolean)}
2249:             * with parameter <code>true</code>.
2250:             * @see #listSubModels()
2251:             * @see #listSubModels(boolean)
2252:             */
2253:            public ExtendedIterator listImportedModels() {
2254:                return listSubModels(true);
2255:            }
2256:
2257:            /**
2258:             * <p>Answer an iterator over the ontology models that are sub-models of
2259:             * this model. Sub-models are used, for example, to represent composite
2260:             * documents such as the imports of a model. So if ontology A imports
2261:             * ontologies B and C, each of B and C will be available as one of
2262:             * the sub-models of the model containing A. This method replaces the
2263:             * older {@link #listImportedModels}. Note that to fully replicate
2264:             * the behaviour of <code>listImportedModels</code>, the
2265:             * <code>withImports</code> flag must be set to true. Each model
2266:             * returned by this method will have been wrapped as an ontology model using the same
2267:             * {@link OntModelSpec} as this model.  If this model has no sub-models,
2268:             * the returned iterator will be non-null but will not have any values.</p>
2269:             *
2270:             * @param withImports If true, each sub-model returned by this method
2271:             * will also include its import models. So if model A imports D, and D
2272:             * imports D, when called with <code>withImports</code> set to true, the
2273:             * return value for <code>modelA.listSubModels(true)</code> will be an
2274:             * iterator, whose only value is a model for D, and that model will contain
2275:             * a sub-model representing the import of E. If <code>withImports</code>
2276:             * is false, E will not be included as a sub-model of D.
2277:             * @return An iterator, each value of which will be an <code>OntModel</code>
2278:             * representing a sub-model of this ontology.
2279:             */
2280:            public ExtendedIterator listSubModels(final boolean withImports) {
2281:                ExtendedIterator i = WrappedIterator.create(getSubGraphs()
2282:                        .iterator());
2283:
2284:                return i.mapWith(new Map1() {
2285:                    public Object map1(Object o) {
2286:                        Model base = ModelFactory
2287:                                .createModelForGraph((Graph) o);
2288:                        OntModel om = new OntModelImpl(m_spec, base,
2289:                                withImports);
2290:                        return om;
2291:                    }
2292:                });
2293:            }
2294:
2295:            /**
2296:             * <p>Answer an iterator over the ontology models that are sub-models of
2297:             * this model. Sub-models are used, for example, to represent composite
2298:             * documents such as the imports of a model. So if ontology A imports
2299:             * ontologies B and C, each of B and C will be available as one of
2300:             * the sub-models of the model containing A.
2301:             * <strong>Important note on behaviour change:</strong> please see
2302:             * the comment on {@link #listSubModels(boolean)} for explanation
2303:             * of the <code>withImports</code> flag. This zero-argument form
2304:             * of <code>listSubModels</code> sets <code>withImports</code> to
2305:             * false, so the returned models will not themselves contain imports.
2306:             * This behaviour differs from the zero-argument method
2307:             * {@link #listImportedModels()} in Jena 2.4 an earlier.</p>
2308:             * @return An iterator, each value of which will be an <code>OntModel</code>
2309:             * representing a sub-model of this ontology.
2310:             * @see #listSubModels(boolean)
2311:             */
2312:            public ExtendedIterator listSubModels() {
2313:                return listSubModels(false);
2314:            }
2315:
2316:            /**
2317:             * <p>Answer the number of sub-models of this model, not including the
2318:             * base model.</p>
2319:             * @return The number of sub-models, &ge; zero.
2320:             */
2321:            public int countSubModels() {
2322:                int count = 0;
2323:                for (Iterator i = getSubGraphs().iterator(); i.hasNext();) {
2324:                    count++;
2325:                    i.next();
2326:                }
2327:                return count;
2328:            }
2329:
2330:            /**
2331:             * <p>Answer an <code>OntModel</code> representing the imported ontology
2332:             * with the given URI. If an ontology with that URI has not been imported,
2333:             * answer null.</p>
2334:             * @param uri The URI of an ontology that may have been imported into the
2335:             * ontology represented by this model
2336:             * @return A model representing the imported ontology with the given URI, or
2337:             * null.
2338:             */
2339:            public OntModel getImportedModel(String uri) {
2340:                if (listImportedOntologyURIs(true).contains(uri)) {
2341:                    Model mi = getDocumentManager().getModel(uri);
2342:
2343:                    if (mi != null) {
2344:                        if (mi instanceof  OntModel) {
2345:                            // already a suitable ont model
2346:                            return (OntModel) mi;
2347:                        } else {
2348:                            // not in ont-model clothing yet, so re-wrap
2349:                            return ModelFactory.createOntologyModel(m_spec, mi);
2350:                        }
2351:                    }
2352:                }
2353:
2354:                return null;
2355:            }
2356:
2357:            /**
2358:             * <p>
2359:             * Answer the base-graph of this model. The base-graph is the graph that
2360:             * contains the triples read from the source document for this ontology.
2361:             * </p>
2362:             *
2363:             * @return The base-graph for this ontology model
2364:             */
2365:            public Graph getBaseGraph() {
2366:                return getUnionGraph().getBaseGraph();
2367:            }
2368:
2369:            /**
2370:             * <p>
2371:             * Answer the base model of this model. The base model is the model wrapping
2372:             * the graph that contains the triples read from the source document for this
2373:             * ontology.  It is therefore the model that will be updated if statements are
2374:             * added to a model that is built from a union of documents (via the
2375:             * <code>imports</code> statements in the source document).
2376:             * </p>
2377:             *
2378:             * @return The base model for this ontology model
2379:             */
2380:            public Model getBaseModel() {
2381:                return ModelFactory.createModelForGraph(getBaseGraph());
2382:            }
2383:
2384:            /**
2385:             * <p>
2386:             * Add the given model as one of the sub-models of the enclosed ontology union model.
2387:             * <strong>Note</strong> that if <code>model</code> is a composite model (i.e. an
2388:             * {@link OntModel} or {@link InfModel}), the model and all of its submodels will
2389:             * be added to the union of sub-models of this model. If this is <strong>not</strong> required,
2390:             * callers should explicitly add only the base model:
2391:             * </p>
2392:             * <pre>
2393:             * parent.addSubModel( child.getBaseModel() );
2394:             * </pre>
2395:             *
2396:             * @param model A sub-model to add
2397:             */
2398:            public void addSubModel(Model model) {
2399:                addSubModel(model, true);
2400:            }
2401:
2402:            /**
2403:             * <p>
2404:             * Add the given model as one of the sub-models of the enclosed ontology union model.
2405:             * <strong>Note</strong> that if <code>model</code> is a composite model (i.e. an
2406:             * {@link OntModel} or {@link InfModel}), the model and all of its submodels will
2407:             * be added to the union of sub-models of this model. If this is <strong>not</strong> required,
2408:             * callers should explicitly add only the base model:
2409:             * </p>
2410:             * <pre>
2411:             * parent.addSubModel( child.getBaseModel(), true );
2412:             * </pre>
2413:             *
2414:             * @param model A sub-model to add
2415:             * @param rebind If true, rebind any associated inferencing engine to the new data (which
2416:             * may be an expensive operation)
2417:             */
2418:            public void addSubModel(Model model, boolean rebind) {
2419:                getUnionGraph().addGraph(model.getGraph());
2420:                if (rebind) {
2421:                    rebind();
2422:                }
2423:            }
2424:
2425:            /**
2426:             * <p>
2427:             * Remove the given model as one of the sub-models of the enclosed ontology union model.    Will
2428:             * cause the associated infererence engine (if any) to update, so this may be
2429:             * an expensive operation in some cases.
2430:             * </p>
2431:             *
2432:             * @param model A sub-model to remove
2433:             * @see #addSubModel( Model, boolean )
2434:             */
2435:            public void removeSubModel(Model model) {
2436:                removeSubModel(model, true);
2437:            }
2438:
2439:            /**
2440:             * <p>
2441:             * Remove the given model as one of the sub-models of the enclosed ontology union model.
2442:             * </p>
2443:             *
2444:             * @param model A sub-model to remove
2445:             * @param rebind If true, rebind any associated inferencing engine to the new data (which
2446:             * may be an expensive operation)
2447:             */
2448:            public void removeSubModel(Model model, boolean rebind) {
2449:                Graph subG = model.getGraph();
2450:                getUnionGraph().removeGraph(subG);
2451:
2452:                // note that it may be the base graph of the given model that was added
2453:                // originally
2454:                if (subG instanceof  MultiUnion) {
2455:                    // we need to get the base graph when removing a ontmodel
2456:                    getUnionGraph().removeGraph(
2457:                            ((MultiUnion) subG).getBaseGraph());
2458:                }
2459:
2460:                if (rebind) {
2461:                    rebind();
2462:                }
2463:            }
2464:
2465:            /**
2466:             * <p>Answer true if the given node is a member of the base model of this ontology model.
2467:             * This is an important distiction, because only the base model receives updates when the
2468:             * ontology model is updated. Thus, removing properties of a resource that is not in the base
2469:             * model will not actually side-effect the overall model.</p>
2470:             * @param node An RDF node (Resource, Property or Literal) to test
2471:             * @return True if the given node is from the base model
2472:             */
2473:            public boolean isInBaseModel(RDFNode node) {
2474:                Node n = node.asNode();
2475:                Graph b = getBaseGraph();
2476:                return b.contains(n, Node.ANY, Node.ANY)
2477:                        || b.contains(Node.ANY, n, Node.ANY)
2478:                        || b.contains(Node.ANY, Node.ANY, n);
2479:            }
2480:
2481:            /**
2482:             * <p>Answer true if the given statement is defined in the base model of this ontology model.
2483:             * This is an important distiction, because only the base model receives updates when the
2484:             * ontology model is updated. Thus, removing a statement that is not in the base
2485:             * model will not actually side-effect the overall model.</p>
2486:             * @param stmt A statement to test
2487:             * @return True if the given statement is from the base model
2488:             */
2489:            public boolean isInBaseModel(Statement stmt) {
2490:                Node s = stmt.getSubject().asNode();
2491:                Node p = stmt.getPredicate().asNode();
2492:                Node o = stmt.getObject().asNode();
2493:                Graph b = getBaseGraph();
2494:                return b.contains(s, p, o);
2495:            }
2496:
2497:            /**
2498:             * <p>
2499:             * Answer true if this model is currently in <i>strict checking mode</i>. Strict
2500:             * mode means
2501:             * that converting a common resource to a particular language element, such as
2502:             * an ontology class, will be subject to some simple syntactic-level checks for
2503:             * appropriateness.
2504:             * </p>
2505:             *
2506:             * @return True if in strict checking mode
2507:             */
2508:            public boolean strictMode() {
2509:                return m_strictMode;
2510:            }
2511:
2512:            /**
2513:             * <p>
2514:             * Set the checking mode to strict or non-strict.
2515:             * </p>
2516:             *
2517:             * @param strict
2518:             * @see #strictMode()
2519:             */
2520:            public void setStrictMode(boolean strict) {
2521:                m_strictMode = strict;
2522:            }
2523:
2524:            /**
2525:             * <p>Set the flag that controls whether adding or removing <i>imports</i>
2526:             * statements into the
2527:             * model will result in the imports closure changing dynamically.</p>
2528:             * @param dynamic If true, adding or removing an imports statement to the
2529:             * model will result in a change in the imports closure.  If false, changes
2530:             * to the imports are not monitored dynamically. Default false.
2531:             */
2532:            public void setDynamicImports(boolean dynamic) {
2533:                if (dynamic) {
2534:                    if (m_importsListener == null) {
2535:                        // turn on dynamic processing
2536:                        m_importsListener = new ImportsListener();
2537:                        register(m_importsListener);
2538:                    }
2539:                } else {
2540:                    if (m_importsListener != null) {
2541:                        // turn off dynamic processing
2542:                        unregister(m_importsListener);
2543:                        m_importsListener = null;
2544:                    }
2545:                }
2546:            }
2547:
2548:            /**
2549:             * <p>Answer true if the imports closure of the model will be dynamically
2550:             * updated as imports statements are added and removed.</p>
2551:             * @return True if the imports closure is updated dynamically.
2552:             */
2553:            public boolean getDynamicImports() {
2554:                return m_importsListener != null;
2555:            }
2556:
2557:            /**
2558:             * <p>Answer the ontology model specification that was used to construct this model</p>
2559:             * @return An ont model spec instance.
2560:             */
2561:            public OntModelSpec getSpecification() {
2562:                return m_spec;
2563:            }
2564:
2565:            /**
2566:             * <p>Answer the ontology event manager attached to this model.  If there is no event
2567:             * manager currently attached, a new one will be created.</p>
2568:             * @return The current, or a new, ontology event mananger
2569:             */
2570:            public OntEventManager getEventManager() {
2571:                if (m_ontEventMgr == null) {
2572:                    m_ontEventMgr = new OntEventManager(this );
2573:                }
2574:
2575:                return m_ontEventMgr;
2576:            }
2577:
2578:            /**
2579:             * <p>
2580:             * Answer the iterator over the resources from the graph that satisfy the given
2581:             * query, followed by the answers to the alternative queries (if specified). A
2582:             * typical scenario is that the main query gets resources of a given class (say,
2583:             * <code>rdfs:Class</code>), while the altQueries query for aliases for that
2584:             * type (such as <code>daml:Class</code>).
2585:             * </p>
2586:             *
2587:             * @param query A query to run against the model
2588:             * @param altQueries An optional list of subsidiary queries to chain on to the first
2589:             * @return ExtendedIterator An iterator over the (assumed single) results of
2590:             * executing the queries.
2591:             */
2592:            public ExtendedIterator queryFor(BindingQueryPlan query,
2593:                    List altQueries, Class asKey) {
2594:                GetBinding firstBinding = new GetBinding(0);
2595:
2596:                // get the results from the main query
2597:                ExtendedIterator mainQuery = query.executeBindings().mapWith(
2598:                        firstBinding);
2599:
2600:                // now add the alternate queries, if defined
2601:                if (altQueries != null) {
2602:                    for (Iterator i = altQueries.iterator(); i.hasNext();) {
2603:                        ExtendedIterator altQuery = ((BindingQueryPlan) i
2604:                                .next()).executeBindings()
2605:                                .mapWith(firstBinding);
2606:                        mainQuery = mainQuery.andThen(altQuery);
2607:                    }
2608:                }
2609:
2610:                // map each answer value to the appropriate ehnanced node
2611:                return mainQuery.filterKeep(new SubjectNodeCanAs(asKey))
2612:                        .mapWith(new SubjectNodeAs(asKey));
2613:            }
2614:
2615:            // output operations - delegate to base model
2616:
2617:            public Model write(Writer writer) {
2618:                return getBaseModel().write(writer);
2619:            }
2620:
2621:            public Model write(Writer writer, String lang) {
2622:                return getBaseModel().write(writer, lang);
2623:            }
2624:
2625:            public Model write(Writer writer, String lang, String base) {
2626:                return getBaseModel().write(writer, lang, base);
2627:            }
2628:
2629:            public Model write(OutputStream out) {
2630:                return getBaseModel().write(out);
2631:            }
2632:
2633:            public Model write(OutputStream out, String lang) {
2634:                return getBaseModel().write(out, lang);
2635:            }
2636:
2637:            public Model write(OutputStream out, String lang, String base) {
2638:                return getBaseModel().write(out, lang, base);
2639:            }
2640:
2641:            public Model writeAll(Writer writer, String lang, String base) {
2642:                return super .write(writer, lang, base);
2643:            }
2644:
2645:            public Model writeAll(OutputStream out, String lang, String base) {
2646:                return super .write(out, lang, base);
2647:            }
2648:
2649:            // Implementation of inf model interface methods
2650:
2651:            /**
2652:             * Return the raw RDF model being processed (i.e. the argument
2653:             * to the Reasonder.bind call that created this InfModel).
2654:             */
2655:            public Model getRawModel() {
2656:                return getBaseModel();
2657:            }
2658:
2659:            /**
2660:             * Return the Reasoner which is being used to answer queries to this graph.
2661:             */
2662:            public Reasoner getReasoner() {
2663:                return (getGraph() instanceof  InfGraph) ? ((InfGraph) getGraph())
2664:                        .getReasoner()
2665:                        : null;
2666:            }
2667:
2668:            /**
2669:             * Cause the inference model  to reconsult the underlying data to take
2670:             * into account changes. Normally changes are made through the InfModel's add and
2671:             * remove calls are will be handled appropriately. However, in some cases changes
2672:             * are made "behind the InfModels's back" and this forces a full reconsult of
2673:             * the changed data.
2674:             */
2675:            public void rebind() {
2676:                if (getGraph() instanceof  InfGraph) {
2677:                    ((InfGraph) getGraph()).rebind();
2678:                }
2679:            }
2680:
2681:            /**
2682:             * Perform any initial processing and caching. This call is optional. Most
2683:             * engines either have negligable set up work or will perform an implicit
2684:             * "prepare" if necessary. The call is provided for those occasions where
2685:             * substantial preparation work is possible (e.g. running a forward chaining
2686:             * rule system) and where an application might wish greater control over when
2687:             * this prepration is done rather than just leaving to be done at first query time.
2688:             */
2689:            public void prepare() {
2690:                if (getGraph() instanceof  InfGraph) {
2691:                    ((InfGraph) getGraph()).prepare();
2692:                }
2693:            }
2694:
2695:            /**
2696:             * Reset any internal caches. Some systems, such as the tabled backchainer,
2697:             * retain information after each query. A reset will wipe this information preventing
2698:             * unbounded memory use at the expense of more expensive future queries. A reset
2699:             * does not cause the raw data to be reconsulted and so is less expensive than a rebind.
2700:             */
2701:            public void reset() {
2702:                if (getGraph() instanceof  InfGraph) {
2703:                    ((InfGraph) getGraph()).reset();
2704:                }
2705:            }
2706:
2707:            /**
2708:             * <p>Returns a derivations model. The rule reasoners typically create a
2709:             * graph containing those triples added to the base graph due to rule firings.
2710:             * In some applications it can useful to be able to access those deductions
2711:             * directly, without seeing the raw data which triggered them. In particular,
2712:             * this allows the forward rules to be used as if they were rewrite transformation
2713:             * rules.</p>
2714:             *
2715:             * @return The derivations model, if one is defined, or else null
2716:             */
2717:            public Model getDeductionsModel() {
2718:                if (m_deductionsModel == null) {
2719:                    InfGraph infGraph = getInfGraph();
2720:                    if (infGraph != null) {
2721:                        Graph deductionsGraph = infGraph.getDeductionsGraph();
2722:                        if (deductionsGraph != null) {
2723:                            m_deductionsModel = ModelFactory
2724:                                    .createModelForGraph(deductionsGraph);
2725:                        }
2726:                    }
2727:                } else {
2728:                    // ensure that the cached model sees the updated changes from the
2729:                    // underlying reasoner graph
2730:                    getInfGraph().prepare();
2731:                }
2732:
2733:                return m_deductionsModel;
2734:            }
2735:
2736:            /**
2737:             * Test the consistency of the underlying data. This normally tests
2738:             * the validity of the bound instance data against the bound
2739:             * schema data.
2740:             * @return a ValidityReport structure
2741:             */
2742:            public ValidityReport validate() {
2743:                return (getGraph() instanceof  InfGraph) ? ((InfGraph) getGraph())
2744:                        .validate()
2745:                        : null;
2746:            }
2747:
2748:            /** Find all the statements matching a pattern.
2749:             * <p>Return an iterator over all the statements in a model
2750:             *  that match a pattern.  The statements selected are those
2751:             *  whose subject matches the <code>subject</code> argument,
2752:             *  whose predicate matches the <code>predicate</code> argument
2753:             *  and whose object matchesthe <code>object</code> argument.
2754:             *  If an argument is <code>null</code> it matches anything.</p>
2755:             * <p>
2756:             * The s/p/o terms may refer to resources which are temporarily defined in the "posit" model.
2757:             * This allows one, for example, to query what resources are of type CE where CE is a
2758:             * class expression rather than a named class - put CE in the posit arg.</p>
2759:             *
2760:             * @return an iterator over the subjects
2761:             * @param subject   The subject sought
2762:             * @param predicate The predicate sought
2763:             * @param object    The value sought
2764:             */
2765:            public StmtIterator listStatements(Resource subject,
2766:                    Property predicate, RDFNode object, Model posit) {
2767:                if (getGraph() instanceof  InfGraph) {
2768:                    Iterator iter = getInfGraph()
2769:                            .find(asNode(subject), asNode(predicate),
2770:                                    asNode(object), posit.getGraph());
2771:                    return IteratorFactory.asStmtIterator(iter, this );
2772:                } else {
2773:                    return null;
2774:                }
2775:            }
2776:
2777:            /**
2778:             * Switch on/off drivation logging. If this is switched on then every time an inference
2779:             * is a made that fact is recorded and the resulting record can be access through a later
2780:             * getDerivation call. This may consume a lot of space!
2781:             */
2782:            public void setDerivationLogging(boolean logOn) {
2783:                if (getGraph() instanceof  InfGraph) {
2784:                    ((InfGraph) getGraph()).setDerivationLogging(logOn);
2785:                }
2786:            }
2787:
2788:            /**
2789:             * Return the derivation of the given statement (which should be the result of
2790:             * some previous list operation).
2791:             * Not all reasoneers will support derivations.
2792:             * @return an iterator over Derivation records or null if there is no derivation information
2793:             * available for this triple.
2794:             */
2795:            public Iterator getDerivation(Statement statement) {
2796:                return (getGraph() instanceof  InfGraph) ? ((InfGraph) getGraph())
2797:                        .getDerivation(statement.asTriple())
2798:                        : null;
2799:            }
2800:
2801:            // Internal implementation methods
2802:            //////////////////////////////////
2803:
2804:            private static void initSyntaxCheckerClass() {
2805:                if (owlSyntaxCheckerClass == null) {
2806:                    try {
2807:                        owlSyntaxCheckerClass = Class
2808:                                .forName(owlSyntaxCheckerClassName);
2809:                        owlSyntaxCheckerClass.newInstance();
2810:                    } catch (Exception e) {
2811:                        throw new ConfigException(
2812:                                "owlsyntax.jar must be on the classpath.", e);
2813:                    }
2814:                }
2815:            }
2816:
2817:            /**
2818:             * <p>Helper method to the constructor, which interprets the spec and generates an appropriate
2819:             * graph for this model</p>
2820:             * @param spec The model spec to interpret
2821:             * @param base The base model, or null
2822:             */
2823:            private static Graph generateGraph(OntModelSpec spec, Graph base) {
2824:                // create a empty union graph
2825:                MultiUnion u = new MultiUnion();
2826:                u.addGraph(base);
2827:                u.setBaseGraph(base);
2828:
2829:                Reasoner r = spec.getReasoner();
2830:                // if we have a reasoner in the spec, bind to the union graph and return
2831:                return r == null ? (Graph) u : r.bind(u);
2832:            }
2833:
2834:            /**
2835:             * <p>Answer the union graph that contains the imports closure for this ontology</p>
2836:             * @return The union graph
2837:             */
2838:            protected MultiUnion getUnionGraph() {
2839:                return m_union;
2840:            }
2841:
2842:            /** Answer the resource with the given URI, if present, as the given facet */
2843:            protected Resource findByURIAs(String uri, Class asKey) {
2844:                if (uri == null) {
2845:                    throw new IllegalArgumentException(
2846:                            "Cannot get() ontology value with a null URI");
2847:                }
2848:
2849:                Node n = Node.createURI(uri);
2850:
2851:                if (getGraph().contains(n, Node.ANY, Node.ANY)) {
2852:                    // this resource is a subject in the graph
2853:                    try {
2854:                        return (Resource) getNodeAs(n, asKey);
2855:                    } catch (ConversionException ignore) {/**/
2856:                    }
2857:                }
2858:
2859:                // not present, or cannot be as'ed to the desired facet
2860:                return null;
2861:            }
2862:
2863:            /**
2864:             * <p>
2865:             * Answer an iterator over all of the resources that have
2866:             * <code>rdf:type</code> type.
2867:             * </p>
2868:             *
2869:             * @param type The resource that is the value of <code>rdf:type</code> we
2870:             * want to match
2871:             * @return An iterator over all triples <code>_x rdf:type type</code>
2872:             */
2873:            protected ExtendedIterator findByType(Resource type) {
2874:                return getGraph().find(null, RDF.type.asNode(), type.asNode());
2875:            }
2876:
2877:            /**
2878:             * <p>
2879:             * Answer an iterator over all of the resources that have
2880:             * <code>rdf:type type</code>, or optionally, one of the alternative types.
2881:             * </p>
2882:             *
2883:             * @param type The resource that is the value of <code>rdf:type</code> we
2884:             * want to match
2885:             * @param alternates An iterator over alternative types to search for, or null
2886:             * @return An iterator over all triples <code>_x rdf:type t</code> where t
2887:             * is <code>type</code> or one of the values from <code>types</code>.
2888:             */
2889:            protected ExtendedIterator findByType(Resource type,
2890:                    Iterator alternates) {
2891:                ExtendedIterator i = findByType(type);
2892:
2893:                // compose onto i the find iterators for the alternate types
2894:                if (alternates != null) {
2895:                    while (alternates.hasNext()) {
2896:                        i = i.andThen(findByType((Resource) alternates.next()));
2897:                    }
2898:                }
2899:
2900:                return UniqueExtendedIterator.create(i);
2901:            }
2902:
2903:            /**
2904:             * <p>
2905:             * Answer an iterator over all of the resources that have
2906:             * <code>rdf:type type</code>, or optionally, one of the alternative types,
2907:             * and present the results <code>as()</code> the given class.
2908:             * </p>
2909:             *
2910:             * @param type The resource that is the value of <code>rdf:type</code> we
2911:             * want to match
2912:             * @param types An iterator over alternative types to search for, or null
2913:             * @param asKey The value to use to present the polymorphic results
2914:             * @return An iterator over all triples <code>_x rdf:type type</code>
2915:             */
2916:            protected ExtendedIterator findByTypeAs(Resource type,
2917:                    Iterator types, Class asKey) {
2918:                return findByType(type, types)
2919:                        .mapWith(new SubjectNodeAs(asKey));
2920:            }
2921:
2922:            /**
2923:             * <p>
2924:             * Answer an iterator over all of the resources that has an
2925:             * <code>rdf:type</code> from the types iterator,
2926:             * and present the results <code>as()</code> the given class.
2927:             * </p>
2928:             *
2929:             * @param types An iterator over types to search for.  An exception will
2930:             * be raised if this iterator does not have at least one next() element.
2931:             * @param asKey The value to use to present the polymorphic results
2932:             * @return An iterator over all triples <code>_x rdf:type type</code>
2933:             */
2934:            protected ExtendedIterator findByTypeAs(Iterator types, Class asKey) {
2935:                return findByTypeAs((Resource) types.next(), types, asKey);
2936:            }
2937:
2938:            /**
2939:             * <p>
2940:             * Answer an iterator over resources with the given rdf:type; for each value
2941:             * in the iterator, ensure that is is presented <code>as()</code> the
2942:             * polymorphic object denoted by the given class key.
2943:             * </p>
2944:             *
2945:             * @param type The rdf:type to search for
2946:             * @param asKey The key to pass to as() on the subject nodes
2947:             * @return An iterator over subjects with the given type, presenting as
2948:             * the given polymorphic class.
2949:             */
2950:            protected ExtendedIterator findByTypeAs(Resource type, Class asKey) {
2951:                return findByType(type).mapWith(new SubjectNodeAs(asKey));
2952:            }
2953:
2954:            /**
2955:             * <p>
2956:             * Answer a binding query that will search for 'an X that has an
2957:             * rdf:type whose rdf:type is C' for some given resource C.
2958:             * </p>
2959:             *
2960:             * @param type The type of the type of the resources we're searching for
2961:             * @return BindingQueryPlan A binding query for the X resources.
2962:             */
2963:            protected BindingQueryPlan queryXTypeOfType(Resource type) {
2964:                if (type != null) {
2965:                    Query q = new Query();
2966:                    // kers: this non-intuitive order should improve search performance
2967:                    q.addMatch(Query.Y, RDF.type.asNode(), type.asNode());
2968:                    q.addMatch(Query.X, RDF.type.asNode(), Query.Y);
2969:
2970:                    return queryHandler().prepareBindings(q,
2971:                            new Node[] { Query.X });
2972:                } else {
2973:                    return null;
2974:                }
2975:            }
2976:
2977:            /**
2978:             * <p>
2979:             * Answer an iterator over nodes that have p as a subject
2980:             * </p>
2981:             *
2982:             * @param p A property
2983:             * @return ExtendedIterator over subjects of p.
2984:             */
2985:            protected ExtendedIterator findByDefiningProperty(Property p) {
2986:                return getGraph().find(null, p.asNode(), null);
2987:            }
2988:
2989:            /**
2990:             * <p>
2991:             * Answer an iterator over nodes that have p as a subject, presented as
2992:             * polymorphic enh resources of the given facet.
2993:             * </p>
2994:             *
2995:             * @param p A property
2996:             * @param asKey A facet type
2997:             * @return ExtendedIterator over subjects of p, presented as the facet.
2998:             */
2999:            protected ExtendedIterator findByDefiningPropertyAs(Property p,
3000:                    Class asKey) {
3001:                return findByDefiningProperty(p).mapWith(
3002:                        new SubjectNodeAs(asKey));
3003:            }
3004:
3005:            /**
3006:             * <p>
3007:             * Answer the resource with the given uri and that optionally has the given <code>rdf:type</code>,
3008:             * creating the resource if necessary.
3009:             * </p>
3010:             *
3011:             * @param uri The uri to use, or null for an anonymous resource
3012:             * @param rdfType The resource to assert as the <code>rdf:type</code>, or null to leave untyped
3013:             * @return A new or existing Resource
3014:             */
3015:            protected Resource getResourceWithType(String uri, Resource rdfType) {
3016:                Resource r = getResource(uri);
3017:                if (rdfType != null) {
3018:                    r.addProperty(RDF.type, rdfType);
3019:                }
3020:                return r;
3021:            }
3022:
3023:            /**
3024:             * <p>Answer a resource presenting the {@link OntResource} facet, which has the given
3025:             * URI. If no such resource is currently present in the model, return null.</p>
3026:             * @param uri The URI of a resource
3027:             * @return An OntResource with the given URI, or null
3028:             */
3029:            public OntResource getOntResource(String uri) {
3030:                Resource r = getResource(uri);
3031:                if (containsResource(r)) {
3032:                    return (OntResource) r.as(OntResource.class);
3033:                }
3034:                return null;
3035:            }
3036:
3037:            /**
3038:             * <p>Answer a resource presenting the {@link OntResource} facet, which
3039:             * corresponds to the given resource but attached to this model.</p>
3040:             * @param res An existing resource
3041:             * @return An {@link OntResource} attached to this model that has the same URI
3042:             * or anonID as the given resource
3043:             */
3044:            public OntResource getOntResource(Resource res) {
3045:                return (OntResource) res.inModel(this ).as(OntResource.class);
3046:            }
3047:
3048:            /**
3049:             * <p>Throw an OntologyException if the term is not in language profile</p>
3050:             *
3051:             * @param profileTerm The entry from the profile
3052:             * @param desc A label for the profile term
3053:             * @exception OntologyException if profileTerm is null.
3054:             */
3055:            protected void checkProfileEntry(Object profileTerm, String desc) {
3056:                if (profileTerm == null) {
3057:                    // not in the profile
3058:                    throw new ProfileException(desc, getProfile());
3059:                }
3060:            }
3061:
3062:            /**
3063:             * <p>Check that every member of the given list has the given rdf:type, and throw an exception if not.</p>
3064:             * @param list The list to be checked
3065:             * @param rdfType The rdf:type value to check for
3066:             * @exception LanguageConsistencyException if any member of the list does not have <code>rdf:type <i>rdfType</i></code>
3067:             */
3068:            protected void checkListMembersRdfType(RDFList list,
3069:                    Resource rdfType) {
3070:                if (strictMode()
3071:                        && !((Boolean) list.reduce(new RdfTypeTestFn(rdfType),
3072:                                Boolean.TRUE)).booleanValue()) {
3073:                    // not all of the members of the list are of the given type
3074:                    throw new LanguageConsistencyException(
3075:                            "The members of the given list are expected to be of rdf:type "
3076:                                    + rdfType.toString());
3077:                }
3078:            }
3079:
3080:            /**
3081:                 Answer the supplied model, unless it's null, in which case answer a new model
3082:                 constructed as per spec.
3083:             */
3084:            private static Model makeBaseModel(OntModelSpec spec, Model model) {
3085:                return model == null ? spec.createBaseModel() : model;
3086:            }
3087:
3088:            /**
3089:             * <p>Answer the InfGraph that this model is wrapping, or null if this ontology
3090:             * model is not wrapping an inf graph.</p>
3091:             * @return The model's graph as an InfGraph, or null
3092:             */
3093:            private InfGraph getInfGraph() {
3094:                return (getGraph() instanceof  InfGraph) ? ((InfGraph) getGraph())
3095:                        : null;
3096:            }
3097:
3098:            //==============================================================================
3099:            // Inner class definitions
3100:            //==============================================================================
3101:
3102:            /** Map triple subjects or single nodes to subject enh nodes, presented as() the given class */
3103:            protected class SubjectNodeAs implements  Map1 {
3104:                protected Class m_asKey;
3105:
3106:                protected SubjectNodeAs(Class asKey) {
3107:                    m_asKey = asKey;
3108:                }
3109:
3110:                public Object map1(Object x) {
3111:                    Node n = (x instanceof  Triple) ? ((Triple) x).getSubject()
3112:                            : ((x instanceof  EnhNode) ? ((EnhNode) x).asNode()
3113:                                    : (Node) x);
3114:                    return getNodeAs(n, m_asKey);
3115:                }
3116:
3117:            }
3118:
3119:            /** Filter that accepts nodes that can be mapped to the given facet */
3120:            protected class SubjectNodeCanAs extends Filter {
3121:                protected Class m_asKey;
3122:
3123:                protected SubjectNodeCanAs(Class asKey) {
3124:                    m_asKey = asKey;
3125:                }
3126:
3127:                public boolean accept(Object x) {
3128:                    Node n = (x instanceof  Triple) ? ((Triple) x).getSubject()
3129:                            : ((x instanceof  EnhNode) ? ((EnhNode) x).asNode()
3130:                                    : (Node) x);
3131:                    try {
3132:                        getNodeAs(n, m_asKey);
3133:                    } catch (Exception ignore) {
3134:                        return false;
3135:                    }
3136:
3137:                    return true;
3138:                }
3139:
3140:            }
3141:
3142:            /** Project out the first element of a list of bindings */
3143:            protected class GetBinding implements  Map1 {
3144:                protected int m_index;
3145:
3146:                protected GetBinding(int index) {
3147:                    m_index = index;
3148:                }
3149:
3150:                public Object map1(Object x) {
3151:                    return ((List) x).get(m_index);
3152:                }
3153:            }
3154:
3155:            /** Function to test the rdf type of a list */
3156:            protected class RdfTypeTestFn implements  RDFList.ReduceFn {
3157:                protected Resource m_type;
3158:
3159:                protected RdfTypeTestFn(Resource type) {
3160:                    m_type = type;
3161:                }
3162:
3163:                public Object reduce(RDFNode node, Object accumulator) {
3164:                    Boolean acc = (Boolean) accumulator;
3165:                    if (acc.booleanValue()) {
3166:                        // true so far
3167:                        Resource r = (Resource) node;
3168:                        return new Boolean(r.hasProperty(RDF.type, m_type));
3169:                    } else {
3170:                        return acc;
3171:                    }
3172:                }
3173:            }
3174:
3175:            /** Listener for model changes that indicate a change in the imports to the model */
3176:            protected class ImportsListener extends StatementListener {
3177:                public void addedStatement(Statement added) {
3178:                    if (added.getPredicate().equals(getProfile().IMPORTS())) {
3179:                        getDocumentManager().loadImport(OntModelImpl.this ,
3180:                                added.getResource().getURI());
3181:                    }
3182:                }
3183:
3184:                public void removedStatement(Statement removed) {
3185:                    if (removed.getPredicate().equals(getProfile().IMPORTS())) {
3186:                        getDocumentManager().unloadImport(OntModelImpl.this ,
3187:                                removed.getResource().getURI());
3188:                    }
3189:                }
3190:            }
3191:        }
3192:
3193:        /*
3194:         (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
3195:         All rights reserved.
3196:
3197:         Redistribution and use in source and binary forms, with or without
3198:         modification, are permitted provided that the following conditions
3199:         are met:
3200:
3201:         1. Redistributions of source code must retain the above copyright
3202:         notice, this list of conditions and the following disclaimer.
3203:
3204:         2. Redistributions in binary form must reproduce the above copyright
3205:         notice, this list of conditions and the following disclaimer in the
3206:         documentation and/or other materials provided with the distribution.
3207:
3208:         3. The name of the author may not be used to endorse or promote products
3209:         derived from this software without specific prior written permission.
3210:
3211:         THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
3212:         IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
3213:         OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3214:         IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3215:         INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3216:         NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3217:         DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3218:         THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3219:         (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3220:         THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3221:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.