Skip to content

Package: JavaTransformer

JavaTransformer

nameinstructionbranchcomplexitylinemethod
JavaTransformer(TransformationConfiguration)
M: 16 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
addCommonClassFields(JCodeModel, JDefinedClass, PropertiesType)
M: 117 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 21 C: 0
0%
M: 1 C: 0
0%
addField(String, JDefinedClass, JType)
M: 91 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 12 C: 0
0%
M: 1 C: 0
0%
create(String, JCodeModel, OWLClass, OWLOntology)
M: 51 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 10 C: 0
0%
M: 1 C: 0
0%
createVocabularyClass(JCodeModel)
M: 28 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
ensureCreated(String, JCodeModel, OWLClass, OWLOntology)
M: 22 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
ensureUniqueIdentifier(String)
M: 20 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
generateAuthorshipDoc(JDocCommentable)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
generateClassJavadoc(OWLOntology, OWLEntity, JDocCommentable)
M: 16 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
generateDataProperty(OWLOntology, JCodeModel, ContextDefinition, OWLClass, JDefinedClass, OWLDataProperty)
M: 114 C: 0
0%
M: 9 C: 0
0%
M: 6 C: 0
0%
M: 21 C: 0
0%
M: 1 C: 0
0%
generateJavadoc(OWLOntology, OWLEntity, JDocCommentable)
M: 50 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 15 C: 0
0%
M: 1 C: 0
0%
generateModel(OWLOntology, ContextDefinition)
M: 33 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
generateModelImpl(OWLOntology, JCodeModel, ContextDefinition, String)
M: 107 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 19 C: 0
0%
M: 1 C: 0
0%
generateObjectProperty(OWLOntology, JCodeModel, ContextDefinition, String, OWLClass, JDefinedClass, OWLObjectProperty)
M: 118 C: 0
0%
M: 11 C: 0
0%
M: 7 C: 0
0%
M: 23 C: 0
0%
M: 1 C: 0
0%
generateOntologyIrisConstants(OWLOntologyManager)
M: 21 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
generateToStringMethod(JDefinedClass, String, String)
M: 49 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
generateVocabulary(OWLOntology, ContextDefinition)
M: 26 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
generateVocabulary(OWLOntology, JCodeModel, ContextDefinition)
M: 130 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 25 C: 0
0%
M: 1 C: 0
0%
isJavaClassNameAnnotation(OWLAnnotation)
M: 19 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
javaClassId(OWLOntology, OWLClass)
M: 25 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
lambda$generateJavadoc$4(OWLAnnotation)
M: 12 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$generateJavadoc$6(OWLAnnotation)
M: 11 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
lambda$generateJavadoc$7(OWLAnnotation)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$generateJavadoc$8(JDocCommentable, OWLLiteral)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$generateJavadoc$9(JDocCommentable, OWLLiteral)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$generateModelImpl$0(IntegrityConstraint)
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$generateModelImpl$1(JDefinedClass, String, JCodeModel, OWLOntology, AtomicBoolean, IntegrityConstraint)
M: 17 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
lambda$generateOntologyIrisConstants$2(OWLOntology)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$generateOntologyIrisConstants$3(IRI)
M: 23 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
lambda$javaClassId$10(OWLAnnotation)
M: 12 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
lambda$null$5(OWLLiteral)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
modelPackageName()
M: 23 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
resolveFieldPrefix(OWLEntity, Set)
M: 50 C: 0
0%
M: 14 C: 0
0%
M: 8 C: 0
0%
M: 13 C: 0
0%
M: 1 C: 0
0%
resolveFieldType(OWLDatatype)
M: 15 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
setParticipationConstraintCardinality(JAnnotationUse, ParticipationConstraint)
M: 20 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 207 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
toJavaNotation(String)
M: 40 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
validJavaID(String)
M: 37 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
validJavaIDForIRI(IRI)
M: 20 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /**
2: * Copyright (C) 2022 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.jopa.owl2java;
16:
17: import com.sun.codemodel.*;
18: import cz.cvut.kbss.jopa.ic.api.AtomicSubClassConstraint;
19: import cz.cvut.kbss.jopa.ic.api.DataParticipationConstraint;
20: import cz.cvut.kbss.jopa.ic.api.ObjectParticipationConstraint;
21: import cz.cvut.kbss.jopa.model.MultilingualString;
22: import cz.cvut.kbss.jopa.model.annotations.OWLAnnotationProperty;
23: import cz.cvut.kbss.jopa.model.annotations.OWLDataProperty;
24: import cz.cvut.kbss.jopa.model.annotations.OWLObjectProperty;
25: import cz.cvut.kbss.jopa.model.annotations.Properties;
26: import cz.cvut.kbss.jopa.model.annotations.*;
27: import cz.cvut.kbss.jopa.owl2java.cli.Option;
28: import cz.cvut.kbss.jopa.owl2java.cli.PropertiesType;
29: import cz.cvut.kbss.jopa.owl2java.config.TransformationConfiguration;
30: import cz.cvut.kbss.jopa.owl2java.exception.OWL2JavaException;
31: import cz.cvut.kbss.jopa.owlapi.DatatypeTransformer;
32: import cz.cvut.kbss.jopa.vocabulary.DC;
33: import cz.cvut.kbss.jopa.vocabulary.RDFS;
34: import org.semanticweb.owlapi.model.OWLClass;
35: import org.semanticweb.owlapi.model.*;
36: import org.semanticweb.owlapi.search.EntitySearcher;
37: import org.slf4j.Logger;
38: import org.slf4j.LoggerFactory;
39:
40: import java.io.Serializable;
41: import java.text.Normalizer;
42: import java.util.*;
43: import java.util.concurrent.atomic.AtomicBoolean;
44: import java.util.stream.Collectors;
45:
46: import static cz.cvut.kbss.jopa.owl2java.Constants.*;
47:
48: public class JavaTransformer {
49:
50: private static final Logger LOG = LoggerFactory.getLogger(OWL2JavaTransformer.class);
51:
52: private static final String[] KEYWORDS = {"abstract",
53: "assert",
54: "boolean",
55: "break",
56: "byte",
57: "case",
58: "catch",
59: "char",
60: "class",
61: "const",
62: "continue",
63: "default",
64: "do",
65: "double",
66: "else",
67: "enum",
68: "extends",
69: "final",
70: "finally",
71: "float",
72: "for",
73: "goto",
74: "if",
75: "implements",
76: "import",
77: "instanceof",
78: "int",
79: "interface",
80: "long",
81: "native",
82: "new",
83: "package",
84: "private",
85: "protected",
86: "public",
87: "return",
88: "short",
89: "static",
90: "strictfp",
91: "super",
92: "switch",
93: "synchronized",
94: "this",
95: "throw",
96: "throws",
97: "transient",
98: "try",
99: "void",
100: "volatile",
101: "while"};
102:
103: private static final String PREFIX_STRING = "s_";
104: private static final String PREFIX_CLASS = "c_";
105: private static final String PREFIX_PROPERTY = "p_";
106: private static final String PREFIX_INDIVIDUAL = "i_";
107: private static final String PREFIX_DATATYPE = "d_";
108:
109: private JDefinedClass voc;
110: private final Map<OWLEntity, JFieldRef> entities = new HashMap<>();
111:
112: private final Map<OWLClass, JDefinedClass> classes = new HashMap<>();
113:
114: private final TransformationConfiguration configuration;
115:
116: JavaTransformer(TransformationConfiguration configuration) {
117: this.configuration = configuration;
118: }
119:
120: private static String validJavaIDForIRI(final IRI iri) {
121:• if (iri.getFragment() != null) {
122: return validJavaID(iri.getFragment());
123: } else {
124: int x = iri.toString().lastIndexOf("/");
125: return validJavaID(iri.toString().substring(x + 1));
126: }
127: }
128:
129: private static String validJavaID(final String s) {
130: String res = s.trim().replace("-", "_").replace("'", "_quote_").replace(".", "_dot_").replace(',', '_');
131: // Replace non-ASCII characters with ASCII ones
132: res = Normalizer.normalize(res, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "");
133:• if (Arrays.binarySearch(KEYWORDS, res) >= 0) {
134: res = "_" + res;
135: }
136: return res;
137: }
138:
139: private static JFieldVar addField(final String name, final JDefinedClass cls,
140: final JType fieldType) {
141: String newName = name;
142:
143: int i = 0;
144:• while (cls.fields().containsKey(newName)) {
145: newName = name + "" + (++i);
146: }
147:
148: final JFieldVar fvId = cls.field(JMod.PROTECTED, fieldType, newName);
149: final String fieldName = fvId.name().substring(0, 1).toUpperCase() + fvId.name().substring(1);
150: final JMethod mSetId = cls.method(JMod.PUBLIC, void.class, "set" + fieldName);
151: final JVar v = mSetId.param(fieldType, fvId.name());
152: mSetId.body().assign(JExpr._this().ref(fvId), v);
153: final JMethod mGetId = cls.method(JMod.PUBLIC, fieldType, "get" + fieldName);
154: mGetId.body()._return(fvId);
155: return fvId;
156: }
157:
158: /**
159: * Generates an object model consisting of JOPA entity classes and a vocabulary file from the specified ontology and
160: * context definition.
161: *
162: * @param ontology Ontology from which the model is generated
163: * @param context Context information
164: * @return The generated object model
165: */
166: public ObjectModel generateModel(final OWLOntology ontology, final ContextDefinition context) {
167: try {
168: final JCodeModel cm = new JCodeModel();
169: voc = createVocabularyClass(cm);
170: generateVocabulary(ontology, cm, context);
171: generateModelImpl(ontology, cm, context, modelPackageName());
172: return new ObjectModel(cm);
173: } catch (JClassAlreadyExistsException e) {
174: throw new OWL2JavaException("Transformation FAILED.", e);
175: }
176: }
177:
178: private String modelPackageName() {
179: final String packageConfig = configuration.getPackageName();
180: final StringBuilder sb = new StringBuilder(packageConfig);
181:• if (!packageConfig.isEmpty()) {
182: sb.append(PACKAGE_SEPARATOR);
183: }
184: sb.append(MODEL_PACKAGE);
185: return sb.toString();
186: }
187:
188: private JDefinedClass createVocabularyClass(JCodeModel codeModel)
189: throws JClassAlreadyExistsException {
190: final String packageName = configuration.getPackageName();
191: final String className =
192:• packageName.isEmpty() ? VOCABULARY_CLASS : packageName + PACKAGE_SEPARATOR + VOCABULARY_CLASS;
193: final JDefinedClass cls = codeModel._class(className);
194: generateAuthorshipDoc(cls);
195: return cls;
196: }
197:
198: private static void generateAuthorshipDoc(JDocCommentable javaElem) {
199: javaElem.javadoc().add("This class was generated by OWL2Java " + VERSION);
200: }
201:
202: /**
203: * Generates only vocabulary of the loaded ontology.
204: *
205: * @param ontology Ontology from which the vocabulary should be generated
206: * @param context Integrity constraints context, if null is supplied, the whole ontology is interpreted as
207: * integrity constraints.
208: * @return The generated object model
209: */
210: public ObjectModel generateVocabulary(final OWLOntology ontology, ContextDefinition context) {
211: try {
212: final JCodeModel cm = new JCodeModel();
213: this.voc = createVocabularyClass(cm);
214: generateVocabulary(ontology, cm, context);
215: return new ObjectModel(cm);
216: } catch (JClassAlreadyExistsException e) {
217: throw new OWL2JavaException("Vocabulary generation FAILED, because the Vocabulary class already exists.",
218: e);
219: }
220: }
221:
222: private void generateObjectProperty(final OWLOntology ontology,
223: final JCodeModel cm,
224: final ContextDefinition context,
225: final String pkg,
226: final OWLClass clazz,
227: final JDefinedClass subj,
228: final org.semanticweb.owlapi.model.OWLObjectProperty prop) {
229: final ClassObjectPropertyComputer comp = new ClassObjectPropertyComputer(
230: clazz,
231: prop,
232: context.set,
233: ontology
234: );
235:
236:• if (Card.NO != comp.getCard()) {
237: JClass filler = ensureCreated(pkg, cm, comp.getFiller(), ontology);
238: final String fieldName = validJavaIDForIRI(prop.getIRI());
239:
240:• switch (comp.getCard()) {
241: case MULTIPLE:
242: filler = cm.ref(java.util.Set.class).narrow(filler);
243: break;
244: case SIMPLELIST:
245: case LIST:
246: filler = cm.ref(java.util.List.class).narrow(filler);
247: break;
248: default:
249: break;
250: }
251:
252: final JFieldVar fv = addField(fieldName, subj, filler);
253: generateJavadoc(ontology, prop, fv);
254:
255:• if (comp.getCard().equals(Card.SIMPLELIST)) {
256: fv.annotate(Sequence.class).param("type", SequenceType.simple);
257: }
258:
259:
260: fv.annotate(OWLObjectProperty.class).param("iri", entities.get(prop));
261:
262: JAnnotationArrayMember use = null;
263:• for (ObjectParticipationConstraint ic : comp.getParticipationConstraints()) {
264:• if (use == null) {
265: use = fv.annotate(ParticipationConstraints.class).paramArray("value");
266: }
267: JAnnotationUse u = use.annotate(ParticipationConstraint.class)
268: .param("owlObjectIRI", entities.get(ic.getObject()));
269: setParticipationConstraintCardinality(u, ic);
270: }
271: }
272: }
273:
274: private static void setParticipationConstraintCardinality(JAnnotationUse u,
275: cz.cvut.kbss.jopa.ic.api.ParticipationConstraint<?, ?> ic) {
276:• if (ic.getMin() != 0) {
277: u.param("min", ic.getMin());
278: }
279:• if (ic.getMin() != -1) {
280: u.param("max", ic.getMax());
281: }
282: }
283:
284: private void generateDataProperty(final OWLOntology ontology,
285: final JCodeModel cm,
286: final ContextDefinition context,
287: final OWLClass clazz,
288: final JDefinedClass subj,
289: final org.semanticweb.owlapi.model.OWLDataProperty prop) {
290: final ClassDataPropertyComputer comp = new ClassDataPropertyComputer(
291: clazz,
292: prop,
293: context.set,
294: ontology
295: );
296:
297:• if (Card.NO != comp.getCard()) {
298:
299: final JType obj = cm._ref(resolveFieldType(comp.getFiller()));
300:
301: final String fieldName = validJavaIDForIRI(prop.getIRI());
302:
303: JFieldVar fv;
304:
305:• switch (comp.getCard()) {
306: case MULTIPLE:
307: fv = addField(fieldName, subj, cm.ref(java.util.Set.class).narrow(obj));
308: break;
309: case ONE:
310: fv = addField(fieldName, subj, obj);
311: break;
312: default:
313: throw new OWL2JavaException("Unsupported data property cardinality type " + comp.getCard());
314: }
315: generateJavadoc(ontology, prop, fv);
316:
317: fv.annotate(OWLDataProperty.class).param("iri", entities.get(prop));
318:
319: JAnnotationArrayMember use = null;
320:• for (DataParticipationConstraint ic : comp.getParticipationConstraints()) {
321:• if (use == null) {
322: use = fv.annotate(ParticipationConstraints.class).paramArray("value");
323: }
324:
325: JAnnotationUse u = use.annotate(ParticipationConstraint.class)
326: .param("owlObjectIRI", comp.getFiller().getIRI().toString());
327:
328: setParticipationConstraintCardinality(u, ic);
329: }
330: }
331: }
332:
333: private Class<?> resolveFieldType(OWLDatatype datatype) {
334: final Class<?> cls = DatatypeTransformer.transformOWLType(datatype);
335:• if (MultilingualString.class.equals(cls) && !configuration.shouldPreferMultilingualStrings()) {
336: return String.class;
337: }
338: return cls;
339: }
340:
341: private void generateModelImpl(final OWLOntology ontology, final JCodeModel cm,
342: final ContextDefinition context, final String pkg) {
343: LOG.info("Generating model ...");
344: final PropertiesType propertiesType = configuration.getPropertiesType();
345:
346: context.classes.add(ontology.getOWLOntologyManager().getOWLDataFactory().getOWLThing());
347:
348:• for (final OWLClass clazz : context.classes) {
349: LOG.info(" Generating class '{}'.", clazz);
350: final JDefinedClass subj = ensureCreated(pkg, cm, clazz, ontology);
351:
352: final AtomicBoolean extendClass = new AtomicBoolean(false);
353: context.set.getClassIntegrityConstraints(clazz).stream()
354: .filter(ic -> ic instanceof AtomicSubClassConstraint).forEach(ic -> {
355: final AtomicSubClassConstraint icc = (AtomicSubClassConstraint) ic;
356: subj._extends(ensureCreated(pkg, cm, icc.getSupClass(), ontology
357: ));
358: extendClass.set(true);
359: });
360:
361:• if (!extendClass.get())
362: addCommonClassFields(cm, subj, propertiesType);
363:• for (final org.semanticweb.owlapi.model.OWLObjectProperty prop : context.objectProperties) {
364: generateObjectProperty(ontology, cm, context, pkg, clazz, subj, prop);
365: }
366:
367:• for (org.semanticweb.owlapi.model.OWLDataProperty prop : context.dataProperties) {
368: generateDataProperty(ontology, cm, context, clazz, subj, prop);
369: }
370: }
371: }
372:
373: private void generateVocabulary(final OWLOntology o, final JCodeModel cm, ContextDefinition context) {
374: final Collection<OWLEntity> col = new LinkedHashSet<>();
375: col.add(o.getOWLOntologyManager().getOWLDataFactory().getOWLThing());
376: col.addAll(context.classes);
377: col.addAll(context.objectProperties);
378: col.addAll(context.dataProperties);
379: col.addAll(context.annotationProperties);
380: col.addAll(context.individuals);
381:
382: generateOntologyIrisConstants(o.getOWLOntologyManager());
383:
384: final Set<IRI> visitedProperties = new HashSet<>(col.size());
385:
386:• for (final OWLEntity c : col) {
387: final Optional<String> prefix = resolveFieldPrefix(c, visitedProperties);
388:• if (!prefix.isPresent()) {
389: continue;
390: }
391: final String sFieldName = ensureUniqueIdentifier(
392: PREFIX_STRING + prefix.get() + validJavaIDForIRI(c.getIRI()));
393:
394: final JFieldVar fv1 = voc.field(JMod.PUBLIC | JMod.STATIC
395: | JMod.FINAL, String.class, sFieldName, JExpr.lit(c.getIRI().toString()));
396:• if (configuration.shouldGenerateOwlapiIris()) {
397: voc.field(JMod.PUBLIC | JMod.STATIC | JMod.FINAL, IRI.class,
398: sFieldName.substring(PREFIX_STRING.length()),
399: cm.ref(IRI.class).staticInvoke("create").arg(fv1));
400: }
401: generateJavadoc(o, c, fv1);
402: entities.put(c, voc.staticRef(fv1));
403: }
404: }
405:
406: private void generateOntologyIrisConstants(OWLOntologyManager ontologyManager) {
407: // Get only unique ontology IRIs sorted
408: final List<IRI> ontologyIris = ontologyManager.ontologies().map(o -> o.getOntologyID().getOntologyIRI())
409: .filter(Optional::isPresent).map(Optional::get).distinct()
410: .sorted(Comparator.comparing(IRI::getIRIString))
411: .collect(Collectors.toList());
412: ontologyIris.forEach(iri -> {
413: final String fieldName = ensureUniqueIdentifier("ONTOLOGY_IRI_" + validJavaIDForIRI(iri));
414: voc.field(JMod.PUBLIC | JMod.STATIC | JMod.FINAL, String.class, fieldName, JExpr.lit(iri.toString()));
415: });
416: }
417:
418: private static Optional<String> resolveFieldPrefix(OWLEntity c, Set<IRI> visitedProperties) {
419:• if (c.isOWLClass()) {
420: return Optional.of(PREFIX_CLASS);
421:• } else if (c.isOWLDatatype()) {
422: return Optional.of(PREFIX_DATATYPE);
423:• } else if (c.isOWLDataProperty() || c.isOWLObjectProperty() || c.isOWLAnnotationProperty()) {
424:• if (visitedProperties.contains(c.getIRI())) {
425: LOG.debug("Property with IRI {} already processed. Skipping.", c.getIRI());
426: return Optional.empty();
427: }
428: visitedProperties.add(c.getIRI());
429: return Optional.of(PREFIX_PROPERTY);
430:• } else if (c.isOWLNamedIndividual()) {
431: return Optional.of(PREFIX_INDIVIDUAL);
432: }
433: return Optional.of("");
434: }
435:
436: private String ensureUniqueIdentifier(String id) {
437: final StringBuilder sb = new StringBuilder(id);
438:• while (voc.fields().containsKey(sb.toString())) {
439: sb.append("_A");
440: }
441: return sb.toString();
442: }
443:
444: /**
445: * Generates Javadoc from rdfs:comment annotation (if present).
446: *
447: * @param ontology Ontology from which the model/vocabulary is being generated
448: * @param owlEntity Annotated entity
449: * @param javaElem Element to document with Javadoc
450: * @return Whether the javadoc comment has been generated
451: */
452: private boolean generateJavadoc(OWLOntology ontology, OWLEntity owlEntity, JDocCommentable javaElem) {
453:• if (!configuration.shouldGenerateJavadoc()) {
454: return false;
455: }
456: final List<OWLAnnotation> comments = EntitySearcher.getAnnotations(owlEntity, ontology)
457:• .filter(a -> a.getProperty().isComment() && a.getValue().isLiteral()).collect(Collectors.toList());
458: final Optional<OWLAnnotation> langComment = comments.stream().filter(a -> a.getValue().asLiteral()
459: .map(l -> l.hasLang(LANGUAGE)).orElse(false)).findFirst();
460: // First try finding a comment with a matching language tag
461:• if (langComment.isPresent()) {
462: langComment.flatMap(a -> a.getValue().asLiteral())
463: .ifPresent(lit -> javaElem.javadoc().add(lit.getLiteral()));
464: return true;
465: }
466: // If there is none such, just use the first available one
467:• if (!comments.isEmpty()) {
468: OWLAnnotation anyComment = comments.get(0);
469: anyComment.getValue().asLiteral().ifPresent(lit -> javaElem.javadoc().add(lit.getLiteral()));
470: return true;
471: }
472: return false;
473: }
474:
475: private JDefinedClass create(final String pkg, final JCodeModel cm, final OWLClass clazz,
476: final OWLOntology ontology) {
477: JDefinedClass cls;
478:
479: String name = pkg + PACKAGE_SEPARATOR + javaClassId(ontology, clazz);
480:
481: try {
482: cls = cm._class(name);
483:
484: cls.annotate(cz.cvut.kbss.jopa.model.annotations.OWLClass.class).param("iri", entities.get(clazz));
485: cls._implements(Serializable.class);
486:
487: generateClassJavadoc(ontology, clazz, cls);
488: } catch (JClassAlreadyExistsException e) {
489: LOG.trace("Class already exists. Using the existing version. {}", e.getMessage());
490: cls = cm._getClass(name);
491: }
492: return cls;
493: }
494:
495: /**
496: * Add common properties such as id and type
497: */
498: private static void addCommonClassFields(final JCodeModel cm, final JDefinedClass cls,
499: final PropertiesType propertiesType) {
500: // @Id(generated = true) protected String id;
501: final JClass ftId = cm.ref(String.class);
502: final JFieldVar fvId = addField("id", cls, ftId);
503: JAnnotationUse a = fvId.annotate(Id.class);
504: a.param("generated", true);
505:
506: // RDFS label
507: final JClass ftLabel = cm.ref(String.class);
508: final JFieldVar fvLabel = addField("name", cls, ftLabel);
509: fvLabel.annotate(OWLAnnotationProperty.class).param("iri", cm.ref(RDFS.class).staticRef("LABEL"));
510:
511: // DC description
512: final JClass ftDescription = cm.ref(String.class);
513: final JFieldVar fvDescription = addField("description", cls, ftDescription);
514: fvDescription.annotate(OWLAnnotationProperty.class)
515: .param("iri", cm.ref(DC.Elements.class).staticRef("DESCRIPTION"));
516:
517: // @Types Set<String> types;
518: final JClass ftTypes = cm.ref(Set.class).narrow(String.class);
519: final JFieldVar fvTypes = addField("types", cls, ftTypes);
520: fvTypes.annotate(Types.class);
521:
522: // @Properties public final Map<String,Set<String>> properties;
523:• final Class<?> propertiesTypeC = (propertiesType == PropertiesType.object ? Object.class : String.class);
524: final JClass ftProperties = cm.ref(Map.class)
525: .narrow(cm.ref(String.class), cm.ref(Set.class).narrow(propertiesTypeC));
526: final JFieldVar fvProperties = addField("properties", cls, ftProperties);
527: fvProperties.annotate(Properties.class);
528:
529: generateToStringMethod(cls, fvId.name(), fvLabel.name());
530: }
531:
532: private String javaClassId(OWLOntology ontology, OWLClass owlClass) {
533: final Optional<OWLAnnotation> res = EntitySearcher.getAnnotations(owlClass, ontology)
534:• .filter(a -> isJavaClassNameAnnotation(a) &&
535:• a.getValue().isLiteral()).findFirst();
536:• if (res.isPresent()) {
537: return res.get().getValue().asLiteral().get().getLiteral();
538: } else {
539: return toJavaNotation(validJavaIDForIRI(owlClass.getIRI()));
540: }
541: }
542:
543: private void generateClassJavadoc(OWLOntology ontology, OWLEntity owlEntity, JDocCommentable javaElem) {
544: final boolean generated = generateJavadoc(ontology, owlEntity, javaElem);
545:• if (generated) {
546: javaElem.javadoc().add("\n\n");
547: }
548: generateAuthorshipDoc(javaElem);
549: }
550:
551: private static void generateToStringMethod(JDefinedClass cls, String idFieldName, String labelFieldName) {
552: final JMethod toString = cls.method(JMod.PUBLIC, String.class, "toString");
553: toString.annotate(Override.class);
554: final JBlock body = toString.body();
555: JExpression expression = JExpr.lit(cls.name() + " {");
556: expression = expression.plus(JExpr.ref(labelFieldName));
557: expression = expression.plus(JExpr.lit("<")).plus(JExpr.ref(idFieldName)).plus(JExpr.lit(">"));
558: expression = expression.plus(JExpr.lit("}"));
559:
560: body._return(expression);
561: }
562:
563: private JDefinedClass ensureCreated(final String pkg, final JCodeModel cm, final OWLClass clazz,
564: final OWLOntology ontology) {
565:• if (!classes.containsKey(clazz)) {
566: classes.put(clazz, create(pkg, cm, clazz, ontology));
567: }
568: return classes.get(clazz);
569: }
570:
571: private boolean isJavaClassNameAnnotation(OWLAnnotation a) {
572: final String classNameProperty = (String) configuration.getCliParams()
573: .valueOf(Option.JAVA_CLASSNAME_ANNOTATION.arg);
574:• return a.getProperty().getIRI()
575: .equals(IRI.create(classNameProperty != null ? classNameProperty : Constants.P_CLASS_NAME));
576: }
577:
578: /**
579: * Converts a class name to the Java camel case notation
580: *
581: * @param className Generated class name
582: * @return Converted class name
583: */
584: private static String toJavaNotation(String className) {
585: StringBuilder result = new StringBuilder();
586:• for (String w : className.split("_")) {
587:• if (!w.isEmpty()) {
588: result.append(w.substring(0, 1).toUpperCase()).append(w.substring(1));
589: }
590: }
591: return result.toString();
592: }
593: }