Skip to contentMethod: getContexts(OWLAxiom)
1: /**
2: * Copyright (C) 2020 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 cz.cvut.kbss.jopa.owl2java.config.TransformationConfiguration;
18: import cz.cvut.kbss.jopa.owl2java.exception.OWL2JavaException;
19: import cz.cvut.kbss.jopa.util.MappingFileParser;
20: import org.semanticweb.owlapi.apibinding.OWLManager;
21: import org.semanticweb.owlapi.model.*;
22: import org.semanticweb.owlapi.search.EntitySearcher;
23: import org.semanticweb.owlapi.util.OWLOntologyMerger;
24: import org.slf4j.Logger;
25: import org.slf4j.LoggerFactory;
26:
27: import javax.annotation.Nonnull;
28: import java.io.File;
29: import java.net.URI;
30: import java.util.*;
31: import java.util.function.Consumer;
32: import java.util.stream.Stream;
33:
34: public class OWL2JavaTransformer {
35:
36: private static final Logger LOG = LoggerFactory.getLogger(OWL2JavaTransformer.class);
37:
38: private OWLOntology ontology;
39:
40: private final ValidContextAnnotationValueVisitor v = new ValidContextAnnotationValueVisitor();
41:
42: private final ContextDefinition defaultContext = new ContextDefinition();
43: private Map<String, ContextDefinition> contexts = new HashMap<>();
44:
45: private boolean ignoreMissingImports;
46:
47: public Collection<String> listContexts() {
48: return contexts.keySet();
49: }
50:
51: public void ignoreMissingImports(boolean ignore) {
52: this.ignoreMissingImports = ignore;
53: }
54:
55: private OWLOntology getWholeOntology(final String owlOntologyName, final String mappingFile) {
56: // reader
57: final OWLOntologyManager m = OWLManager.createOWLOntologyManager();
58:
59: if (mappingFile != null) {
60: LOG.info("Using mapping file '{}'.", mappingFile);
61:
62: final Map<URI, URI> map = MappingFileParser.getMappings(new File(mappingFile));
63: m.getIRIMappers().add(ontologyIRI -> {
64: final URI value = map.get(ontologyIRI.toURI());
65:
66: if (value == null) {
67: return null;
68: } else {
69: return IRI.create(value);
70: }
71: });
72: LOG.info("Mapping file successfully parsed.");
73: }
74:
75: LOG.info("Loading ontology {}... ", owlOntologyName);
76: if (ignoreMissingImports) {
77: m.getOntologyConfigurator().setMissingImportHandlingStrategy(MissingImportHandlingStrategy.SILENT);
78: m.addMissingImportListener(e -> LOG.warn("Unable to import ontology {}.", e.getImportedOntologyURI()));
79: }
80:
81: try {
82: m.loadOntology(IRI.create(owlOntologyName));
83: return new OWLOntologyMerger(m).createMergedOntology(m, IRI.create(owlOntologyName + "-generated"));
84: } catch (OWLException | OWLRuntimeException e) {
85: LOG.error(e.getMessage(), e);
86: throw new OWL2JavaException("Unable to load ontology " + owlOntologyName, e);
87: }
88: }
89:
90: public void setOntology(final String owlOntologyName, final String mappingFile) {
91: this.ontology = getWholeOntology(owlOntologyName, mappingFile);
92:
93: LOG.debug("Parsing integrity constraints");
94:
95: ontology.axioms().forEach(a -> {
96: defaultContext.addAxiom(a);
97: for (final String icContextName : getContexts(a)) {
98: ContextDefinition ctx = getContextDefinition(icContextName);
99: ctx.addAxiom(a);
100: }
101: });
102: registerEntitiesInContexts();
103:
104: defaultContext.parse();
105: for (final ContextDefinition ctx : contexts.values()) {
106: ctx.parse();
107: }
108:
109: LOG.debug("Integrity constraints successfully parsed.");
110: }
111:
112: private void registerEntitiesInContexts() {
113: final Consumer<Stream<? extends OWLEntity>> consumer = stream -> stream.forEach(e -> {
114: defaultContext.add(e);
115: for (final String context : getContexts(e)) {
116: getContextDefinition(context).add(e);
117: }
118: });
119: consumer.accept(ontology.classesInSignature());
120: consumer.accept(ontology.objectPropertiesInSignature());
121: consumer.accept(ontology.dataPropertiesInSignature());
122: consumer.accept(ontology.annotationPropertiesInSignature());
123: }
124:
125: private ContextDefinition getContextDefinition(String icContextName) {
126: return contexts.computeIfAbsent(icContextName, name -> new ContextDefinition());
127: }
128:
129: private List<String> getContexts(final OWLAxiom a) {
130: final List<String> icContexts = new ArrayList<>();
131: a.annotations().filter(p -> p.getProperty().getIRI().toString().equals(Constants.P_IS_INTEGRITY_CONSTRAINT_FOR))
132: .forEach(p -> {
133: LOG.trace("Processing annotation : " + p);
134: p.getValue().accept(v);
135: final String icContextName = v.getName();
136: LOG.trace("CONTEXT:" + icContextName);
137: if (icContextName == null) {
138: return;
139: }
140: LOG.debug("Found IC {} for context {}", a, icContextName);
141: icContexts.add(icContextName);
142: });
143: return icContexts;
144: }
145:
146: private List<String> getContexts(final OWLEntity entity) {
147: final List<String> icContexts = new ArrayList<>();
148: EntitySearcher.getAnnotations(entity, ontology)
149: .filter(p -> p.getProperty().getIRI().toString().equals(Constants.P_IS_INTEGRITY_CONSTRAINT_FOR))
150: .forEach(p -> {
151: LOG.trace("Processing annotation : " + p);
152: p.getValue().accept(v);
153: final String icContextName = v.getName();
154: LOG.trace("CONTEXT:" + icContextName);
155: if (icContextName == null) {
156: return;
157: }
158: LOG.debug("Found OWLEntity declaration {} for context {}", entity, icContextName);
159: icContexts.add(icContextName);
160: });
161: return icContexts;
162: }
163:
164: private void verifyContextExistence(String context) {
165: if (!contexts.containsKey(context)) {
166: throw new IllegalArgumentException(
167: "Context " + context + " not found. Existing contexts: " + listContexts());
168: }
169: }
170:
171: public void transform(TransformationConfiguration transformConfig) {
172: final ContextDefinition def = getValidContext(transformConfig);
173: LOG.info("Transforming context ...");
174: final ObjectModel result = new JavaTransformer(transformConfig).generateModel(ontology, def);
175: result.writeModel(transformConfig.getTargetDir());
176: LOG.info("Transformation SUCCESSFUL.");
177: }
178:
179: private ContextDefinition getValidContext(TransformationConfiguration configuration) {
180: if (configuration.areAllAxiomsIntegrityConstraints()) {
181: LOG.info(" - for all axioms");
182: return defaultContext;
183: }
184: final String context = configuration.getContext();
185: verifyContextExistence(context);
186: LOG.info(" - for context '{}'.", context);
187: return contexts.get(context);
188: }
189:
190: /**
191: * Generates only vocabulary of the loaded ontology.
192: *
193: * @param transformConfig Configuration of the generation process
194: */
195: public void generateVocabulary(TransformationConfiguration transformConfig) {
196: LOG.info("Generating vocabulary ...");
197:
198: ContextDefinition def = getValidContext(transformConfig);
199: final ObjectModel result = new JavaTransformer(transformConfig).generateVocabulary(ontology, def);
200: result.writeModel(transformConfig.getTargetDir());
201: }
202:
203: private class ValidContextAnnotationValueVisitor implements OWLAnnotationValueVisitor {
204:
205: private String name;
206:
207: String getName() {
208: return name;
209: }
210:
211: @Override
212: public void visit(@Nonnull IRI iri) {
213: }
214:
215: @Override
216: public void visit(@Nonnull OWLAnonymousIndividual individual) {
217: }
218:
219: @Override
220: public void visit(@Nonnull OWLLiteral literal) {
221: this.name = literal.getLiteral();
222: }
223: }
224: }