Skip to content

Method: lambda$generateJavadoc$4(OWLAnnotation)

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