1
18 package gate.creole.ontology;
19
20 import java.util.HashSet;
21 import java.util.Iterator;
22 import java.util.LinkedList;
23 import java.util.Set;
24 import com.ontotext.gate.ontology.OntologyImpl;
25
26
30 public class PropertyImpl extends OntologyResourceImpl implements Property {
31
37 protected Set domain;
38
42 protected Set directDomain;
43
49 protected Set range;
50
54 protected Set directRange;
55 protected Set samePropertiesSet;
56 protected Set superPropertiesSet;
57 protected Set subPropertiesSet;
58 protected Set superPropertiesTransitiveClosure;
59 protected Set subPropertiesTransitiveClosure;
60 protected boolean functional;
61 protected boolean inverseFunctional;
62
63
77 public PropertyImpl(String name, String comment, Set domain, Set range,
78 Ontology ontology) {
79 super(name, comment, ontology);
80 this.directDomain = new HashSet(domain);
81 this.domain = new HashSet(directDomain);
82 this.directRange = new HashSet(range);
83 this.range = new HashSet(directRange);
84 samePropertiesSet = new HashSet();
85 superPropertiesSet = new HashSet();
86 subPropertiesSet = new HashSet();
87 superPropertiesTransitiveClosure = new HashSet();
88 subPropertiesTransitiveClosure = new HashSet();
89 this.functional = false;
90 this.inverseFunctional = false;
91 }
92
93 public PropertyImpl(String name, String comment, OClass aDomainClass,
94 Object aRangeType, Ontology ontology) {
95 this(name, comment, new HashSet(), new HashSet(), ontology);
96 if(aDomainClass != null) {
97 this.directDomain.add(aDomainClass);
98 this.domain.add(aDomainClass);
99 }
100 this.directRange.add(aRangeType);
101 this.range.add(aRangeType);
102 }
103
104 public String getName() {
105 return name;
106 }
107
108 public String getURI() {
109 return uri;
110 }
111
112 public void setURI(String theURI) {
113 uri = theURI;
114 }
115
116 public void setSamePropertyAs(Property theProperty) {
117 this.samePropertiesSet.add(theProperty);
118 }
119
120 public Set getSamePropertyAs() {
121 if(this.samePropertiesSet.isEmpty()
122 && !this.getOntology().getPropertyDefinitions().contains(this)) {
123 Property propDefinition = this.getOntology().getPropertyDefinitionByName(
124 this.name);
125 if(propDefinition == null)
126 return this.samePropertiesSet;
127 else return propDefinition.getSamePropertyAs();
128 }
129 return this.samePropertiesSet;
130 }
131
132 public void addSuperProperty(Property property) {
133 this.superPropertiesSet.add(property);
134 domain.addAll(property.getDomain());
136 OntologyImpl.reduceToMostSpecificClasses(domain);
137 Iterator subPropIter = getSubProperties(TRANSITIVE_CLOSURE).iterator();
139 while(subPropIter.hasNext()) {
140 Property aSubProperty = (Property)subPropIter.next();
141 if(aSubProperty instanceof PropertyImpl) {
142 ((PropertyImpl)aSubProperty).recalculateDomain();
143 ((PropertyImpl)aSubProperty).recalculateRange();
144 }
145 }
146 }
147
148
152 protected void recalculateDomain() {
153 domain.clear();
154 domain.addAll(directDomain);
155 Iterator superPropIter = getSuperProperties(TRANSITIVE_CLOSURE).iterator();
156 while(superPropIter.hasNext()) {
157 domain.addAll(((Property)superPropIter.next()).getDomain());
158 }
159 OntologyImpl.reduceToMostSpecificClasses(domain);
160 }
161
162
166 protected void recalculateRange() {
167 range.clear();
168 range.addAll(directRange);
169 Iterator superPropIter = getSuperProperties(TRANSITIVE_CLOSURE).iterator();
170 while(superPropIter.hasNext()) {
171 range.addAll(((Property)superPropIter.next()).getRange());
172 }
173 OntologyImpl.reduceToMostSpecificClasses(range);
174 }
175
176 public void removeSuperProperty(Property property) {
177 this.superPropertiesSet.remove(property);
178 }
179
180
185 public void addSubProperty(Property property) {
186 this.subPropertiesSet.add(property);
187 }
188
189 public void removeSubProperty(Property property) {
190 this.subPropertiesSet.remove(property);
191 }
192
193
198 public Set getDomain() {
199 return this.domain;
200 }
201
202
207 public Set getRange() {
208 return this.range;
209 }
210
211
216 public boolean isFunctional() {
217 return functional;
218 }
219
220
225 public boolean isInverseFunctional() {
226 return inverseFunctional;
227 }
228
229
234 public void setFunctional(boolean functional) {
235 this.functional = functional;
236 }
237
238
243 public void setInverseFunctional(boolean inverseFunctional) {
244 this.inverseFunctional = inverseFunctional;
245 }
246
247
260 public boolean isValidDomain(OntologyResource resource) {
261 if(resource instanceof OInstance) {
262 OInstance instance = (OInstance)resource;
263 Set domainClasses = new HashSet(getDomain());
264 boolean result = true;
265 if(domainClasses.isEmpty()) return true;
267 Iterator instanceClassIter = instance.getOClasses().iterator();
268 while(result && instanceClassIter.hasNext()) {
269 OClass anInstanceClass = (OClass)instanceClassIter.next();
270 if(!domainClasses.contains(anInstanceClass)) {
272 Set superClasses = anInstanceClass
275 .getSuperClasses(OntologyConstants.TRANSITIVE_CLOSURE);
276 Set intersection = new HashSet(superClasses);
277 intersection.retainAll(domainClasses);
278 if(intersection.isEmpty()) result = false;
279 }
280 }
281 return result;
282 } else return true;
283 }
284
285
296 public boolean isValidRange(Object value) {
297 if(value instanceof OInstance) {
298 OInstance instance = (OInstance)value;
300 Set rangeClasses = new HashSet(getRange());
301 boolean result = true;
302 Iterator instanceClassIter = instance.getOClasses().iterator();
303 while(result && instanceClassIter.hasNext()) {
304 OClass anInstanceClass = (OClass)instanceClassIter.next();
305 if(!rangeClasses.contains(anInstanceClass)) {
307 Set superClasses = anInstanceClass
310 .getSuperClasses(OntologyConstants.TRANSITIVE_CLOSURE);
311 Set intersection = new HashSet(superClasses);
312 intersection.retainAll(rangeClasses);
313 if(intersection.isEmpty()) result = false;
314 }
315 }
316 return result;
317 } else if(value instanceof OntologyResource) {
318 return true;
320 } else {
321 Iterator rangIter = getRange().iterator();
323 while(rangIter.hasNext()) {
324 if(!((Class)rangIter.next()).isAssignableFrom(value.getClass()))
325 return false;
326 }
327 return true;
328 }
329 }
330
331 public String toString() {
332 return getName();
333 }
334
335
344 public Set getSuperProperties(byte closure) {
345 switch(closure){
346 case DIRECT_CLOSURE:
347 return superPropertiesSet;
348 case TRANSITIVE_CLOSURE:
349 if(superPropertiesTransitiveClosure.size() == 0
350 || getOntology().isModified())
351 calculateSuperPropertiesClosure();
352 return superPropertiesTransitiveClosure;
353 default:
354 throw new IllegalArgumentException("Unknown closure type: " + closure);
355 }
356 }
357
358 protected void calculateSuperPropertiesClosure() {
359 superPropertiesTransitiveClosure.clear();
360 LinkedList properties = new LinkedList(superPropertiesSet);
361 while(properties.size() > 0) {
362 Property aSuperProperty = (Property)properties.remove(0);
363 if(superPropertiesTransitiveClosure.add(aSuperProperty)) {
364 properties.addAll(aSuperProperty.getSuperProperties(DIRECT_CLOSURE));
366 }
367 }
368 }
369
370
379 public Set getSubProperties(byte closure) {
380 switch(closure){
381 case DIRECT_CLOSURE:
382 return subPropertiesSet;
383 case TRANSITIVE_CLOSURE:
384 if(subPropertiesTransitiveClosure.isEmpty()
385 || getOntology().isModified()) calculateSubPropertiesClosure();
386 return subPropertiesTransitiveClosure;
387 default:
388 throw new IllegalArgumentException("Unknown closure type: " + closure);
389 }
390 }
391
392 protected void calculateSubPropertiesClosure() {
393 subPropertiesTransitiveClosure.clear();
394 LinkedList properties = new LinkedList(subPropertiesSet);
395 while(properties.size() > 0) {
396 Property aSuperProperty = (Property)properties.remove(0);
397 if(subPropertiesTransitiveClosure.add(aSuperProperty)) {
398 properties.addAll(aSuperProperty.getSubProperties(DIRECT_CLOSURE));
400 }
401 }
402 }
403 }
404