001: /*****************************************************************************
002: * Source code information
003: * -----------------------
004: * Original author Ian Dickinson, HP Labs Bristol
005: * Author email Ian.Dickinson@hp.com
006: * Package Jena 2
007: * Web http://sourceforge.net/projects/jena/
008: * Created 13-May-2003
009: * Filename $RCSfile: OntModelSpec.java,v $
010: * Revision $Revision: 1.54 $
011: * Release status $State: Exp $
012: *
013: * Last modified on $Date: 2008/01/15 08:19:17 $
014: * by $Author: chris-dollin $
015: *
016: * (c) Copyright 2002, 2003, 204, Hewlett-Packard Development Company, LP
017: * (see footer for full conditions)
018: *****************************************************************************/package com.hp.hpl.jena.ontology;
019:
020: // Imports
021: ///////////////
022:
023: import com.hp.hpl.jena.assembler.*;
024: import com.hp.hpl.jena.ontology.impl.OntModelImpl;
025: import com.hp.hpl.jena.rdf.model.*;
026: import com.hp.hpl.jena.reasoner.Reasoner;
027: import com.hp.hpl.jena.reasoner.ReasonerFactory;
028: import com.hp.hpl.jena.reasoner.rulesys.*;
029: import com.hp.hpl.jena.reasoner.transitiveReasoner.TransitiveReasonerFactory;
030: import com.hp.hpl.jena.shared.JenaException;
031:
032: /**
033: * <p>
034: * Encapsulates a description of the components of an ontology model, including the
035: * storage scheme, reasoner and language profile.
036: * </p>
037: *
038: * @author Ian Dickinson, HP Labs
039: * (<a href="mailto:Ian.Dickinson@hp.com" >email</a>)
040: * @version CVS $Id: OntModelSpec.java,v 1.54 2008/01/15 08:19:17 chris-dollin Exp $
041: */
042: public class OntModelSpec {
043: // Constants
044: //////////////////////////////////
045: // Static variables
046: //////////////////////////////////
047:
048: /** A specification for OWL models that are stored in memory and do no additional entailment reasoning */
049: public static final OntModelSpec OWL_MEM = new OntModelSpec(
050: ModelFactory.createMemModelMaker(), null, null,
051: ProfileRegistry.OWL_LANG);
052:
053: /** A specification for OWL models that are stored in memory and use the RDFS inferencer for additional entailments */
054: public static final OntModelSpec OWL_MEM_RDFS_INF = new OntModelSpec(
055: ModelFactory.createMemModelMaker(), null,
056: RDFSRuleReasonerFactory.theInstance(),
057: ProfileRegistry.OWL_LANG);
058:
059: /** A specification for OWL models that are stored in memory and use the transitive inferencer for additional entailments */
060: public static final OntModelSpec OWL_MEM_TRANS_INF = new OntModelSpec(
061: ModelFactory.createMemModelMaker(), null,
062: TransitiveReasonerFactory.theInstance(),
063: ProfileRegistry.OWL_LANG);
064:
065: /** A specification for OWL models that are stored in memory and use the OWL rules inference engine for additional entailments */
066: public static final OntModelSpec OWL_MEM_RULE_INF = new OntModelSpec(
067: ModelFactory.createMemModelMaker(), null,
068: OWLFBRuleReasonerFactory.theInstance(),
069: ProfileRegistry.OWL_LANG);
070:
071: /** A specification for OWL models that are stored in memory and use the micro OWL rules inference engine for additional entailments */
072: public static final OntModelSpec OWL_MEM_MICRO_RULE_INF = new OntModelSpec(
073: ModelFactory.createMemModelMaker(), null,
074: OWLMicroReasonerFactory.theInstance(),
075: ProfileRegistry.OWL_LANG);
076:
077: /** A specification for OWL models that are stored in memory and use the mini OWL rules inference engine for additional entailments */
078: public static final OntModelSpec OWL_MEM_MINI_RULE_INF = new OntModelSpec(
079: ModelFactory.createMemModelMaker(), null,
080: OWLMiniReasonerFactory.theInstance(),
081: ProfileRegistry.OWL_LANG);
082:
083: /** A specification for OWL DL models that are stored in memory and do no additional entailment reasoning */
084: public static final OntModelSpec OWL_DL_MEM = new OntModelSpec(
085: ModelFactory.createMemModelMaker(), null, null,
086: ProfileRegistry.OWL_DL_LANG);
087:
088: /** A specification for OWL DL models that are stored in memory and use the RDFS inferencer for additional entailments */
089: public static final OntModelSpec OWL_DL_MEM_RDFS_INF = new OntModelSpec(
090: ModelFactory.createMemModelMaker(), null,
091: RDFSRuleReasonerFactory.theInstance(),
092: ProfileRegistry.OWL_DL_LANG);
093:
094: /** A specification for OWL DL models that are stored in memory and use the transitive inferencer for additional entailments */
095: public static final OntModelSpec OWL_DL_MEM_TRANS_INF = new OntModelSpec(
096: ModelFactory.createMemModelMaker(), null,
097: TransitiveReasonerFactory.theInstance(),
098: ProfileRegistry.OWL_DL_LANG);
099:
100: /** A specification for OWL DL models that are stored in memory and use the OWL rules inference engine for additional entailments */
101: public static final OntModelSpec OWL_DL_MEM_RULE_INF = new OntModelSpec(
102: ModelFactory.createMemModelMaker(), null,
103: OWLFBRuleReasonerFactory.theInstance(),
104: ProfileRegistry.OWL_DL_LANG);
105:
106: /** A specification for OWL Lite models that are stored in memory and do no entailment additional reasoning */
107: public static final OntModelSpec OWL_LITE_MEM = new OntModelSpec(
108: ModelFactory.createMemModelMaker(), null, null,
109: ProfileRegistry.OWL_LITE_LANG);
110:
111: /** A specification for OWL Lite models that are stored in memory and use the transitive inferencer for additional entailments */
112: public static final OntModelSpec OWL_LITE_MEM_TRANS_INF = new OntModelSpec(
113: ModelFactory.createMemModelMaker(), null,
114: TransitiveReasonerFactory.theInstance(),
115: ProfileRegistry.OWL_LITE_LANG);
116:
117: /** A specification for OWL Lite models that are stored in memory and use the RDFS inferencer for additional entailments */
118: public static final OntModelSpec OWL_LITE_MEM_RDFS_INF = new OntModelSpec(
119: ModelFactory.createMemModelMaker(), null,
120: RDFSRuleReasonerFactory.theInstance(),
121: ProfileRegistry.OWL_LITE_LANG);
122:
123: /** A specification for OWL Lite models that are stored in memory and use the OWL rules inference engine for additional entailments */
124: public static final OntModelSpec OWL_LITE_MEM_RULES_INF = new OntModelSpec(
125: ModelFactory.createMemModelMaker(), null,
126: OWLFBRuleReasonerFactory.theInstance(),
127: ProfileRegistry.OWL_LITE_LANG);
128:
129: /** A specification for DAML models that are stored in memory and do no additional entailment reasoning */
130: public static final OntModelSpec DAML_MEM = new OntModelSpec(
131: ModelFactory.createMemModelMaker(), null, null,
132: ProfileRegistry.DAML_LANG);
133:
134: /** A specification for DAML models that are stored in memory and use the transitive reasoner for entailments */
135: public static final OntModelSpec DAML_MEM_TRANS_INF = new OntModelSpec(
136: ModelFactory.createMemModelMaker(), null,
137: TransitiveReasonerFactory.theInstance(),
138: ProfileRegistry.DAML_LANG);
139:
140: /** A specification for DAML models that are stored in memory and use the RDFS inferencer for additional entailments */
141: public static final OntModelSpec DAML_MEM_RDFS_INF = new OntModelSpec(
142: ModelFactory.createMemModelMaker(), null,
143: RDFSRuleReasonerFactory.theInstance(),
144: ProfileRegistry.DAML_LANG);
145:
146: /** A specification for DAML models that are stored in memory and use a subset of the DAML semantic model additional entailments */
147: public static final OntModelSpec DAML_MEM_RULE_INF = new OntModelSpec(
148: ModelFactory.createMemModelMaker(), null,
149: DAMLMicroReasonerFactory.theInstance(),
150: ProfileRegistry.DAML_LANG);
151:
152: /** A specification for RDFS ontology models that are stored in memory and do no additional entailment reasoning */
153: public static final OntModelSpec RDFS_MEM = new OntModelSpec(
154: ModelFactory.createMemModelMaker(), null, null,
155: ProfileRegistry.RDFS_LANG);
156:
157: /** A specification for RDFS ontology models that are stored in memory and use the transitive reasoner for entailments */
158: public static final OntModelSpec RDFS_MEM_TRANS_INF = new OntModelSpec(
159: ModelFactory.createMemModelMaker(), null,
160: TransitiveReasonerFactory.theInstance(),
161: ProfileRegistry.RDFS_LANG);
162:
163: /** A specification for RDFS ontology models that are stored in memory and use the RDFS inferencer for additional entailments */
164: public static final OntModelSpec RDFS_MEM_RDFS_INF = new OntModelSpec(
165: ModelFactory.createMemModelMaker(), null,
166: RDFSRuleReasonerFactory.theInstance(),
167: ProfileRegistry.RDFS_LANG);
168:
169: // Instance variables
170: //////////////////////////////////
171:
172: /** The specification document manager */
173: protected OntDocumentManager m_docManager = null;
174:
175: /** The specification reasoner */
176: protected Reasoner m_reasoner = null;
177:
178: /** The language URI for the ontology */
179: protected String m_languageURI;
180:
181: /** The ontology language profile */
182: protected Profile m_profile = null;
183:
184: /** The reasoner factory for creating the reasoner on demand */
185: protected ReasonerFactory m_rFactory = null;
186:
187: /** The ModelMaker used for creating imported models */
188: protected ModelMaker m_importsMaker;
189:
190: /** the name of the base model in the baseModelMaker, if specified */
191: protected String m_baseModelName;
192:
193: /** the ModelGetter which will be used - eventually - for imports */
194: protected ModelGetter importModelGetter;
195:
196: // Constructors
197: //////////////////////////////////
198:
199: /**
200: * <p>Construct a new ontology model specification with the given specification parameters</p>
201: * @param importsMaker The model maker, which will be used to construct stores for statements in the
202: * imported ontologies and the base ontology. Use null to get a default (memory) model maker.
203: * @param docMgr The document manager, or null for the default document manager.
204: * @param rFactory The factory for the reasoner to use to infer additional triples in the model, or null for no reasoner
205: * @param languageURI The URI of the ontology language. Required.
206: */
207: public OntModelSpec(ModelMaker importsMaker,
208: OntDocumentManager docMgr, ReasonerFactory rFactory,
209: String languageURI) {
210: this (ModelFactory.createMemModelMaker(), importsMaker, docMgr,
211: rFactory, languageURI);
212: }
213:
214: /**
215: * Construct a new ontology model specification from the supplied components.
216: * @param baseMaker the model-maker to use for the base model
217: * @param importsMaker the model-maker to use for imported models
218: * @param docMgr the document manager (null for the default manager)
219: * @param rFactory the reasoner (null for no reasoner)
220: * @param languageURI the ontology language URI (must not be null)
221: */
222: public OntModelSpec(ModelMaker baseMaker, ModelMaker importsMaker,
223: OntDocumentManager docMgr, ReasonerFactory rFactory,
224: String languageURI) {
225: this (null, baseMaker, importsMaker, docMgr, rFactory,
226: languageURI);
227: }
228:
229: protected ModelMaker maker;
230:
231: /**
232: * Construct a new ontology model specification from the supplied components.
233: * @param baseModelName the name of the model in the baseModelMaker
234: * @param baseMaker the model-maker to use for the base model
235: * @param importsMaker the model-maker to use for imported models
236: * @param docMgr the document manager (null for the default manager)
237: * @param rFactory the reasoner (null for no reasoner)
238: * @param languageURI the ontology language URI (must not be null)
239: */
240: public OntModelSpec(String baseModelName, ModelMaker baseMaker,
241: ModelMaker importsMaker, OntDocumentManager docMgr,
242: ReasonerFactory rFactory, String languageURI) {
243: // super( baseMaker );
244: this .maker = baseMaker;
245: m_baseModelName = baseModelName;
246: m_importsMaker = importsMaker == null ? ModelFactory
247: .createMemModelMaker() : importsMaker;
248: setDocumentManager(docMgr);
249: setReasonerFactory(rFactory);
250:
251: if (languageURI == null) {
252: throw new IllegalArgumentException(
253: "Cannot create OntModelSpec with a null ontology language");
254: }
255: setLanguage(languageURI);
256: }
257:
258: /**
259: * <p>Create one model spec as a copy of another. This is useful when what is required is similar to
260: * an existing spec, but with some changes. <strong>Note:</strong> this is only a shallow copy, so the
261: * structured objects (reasoners, document managers, etc) are not themselves copied. Thus, even after
262: * calling this copy constructor, making a change to the document manager in the copy specification
263: * will also affect the one that the copy was made from. The correct idiom is to replace the object
264: * before side-effecting it, e.g:
265: * <code><pre>
266: * OntModelSpec newSpec = new OntModelSpec( existingSpec );
267: * newSpec.setDocumentManager( new OntDocumentManager() );
268: * newSpec.getDocumentManager().setMetaDataSearchPath( "..." );
269: * </pre></code>
270: * @param spec
271: */
272: public OntModelSpec(OntModelSpec spec) {
273: this (spec.getBaseModelMaker(), spec.getImportModelMaker(), spec
274: .getDocumentManager(), spec.getReasonerFactory(), spec
275: .getLanguage());
276: }
277:
278: public boolean equals(Object other) {
279: return other instanceof OntModelSpec
280: && same((OntModelSpec) other);
281: }
282:
283: private boolean same(OntModelSpec other) {
284: return getLanguage().equals(other.getLanguage())
285: && sameReasonerFactory(other)
286: && getDocumentManager().equals(
287: other.getDocumentManager())
288: && getImportModelGetter().equals(
289: other.getImportModelGetter());
290: }
291:
292: private boolean sameReasonerFactory(OntModelSpec other) {
293: ReasonerFactory rf = getReasonerFactory();
294: ReasonerFactory orf = other.getReasonerFactory();
295: return rf == null ? orf == null : rf.equals(orf);
296: }
297:
298: /**
299: * Answer the model maker used for creating imported models.
300: * @return The ModelMaker that is used to get or create a model used
301: * to hold imports to an OntModel.
302: */
303: public ModelMaker getImportModelMaker() {
304: return m_importsMaker;
305: }
306:
307: /**
308: * Answer the model maker used for creating base models.
309: */
310: public ModelMaker getBaseModelMaker() {
311: return maker;
312: }
313:
314: public ModelGetter getImportModelGetter() {
315: if (importModelGetter == null)
316: importModelGetter = m_importsMaker; // fabricateModelGetter();
317: return importModelGetter;
318: }
319:
320: public void setImportModelGetter(ModelGetter mg) {
321: importModelGetter = mg;
322: }
323:
324: /**
325: Answer the OntModelSpec described using the Jena Assembler vocabulary
326: properties of <code>root</code>. If the assembled resource is not
327: an OntModelSpec, throw an exception reporting the constructed class.
328: */
329: public static OntModelSpec assemble(Resource root) {
330: Object assembled = Assembler.general.open(root);
331: if (!(assembled instanceof OntModelSpec))
332: throw new JenaException(
333: "assemble: expected an OntModelSpec, but got a "
334: + assembled.getClass().getName());
335: return (OntModelSpec) assembled;
336: }
337:
338: /**
339: Answer the OntModelSpec described using the Jena Assembler vocabulary
340: properties of the single resource in <code>model</code> of type
341: JA:OntModelSpec.
342: */
343: public static OntModelSpec assemble(Model model) {
344: return assemble(AssemblerHelp
345: .singleRoot(model, JA.OntModelSpec));
346: }
347:
348: /**
349: * <p>Answer a default specification for the given language URI. This default
350: * will typically use a memory model and have minimal inferencing capabilities.
351: * Specifically, OWL and RDFS languages will have RDFS level inferencing
352: * capability (chosen to give a reasonable balance between power and efficiency
353: * of computation), and DAML language will have the minimal DAML rule reasoner.
354: * To get other (more powerful or less powerful) reasoning capabilities, users
355: * should create ontology models by passing an explicit <code>OntModelSpec</code>
356: * parameter to the
357: * {@link ModelFactory#createOntologyModel( OntModelSpec, Model ) model factory}.
358: * </p>
359: * @param languageURI The ontology language we want a default model spec for
360: * @return The default model spec for that language
361: * @exception OntologyException if the URI is not a recognised name of an ontology language
362: */
363: public static OntModelSpec getDefaultSpec(String languageURI) {
364: if (languageURI.equals(ProfileRegistry.OWL_LANG)) {
365: return OWL_MEM_RDFS_INF;
366: } else if (languageURI.equals(ProfileRegistry.OWL_DL_LANG)) {
367: return OWL_DL_MEM_RDFS_INF;
368: } else if (languageURI.equals(ProfileRegistry.OWL_LITE_LANG)) {
369: return OWL_LITE_MEM_RDFS_INF;
370: } else if (languageURI.equals(ProfileRegistry.DAML_LANG)) {
371: return DAML_MEM_RULE_INF;
372: } else if (languageURI.equals(ProfileRegistry.RDFS_LANG)) {
373: return RDFS_MEM_RDFS_INF;
374: } else {
375: throw new OntologyException(
376: "Did not recognise this language URI, so cannot determine default model spec: "
377: + languageURI);
378: }
379: }
380:
381: /**
382: * <p>Answer the document manager for this model specification. Defaults to
383: * a standard instance of {@link OntDocumentManager}</p>
384: * @return The document manager to be used by models matching this specification
385: */
386: public OntDocumentManager getDocumentManager() {
387: if (m_docManager == null) {
388: // need to set the default document manager
389: m_docManager = OntDocumentManager.getInstance();
390: }
391:
392: return m_docManager;
393: }
394:
395: /**
396: * <p>Set the document manager in this specification</p>
397: * @param docMgr The new document manager
398: */
399: public void setDocumentManager(OntDocumentManager docMgr) {
400: m_docManager = docMgr;
401: }
402:
403: /**
404: * <p>Set the model maker that will be used when the ontology model needs to create
405: * an additional container for an imported ontology</p>
406: * @param maker The new model maker to use
407: */
408: public void setImportModelMaker(ModelMaker maker) {
409: m_importsMaker = maker;
410: }
411:
412: /**
413: * <p>Set the model maker used for base models.</p>
414: * @param m The model maker that is used to create the base model
415: * if one is not supplied when a model is created.
416: */
417: public void setBaseModelMaker(ModelMaker m) {
418: this .maker = m;
419: }
420:
421: /**
422: * <p>Answer the reasoner that will be used to infer additional entailed
423: * triples in the ontology model.</p>
424: * @return The reasoner for this specification
425: */
426: public Reasoner getReasoner() {
427: if (m_reasoner == null && m_rFactory != null) {
428: // we need to create the reasoner
429: // create a new one on each call since reasoners aren't guaranteed to be reusable
430: return m_rFactory.create(null);
431: }
432:
433: return m_reasoner;
434: }
435:
436: /**
437: * <p>Set the reasoner that will be used by ontology models that conform
438: * to this specification to compute entailments.
439: * <strong>Note:</strong> The reasoner is generated on demand by the reasoner
440: * factory. To prevent this spec from having a reasoner, set the reasoner factory
441: * to null, see {@link #setReasonerFactory}.
442: * </p>
443: * @param reasoner The new reasoner
444: */
445: public void setReasoner(Reasoner reasoner) {
446: m_reasoner = reasoner;
447: }
448:
449: /**
450: * <p>Set the factory object that will be used to generate the reasoner object
451: * for this model specification. <strong>Note</strong> that the reasoner itself is cached, so setting
452: * the factory after a call to {@link #getReasoner()} will have no effect.</p>
453: * @param rFactory The new reasoner factory, or null to prevent any reasoner being used
454: */
455: public void setReasonerFactory(ReasonerFactory rFactory) {
456: m_rFactory = rFactory;
457: }
458:
459: /**
460: * <p>Answer the current reasoner factory</p>
461: * @return The reasoner factory, or null.
462: */
463: public ReasonerFactory getReasonerFactory() {
464: return m_rFactory;
465: }
466:
467: /**
468: * <p>Answer the URI of the ontology language to use when constructing
469: * models from this specification. Well known language URI's are
470: * available from the {@link ProfileRegistry}</p>
471: * @return The ontology language URI
472: */
473: public String getLanguage() {
474: return m_languageURI;
475: }
476:
477: /**
478: * <p>Set the URI of the ontology to use for models that conform to
479: * this specification.</p>
480: * @param languageURI The new language URI
481: * @exception OntologyException if the URI does not map to a known language profile
482: */
483: public void setLanguage(String languageURI) {
484: m_languageURI = languageURI;
485: m_profile = ProfileRegistry.getInstance().getProfile(
486: m_languageURI);
487:
488: if (m_profile == null) {
489: throw new OntologyException(
490: "Could not determine an ontology language profile for URI "
491: + m_languageURI);
492: }
493: }
494:
495: /**
496: * <p>Answer the language profile for this ontology specification</p>
497: * @return An ontology language profile object
498: */
499: public Profile getProfile() {
500: return m_profile;
501: }
502:
503: /**
504: * <p>Create an OntModel according to this model specification.
505: * The base model comes from the attached base ModelMaker.</p>
506: * @return an OntModel satisfying this specification
507: */
508: public Model doCreateModel() {
509: Model m = m_baseModelName == null ? maker.createFreshModel()
510: : maker.createModel(m_baseModelName);
511: return new OntModelImpl(this , m);
512: }
513:
514: /**
515: * <p>Create an OntModel according to this model specification.
516: * The base model comes from the underlying ModelMaker and is named by the
517: * given name.</p>
518: */
519: public Model implementCreateModelOver(String name) {
520: return new OntModelImpl(this , maker.createModel(name, false));
521: }
522:
523: /**
524: Answer a base model constructed according to this specification. This is used for the
525: "base" (i.e. non-imported) model for an OntModel.
526: */
527: public Model createBaseModel() {
528: return ModelFactory.createDefaultModel();
529: }
530:
531: }
532:
533: /*
534: (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
535: All rights reserved.
536:
537: Redistribution and use in source and binary forms, with or without
538: modification, are permitted provided that the following conditions
539: are met:
540:
541: 1. Redistributions of source code must retain the above copyright
542: notice, this list of conditions and the following disclaimer.
543:
544: 2. Redistributions in binary form must reproduce the above copyright
545: notice, this list of conditions and the following disclaimer in the
546: documentation and/or other materials provided with the distribution.
547:
548: 3. The name of the author may not be used to endorse or promote products
549: derived from this software without specific prior written permission.
550:
551: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
552: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
553: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
554: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
555: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
556: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
557: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
558: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
559: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
560: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
561: */
|