Skip to contentMethod: rollback()
1: /**
2: * Copyright (C) 2016 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.ontodriver.sesame;
16:
17: import cz.cvut.kbss.ontodriver.Closeable;
18: import cz.cvut.kbss.ontodriver.Wrapper;
19: import cz.cvut.kbss.ontodriver.config.ConfigParam;
20: import cz.cvut.kbss.ontodriver.config.Configuration;
21: import cz.cvut.kbss.ontodriver.descriptor.*;
22: import cz.cvut.kbss.ontodriver.exception.IdentifierGenerationException;
23: import cz.cvut.kbss.ontodriver.exception.OWLIndividualExistsException;
24: import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
25: import cz.cvut.kbss.ontodriver.model.Axiom;
26: import cz.cvut.kbss.ontodriver.model.NamedResource;
27: import cz.cvut.kbss.ontodriver.sesame.connector.Connector;
28: import cz.cvut.kbss.ontodriver.sesame.connector.StatementExecutor;
29: import cz.cvut.kbss.ontodriver.sesame.exceptions.SesameDriverException;
30: import org.openrdf.model.Resource;
31: import org.openrdf.model.Statement;
32: import org.openrdf.model.Value;
33: import org.openrdf.model.ValueFactory;
34: import org.openrdf.model.vocabulary.RDF;
35:
36: import java.net.URI;
37: import java.util.ArrayList;
38: import java.util.Collection;
39: import java.util.List;
40: import java.util.Random;
41:
42: class SesameAdapter implements Closeable, Wrapper {
43:
44: /**
45: * Maximum number of attempts to generate a unique identifier
46: */
47: private static final int ID_GENERATION_THRESHOLD = 64;
48: private static final Random RANDOM = new Random();
49:
50: private final Connector connector;
51: private final ValueFactory valueFactory;
52: private final String language;
53: private boolean open;
54: private final Transaction transaction;
55:
56: public SesameAdapter(Connector connector, Configuration configuration) {
57: assert connector != null;
58:
59: this.connector = connector;
60: this.valueFactory = connector.getValueFactory();
61: this.language = configuration.getProperty(ConfigParam.ONTOLOGY_LANGUAGE);
62: this.open = true;
63: this.transaction = new Transaction();
64: }
65:
66: Connector getConnector() {
67: return connector;
68: }
69:
70: ValueFactory getValueFactory() {
71: return valueFactory;
72: }
73:
74: String getLanguage() {
75: return language;
76: }
77:
78: @Override
79: public void close() throws OntoDriverException {
80: if (!open) {
81: return;
82: }
83: try {
84: connector.close();
85: } finally {
86: this.open = false;
87: }
88: }
89:
90: @Override
91: public boolean isOpen() {
92: return open;
93: }
94:
95: void commit() throws SesameDriverException {
96: if (transaction.isActive()) {
97: transaction.commit();
98: connector.commit();
99: transaction.afterCommit();
100: }
101: }
102:
103: void rollback() throws SesameDriverException {
104:• if (transaction.isActive()) {
105: transaction.rollback();
106: connector.rollback();
107: transaction.afterRollback();
108: }
109: }
110:
111: boolean isConsistent(URI context) {
112: // Sesame currently doesn't support any consistency checking
113: // functionality
114: return true;
115: }
116:
117: List<URI> getContexts() throws SesameDriverException {
118: final List<Resource> contextIds = connector.getContexts();
119: final List<URI> contexts = new ArrayList<>(contextIds.size());
120: for (Resource res : contextIds) {
121: final URI context = SesameUtils.toJavaUri(res);
122: // We support only named contexts (no blank nodes)
123: if (context != null) {
124: contexts.add(context);
125: }
126: }
127: return contexts;
128: }
129:
130: URI generateIdentifier(URI classUri) throws SesameDriverException {
131: startTransactionIfNotActive();
132: boolean unique = false;
133: URI id = null;
134: int counter = 0;
135: while (!unique && counter++ < ID_GENERATION_THRESHOLD) {
136: if (classUri.getFragment() != null) {
137: id = URI.create(classUri.toString() + "_instance" + RANDOM.nextInt());
138: } else {
139: String base = classUri.toString();
140: if (base.endsWith("/")) {
141: id = URI.create(base + "_instance" + RANDOM.nextInt());
142: } else {
143: id = URI.create(base + "#instance" + RANDOM.nextInt());
144: }
145: }
146: unique = isIdentifierUnique(id, classUri);
147: }
148: if (!unique) {
149: throw new IdentifierGenerationException("Unable to generate a unique identifier.");
150: }
151: return id;
152:
153: }
154:
155: private void startTransactionIfNotActive() throws SesameDriverException {
156: if (!transaction.isActive()) {
157: connector.begin();
158: transaction.begin();
159: }
160: }
161:
162: private boolean isIdentifierUnique(URI identifier, URI classUri) throws SesameDriverException {
163: final Collection<Statement> stmts = connector.findStatements(
164: SesameUtils.toSesameUri(identifier, valueFactory), RDF.TYPE,
165: SesameUtils.toSesameUri(classUri, valueFactory), true);
166: return stmts.isEmpty();
167: }
168:
169: boolean contains(Axiom<?> axiom, URI context) throws SesameDriverException {
170: startTransactionIfNotActive();
171: Value value;
172: if (SesameUtils.isResourceIdentifier(axiom.getValue().getValue())) {
173: value = valueFactory.createURI(axiom.getValue().stringValue());
174: } else {
175: value = SesameUtils.createDataPropertyLiteral(axiom.getValue().getValue(), language,
176: valueFactory);
177: }
178: return !(connector.findStatements(
179: SesameUtils.toSesameUri(axiom.getSubject().getIdentifier(), valueFactory),
180: SesameUtils.toSesameUri(axiom.getAssertion().getIdentifier(), valueFactory), value,
181: true, SesameUtils.toSesameUri(context, valueFactory)).isEmpty());
182: }
183:
184: Collection<Axiom<?>> find(AxiomDescriptor axiomDescriptor) throws SesameDriverException {
185: startTransactionIfNotActive();
186: return new AxiomLoader(connector, valueFactory).loadAxioms(axiomDescriptor);
187: }
188:
189: void persist(AxiomValueDescriptor axiomDescriptor) throws SesameDriverException {
190: startTransactionIfNotActive();
191: if (individualExists(axiomDescriptor.getSubject(), axiomDescriptor.getSubjectContext())) {
192: throw new SesameDriverException(new OWLIndividualExistsException("An individual with identifier "
193: + axiomDescriptor.getSubject() + " already exists in context "
194: + axiomDescriptor.getSubjectContext()));
195: }
196: new AxiomSaver(connector, valueFactory, language).persistAxioms(axiomDescriptor);
197: }
198:
199: private boolean individualExists(NamedResource subject, URI subjectContext)
200: throws SesameDriverException {
201: final org.openrdf.model.URI sesameSubject = SesameUtils.toSesameUri(
202: subject.getIdentifier(), valueFactory);
203: final Collection<Statement> result = connector.findStatements(sesameSubject, RDF.TYPE,
204: null, true, SesameUtils.toSesameUri(subjectContext, valueFactory));
205: return !result.isEmpty();
206: }
207:
208: void update(AxiomValueDescriptor axiomDescriptor) throws SesameDriverException {
209: startTransactionIfNotActive();
210: new EpistemicAxiomRemover(connector, valueFactory, language).remove(axiomDescriptor);
211: new AxiomSaver(connector, valueFactory, language).persistAxioms(axiomDescriptor);
212: }
213:
214: void remove(AxiomDescriptor axiomDescriptor) throws SesameDriverException {
215: startTransactionIfNotActive();
216: new EpistemicAxiomRemover(connector, valueFactory, language).remove(axiomDescriptor);
217: }
218:
219: StatementExecutor getQueryExecutor() {
220: return connector;
221: }
222:
223: ListHandler<SimpleListDescriptor, SimpleListValueDescriptor> getSimpleListHandler() {
224: return ListHandler.createForSimpleList(connector, valueFactory);
225: }
226:
227: ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor> getReferencedListHandler() {
228: return ListHandler.createForReferencedList(connector, valueFactory);
229: }
230:
231: TypesHandler getTypesHandler() {
232: return new TypesHandler(connector, valueFactory);
233: }
234:
235: @Override
236: public <T> T unwrap(Class<T> cls) throws OntoDriverException {
237: if (cls.isAssignableFrom(this.getClass())) {
238: return cls.cast(this);
239: } else if (cls.isAssignableFrom(valueFactory.getClass())) {
240: return cls.cast(valueFactory);
241: }
242: return connector.unwrap(cls);
243: }
244: }