001 package nl.tudelft.tbm.eeni.owl2java.model.jmodel;
002
003 import com.hp.hpl.jena.ontology.OntClass;
004 import nl.tudelft.tbm.eeni.owl2java.model.jmodel.utils.LogUtils;
005 import nl.tudelft.tbm.eeni.owl2java.model.jmodel.utils.NamingUtils;
006 import nl.tudelft.tbm.eeni.owl2java.utils.StringUtils;
007 import org.apache.commons.logging.Log;
008 import org.apache.commons.logging.LogFactory;
009 import org.jgraph.graph.DefaultEdge;
010
011 import java.util.*;
012
013
014 public class JClass extends JMapped {
015 public static enum AnonymousClassType {
016 NONE, // Not an anonymous class
017 INTERSECTION, // Anonymous intersection class
018 UNION // Anonymous union class
019 }
020
021 private static Log log = LogFactory.getLog(JClass.class);
022
023 private OntClass ontClass;
024 private JModel jModel;
025 private JPackage jPkg;
026
027 AnonymousClassType anonymousClassType = AnonymousClassType.NONE;
028 List<? extends OntClass> anonymousClassOperands = null;
029
030 private List<JProperty> domainProperties = new ArrayList<JProperty>();
031 private List<JProperty> aggregatedProperties = new ArrayList<JProperty>();
032 private List<JClass> equivalentClasses = new ArrayList<JClass>();
033
034 private Map<JProperty, JRestrictionsContainer> domainPropertyRestrictions = new HashMap<JProperty, JRestrictionsContainer>();
035 private Map<JProperty, JRestrictionsContainer> aggregatedPropertyRestrictions = new HashMap<JProperty, JRestrictionsContainer>();
036 // PropRepresentation = (0..1) CardRestriction + 1 AllValuesRestriction + (0..1) + OtherRestriction
037 private List<JPropertyRepresentation> domainPropertyRepresentations = new ArrayList<JPropertyRepresentation>();
038 private List<JPropertyRepresentation> aggregatedPropertyRepresentations = new ArrayList<JPropertyRepresentation>();
039
040 public JClass(JModel model, String name, String mapUri) {
041 super(name, mapUri);
042 this.jModel = model;
043 this.jModel.getClassGraph().addVertex(this);
044 }
045
046 public void addDomainProperty(JProperty prop) {
047 if (!domainProperties.contains(prop))
048 domainProperties.add(prop);
049 if (!prop.propertyDomain.contains(this))
050 prop.propertyDomain.add(this);
051 if (!domainPropertyRestrictions.containsKey(prop)) {
052 log.debug(LogUtils.toLogName(this, prop) + ": Creating RestrictionsContainer");
053 JRestrictionsContainer rc = new JRestrictionsContainer(this, prop);
054 domainPropertyRestrictions.put(prop, rc);
055 }
056 }
057
058 public void addEquivalentClass(JClass cls) {
059 if (!equivalentClasses.contains(cls))
060 equivalentClasses.add(cls);
061 if (!cls.equivalentClasses.contains(this))
062 cls.equivalentClasses.add(this);
063 }
064
065 public void addDomainRestrictionsContainer(JProperty property, JRestrictionsContainer rc) {
066 if (!domainPropertyRestrictions.containsKey(property))
067 domainPropertyRestrictions.put(property, rc);
068 }
069
070 public void addSubClass(JClass cls) {
071 jModel.getClassGraph().addChildVertex(this, cls);
072 }
073
074 public void addSuperClass(JClass cls) {
075 jModel.getClassGraph().addParentVertex(this, cls);
076 }
077
078 public int aggegrateAll() {
079 int aggregateActions = 0;
080 if (jModel.isBaseThing(this)) {
081 log.debug(LogUtils.toLogName(this) + ": No aggregation for BaseThing");
082 return aggregateActions;
083 }
084 log.debug(LogUtils.toLogName(this) + ": Aggregating all definitions from parent classes");
085 List<JClass> parentClasses = jModel.getClassGraph().listDirectParents(this);
086 aggregateActions += aggregateProperties(parentClasses);
087 aggregateActions += aggregateRestrictionContainers(parentClasses);
088 aggregateActions += aggegrateRestrictionDefinitions(parentClasses);
089 aggregateActions += aggregatePropertyRepresentations(parentClasses);
090 return aggregateActions;
091 }
092
093 protected int aggregatePropertyRepresentations(List<JClass> parentClasses) {
094 int aggregateActions = 0;
095 // copy local domain property representations to all representations
096 for (JPropertyRepresentation rep : domainPropertyRepresentations) {
097 // already aggregated in previous run
098 if (hasAggregatedPropertyRepresentation(rep.getOnProperty()))
099 continue;
100 aggregatedPropertyRepresentations.add(rep);
101 aggregateActions++;
102 }
103
104 // copy parent representations to all representations
105 for (JClass cls : parentClasses) {
106 log.debug(LogUtils.toLogName(this) + ": Aggregating property presentations of parent class "
107 + LogUtils.toLogName(cls));
108
109 for (JPropertyRepresentation representation : cls.listAggregatedPropertyRepresentations()) {
110
111 // clone the representation and add it to our list of aggregated representations
112 JPropertyRepresentation pr = representation.clone();
113
114
115 // Check for identity. Otherwise, two parent provide the same representation
116 // We ignore the deprecated status as this can change later on
117 boolean prExists = hasAggregatedPropertyRepresentation(pr);
118 if (prExists) {
119 log.debug(LogUtils.toLogName(this) + ": Skipping identical representation from parent class "
120 + LogUtils.toLogName(cls));
121 } else {
122 // if we have a domain representation for a property -> mark deprecated + add
123 if (hasAggregatedPropertyRepresentation(pr.getOnProperty())) {
124 log.debug(LogUtils.toLogName(this) + ": Setting parent representation to deprecated");
125 pr.setDeprecated(true);
126 }
127 aggregatedPropertyRepresentations.add(pr);
128 aggregateActions++;
129 log.debug(LogUtils.toLogName(this) + ": Adding parent representation");
130 }
131 }
132 }
133 return aggregateActions;
134 }
135
136 public List<JPropertyRepresentation> listAggregatedPropertyRepresentations() {
137 return aggregatedPropertyRepresentations;
138 }
139
140 protected int aggegrateRestrictionDefinitions(List<JClass> parentClasses) {
141 int aggregateActions = 0;
142 Iterator<JProperty> it = aggregatedPropertyRestrictions.keySet().iterator();
143 while (it.hasNext()) {
144 JProperty property = (JProperty) it.next();
145 JRestrictionsContainer propertyRestrictionContainer = getAggregatedRestrictionsContainer(property
146 .getMapUri());
147 propertyRestrictionContainer.aggregateRestrictions(parentClasses);
148 log.debug(LogUtils.toLogName(this) + ": Merging restriction definitions for property "
149 + LogUtils.toLogName(property));
150 }
151 return aggregateActions;
152 }
153
154 protected int aggregateProperties(List<JClass> parentClasses) {
155 int aggregateActions = 0;
156 // copy local domain properties to allProperites
157 for (JProperty property : domainProperties) {
158 if (hasAggregatedProperty(property.getMapUri()))
159 continue;
160 aggregateActions++;
161 aggregatedProperties.add(property);
162 }
163
164 // copy parent properties to allProperties
165 for (JClass cls : parentClasses) {
166 log.debug(LogUtils.toLogName(this) + ": Aggregating domain properties of parent class "
167 + LogUtils.toLogName(cls));
168
169 for (JProperty property : cls.listAggregatedProperties()) {
170 if (!hasAggregatedProperty(property.getMapUri())) {
171 aggregateActions++;
172 aggregatedProperties.add(property);
173 }
174 }
175 }
176 return aggregateActions;
177 }
178
179 protected int aggregateRestrictionContainers(List<JClass> parentClasses) {
180 int aggregateActions = 0;
181 // add our restrictions
182 for (JProperty property : domainPropertyRestrictions.keySet()) {
183 log.debug(LogUtils.toLogName(this) + ": Aggregating domain restriction containers ");
184 JRestrictionsContainer rc = domainPropertyRestrictions.get(property);
185 // already added in previous run
186 if (hasAggregatedRestrictionsContainer(property.getMapUri()))
187 continue;
188 aggregateActions++;
189 aggregatedPropertyRestrictions.put(property, rc);
190 }
191
192 // add parent class stuff
193 for (JClass cls : parentClasses) {
194 log.debug(LogUtils.toLogName(this) + ": Aggregating restriction containers of parent class "
195 + LogUtils.toLogName(cls));
196
197 // aggregate the restriction containers from parent classes
198 for (JProperty property : cls.listAggregatedProperties()) {
199 // already present -> skip (handled in aggegateRestrictionDefinitions)
200 if (hasAggregatedRestrictionsContainer(property.getMapUri()))
201 continue;
202 // copy restriction container to here
203 JRestrictionsContainer rc = cls.getAggregatedRestrictionsContainer(property);
204 aggregatedPropertyRestrictions.put(property, rc.clone());
205 aggregateActions++;
206 }
207 }
208 return aggregateActions;
209 }
210
211 public void createDomainPropertyRepresentations() {
212 log.debug(LogUtils.toLogName(this) + ": Creating property representations for domain properties");
213 // loop over all properties
214
215 for (JProperty property : domainPropertyRestrictions.keySet()) {
216 log.debug(LogUtils.toLogName(this) + ": Creating domain property representations for "
217 + LogUtils.toLogName(property));
218 JRestrictionsContainer rc = domainPropertyRestrictions.get(property);
219
220 // create the default representation based on the property range
221 // if no allValues restriction for this property
222 // -> otherwise the domain property has a allValues additional restriction
223 // and is handled below
224 if (rc.listAllValuesRestrictions().isEmpty()) {
225 log.debug(LogUtils.toLogName(property) + ": Creating default representation");
226 JPropertyRepresentation jpr = new JPropertyRepresentation(property);
227 jpr.setHasDefaultPropertyRange(true);
228 if (rc.hasCardinalityRestriction())
229 jpr.setCardinalityRestriction(rc.getCardinalityRestriction().clone());
230 if (rc.hasOtherRestriction())
231 jpr.setOtherRestriction(rc.getOtherRestriction().clone());
232 domainPropertyRepresentations.add(jpr);
233 }
234
235 // for each AllValues create a single representation
236 for (JAllValuesRestriction avr : rc.listAllValuesRestrictions()) {
237 log.debug(LogUtils.toLogName(property) + ": Creating representation for AllValues "
238 + LogUtils.toLogName(avr.getAllValues()));
239 JPropertyRepresentation pr = new JPropertyRepresentation(property);
240 pr.setHasDefaultPropertyRange(false);
241 pr.setAllValuesRestriction(avr);
242 pr.setCardinalityRestriction(rc.getCardinalityRestriction());
243 pr.setOtherRestriction(rc.getOtherRestriction());
244 domainPropertyRepresentations.add(pr);
245 }
246 }
247 }
248
249 public String getJavaClassFullName() {
250 return NamingUtils.getJavaFullName(jPkg, getJavaClassName());
251
252 }
253
254 public String getJavaClassName() {
255 if (this.ontClass != null)
256 return NamingUtils.getJavaClassName(this.ontClass);
257
258 // no OntClass given (base.thing e. g. )
259 return NamingUtils.getJavaClassName(getName(), JModel.BASEPREFIX);
260 }
261
262 public String getJavaInterfaceFullName() {
263 return NamingUtils.getJavaFullName(jPkg, getJavaInterfaceName());
264 }
265
266 public String getJavaInterfaceName() {
267 if (this.ontClass != null)
268 return NamingUtils.getJavaInterfaceName(this.ontClass);
269
270 // no OntClass given (base.thing e. g. )
271 String javaName = NamingUtils.getJavaInterfaceName(getName(), JModel.BASEPREFIX);
272 return javaName;
273 }
274
275 public String getJavaPackageName() {
276 return jPkg.getPackageName();
277 }
278
279 public JModel getJModel() {
280 return jModel;
281 }
282
283 public OntClass getOntClass() {
284 return ontClass;
285 }
286
287 public JPackage getPackage() {
288 return jPkg;
289 }
290
291 public List<JPropertyRepresentation> getDomainPropertyRepresentations() {
292 return domainPropertyRepresentations;
293 }
294
295 public List<JPropertyRepresentation> getAggregatedPropertyRepresentations() {
296 return aggregatedPropertyRepresentations;
297 }
298
299 @Override
300 public String getJModelReport() {
301 String report = new String();
302 report += StringUtils.toSubHeader("Class " + getJavaClassFullName());
303
304 report += StringUtils.indentText("Parent Classes\n");
305 Iterator<DefaultEdge> parentIt = jModel.getClassGraph().incomingEdgesOf(this).iterator();
306 while (parentIt.hasNext()) {
307 DefaultEdge edge = parentIt.next();
308 JClass parent = jModel.getClassGraph().getEdgeSource(edge);
309 report += StringUtils.indentText(parent.getJavaClassFullName(), 2) + "\n";
310 }
311
312 report += StringUtils.indentText("Child Classes\n");
313 Iterator<DefaultEdge> childIt = jModel.getClassGraph().outgoingEdgesOf(this).iterator();
314 while (childIt.hasNext()) {
315 DefaultEdge edge = childIt.next();
316 JClass parent = jModel.getClassGraph().getEdgeTarget(edge);
317 report += StringUtils.indentText(parent.getJavaClassFullName(), 2) + "\n";
318 }
319
320 report += StringUtils.indentText("Equivalent Classes\n");
321 for (JClass child : equivalentClasses) {
322 report += StringUtils.indentText(child.getJavaClassFullName(), 2) + "\n";
323 }
324
325 report += StringUtils.indentText("Domain Properties\n");
326 for (JProperty prop : domainProperties) {
327 report += StringUtils.indentText(prop.getJavaName(), 2) + "\n";
328 report += prop.getJModelReport();
329 }
330
331 report += StringUtils.indentText("Class Restrictions\n");
332 for (JRestrictionsContainer restr : domainPropertyRestrictions.values()) {
333 report += StringUtils.indentText(restr.getJModelReport(), 3) + "\n";
334 }
335 return report;
336 }
337
338 public JRestrictionsContainer getDomainRestrictionsContainer(JProperty prop) {
339 return getDomainRestrictionsContainer(prop.getMapUri());
340 }
341
342 public JRestrictionsContainer getAggregatedRestrictionsContainer(JProperty prop) {
343 return getAggregatedRestrictionsContainer(prop.getMapUri());
344 }
345
346 public JRestrictionsContainer getDomainRestrictionsContainer(String uri) {
347 for (JProperty property : domainPropertyRestrictions.keySet()) {
348 if (property.getMapUri().equals(uri))
349 return domainPropertyRestrictions.get(property);
350 }
351 return null;
352 }
353
354 public JRestrictionsContainer getAggregatedRestrictionsContainer(String uri) {
355 for (JProperty property : aggregatedPropertyRestrictions.keySet()) {
356 if (property.getMapUri().equals(uri))
357 return aggregatedPropertyRestrictions.get(property);
358 }
359 return null;
360 }
361
362 public boolean hasDomainProperty(JProperty property) {
363 return hasDomainProperty(property.getMapUri());
364 }
365
366 public boolean hasDomainProperty(String uri) {
367 for (JProperty domainProp : domainProperties) {
368 if (domainProp.getMapUri().equals(uri))
369 return true;
370 }
371 return false;
372 }
373
374 public boolean hasAggregatedProperty(String uri) {
375 for (JProperty prop : aggregatedProperties) {
376 if (prop.getMapUri().equals(uri))
377 return true;
378 }
379 return false;
380 }
381
382 public boolean hasDomainPropertyRepresentation(JPropertyRepresentation representation) {
383 return domainPropertyRepresentations.contains(representation);
384 }
385
386 public boolean hasAggregatedPropertyRepresentation(JProperty property) {
387 for (JPropertyRepresentation pr : aggregatedPropertyRepresentations) {
388 if (pr.getOnProperty().getMapUri().equals(property.getMapUri()))
389 return true;
390 }
391 return false;
392 }
393
394 private boolean hasAggregatedPropertyRepresentation(JPropertyRepresentation representation) {
395 for (JPropertyRepresentation pr : aggregatedPropertyRepresentations) {
396 if (pr.equalsIgnoreDeprecated(representation))
397 return true;
398 }
399 return false;
400 }
401
402 public boolean hasDomainRestrictionsContainer(String propertyUri) {
403 for (JProperty prop : domainPropertyRestrictions.keySet()) {
404 JRestrictionsContainer rc = domainPropertyRestrictions.get(prop);
405 if (prop.getMapUri().equals(propertyUri) && rc != null)
406 return true;
407 }
408 return false;
409 }
410
411 public boolean hasAggregatedRestrictionsContainer(String propertyUri) {
412 for (JProperty prop : aggregatedPropertyRestrictions.keySet()) {
413 JRestrictionsContainer rc = aggregatedPropertyRestrictions.get(prop);
414 if (prop.getMapUri().equals(propertyUri) && rc != null)
415 return true;
416 }
417 return false;
418 }
419
420 public boolean hasDomainRestrictionsContainer(JProperty property) {
421 return hasDomainRestrictionsContainer(property.getMapUri());
422 }
423
424 public boolean hasDomainRestrictionsContainer(JRestrictionsContainer restriction) {
425 return domainPropertyRestrictions.containsValue(restriction);
426 }
427
428 public boolean hasSubClass(JClass cls, boolean recursive) {
429 return jModel.getClassGraph().hasChild(this, cls, recursive);
430 }
431
432 public boolean hasSuperClass(JClass cls, boolean recursive) {
433 return jModel.getClassGraph().hasParent(this, cls, recursive);
434 }
435
436 public boolean hasSuperClasses() {
437 if (jModel.getClassGraph().incomingEdgesOf(this).size() > 0)
438 return true;
439 return false;
440 }
441
442 /**
443 * List JClass representations of all (direct and indirect) subclasses of this class
444 */
445 public List<JClass> listAllSubClasses() {
446 return listAllSubClasses(this);
447 }
448
449 private List<JClass> listAllSubClasses(JClass cls) {
450 List<JClass> subClasses = new ArrayList<JClass>();
451 for (JClass subClass : jModel.getClassGraph().listDirectChildren(cls)) {
452 subClasses.add(subClass);
453 subClasses.addAll(listAllSubClasses(subClass));
454 }
455 return subClasses;
456 }
457
458 public boolean isAnonymous() {
459 return anonymousClassType != AnonymousClassType.NONE;
460 }
461
462 public AnonymousClassType getAnonymousClassType() {
463 return anonymousClassType;
464 }
465
466 public List<? extends OntClass> getAnonymousClassOperands() {
467 return anonymousClassOperands;
468 }
469
470 public void setAnonymous(AnonymousClassType type, List<? extends OntClass> operands) {
471 this.anonymousClassType = type;
472 this.anonymousClassOperands = operands;
473 }
474
475 public boolean isRootClass() {
476 return (!hasSuperClasses());
477 }
478
479 public List<JProperty> listAggregatedProperties() {
480 return aggregatedProperties;
481 }
482
483 public List<JProperty> listDomainProperties() {
484 return domainProperties;
485 }
486
487 public List<JPropertyRepresentation> listDomainPropertyRepresentations() {
488 return domainPropertyRepresentations;
489 }
490
491 public List<JPropertyRepresentation> listDomainPropertyRepresentations(JProperty property) {
492 List<JPropertyRepresentation> representations = new ArrayList<JPropertyRepresentation>();
493 for (JPropertyRepresentation rep : domainPropertyRepresentations) {
494 if (rep.getOnProperty().getMapUri().equals(property.getMapUri()))
495 representations.add(rep);
496 }
497 return representations;
498 }
499
500 public List<JPropertyRepresentation> listAggregatedPropertyRepresentations(JProperty property) {
501 List<JPropertyRepresentation> representations = new ArrayList<JPropertyRepresentation>();
502 for (JPropertyRepresentation rep : aggregatedPropertyRepresentations) {
503 if (rep.getOnProperty().getMapUri().equals(property.getMapUri()))
504 representations.add(rep);
505 }
506 return representations;
507 }
508
509 public List<JClass> listDirectSubClasses() {
510 List<JClass> subClasses = new ArrayList<JClass>();
511 Iterator<DefaultEdge> children = jModel.getClassGraph().outgoingEdgesOf(this).iterator();
512 while (children.hasNext()) {
513 DefaultEdge edge = (DefaultEdge) children.next();
514 JClass child = jModel.getClassGraph().getEdgeTarget(edge);
515 subClasses.add(child);
516 }
517
518 return subClasses;
519 }
520
521 public List<JClass> listDirectSuperClasses() {
522 List<JClass> superClasses = new ArrayList<JClass>();
523 Iterator<DefaultEdge> parents = jModel.getClassGraph().incomingEdgesOf(this).iterator();
524 while (parents.hasNext()) {
525 DefaultEdge edge = (DefaultEdge) parents.next();
526 JClass parent = jModel.getClassGraph().getEdgeSource(edge);
527 superClasses.add(parent);
528 }
529 return superClasses;
530 }
531
532 public JClass getFirstDirectSuperClass() {
533 return listDirectSuperClasses().get(0);
534 }
535
536
537 public Map<String, JProperty> listDomainPropertiesAsMap(boolean recursive) {
538 Map<String, JProperty> uri2prop = new HashMap<String, JProperty>();
539
540 // add current props, if not present
541 for (JProperty p : domainProperties) {
542 if (!uri2prop.containsKey(p.getMapUri()))
543 uri2prop.put(p.getMapUri(), p);
544 }
545
546 if (recursive) {
547 List<JClass> superClasses = jModel.getClassGraph().listDirectParents(this);
548 for (JClass sCls : superClasses) {
549 uri2prop.putAll(sCls.listDomainPropertiesAsMap(recursive));
550 }
551 }
552 return uri2prop;
553 }
554
555 public List<JRestrictionsContainer> listDomainRestrictionContainers() {
556 List<JRestrictionsContainer> restrictions = new ArrayList<JRestrictionsContainer>();
557 restrictions.addAll(domainPropertyRestrictions.values());
558 return restrictions;
559 }
560
561 public void removeAllPropertyRepresentations() {
562 domainPropertyRepresentations.clear();
563 }
564
565 public void removeDomainProperty(JProperty property) {
566 if (domainProperties.contains(property))
567 domainProperties.remove(property);
568 }
569
570 public void removeDomainRestrictionsContainer(JProperty property) {
571 if (domainPropertyRestrictions.containsKey(property))
572 domainPropertyRestrictions.remove(property);
573 }
574
575 public void removeSubClassRelation(JClass subCls) {
576 jModel.getClassGraph().removeAllEdges(this, subCls);
577 // jModel.getClassGraph().removeVertex(subCls);
578 }
579
580 public void removeSuperClassRelation(JClass superCls) {
581 jModel.getClassGraph().removeAllEdges(superCls, this);
582 // jModel.getClassGraph().removeVertex(superCls);
583 }
584
585 public void setOntClass(OntClass ontClass) {
586 this.ontClass = ontClass;
587 }
588
589 public void setPackage(JPackage pkg) {
590 this.jPkg = pkg;
591 pkg.addClass(this);
592 }
593
594 public String toString() {
595 return getJavaClassName();
596 }
597
598 }