001    package nl.tudelft.tbm.eeni.owl2java.model.jmodel;
002    
003    import com.hp.hpl.jena.ontology.OntProperty;
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.model.xsd.XsdGraph;
007    import nl.tudelft.tbm.eeni.owl2java.model.xsd.XsdTypeMapper;
008    import nl.tudelft.tbm.eeni.owl2java.utils.StringUtils;
009    import org.apache.commons.logging.Log;
010    import org.apache.commons.logging.LogFactory;
011    import org.jgraph.graph.DefaultEdge;
012    
013    import java.util.*;
014    
015    
016    public class JProperty extends JMapped {
017    
018        public static final String DataTypeProperty = "DataTypeProperty";
019        public static final String ObjectProperty = "ObjectProperty";
020    
021        private static Log log = LogFactory.getLog(JProperty.class);
022    
023        private OntProperty ontProperty;
024        private JModel jmodel;
025    
026        protected List<JClass> propertyDomain = new ArrayList<JClass>();
027        // propertyRange is of type List<String (URI)> for a datatype property, List<JClass> for a object property
028        @SuppressWarnings("unchecked")
029        protected List propertyRange = new ArrayList();
030        private String propertyType;
031    
032        private List<JProperty> equivalentProps = new ArrayList<JProperty>();
033        private List<JProperty> inverseProps = new ArrayList<JProperty>();
034    
035        private Map<JClass, JRestrictionsContainer> classRestrictions = new HashMap<JClass, JRestrictionsContainer>();
036    
037        private boolean isFunctional = false;
038        private boolean isInverseFunctional = false;
039        private boolean isSymetric = false;
040        private boolean isTransitive = false;
041    
042        public JProperty(JModel model, String name, String mappedTo) {
043            super(name, mappedTo);
044            this.jmodel = model;
045            this.jmodel.getPropertyGraph().addVertex(this);
046        }
047    
048        public void removeClassRestrictions(JClass cls) {
049            if (classRestrictions.containsKey(cls))
050                classRestrictions.remove(cls);
051        }
052    
053        public void addDomain(JClass domainCls) {
054            log.debug(LogUtils.toLogName(domainCls) + ": Adding domain property " + LogUtils.toLogName(this));
055            if (!this.propertyDomain.contains(domainCls))
056                this.propertyDomain.add(domainCls);
057            if (!domainCls.hasDomainProperty(this))
058                domainCls.addDomainProperty(this);
059        }
060    
061        public void addEquivalentProperty(JProperty property) {
062            if (!this.equivalentProps.contains(property))
063                this.equivalentProps.add(property);
064            if (!property.equivalentProps.contains(this))
065                property.equivalentProps.add(this);
066        }
067    
068        public boolean hasEquivalentProperty(JProperty property) {
069            return equivalentProps.contains(property);
070        }
071    
072        public void addInverseProperty(JProperty prop) {
073            if (!this.inverseProps.contains(prop))
074                this.inverseProps.add(prop);
075            if (!prop.inverseProps.contains(this))
076                prop.inverseProps.add(this);
077        }
078    
079        @SuppressWarnings("unchecked")
080        public void addRange(JClass range) {
081            if (propertyType == DataTypeProperty) {
082                log.warn("Adding a JClass object to a Datatype property. Ignored");
083                return;
084            }
085            if (!this.propertyRange.contains(range))
086                this.propertyRange.add(range);
087        }
088    
089        @SuppressWarnings("unchecked")
090        public void addRange(String range) {
091            if (propertyType == ObjectProperty) {
092                log.warn("Adding a String to a Objectproperty. Ignored");
093                return;
094            }
095    
096            if (!this.propertyRange.contains(range))
097                this.propertyRange.add(range);
098        }
099    
100        public void addSubProperty(JProperty prop) {
101            jmodel.getPropertyGraph().addChildVertex(this, prop);
102        }
103    
104        public void addSuperProperty(JProperty prop) {
105            jmodel.getPropertyGraph().addParentVertex(this, prop);
106        }
107    
108        public boolean equals(Object other) {
109            // same URI
110            return other instanceof JProperty && ((JProperty) other).getMapUri().equals(getMapUri());
111        }
112    
113        public String getDataRangeMethod() {
114            String rangeUri = getRangeUri();
115            return XsdTypeMapper.getAccessMethod(rangeUri);
116        }
117    
118        public String getJavaName() {
119            return NamingUtils.getPropertyName(ontProperty);
120        }
121    
122        public OntProperty getOntProperty() {
123            return ontProperty;
124        }
125    
126        public String getPropertyType() {
127            return propertyType;
128        }
129    
130        public String getRangeJava() {
131            String rangeName = new String();
132            ;
133            String rangeUri = getRangeUri();
134            if (this.isDataTypeProperty()) {
135                rangeName = XsdTypeMapper.getJavaClassName(rangeUri);
136                // go from java.lang.String to String
137                rangeName = rangeName.substring(rangeName.lastIndexOf(".") + 1);
138            } else {
139                JClass cls = jmodel.getJClass(rangeUri);
140                rangeName = cls.getJavaClassName();
141            }
142            return rangeName;
143        }
144    
145        public String getRangeJavaFull() {
146            String rangeName = new String();
147            ;
148            String rangeUri = getRangeUri();
149            if (isDataTypeProperty()) {
150                rangeName = XsdTypeMapper.getJavaClassName(rangeUri);
151            } else {
152                JClass cls = jmodel.getJClass(rangeUri);
153                rangeName = cls.getJavaClassFullName();
154            }
155            return rangeName;
156        }
157    
158        public String getRangeInterfaceJava() {
159            String rangeName = new String();
160            ;
161            String rangeUri = getRangeUri();
162            if (this.isObjectProperty()) {
163                JClass cls = jmodel.getJClass(rangeUri);
164                rangeName = cls.getJavaInterfaceName();
165            }
166            return rangeName;
167        }
168    
169        public String getRangeInterfaceJavaFull() {
170            String rangeName = new String();
171            ;
172            String rangeUri = getRangeUri();
173            if (this.isObjectProperty()) {
174                JClass cls = jmodel.getJClass(rangeUri);
175                rangeName = cls.getJavaInterfaceFullName();
176            }
177            return rangeName;
178        }
179    
180        @SuppressWarnings("unchecked")
181        public String getRangeUri() {
182            String rangeUri;
183            if (this.getPropertyType() == JProperty.DataTypeProperty)
184                if (propertyRange.isEmpty()) {
185                    log.debug(LogUtils.toLogName(this) + ": Range is empty! Setting range to XMLLiteral");
186                    rangeUri = "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral";
187                } else if (propertyRange.size() > 1) {
188                    rangeUri = XsdGraph.findBestSuperXsdType(propertyRange);
189                    log.info(LogUtils.toLogName(this) + ": multiple range! Setting range to best " + "super type "
190                            + rangeUri);
191                } else {
192                    rangeUri = (String) propertyRange.get(0);
193                    log.debug(LogUtils.toLogName(this) + ": Setting range to " + rangeUri);
194                }
195            else {
196                if (propertyRange.isEmpty()) {
197                    log.debug(LogUtils.toLogName(this) + ": Range is empty! Setting range to BaseThing Uri");
198                    rangeUri = jmodel.getBaseThingUri();
199                } else if (propertyRange.size() > 1) {
200                    log.error(LogUtils.toLogName(this) + ": Multiple range! This should have been "
201                            + "be handled before. Aborting");
202                    System.exit(1);
203                    rangeUri = jmodel.getBaseThingUri();
204                } else {
205                    JClass cls = (JClass) propertyRange.get(0);
206                    rangeUri = cls.getMapUri();
207                }
208            }
209            return rangeUri;
210        }
211    
212        @SuppressWarnings("unchecked")
213        @Override
214        public String getJModelReport() {
215            String report = new String();
216            String rng = new String();
217    
218            // Super, sub
219            Iterator it;
220            Set<DefaultEdge> edgesIn = jmodel.getPropertyGraph().incomingEdgesOf(this);
221            it = edgesIn.iterator();
222            while (it.hasNext()) {
223                DefaultEdge edge = (DefaultEdge) it.next();
224                JProperty src = jmodel.getPropertyGraph().getEdgeSource(edge);
225                rng += src.getJavaName() + ", ";
226            }
227            report += StringUtils.indentText("Parent Properties: " + rng + "\n", 3);
228    
229            Set<DefaultEdge> edgesOut = jmodel.getPropertyGraph().outgoingEdgesOf(this);
230            it = edgesOut.iterator();
231            rng = new String();
232            while (it.hasNext()) {
233                DefaultEdge edge = (DefaultEdge) it.next();
234                JProperty src = jmodel.getPropertyGraph().getEdgeTarget(edge);
235                rng += src.getJavaName() + ",";
236            }
237            report += StringUtils.indentText("Child Properties: " + rng + "\n", 3);
238    
239            rng = new String();
240            for (JProperty equProperty : equivalentProps)
241                rng += equProperty.getJavaName() + ", ";
242            report += StringUtils.indentText("Equivalent Properties: " + rng + "\n", 3);
243    
244            String range = new String();
245            if (propertyType == DataTypeProperty) {
246                it = propertyRange.iterator();
247                while (it.hasNext()) {
248                    String rangeUri = (String) it.next();
249                    range += (String) rangeUri + ", ";
250                }
251            } else {
252                it = propertyRange.iterator();
253                while (it.hasNext()) {
254                    JClass cls = (JClass) it.next();
255                    range += cls.getJavaInterfaceFullName() + ", ";
256                }
257            }
258    
259            report += StringUtils.indentText("Range: " + range + "\n", 3);
260    
261            report += StringUtils.indentText("Inverse Properties: " + "\n", 3);
262            for (JProperty property : inverseProps)
263                report += StringUtils.indentText(property.getJavaName() + "\n", 3);
264    
265            report += StringUtils.indentText("Property Restrictions\n", 3);
266    
267            for (JRestrictionsContainer rc : classRestrictions.values()) {
268                report += StringUtils.indentText(rc.getJModelReport(), 4) + "\n";
269            }
270            report += StringUtils.indentText("Functional: " + isFunctional + "\n", 3);
271            return report;
272        }
273    
274        public boolean hasInverseProperties() {
275            return (!this.inverseProps.isEmpty());
276        }
277    
278        public boolean hasInverseProperty(JProperty prop) {
279            return this.inverseProps.contains(prop);
280        }
281    
282        public boolean isDataTypeProperty() {
283            return (propertyType == JProperty.DataTypeProperty);
284        }
285    
286        public boolean isFunctional() {
287            return isFunctional;
288        }
289    
290        public boolean isObjectProperty() {
291            return (propertyType == JProperty.ObjectProperty);
292        }
293    
294        @SuppressWarnings("unchecked")
295        public List<JClass> listObjectPropertyRange() {
296            if (propertyType == JProperty.ObjectProperty)
297                return propertyRange;
298            return null;
299        }
300    
301        @SuppressWarnings("unchecked")
302        public List<String> listDatatypePropertyRange() {
303            if (propertyType == JProperty.DataTypeProperty)
304                return propertyRange;
305            return null;
306        }
307    
308        public void removeDomain(JClass domainCls) {
309            log.debug(LogUtils.toLogName(domainCls) + ": Removing domain property " + LogUtils.toLogName(this));
310            domainCls.listDomainProperties().remove(this);
311            propertyDomain.remove(domainCls);
312        }
313    
314        public void setFunctional(boolean isFunctional) {
315            this.isFunctional = isFunctional;
316        }
317    
318        public void setOntProperty(OntProperty ontProperty) {
319            this.ontProperty = ontProperty;
320        }
321    
322        public void setPropertyType(String propertyType) {
323            this.propertyType = propertyType;
324        }
325    
326        public void setSymetric(boolean isSymetric) {
327            this.isSymetric = isSymetric;
328        }
329    
330        public boolean isTransitive() {
331            return isTransitive;
332        }
333    
334        public void setTransitive(boolean isTransitive) {
335            this.isTransitive = isTransitive;
336        }
337    
338        public boolean isSymetric() {
339            return isSymetric;
340        }
341    
342        public boolean isInverseFunctional() {
343            return isInverseFunctional;
344        }
345    
346        public void setInverseFunctional(boolean isInverseFunctional) {
347            this.isInverseFunctional = isInverseFunctional;
348        }
349    
350        public String toString() {
351            return getJavaName();
352        }
353    
354        public void addRestrictionsContainer(JClass cls, JRestrictionsContainer rc) {
355            if (!classRestrictions.containsKey(cls))
356                classRestrictions.put(cls, rc);
357        }
358    
359        public JRestrictionsContainer getRestrictionsContainer(JClass cls) {
360            return classRestrictions.get(cls);
361        }
362    
363        public boolean hasRestrictionsContainer(JRestrictionsContainer restriction) {
364            return classRestrictions.containsValue(restriction);
365        }
366    
367        public boolean hasRestrictionsContainer(JClass cls) {
368            return classRestrictions.containsKey(cls);
369        }
370    
371    }