Skip to contentMethod: fieldSpecification(Class, String)
1: /*
2: * JOPA
3: * Copyright (C) 2024 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.test.runner;
19:
20: import cz.cvut.kbss.jopa.model.EntityManager;
21: import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
22: import cz.cvut.kbss.jopa.model.metamodel.FieldSpecification;
23: import cz.cvut.kbss.jopa.test.*;
24: import cz.cvut.kbss.jopa.test.environment.DataAccessor;
25: import cz.cvut.kbss.jopa.test.environment.PersistenceFactory;
26: import cz.cvut.kbss.jopa.test.environment.Quad;
27: import org.junit.jupiter.api.AfterEach;
28: import org.junit.jupiter.api.function.Executable;
29: import org.slf4j.Logger;
30:
31: import java.net.URI;
32: import java.util.*;
33:
34: import static org.junit.jupiter.api.Assertions.*;
35:
36:
37: public abstract class BaseRunner {
38:
39: protected static final URI CONTEXT_ONE = URI.create("http://krizik.felk.cvut.cz/jopa/contexts#One");
40: protected static final URI CONTEXT_TWO = URI.create("http://krizik.felk.cvut.cz/jopa/contexts#Two");
41:
42:
43: protected final Logger logger;
44:
45: protected EntityManager em;
46:
47: protected OWLClassA entityA;
48: protected OWLClassB entityB;
49: protected OWLClassC entityC;
50: protected OWLClassD entityD;
51: // Generated IRI
52: protected OWLClassE entityE;
53: // Two relationships, cascade
54: protected OWLClassG entityG;
55: protected OWLClassH entityH;
56: // Lazy reference to OWLClassA
57: protected OWLClassI entityI;
58: protected OWLClassM entityM;
59: protected OWLClassN entityN;
60: protected OWLClassP entityP;
61: // Mapped superclass
62: protected OWLClassQ entityQ;
63: // Query based attribute
64: protected OWLClassWithQueryAttr entityWithQueryAttr;
65: protected OWLClassWithQueryAttr2 entityWithQueryAttr2;
66: protected OWLClassWithQueryAttr3 entityWithQueryAttr3;
67: protected OWLClassWithQueryAttr4 entityWithQueryAttr4;
68: protected OWLClassWithQueryAttr5 entityWithQueryAttr5;
69: protected OWLClassWithQueryAttr6 entityWithQueryAttr6;
70:
71: protected final DataAccessor dataAccessor;
72: protected final PersistenceFactory persistenceFactory;
73:
74: public BaseRunner(Logger logger, PersistenceFactory persistenceFactory, DataAccessor dataAccessor) {
75: assert logger != null;
76: this.logger = logger;
77: this.persistenceFactory = persistenceFactory;
78: this.dataAccessor = dataAccessor;
79: init();
80: }
81:
82: /**
83: * Initializes the test entities in the following manner:
84: * <pre>
85: * <ul>
86: * <li>entityA contains non-empty types</li>
87: * <li>entityB's properties are null</li>
88: * <li>entityC's simple and referenced lists are null</li>
89: * <li>entityD's reference to OWLClassA is set to entityA</li>
90: * <li>entityE's URI is left null for ID generation</li>
91: * <li>entityG's reference to OWLClassH is set to entityH</li>
92: * <li>entityH's reference to OWLClassA is set to entityA</li>
93: * <li>entityI's reference to OWLClassA is set to entityA</li>
94: * <li>entityM has all fields set to some values</li>
95: * <li>entityN has required fields set</li>
96: * <li>entityP's properties and uri are null</li>
97: * <li>entityQ's reference to OWLClassA is set to entityA</li>
98: * </ul>
99: * </pre>
100: */
101: private void init() {
102: this.entityA = new OWLClassA(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityA"));
103: entityA.setStringAttribute("entityAStringAttribute");
104: final Set<String> types = new HashSet<>();
105: types.add("http://krizik.felk.cvut.cz/ontologies/jopa/entities#OWLClassU");
106: entityA.setTypes(types);
107: this.entityB = new OWLClassB();
108: entityB.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityB"));
109: entityB.setStringAttribute("entityBStringAttribute");
110: this.entityC = new OWLClassC();
111: entityC.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityC"));
112: this.entityD = new OWLClassD(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityD"));
113: entityD.setOwlClassA(entityA);
114: this.entityE = new OWLClassE();
115: entityE.setStringAttribute("entityEStringAttribute");
116: this.entityH = new OWLClassH();
117: entityH.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityH"));
118: entityH.setOwlClassA(entityA);
119: this.entityG = new OWLClassG();
120: entityG.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityG"));
121: entityG.setOwlClassH(entityH);
122: this.entityI = new OWLClassI();
123: entityI.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityI"));
124: entityI.setOwlClassA(entityA);
125: this.entityM = new OWLClassM();
126: entityM.initializeTestValues(true);
127: this.entityN = new OWLClassN();
128: entityN.setStringAttribute("entityNStringAttribute");
129: this.entityP = new OWLClassP();
130: this.entityQ = new OWLClassQ();
131: entityQ.setStringAttribute("entityQStringAttribute");
132: entityQ.setParentString("entityQParentStringAttribute");
133: entityQ.setLabel("entityQLabel");
134: entityQ.setOwlClassA(entityA);
135: this.entityWithQueryAttr = new OWLClassWithQueryAttr();
136: entityWithQueryAttr.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityWithQueryAttr"));
137: entityWithQueryAttr.setStringAttribute("EntityWithQueryAttrStringAttribute");
138: this.entityWithQueryAttr2 = new OWLClassWithQueryAttr2();
139: entityWithQueryAttr2.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityWithQueryAttr2"));
140: entityWithQueryAttr2.setEntityAttribute(entityA);
141: this.entityWithQueryAttr3 = new OWLClassWithQueryAttr3();
142: entityWithQueryAttr3.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityWithQueryAttr3"));
143: this.entityWithQueryAttr4 = new OWLClassWithQueryAttr4();
144: entityWithQueryAttr4.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityWithQueryAttr4"));
145: entityWithQueryAttr4.setStringAttribute("EntityWithQueryAttrStringAttribute4");
146: this.entityWithQueryAttr5 = new OWLClassWithQueryAttr5();
147: entityWithQueryAttr5.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityWithQueryAttr5"));
148: this.entityWithQueryAttr6 = new OWLClassWithQueryAttr6();
149: entityWithQueryAttr6.setUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityWithQueryAttr6"));
150: }
151:
152: @AfterEach
153: public void tearDown() {
154: if (em != null && em.isOpen()) {
155: if (em.getTransaction().isActive()) {
156: em.getTransaction().rollback();
157: }
158: em.close();
159: em.getEntityManagerFactory().close();
160: }
161: }
162:
163: /**
164: * Persists the specified instance(s) in a separate transaction.
165: *
166: * @param entity Entity to persist
167: */
168: protected void persist(Object... entity) {
169: transactional(() -> {
170: for (Object ent : entity) {
171: em.persist(ent);
172: }
173: });
174: }
175:
176: /**
177: * Runs the specified action in a transaction on the current entity manager.
178: *
179: * @param action The code to run
180: */
181: protected void transactional(Runnable action) {
182: em.getTransaction().begin();
183: action.run();
184: em.getTransaction().commit();
185: }
186:
187: /**
188: * Runs the specified action in a transaction on the current entity manager.
189: * <p>
190: * This allows using also actions which throw checked exceptions.
191: *
192: * @param action The code to run
193: * @see #transactional(Runnable)
194: */
195: protected void transactionalThrowing(Executable action) {
196: try {
197: em.getTransaction().begin();
198: action.execute();
199: em.getTransaction().commit();
200: } catch (Throwable e) {
201: throw new RuntimeException(e);
202: }
203: }
204:
205: /**
206: * Verifies that no statements with the specified individual as subject exist in the ontology any more.
207: *
208: * @param identifier Individual identifier
209: */
210: protected void verifyIndividualWasRemoved(URI identifier) {
211: // There is a bug in OWL2Query - the query returns true, because it finds the top object and data property assertion for an individual
212: // which doesn't exist anymore (but is a part of the query)
213: final boolean remains = em.createNativeQuery("ASK WHERE { ?instance ?y ?z . }", Boolean.class)
214: .setParameter("instance", identifier).getSingleResult();
215: assertFalse(remains);
216: }
217:
218: protected EntityManager getEntityManager(String repositoryName, boolean cacheEnabled) {
219: return getEntityManager(repositoryName, cacheEnabled, Collections.emptyMap());
220: }
221:
222: protected EntityManager getEntityManager(String repositoryName, boolean cacheEnabled,
223: Map<String, String> properties) {
224: return persistenceFactory.getEntityManager(repositoryName, cacheEnabled, properties);
225: }
226:
227: protected void persistTestData(Collection<Quad> data, EntityManager em) throws Exception {
228: dataAccessor.persistTestData(data, em);
229: }
230:
231: protected void verifyStatementsPresent(Collection<Quad> expected, EntityManager em) throws Exception {
232: dataAccessor.verifyDataPresent(expected, em);
233: }
234:
235: protected void verifyStatementsNotPresent(Collection<Quad> notExpected, EntityManager em) throws Exception {
236: dataAccessor.verifyDataNotPresent(notExpected, em);
237: }
238:
239: // Utility methods to reduce duplication
240:
241: /**
242: * Persists the specified instance of {@link OWLClassC} together will all items in the lists (if specified).
243: *
244: * @param instance Instance to persist
245: */
246: void persistCWithLists(OWLClassC instance) {
247: transactional(() -> {
248: em.persist(instance);
249: if (instance.getSimpleList() != null) {
250: instance.getSimpleList().forEach(em::persist);
251: }
252: if (instance.getReferencedList() != null) {
253: instance.getReferencedList().forEach(em::persist);
254: }
255: if (instance.getRdfCollection() != null) {
256: instance.getRdfCollection().forEach(em::persist);
257: }
258: });
259: }
260:
261: /**
262: * Finds instance and checks for it not being {@code null}.
263: *
264: * @return The found instance
265: */
266: protected <T> T findRequired(Class<T> type, Object identifier) {
267: final T result = em.find(type, identifier);
268: assertNotNull(result);
269: return result;
270: }
271:
272: /**
273: * Finds instance and checks for it not being {@code null}.
274: *
275: * @return The found instance
276: */
277: <T> T findRequired(Class<T> type, Object identifier, Descriptor descriptor) {
278: final T result = em.find(type, identifier, descriptor);
279: assertNotNull(result);
280: return result;
281: }
282:
283: <T> void verifyExists(Class<T> type, Object identifier) {
284: assertNotNull(em.find(type, identifier));
285: }
286:
287: protected void verifyValueDatatype(URI identifier, String property, String expectedDatatype) {
288: assertTrue(em.createNativeQuery("ASK WHERE { ?x ?property ?value . " +
289: "FILTER (DATATYPE(?value) = ?datatype) }", Boolean.class)
290: .setParameter("x", identifier)
291: .setParameter("property", URI.create(property))
292: .setParameter("datatype", URI.create(expectedDatatype)).getSingleResult());
293: }
294:
295: protected <T> FieldSpecification<? super T, ?> fieldSpecification(Class<T> cls, String attName) {
296: return em.getMetamodel().entity(cls).getFieldSpecification(attName);
297: }
298: }