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 10 Feb 2003
009: * Filename $RCSfile: OWLProfile.java,v $
010: * Revision $Revision: 1.35 $
011: * Release status $State: Exp $
012: *
013: * Last modified on $Date: 2008/01/02 12:08:02 $
014: * by $Author: andy_seaborne $
015: *
016: * (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
017: * (see footer for full conditions)
018: *****************************************************************************/package com.hp.hpl.jena.ontology.impl;
019:
020: // Imports
021: ///////////////
022: import com.hp.hpl.jena.vocabulary.*;
023: import com.hp.hpl.jena.enhanced.*;
024: import com.hp.hpl.jena.graph.*;
025: import com.hp.hpl.jena.ontology.*;
026: import com.hp.hpl.jena.rdf.model.*;
027:
028: import java.util.*;
029:
030: /**
031: * <p>
032: * Ontology language profile implementation for the Full variant of the OWL 2002/07 language.
033: * </p>
034: *
035: * @author Ian Dickinson, HP Labs
036: * (<a href="mailto:Ian.Dickinson@hp.com" >email</a>)
037: * @version CVS $Id: OWLProfile.java,v 1.35 2008/01/02 12:08:02 andy_seaborne Exp $
038: */
039: public class OWLProfile extends AbstractProfile {
040: // Constants
041: //////////////////////////////////
042:
043: // Instance variables
044: //////////////////////////////////
045:
046: // Constructors
047: //////////////////////////////////
048:
049: // External signature methods
050: //////////////////////////////////
051:
052: public String NAMESPACE() {
053: return OWL.getURI();
054: }
055:
056: public Resource CLASS() {
057: return OWL.Class;
058: }
059:
060: public Resource RESTRICTION() {
061: return OWL.Restriction;
062: }
063:
064: public Resource THING() {
065: return OWL.Thing;
066: }
067:
068: public Resource NOTHING() {
069: return OWL.Nothing;
070: }
071:
072: public Resource PROPERTY() {
073: return RDF.Property;
074: }
075:
076: public Resource OBJECT_PROPERTY() {
077: return OWL.ObjectProperty;
078: }
079:
080: public Resource DATATYPE_PROPERTY() {
081: return OWL.DatatypeProperty;
082: }
083:
084: public Resource TRANSITIVE_PROPERTY() {
085: return OWL.TransitiveProperty;
086: }
087:
088: public Resource SYMMETRIC_PROPERTY() {
089: return OWL.SymmetricProperty;
090: }
091:
092: public Resource FUNCTIONAL_PROPERTY() {
093: return OWL.FunctionalProperty;
094: }
095:
096: public Resource INVERSE_FUNCTIONAL_PROPERTY() {
097: return OWL.InverseFunctionalProperty;
098: }
099:
100: public Resource ALL_DIFFERENT() {
101: return OWL.AllDifferent;
102: }
103:
104: public Resource ONTOLOGY() {
105: return OWL.Ontology;
106: }
107:
108: public Resource DEPRECATED_CLASS() {
109: return OWL.DeprecatedClass;
110: }
111:
112: public Resource DEPRECATED_PROPERTY() {
113: return OWL.DeprecatedProperty;
114: }
115:
116: public Resource ANNOTATION_PROPERTY() {
117: return OWL.AnnotationProperty;
118: }
119:
120: public Resource ONTOLOGY_PROPERTY() {
121: return OWL.OntologyProperty;
122: }
123:
124: public Resource LIST() {
125: return RDF.List;
126: }
127:
128: public Resource NIL() {
129: return RDF.nil;
130: }
131:
132: public Resource DATARANGE() {
133: return OWL.DataRange;
134: }
135:
136: public Property EQUIVALENT_PROPERTY() {
137: return OWL.equivalentProperty;
138: }
139:
140: public Property EQUIVALENT_CLASS() {
141: return OWL.equivalentClass;
142: }
143:
144: public Property DISJOINT_WITH() {
145: return OWL.disjointWith;
146: }
147:
148: public Property SAME_INDIVIDUAL_AS() {
149: return null;
150: }
151:
152: public Property SAME_AS() {
153: return OWL.sameAs;
154: }
155:
156: public Property DIFFERENT_FROM() {
157: return OWL.differentFrom;
158: }
159:
160: public Property DISTINCT_MEMBERS() {
161: return OWL.distinctMembers;
162: }
163:
164: public Property UNION_OF() {
165: return OWL.unionOf;
166: }
167:
168: public Property INTERSECTION_OF() {
169: return OWL.intersectionOf;
170: }
171:
172: public Property COMPLEMENT_OF() {
173: return OWL.complementOf;
174: }
175:
176: public Property ONE_OF() {
177: return OWL.oneOf;
178: }
179:
180: public Property ON_PROPERTY() {
181: return OWL.onProperty;
182: }
183:
184: public Property ALL_VALUES_FROM() {
185: return OWL.allValuesFrom;
186: }
187:
188: public Property HAS_VALUE() {
189: return OWL.hasValue;
190: }
191:
192: public Property SOME_VALUES_FROM() {
193: return OWL.someValuesFrom;
194: }
195:
196: public Property MIN_CARDINALITY() {
197: return OWL.minCardinality;
198: }
199:
200: public Property MAX_CARDINALITY() {
201: return OWL.maxCardinality;
202: }
203:
204: public Property CARDINALITY() {
205: return OWL.cardinality;
206: }
207:
208: public Property INVERSE_OF() {
209: return OWL.inverseOf;
210: }
211:
212: public Property IMPORTS() {
213: return OWL.imports;
214: }
215:
216: public Property PRIOR_VERSION() {
217: return OWL.priorVersion;
218: }
219:
220: public Property BACKWARD_COMPATIBLE_WITH() {
221: return OWL.backwardCompatibleWith;
222: }
223:
224: public Property INCOMPATIBLE_WITH() {
225: return OWL.incompatibleWith;
226: }
227:
228: public Property SUB_PROPERTY_OF() {
229: return RDFS.subPropertyOf;
230: }
231:
232: public Property SUB_CLASS_OF() {
233: return RDFS.subClassOf;
234: }
235:
236: public Property DOMAIN() {
237: return RDFS.domain;
238: }
239:
240: public Property RANGE() {
241: return RDFS.range;
242: }
243:
244: public Property FIRST() {
245: return RDF.first;
246: }
247:
248: public Property REST() {
249: return RDF.rest;
250: }
251:
252: public Property MIN_CARDINALITY_Q() {
253: return null;
254: } // qualified restrictions are not in the first version of OWL
255:
256: public Property MAX_CARDINALITY_Q() {
257: return null;
258: }
259:
260: public Property CARDINALITY_Q() {
261: return null;
262: }
263:
264: public Property HAS_CLASS_Q() {
265: return null;
266: }
267:
268: // Annotations
269: public Property VERSION_INFO() {
270: return OWL.versionInfo;
271: }
272:
273: public Property LABEL() {
274: return RDFS.label;
275: }
276:
277: public Property COMMENT() {
278: return RDFS.comment;
279: }
280:
281: public Property SEE_ALSO() {
282: return RDFS.seeAlso;
283: }
284:
285: public Property IS_DEFINED_BY() {
286: return RDFS.isDefinedBy;
287: }
288:
289: protected Resource[][] aliasTable() {
290: return new Resource[][] {};
291: }
292:
293: /** The only first-class axiom type in OWL is AllDifferent */
294: public Iterator getAxiomTypes() {
295: return Arrays.asList(new Resource[] { OWL.AllDifferent })
296: .iterator();
297: }
298:
299: /** The annotation properties of OWL */
300: public Iterator getAnnotationProperties() {
301: return Arrays.asList(
302: new Resource[] { OWL.versionInfo, RDFS.label,
303: RDFS.seeAlso, RDFS.comment, RDFS.isDefinedBy })
304: .iterator();
305: }
306:
307: public Iterator getClassDescriptionTypes() {
308: return Arrays.asList(
309: new Resource[] { OWL.Class, OWL.Restriction })
310: .iterator();
311: }
312:
313: /**
314: * <p>
315: * Answer true if the given graph supports a view of this node as the given
316: * language element, according to the semantic constraints of the profile.
317: * If strict checking on the ontology model is turned off, this check is
318: * skipped.
319: * </p>
320: *
321: * @param n A node to test
322: * @param g The enhanced graph containing <code>n</code>, which is assumed to
323: * be an {@link OntModel}.
324: * @param type A class indicating the facet that we are testing against.
325: * @return True if strict checking is off, or if <code>n</code> can be
326: * viewed according to the facet resource <code>res</code>
327: */
328: public boolean isSupported(Node n, EnhGraph g, Class type) {
329: if (g instanceof OntModel) {
330: OntModel m = (OntModel) g;
331:
332: if (!m.strictMode()) {
333: // checking turned off
334: return true;
335: } else {
336: // lookup the profile check for this resource
337: SupportsCheck check = (SupportsCheck) getCheckTable()
338: .get(type);
339:
340: // a check must be defined for the test to succeed
341: return (check != null) && check.doCheck(n, g);
342: }
343: } else {
344: return false;
345: }
346: }
347:
348: /**
349: * <p>
350: * Answer a descriptive string for this profile, for use in debugging and other output.
351: * </p>
352: * @return "OWL Full"
353: */
354: public String getLabel() {
355: return "OWL Full";
356: }
357:
358: // Internal implementation methods
359: //////////////////////////////////
360:
361: //==============================================================================
362: // Inner class definitions
363: //==============================================================================
364:
365: /** Helper class for doing syntactic/semantic checks on a node */
366: protected static class SupportsCheck {
367: public boolean doCheck(Node n, EnhGraph g) {
368: return true;
369: }
370: }
371:
372: // Table of check data
373: //////////////////////
374:
375: private static Object[][] s_supportsCheckData = new Object[][] {
376: // Resource (key), check method
377: { AllDifferent.class, new SupportsCheck() {
378: public boolean doCheck(Node n, EnhGraph g) {
379: return g.asGraph().contains(n, RDF.type.asNode(),
380: OWL.AllDifferent.asNode());
381: }
382: } },
383: { AnnotationProperty.class, new SupportsCheck() {
384: public boolean doCheck(Node n, EnhGraph g) {
385: for (Iterator i = ((OntModel) g).getProfile()
386: .getAnnotationProperties(); i.hasNext();) {
387: if (((Resource) i.next()).asNode().equals(n)) {
388: // a built-in annotation property
389: return true;
390: }
391: }
392: return g.asGraph().contains(n, RDF.type.asNode(),
393: OWL.AnnotationProperty.asNode());
394: }
395: } },
396: { OntClass.class, new SupportsCheck() {
397: public boolean doCheck(Node n, EnhGraph eg) {
398: Graph g = eg.asGraph();
399: Node rdfTypeNode = RDF.type.asNode();
400: return g.contains(n, rdfTypeNode, OWL.Class
401: .asNode())
402: || g.contains(n, rdfTypeNode,
403: OWL.Restriction.asNode())
404: || g.contains(n, rdfTypeNode, RDFS.Class
405: .asNode())
406: || g.contains(n, rdfTypeNode, RDFS.Datatype
407: .asNode())
408: ||
409: // These are common cases that we should support
410: n.equals(OWL.Thing.asNode())
411: || n.equals(OWL.Nothing.asNode())
412: || g.contains(Node.ANY, RDFS.domain
413: .asNode(), n)
414: || g.contains(Node.ANY,
415: RDFS.range.asNode(), n)
416: || g.contains(n, OWL.intersectionOf
417: .asNode(), Node.ANY)
418: || g.contains(n, OWL.unionOf.asNode(),
419: Node.ANY)
420: || g.contains(n, OWL.complementOf.asNode(),
421: Node.ANY);
422: }
423: } },
424: { DatatypeProperty.class, new SupportsCheck() {
425: public boolean doCheck(Node n, EnhGraph g) {
426: return g.asGraph().contains(n, RDF.type.asNode(),
427: OWL.DatatypeProperty.asNode());
428: }
429: } },
430: { ObjectProperty.class, new SupportsCheck() {
431: public boolean doCheck(Node n, EnhGraph g) {
432: return g.asGraph().contains(n, RDF.type.asNode(),
433: OWL.ObjectProperty.asNode())
434: || g.asGraph().contains(n,
435: RDF.type.asNode(),
436: OWL.TransitiveProperty.asNode())
437: || g.asGraph().contains(n,
438: RDF.type.asNode(),
439: OWL.SymmetricProperty.asNode())
440: || g.asGraph().contains(
441: n,
442: RDF.type.asNode(),
443: OWL.InverseFunctionalProperty
444: .asNode());
445: }
446: } },
447: { FunctionalProperty.class, new SupportsCheck() {
448: public boolean doCheck(Node n, EnhGraph g) {
449: return g.asGraph().contains(n, RDF.type.asNode(),
450: OWL.FunctionalProperty.asNode());
451: }
452: } },
453: { InverseFunctionalProperty.class, new SupportsCheck() {
454: public boolean doCheck(Node n, EnhGraph g) {
455: return g.asGraph().contains(n, RDF.type.asNode(),
456: OWL.InverseFunctionalProperty.asNode());
457: }
458: } },
459: { RDFList.class, new SupportsCheck() {
460: public boolean doCheck(Node n, EnhGraph g) {
461: return n.equals(RDF.nil.asNode())
462: || g.asGraph().contains(n,
463: RDF.type.asNode(),
464: RDF.List.asNode());
465: }
466: } },
467: { OntProperty.class, new SupportsCheck() {
468: public boolean doCheck(Node n, EnhGraph g) {
469: return g.asGraph().contains(n, RDF.type.asNode(),
470: RDF.Property.asNode())
471: || g.asGraph().contains(n,
472: RDF.type.asNode(),
473: OWL.ObjectProperty.asNode())
474: || g.asGraph().contains(n,
475: RDF.type.asNode(),
476: OWL.DatatypeProperty.asNode())
477: || g.asGraph().contains(n,
478: RDF.type.asNode(),
479: OWL.AnnotationProperty.asNode())
480: || g.asGraph().contains(n,
481: RDF.type.asNode(),
482: OWL.TransitiveProperty.asNode())
483: || g.asGraph().contains(n,
484: RDF.type.asNode(),
485: OWL.SymmetricProperty.asNode())
486: || g.asGraph().contains(n,
487: RDF.type.asNode(),
488: OWL.FunctionalProperty.asNode())
489: || g.asGraph().contains(
490: n,
491: RDF.type.asNode(),
492: OWL.InverseFunctionalProperty
493: .asNode());
494: }
495: } },
496: { Ontology.class, new SupportsCheck() {
497: public boolean doCheck(Node n, EnhGraph g) {
498: return g.asGraph().contains(n, RDF.type.asNode(),
499: OWL.Ontology.asNode());
500: }
501: } },
502: { Restriction.class, new SupportsCheck() {
503: public boolean doCheck(Node n, EnhGraph g) {
504: return g.asGraph().contains(n, RDF.type.asNode(),
505: OWL.Restriction.asNode());
506: }
507: } },
508: { HasValueRestriction.class, new SupportsCheck() {
509: public boolean doCheck(Node n, EnhGraph g) {
510: return g.asGraph().contains(n, RDF.type.asNode(),
511: OWL.Restriction.asNode())
512: && containsSome(g, n, OWL.hasValue)
513: && containsSome(g, n, OWL.onProperty);
514: }
515: } },
516: { AllValuesFromRestriction.class, new SupportsCheck() {
517: public boolean doCheck(Node n, EnhGraph g) {
518: return g.asGraph().contains(n, RDF.type.asNode(),
519: OWL.Restriction.asNode())
520: && containsSome(g, n, OWL.allValuesFrom)
521: && containsSome(g, n, OWL.onProperty);
522: }
523: } },
524: { SomeValuesFromRestriction.class, new SupportsCheck() {
525: public boolean doCheck(Node n, EnhGraph g) {
526: return g.asGraph().contains(n, RDF.type.asNode(),
527: OWL.Restriction.asNode())
528: && containsSome(g, n, OWL.someValuesFrom)
529: && containsSome(g, n, OWL.onProperty);
530: }
531: } },
532: { CardinalityRestriction.class, new SupportsCheck() {
533: public boolean doCheck(Node n, EnhGraph g) {
534: return g.asGraph().contains(n, RDF.type.asNode(),
535: OWL.Restriction.asNode())
536: && containsSome(g, n, OWL.cardinality)
537: && containsSome(g, n, OWL.onProperty);
538: }
539: } },
540: { MinCardinalityRestriction.class, new SupportsCheck() {
541: public boolean doCheck(Node n, EnhGraph g) {
542: return g.asGraph().contains(n, RDF.type.asNode(),
543: OWL.Restriction.asNode())
544: && containsSome(g, n, OWL.minCardinality)
545: && containsSome(g, n, OWL.onProperty);
546: }
547: } },
548: { MaxCardinalityRestriction.class, new SupportsCheck() {
549: public boolean doCheck(Node n, EnhGraph g) {
550: return g.asGraph().contains(n, RDF.type.asNode(),
551: OWL.Restriction.asNode())
552: && containsSome(g, n, OWL.maxCardinality)
553: && containsSome(g, n, OWL.onProperty);
554: }
555: } }, { SymmetricProperty.class, new SupportsCheck() {
556: public boolean doCheck(Node n, EnhGraph g) {
557: return g.asGraph().contains(n, RDF.type.asNode(),
558: OWL.SymmetricProperty.asNode())
559: && !g.asGraph().contains(n,
560: RDF.type.asNode(),
561: OWL.DatatypeProperty.asNode());
562: }
563: } }, { TransitiveProperty.class, new SupportsCheck() {
564: public boolean doCheck(Node n, EnhGraph g) {
565: return g.asGraph().contains(n, RDF.type.asNode(),
566: OWL.TransitiveProperty.asNode())
567: && !g.asGraph().contains(n,
568: RDF.type.asNode(),
569: OWL.DatatypeProperty.asNode());
570: }
571: } }, { Individual.class, new SupportsCheck() {
572: public boolean doCheck(Node n, EnhGraph g) {
573: return n instanceof Node_URI
574: || n instanceof Node_Blank;
575: }
576: } }, { DataRange.class, new SupportsCheck() {
577: public boolean doCheck(Node n, EnhGraph g) {
578: return n instanceof Node_Blank
579: && g.asGraph().contains(n,
580: RDF.type.asNode(),
581: OWL.DataRange.asNode());
582: }
583: } } };
584:
585: // to allow concise reference in the code above.
586: public static boolean containsSome(EnhGraph g, Node n, Property p) {
587: return AbstractProfile.containsSome(g, n, p);
588: }
589:
590: // Static variables
591: //////////////////////////////////
592:
593: /** Map from resource to syntactic/semantic checks that a node can be seen as the given facet */
594: private static HashMap s_supportsChecks = new HashMap();
595:
596: static {
597: // initialise the map of supports checks from a table of static data
598: for (int i = 0; i < s_supportsCheckData.length; i++) {
599: s_supportsChecks.put(s_supportsCheckData[i][0],
600: s_supportsCheckData[i][1]);
601: }
602: }
603:
604: protected Map getCheckTable() {
605: return s_supportsChecks;
606: }
607: }
608:
609: /*
610: (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
611: All rights reserved.
612:
613: Redistribution and use in source and binary forms, with or without
614: modification, are permitted provided that the following conditions
615: are met:
616:
617: 1. Redistributions of source code must retain the above copyright
618: notice, this list of conditions and the following disclaimer.
619:
620: 2. Redistributions in binary form must reproduce the above copyright
621: notice, this list of conditions and the following disclaimer in the
622: documentation and/or other materials provided with the distribution.
623:
624: 3. The name of the author may not be used to endorse or promote products
625: derived from this software without specific prior written permission.
626:
627: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
628: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
629: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
630: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
631: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
632: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
633: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
634: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
635: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
636: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
637: */
|