Skip to content

Method: checkConsistency(String)

1: /**
2: * Copyright (C) 2020 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.ontodriver.jena.connector;
14:
15: import cz.cvut.kbss.ontodriver.config.DriverConfigParam;
16: import cz.cvut.kbss.ontodriver.config.DriverConfiguration;
17: import cz.cvut.kbss.ontodriver.jena.exception.ReasonerInitializationException;
18: import org.apache.jena.query.Dataset;
19: import org.apache.jena.query.DatasetFactory;
20: import org.apache.jena.rdf.model.InfModel;
21: import org.apache.jena.rdf.model.Model;
22: import org.apache.jena.rdf.model.ModelFactory;
23: import org.apache.jena.rdf.model.Property;
24: import org.apache.jena.reasoner.IllegalParameterException;
25: import org.apache.jena.reasoner.Reasoner;
26: import org.apache.jena.reasoner.ReasonerFactory;
27: import org.apache.jena.reasoner.ValidityReport;
28: import org.apache.jena.system.Txn;
29: import org.apache.jena.vocabulary.ReasonerVocabulary;
30:
31: import java.lang.reflect.InvocationTargetException;
32: import java.lang.reflect.Method;
33: import java.util.*;
34: import java.util.stream.Collectors;
35:
36: import static org.apache.jena.rdf.model.ResourceFactory.createProperty;
37:
38: class SnapshotStorageWithInference extends SnapshotStorage {
39:
40: /**
41: * Configuration parameters supported by at least one of the Jena reasoners. Used to pre-filter reasoner config.
42: */
43: private static final Set<String> SUPPORTED_CONFIG = new HashSet<>(Arrays.asList(
44: ReasonerVocabulary.PROPderivationLogging.getURI(),
45: ReasonerVocabulary.PROPenableCMPScan.getURI(),
46: ReasonerVocabulary.PROPenableFunctorFiltering.getURI(),
47: ReasonerVocabulary.PROPenableOWLTranslation.getURI(),
48: ReasonerVocabulary.PROPenableTGCCaching.getURI(),
49: ReasonerVocabulary.PROPruleMode.getURI(),
50: ReasonerVocabulary.PROPruleSet.getURI(),
51: ReasonerVocabulary.PROPsetRDFSLevel.getURI(),
52: ReasonerVocabulary.PROPtraceOn.getURI()
53: ));
54:
55: private final ReasonerFactory reasonerFactory;
56: private final Map<String, String> reasonerConfig;
57:
58: private final Map<String, InfModel> inferredGraphs = new HashMap<>();
59:
60: SnapshotStorageWithInference(DriverConfiguration configuration, Map<String, String> reasonerConfig) {
61: super(configuration);
62: this.reasonerFactory = initReasonerFactory(configuration);
63: this.reasonerConfig = reasonerConfig.entrySet().stream()
64: .filter(e -> SUPPORTED_CONFIG.contains(e.getKey()))
65: .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
66: }
67:
68: private ReasonerFactory initReasonerFactory(DriverConfiguration configuration) {
69: final String factoryClass = configuration.getProperty(DriverConfigParam.REASONER_FACTORY_CLASS, "");
70: LOG.trace("Creating reasoner using reasoner factory class {}.", factoryClass);
71: try {
72: final Class<? extends ReasonerFactory> rfClass =
73: (Class<? extends ReasonerFactory>) Class.forName(factoryClass);
74: final Method instanceMethod = rfClass.getMethod("theInstance");
75: return (ReasonerFactory) instanceMethod.invoke(null);
76: } catch (ClassNotFoundException e) {
77: throw new ReasonerInitializationException("Reasoner factory class " + factoryClass + " not found.", e);
78: } catch (NoSuchMethodException e) {
79: throw new ReasonerInitializationException("Class " + factoryClass +
80: " is not a ReasonerFactory implementation or does not contain static 'theInstance' method.");
81: } catch (IllegalAccessException | InvocationTargetException e) {
82: throw new ReasonerInitializationException(
83: "Unable to instantiate Jena reasoner from factory " + factoryClass, e);
84: }
85: }
86:
87: @Override
88: void initialize() {
89: this.dataset = DatasetFactory.createGeneral();
90: }
91:
92: @Override
93: void addCentralData(Dataset central) {
94: Txn.executeRead(central, () -> {
95: final Iterator<String> it = central.listNames();
96: InfModel clonedModel;
97: while (it.hasNext()) {
98: final String name = it.next();
99: clonedModel = cloneModel(central.getNamedModel(name));
100: inferredGraphs.put(name, clonedModel);
101: dataset.addNamedModel(name, clonedModel);
102: }
103: clonedModel = cloneModel(central.getDefaultModel());
104: inferredGraphs.put(null, clonedModel);
105: dataset.setDefaultModel(clonedModel);
106: });
107: }
108:
109: private InfModel cloneModel(Model model) {
110: return ModelFactory.createInfModel(createReasoner(), ModelFactory.createDefaultModel().add(model));
111: }
112:
113: @Override
114: InfModel getDefaultGraph() {
115: return inferredGraphs.get(null);
116: }
117:
118: private Reasoner createReasoner() {
119: final Reasoner reasoner = reasonerFactory.create(null);
120: reasonerConfig.forEach((key, value) -> {
121: final Property prop = createProperty(key);
122: try {
123: reasoner.setParameter(prop, value);
124: } catch (IllegalParameterException ex) {
125: LOG.error("Failed to set property " + prop + " on reasoner.", ex);
126: }
127: });
128: return reasoner;
129: }
130:
131: Model getRawDefaultGraph() {
132: return inferredGraphs.containsKey(null) ? inferredGraphs.get(null).getRawModel() : dataset.getDefaultModel();
133: }
134:
135: @Override
136: InfModel getNamedGraph(String context) {
137: return inferredGraphs.computeIfAbsent(context, c -> {
138: // If the context does not exist, we need to create it, so that the default Dataset behavior is preserved
139: final InfModel model = ModelFactory.createInfModel(createReasoner(), ModelFactory.createDefaultModel());
140: dataset.addNamedModel(context, model);
141: return model;
142: });
143: }
144:
145: Model getRawNamedGraph(String context) {
146: return inferredGraphs.containsKey(context) ? inferredGraphs.get(context).getRawModel() :
147: dataset.getNamedModel(context);
148: }
149:
150: ValidityReport checkConsistency(String context) {
151:• return context != null ? getNamedGraph(context).validate() : getDefaultGraph().validate();
152: }
153: }