001 /*
002 * The contents of this file are subject to the Mozilla Public License
003 * Version 1.1 (the "License"); you may not use this file except in
004 * compliance with the License. You may obtain a copy of the License at
005 * http://www.mozilla.org/MPL/
006 *
007 * Software distributed under the License is distributed on an "AS IS" basis,
008 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009 * the specific language governing rights and limitations under the License.
010 *
011 * The Original Code is Protege-2000.
012 *
013 * The Initial Developer of the Original Code is Stanford University. Portions
014 * created by Stanford University are Copyright (C) 2007. All Rights Reserved.
015 *
016 * Protege was developed by Stanford Medical Informatics
017 * (http://www.smi.stanford.edu) at the Stanford University School of Medicine
018 * with support from the National Library of Medicine, the National Science
019 * Foundation, and the Defense Advanced Research Projects Agency. Current
020 * information about Protege can be obtained at http://protege.stanford.edu.
021 *
022 */
023
024 package edu.stanford.smi.protegex.owl.model.impl;
025
026 import java.util.ArrayList;
027 import java.util.Collection;
028 import java.util.Collections;
029 import java.util.HashSet;
030 import java.util.Iterator;
031 import java.util.Set;
032
033 import javax.swing.Icon;
034 import javax.swing.ImageIcon;
035
036 import edu.stanford.smi.protege.model.Cls;
037 import edu.stanford.smi.protege.model.FrameID;
038 import edu.stanford.smi.protege.model.KnowledgeBase;
039 import edu.stanford.smi.protege.model.Slot;
040 import edu.stanford.smi.protegex.owl.model.OWLAllValuesFrom;
041 import edu.stanford.smi.protegex.owl.model.OWLAnonymousClass;
042 import edu.stanford.smi.protegex.owl.model.OWLCardinality;
043 import edu.stanford.smi.protegex.owl.model.OWLCardinalityBase;
044 import edu.stanford.smi.protegex.owl.model.OWLDatatypeProperty;
045 import edu.stanford.smi.protegex.owl.model.OWLHasValue;
046 import edu.stanford.smi.protegex.owl.model.OWLIndividual;
047 import edu.stanford.smi.protegex.owl.model.OWLIntersectionClass;
048 import edu.stanford.smi.protegex.owl.model.OWLMaxCardinality;
049 import edu.stanford.smi.protegex.owl.model.OWLMinCardinality;
050 import edu.stanford.smi.protegex.owl.model.OWLNamedClass;
051 import edu.stanford.smi.protegex.owl.model.OWLNames;
052 import edu.stanford.smi.protegex.owl.model.OWLRestriction;
053 import edu.stanford.smi.protegex.owl.model.OWLSomeValuesFrom;
054 import edu.stanford.smi.protegex.owl.model.ProtegeNames;
055 import edu.stanford.smi.protegex.owl.model.RDFProperty;
056 import edu.stanford.smi.protegex.owl.model.RDFResource;
057 import edu.stanford.smi.protegex.owl.model.RDFSClass;
058 import edu.stanford.smi.protegex.owl.model.RDFSNamedClass;
059 import edu.stanford.smi.protege.model.Transaction;
060 import edu.stanford.smi.protegex.owl.model.*;
061 import edu.stanford.smi.protegex.owl.model.visitor.OWLModelVisitor;
062 import edu.stanford.smi.protegex.owl.ui.icons.OWLIcons;
063
064 /**
065 * The default implementation of the OWLNamedClass interface.
066 *
067 * @author Holger Knublauch <holger@knublauch.com>
068 */
069 public class DefaultOWLNamedClass extends DefaultRDFSNamedClass implements OWLNamedClass {
070
071
072 public DefaultOWLNamedClass(KnowledgeBase kb, FrameID id) {
073 super(kb, id);
074 }
075
076
077 public DefaultOWLNamedClass() {
078 }
079
080
081 public void addDisjointClass(RDFSClass aClass) {
082 Slot disjointClassesSlot = getOWLModel().getOWLDisjointWithProperty();
083 addOwnSlotValue(disjointClassesSlot, aClass);
084 }
085
086
087 public void addEquivalentClass(final RDFSClass aClass) {
088 new Transaction(getOWLModel(), "Add Equivalent Class" + Transaction.APPLY_TO_TRAILER_STRING + this.getName()) {
089 public boolean doOperations() {
090 if (!hasDirectSuperclass(aClass)) {
091 addDirectSuperclass(aClass);
092 }
093 if (!aClass.isSubclassOf(DefaultOWLNamedClass.this)) {
094 aClass.addSuperclass(DefaultOWLNamedClass.this);
095 }
096 return true;
097 };
098 }.execute();
099 }
100
101
102 public void addInferredSuperclass(RDFSClass superclass) {
103 Slot superclassesSlot = getAbstractOWLModel().getProtegeInferredSuperclassesProperty();
104 addOwnSlotValue(superclassesSlot, superclass);
105 if (superclass instanceof OWLNamedClass) {
106 Slot subclassesSlot = getAbstractOWLModel().getProtegeInferredSubclassesProperty();
107 ((Cls) superclass).addOwnSlotValue(subclassesSlot, this);
108 }
109 }
110
111
112 public OWLIndividual createOWLIndividual(String name) {
113 return (OWLIndividual) createInstance(OWLUtil.getInternalFullName(getOWLModel(), name));
114 }
115
116
117 public boolean equalsStructurally(RDFSClass cls) {
118 return getName().equals(cls.getName());
119 }
120
121
122 public RDFResource getAllValuesFrom(RDFProperty property) {
123 Collection restrictions = getRestrictions(property, true);
124 for (Iterator it = restrictions.iterator(); it.hasNext();) {
125 OWLRestriction restriction = (OWLRestriction) it.next();
126 if (restriction instanceof OWLAllValuesFrom) {
127 return ((OWLAllValuesFrom) restriction).getAllValuesFrom();
128 }
129 }
130 return property.getRange();
131 }
132
133
134 @Override
135 public Set getAssociatedProperties() {
136 Set set = super.getAssociatedProperties();
137 Set maxZeroProperties = new HashSet();
138 Iterator restrictions = getRestrictions(true).iterator();
139 while (restrictions.hasNext()) {
140 OWLRestriction restriction = (OWLRestriction) restrictions.next();
141 RDFProperty property = restriction.getOnProperty();
142 if ((restriction instanceof OWLCardinality || restriction instanceof OWLMaxCardinality) &&
143 ((OWLCardinalityBase) restriction).getCardinality() == 0) {
144 maxZeroProperties.add(property);
145 maxZeroProperties.add(property.getSubproperties(true));
146 }
147 else {
148 set.add(property);
149 set.addAll(property.getSubproperties(true));
150 }
151 }
152 set.removeAll(maxZeroProperties);
153 return set;
154 }
155
156
157 public int getClassificationStatus() {
158 final Slot slot = getAbstractOWLModel().getProtegeClassificationStatusProperty();
159 Collection values = getDirectOwnSlotValues(slot);
160 if (values.size() == 0) {
161 return OWLNames.CLASSIFICATION_STATUS_UNDEFINED;
162 }
163 else {
164 return ((Integer) values.iterator().next()).intValue();
165 }
166 }
167
168
169 public Collection getDirectRestrictions() {
170 Collection result = new ArrayList();
171 getDirectRestrictions(result, getDirectSuperclasses().iterator());
172 return result;
173 }
174
175
176 public Collection getHasValues(RDFProperty property) {
177 Set hasValues = new HashSet();
178
179 for (Iterator it = getRestrictions(property, true).iterator(); it.hasNext();) {
180 OWLRestriction restriction = (OWLRestriction) it.next();
181 if (restriction instanceof OWLHasValue) {
182 OWLHasValue hasValue = (OWLHasValue) restriction;
183 hasValues.add(hasValue.getHasValue());
184 }
185 }
186 return hasValues;
187 }
188
189 public Object getHasValue(RDFProperty property) {
190 for (Iterator it = getRestrictions(property, true).iterator(); it.hasNext();) {
191 OWLRestriction restriction = (OWLRestriction) it.next();
192 if (restriction instanceof OWLHasValue) {
193 OWLHasValue hasValue = (OWLHasValue) restriction;
194 return hasValue.getHasValue();
195 }
196 }
197 return null;
198 }
199
200
201 public Collection getInferredEquivalentClasses() {
202 Collection result = new HashSet();
203 for (Iterator it = getInferredSuperclasses().iterator(); it.hasNext();) {
204 Cls superCls = (Cls) it.next();
205 if (getInferredSubclasses().contains(superCls)) {
206 result.add(superCls);
207 }
208 }
209 return result;
210 }
211
212
213 private void getDirectRestrictions(Collection results, Iterator clses) {
214 while (clses.hasNext()) {
215 Cls cls = (Cls) clses.next();
216 if (cls instanceof OWLRestriction) {
217 results.add(cls);
218 }
219 else if (cls instanceof OWLIntersectionClass) {
220 OWLIntersectionClass logicalCls = (OWLIntersectionClass) cls;
221 getDirectRestrictions(results, logicalCls.getOperands().iterator());
222 }
223 }
224 }
225
226
227 public Collection getInferredSubclasses() {
228 Slot slot = getAbstractOWLModel().getProtegeInferredSubclassesProperty();
229 return getDirectOwnSlotValues(slot);
230 }
231
232
233 public Collection getInferredSuperclasses() {
234 Slot slot = getAbstractOWLModel().getProtegeInferredSuperclassesProperty();
235 return getDirectOwnSlotValues(slot);
236 }
237
238
239 public int getMaxCardinality(RDFProperty property) {
240 if (property.isFunctional()) {
241 return 1;
242 }
243 Collection restrictions = getRestrictions(property, true);
244 for (Iterator it = restrictions.iterator(); it.hasNext();) {
245 OWLRestriction restriction = (OWLRestriction) it.next();
246 if (restriction instanceof OWLCardinalityBase) {
247 OWLCardinalityBase base = (OWLCardinalityBase) restriction;
248 if (!base.isQualified()) {
249 if (restriction instanceof OWLMaxCardinality) {
250 return ((OWLMaxCardinality) restriction).getCardinality();
251 }
252 else if (restriction instanceof OWLCardinality) {
253 return ((OWLCardinality) restriction).getCardinality();
254 }
255 }
256 }
257 }
258 return -1;
259 }
260
261
262 public int getMinCardinality(RDFProperty property) {
263 Collection restrictions = getRestrictions(property, true);
264 for (Iterator it = restrictions.iterator(); it.hasNext();) {
265 OWLRestriction restriction = (OWLRestriction) it.next();
266 if (restriction instanceof OWLMinCardinality) {
267 return ((OWLMinCardinality) restriction).getCardinality();
268 }
269 else if (restriction instanceof OWLCardinality) {
270 return ((OWLCardinality) restriction).getCardinality();
271 }
272 }
273 return 0;
274 }
275
276
277 public Collection getRestrictions() {
278 return getRestrictions(false);
279 }
280
281
282 @Override
283 public Icon getIcon() {
284 if (!getOWLModel().getProject().isMultiUserClient() && isMetaCls()) {
285 return super.getIcon();
286 }
287 else {
288 ImageIcon ii = getImageIconForNonMetaclass();
289 if (isEditable()) {
290 return ii;
291 }
292 else {
293 return OWLIcons.getReadOnlyClsIcon(ii);
294 }
295 }
296 }
297
298
299 @Override
300 public String getIconName() {
301 if(isMetaclass()) {
302 return super.getIconName();
303 }
304 else {
305 return getImageIconNameForNonMetaclass();
306 }
307 }
308
309
310 @Override
311 public ImageIcon getImageIcon() {
312 if (isMetaCls()) {
313 return super.getImageIcon();
314 }
315 else {
316 return getImageIconForNonMetaclass();
317 }
318 }
319
320
321 private ImageIcon getImageIconForNonMetaclass() {
322 String str = getImageIconNameForNonMetaclass();
323 return OWLIcons.getImageIcon(str);
324 }
325
326
327 private String getImageIconNameForNonMetaclass() {
328 String str = null;
329 if (getPropertyValueCount(getOWLModel().getOWLEquivalentClassProperty()) == 0) {
330 str = OWLIcons.PRIMITIVE_OWL_CLASS;
331 }
332 else {
333 str = OWLIcons.DEFINED_OWL_CLASS;
334 }
335 if (!getOWLModel().getProject().isMultiUserClient()) {
336 if (isConsistent() == false) {
337 str += "Inconsistent";
338 }
339 if (getSubclassesDisjoint()) {
340 str += "SD";
341 }
342 }
343 return str;
344 }
345
346
347 public Collection getRestrictions(boolean includingSuperclassRestrictions) {
348 if (includingSuperclassRestrictions) {
349 Set reached = new HashSet();
350 Collection restrictions = new ArrayList();
351 getRestrictions(this, reached, restrictions);
352 return restrictions;
353 }
354 else {
355 return getDirectRestrictions();
356 }
357 }
358
359
360 public Collection getRestrictions(RDFProperty property, boolean includingSuperclassRestrictions) {
361 Collection result = new ArrayList();
362 Collection rs = getRestrictions(includingSuperclassRestrictions);
363 for (Iterator it = rs.iterator(); it.hasNext();) {
364 OWLRestriction restriction = (OWLRestriction) it.next();
365 if (property.equals(restriction.getOnProperty())) {
366 result.add(restriction);
367 }
368 }
369 return result;
370 }
371
372
373 private static void getRestrictions(OWLNamedClass cls, Set reached, Collection results) {
374 reached.add(cls);
375 Collection restrictions = cls.getRestrictions(false);
376 for (Iterator rit = restrictions.iterator(); rit.hasNext();) {
377 OWLRestriction restriction = (OWLRestriction) rit.next();
378 if (restriction instanceof OWLAllValuesFrom) {
379 if (!isOverloadedAllValuesFrom((OWLAllValuesFrom) restriction, results)) {
380 results.add(restriction);
381 }
382 }
383 else if (restriction instanceof OWLMinCardinality) {
384 if (!isOverloadedMinCardinality((OWLMinCardinality) restriction, results)) {
385 results.add(restriction);
386 }
387 }
388 else if (restriction instanceof OWLMaxCardinality) {
389 if (!isOverloadedMaxCardinality((OWLMaxCardinality) restriction, results)) {
390 results.add(restriction);
391 }
392 }
393 else if (restriction instanceof OWLCardinality) {
394 if (!isOverloadedCardinality((OWLCardinality) restriction, results)) {
395 results.add(restriction);
396 }
397 }
398 else { // owl:hasValue or owl:someValuesFrom cannot be overloaded
399 results.add(restriction);
400 }
401 }
402
403 for (Iterator it = cls.getNamedSuperclasses().iterator(); it.hasNext();) {
404 RDFSNamedClass superclass = (RDFSNamedClass) it.next();
405 if (superclass instanceof OWLNamedClass && !reached.contains(superclass)) {
406 getRestrictions((OWLNamedClass) superclass, reached, results);
407 }
408 }
409 }
410
411
412 public RDFResource getSomeValuesFrom(RDFProperty property) {
413 Collection restrictions = getRestrictions(property, true);
414 for (Iterator it = restrictions.iterator(); it.hasNext();) {
415 OWLRestriction restriction = (OWLRestriction) it.next();
416 if (restriction instanceof OWLSomeValuesFrom) {
417 return ((OWLSomeValuesFrom) restriction).getSomeValuesFrom();
418 }
419 }
420 return null;
421 }
422
423
424 public boolean isConsistent() {
425 return getInferredSuperclasses().contains(getOWLModel().getOWLNothing()) == false;
426 }
427
428
429 private static boolean isOverloadedAllValuesFrom(OWLAllValuesFrom restriction, Collection restrictions) {
430 RDFProperty property = restriction.getOnProperty();
431 for (Iterator it = restrictions.iterator(); it.hasNext();) {
432 OWLRestriction owlRestriction = (OWLRestriction) it.next();
433 if (owlRestriction instanceof OWLAllValuesFrom && owlRestriction.getOnProperty().equals(property)) {
434 return true;
435 }
436 }
437 return false;
438 }
439
440
441 private static boolean isOverloadedCardinality(OWLCardinality restriction, Collection restrictions) {
442 RDFProperty property = restriction.getOnProperty();
443 for (Iterator it = restrictions.iterator(); it.hasNext();) {
444 OWLRestriction owlRestriction = (OWLRestriction) it.next();
445 if (property.equals(owlRestriction.getOnProperty())) {
446 if (owlRestriction instanceof OWLCardinality) {
447 return true;
448 }
449 }
450 }
451 return false;
452 }
453
454
455 private static boolean isOverloadedMaxCardinality(OWLMaxCardinality restriction, Collection restrictions) {
456 RDFProperty property = restriction.getOnProperty();
457 for (Iterator it = restrictions.iterator(); it.hasNext();) {
458 OWLRestriction owlRestriction = (OWLRestriction) it.next();
459 if (property.equals(owlRestriction.getOnProperty())) {
460 if (owlRestriction instanceof OWLCardinality || owlRestriction instanceof OWLMaxCardinality) {
461 return true;
462 }
463 }
464 }
465 return false;
466 }
467
468
469 private static boolean isOverloadedMinCardinality(OWLMinCardinality restriction, Collection restrictions) {
470 RDFProperty property = restriction.getOnProperty();
471 for (Iterator it = restrictions.iterator(); it.hasNext();) {
472 OWLRestriction owlRestriction = (OWLRestriction) it.next();
473 if (property.equals(owlRestriction.getOnProperty())) {
474 if (owlRestriction instanceof OWLCardinality || owlRestriction instanceof OWLMinCardinality) {
475 return true;
476 }
477 }
478 }
479 return false;
480 }
481
482
483 public boolean getSubclassesDisjoint() {
484 final Slot slot = getOWLModel().getProtegeSubclassesDisjointProperty();
485 if (slot != null) {
486 final Object value = getDirectOwnSlotValue(slot);
487 if (value instanceof Boolean) {
488 return ((Boolean) value).booleanValue();
489 }
490 }
491 return false;
492 }
493
494
495 public boolean hasNamedSuperclass() {
496 return getNamedSuperclasses().size() > 0;
497 }
498
499
500 public boolean isDefinedClass() {
501 return getDefinition() != null;
502 }
503
504
505 @Override
506 public boolean isFunctionalProperty(RDFProperty property) {
507 int max = getMaxCardinality(property);
508 return max == 0 || max == 1;
509 }
510
511
512 public boolean hasNamedSuperClass() {
513 return hasNamedSuperclass();
514 }
515
516
517 public boolean isProbeClass() {
518 Slot slot = getKnowledgeBase().getSlot(ProtegeNames.getProbeClassSlotName());
519 if (slot instanceof OWLDatatypeProperty) {
520 return Boolean.TRUE.equals(getDirectOwnSlotValue(slot));
521 }
522 return false;
523 }
524
525
526 public void removeDisjointClass(RDFSClass aClass) {
527 Slot disjointClassesSlot = getOWLModel().getOWLDisjointWithProperty();
528 removeOwnSlotValue(disjointClassesSlot, aClass);
529 if (aClass.isAnonymous()) {
530 getKnowledgeBase().deleteCls(aClass);
531 }
532 }
533
534
535 public void removeEquivalentClass(final RDFSClass equivalentClass) {
536 new Transaction(getOWLModel(), "Remove Equivalent Class" + Transaction.APPLY_TO_TRAILER_STRING + this.getName()) {
537 public boolean doOperations() {
538 if (equivalentClass instanceof OWLAnonymousClass) {
539 removeDirectSuperclass(equivalentClass);
540 }
541 else {
542 removeDirectSuperclass(equivalentClass);
543 equivalentClass.removeSuperclass(DefaultOWLNamedClass.this);
544 }
545 return true;
546 };
547 }.execute();
548 }
549
550
551 public void removeInferredSuperclass(RDFSClass superclass) {
552 Slot superclassesSlot = getAbstractOWLModel().getProtegeInferredSuperclassesProperty();
553 Slot subclassesSlot = getAbstractOWLModel().getProtegeInferredSubclassesProperty();
554 removeOwnSlotValue(superclassesSlot, superclass);
555 ((Cls) superclass).removeOwnSlotValue(subclassesSlot, this);
556 }
557
558
559 public void setClassificationStatus(int value) {
560 if (value != getClassificationStatus()) {
561 final Slot slot = getAbstractOWLModel().getProtegeClassificationStatusProperty();
562 setOwnSlotValue(slot, new Integer(value));
563 }
564 }
565
566
567 public void setDefinition(RDFSClass definingClass) {
568 for (Iterator it = getEquivalentClasses().iterator(); it.hasNext();) {
569 RDFSClass cls = (RDFSClass) it.next();
570 removeEquivalentClass(cls);
571 }
572 if (definingClass != null) {
573 addEquivalentClass(definingClass);
574 }
575 if (!hasNamedSuperClass()) {
576 addDirectSuperclass(getKnowledgeBase().getRootCls());
577 }
578 }
579
580
581 public void setSubclassesDisjoint(boolean value) {
582 final Slot slot = getOWLModel().getProtegeSubclassesDisjointProperty();
583 if (slot == null) {
584 throw new RuntimeException("Could not find slot " + ProtegeNames.getSubclassesDisjointSlotName());
585 }
586 if (value) {
587 setDirectOwnSlotValue(slot, Boolean.TRUE);
588 OWLUtil.ensureSubclassesDisjoint(this);
589 }
590 else {
591 setDirectOwnSlotValues(slot, Collections.EMPTY_LIST);
592 OWLUtil.removeSubclassesDisjoint(this);
593 }
594 }
595
596
597 @Override
598 public void accept(OWLModelVisitor visitor) {
599 visitor.visitOWLNamedClass(this);
600 }
601 }
602