001 package nl.tudelft.tbm.eeni.owl2java.generator;
002
003 import com.hp.hpl.jena.ontology.OntClass;
004 import com.hp.hpl.jena.ontology.OntProperty;
005 import nl.tudelft.tbm.eeni.owl2java.model.jenautils.RestrictionUtils;
006 import nl.tudelft.tbm.eeni.owl2java.model.jmodel.*;
007 import nl.tudelft.tbm.eeni.owl2java.model.jmodel.utils.LogUtils;
008 import org.apache.commons.logging.Log;
009 import org.apache.commons.logging.LogFactory;
010 import org.jgraph.graph.DefaultEdge;
011 import org.jgrapht.traverse.BreadthFirstIterator;
012
013 import java.util.ArrayList;
014 import java.util.List;
015
016
017 public class ModelPreparation {
018
019 private static Log log = LogFactory.getLog(ModelPreparation.class);
020
021 private boolean reasignDomainlessProperties;
022 private JModel jModel;
023
024 JClass baseCls;
025
026 public JModel prepareModel(JModel model) {
027 jModel = model;
028 baseCls = jModel.getJClass(jModel.getBaseThingUri());
029 log.info("");
030 log.info("Prepaing model for class writer");
031
032 // assign properties without domain to restrictions
033 if (reasignDomainlessProperties)
034 reasignProperties();
035
036 // createPropertyRepresentations
037 createDomainPropertyRepresentations();
038
039 // aggregate properties, restriction containers...
040
041 int aggregateActions = 1;
042 while (aggregateActions != 0) {
043 aggregateActions = aggregateAllOnClass();
044 }
045
046
047 return jModel;
048 }
049
050 protected void createDomainPropertyRepresentations() {
051 log.info("Creating domain property representations");
052 JClass baseCls = jModel.getBaseThing();
053 JInheritanceGraph<JClass, DefaultEdge> classGraph = jModel.getClassGraph();
054 BreadthFirstIterator<JClass, DefaultEdge> it = new BreadthFirstIterator<JClass, DefaultEdge>(classGraph,
055 baseCls);
056 it.setCrossComponentTraversal(true);
057 while (it.hasNext()) {
058 JClass c = (JClass) it.next();
059 c.createDomainPropertyRepresentations();
060 }
061 }
062
063 protected int aggregateAllOnClass() {
064 int aggregateActions = 0;
065 JClass baseCls = jModel.getBaseThing();
066 JInheritanceGraph<JClass, DefaultEdge> classGraph = jModel.getClassGraph();
067 BreadthFirstIterator<JClass, DefaultEdge> it = new BreadthFirstIterator<JClass, DefaultEdge>(classGraph,
068 baseCls);
069 it.setCrossComponentTraversal(true);
070 while (it.hasNext()) {
071 JClass c = (JClass) it.next();
072 int count = c.aggegrateAll();
073 aggregateActions = aggregateActions + count;
074 }
075 log.info("Aggregating all from parent classes: " + aggregateActions + " Actions");
076 return aggregateActions;
077 }
078
079 protected boolean reasignProperty(JClass cls, JProperty property) {
080
081 boolean success = false;
082
083 // we check for each property, if we have a restriction with the given class
084 // as subject
085 OntClass ontClass = cls.getOntClass();
086 OntProperty ontProperty = property.getOntProperty();
087
088 if (RestrictionUtils.hasRestrictionOnProperty(ontClass, ontProperty)) {
089 // baseCls as we are only testing base properties here
090 log.debug(LogUtils.toLogName(property) + ": Changing domain from " + LogUtils.toLogName(baseCls) + " to "
091 + LogUtils.toLogName(cls));
092 property.addDomain(cls);
093
094 // restriction container is is empty for baseClass > we ignore it (remove would be better)
095
096 // We no longer have a global property with a local restriction!
097 // -> update "enabled" cardinality status based on cardinality
098 // -> for local restriction "aProperty max 1" disable multiple accessors
099 JRestrictionsContainer rc = cls.getDomainRestrictionsContainer(property);
100 if (rc != null) {
101 if (rc.hasCardinalityRestriction()) {
102 if (rc.getCardinalityRestriction().getMaxCardinality() == 1) {
103 rc.getCardinalityRestriction().setMultipleEnabled(false);
104 rc.getCardinalityRestriction().setSingleEnabled(true);
105
106 // with maxCardinality = 1 this is identical with a functional
107 // property > marking it.
108 property.setFunctional(true);
109 }
110 if (rc.getCardinalityRestriction().getMaxCardinality() == 0) {
111 rc.getCardinalityRestriction().setMultipleEnabled(false);
112 rc.getCardinalityRestriction().setSingleEnabled(false);
113 }
114 }
115 }
116 success = true;
117 } else {
118 // test all subclasses, calls this method recursively
119 for (JClass subCls : cls.listDirectSubClasses()) {
120 boolean suc = reasignProperty(subCls, property);
121 // if successful for this subclass, set success to true
122 if (suc)
123 success = true;
124 }
125 }
126 return success;
127 }
128
129 protected void reasignProperties() {
130 log.info("Reasigning unbound properties to corresponding classes with restrictions");
131
132 // XXX use depth first traversal here? - how to move to next branch upon success?
133
134 // loop over all domainless properties (p's with domain OwlThing)
135 // and mark them for removal from domain OwlThing
136 List<JProperty> properties = baseCls.listDomainProperties();
137 List<JProperty> propsToRemove = new ArrayList<JProperty>();
138
139 for (JProperty property : properties) {
140 boolean success = reasignProperty(baseCls, property);
141 if (success)
142 propsToRemove.add(property);
143 }
144
145 // remove the marked properties and the restriction containers
146 for (JProperty prop : propsToRemove) {
147 prop.removeDomain(baseCls);
148 prop.removeClassRestrictions(baseCls);
149 baseCls.removeDomainRestrictionsContainer(prop);
150
151 }
152
153 }
154
155 public void setReasignDomainlessProperties(boolean reasignDomainlessProperties) {
156 this.reasignDomainlessProperties = reasignDomainlessProperties;
157 }
158 }