Skip to content

Package: EntityConstructor

EntityConstructor

nameinstructionbranchcomplexitylinemethod
EntityConstructor(ObjectOntologyMapperImpl)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
axiomsContainEntityClassAssertion(Collection, EntityType)
M: 0 C: 19
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
createEntityInstance(URI, EntityType)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getFieldLoader(Axiom, Map, Map, EntityType, Descriptor)
M: 0 C: 39
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
indexEntityAttributes(EntityType)
M: 0 C: 38
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
populateAttributes(Object, EntityType, Descriptor, Collection)
M: 0 C: 65
100%
M: 1 C: 9
90%
M: 1 C: 5
83%
M: 0 C: 16
100%
M: 0 C: 1
100%
reconstructEntity(URI, EntityType, Descriptor, Collection)
M: 4 C: 34
89%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 8
100%
M: 0 C: 1
100%
setFieldValue(Object, Field, Collection, EntityType, Descriptor)
M: 0 C: 36
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
shouldSkipICValidationOnLoad()
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
static {...}
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
validateIntegrityConstraints(Object, EntityType)
M: 0 C: 10
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
validateIntegrityConstraints(Object, FieldSpecification, EntityType)
M: 0 C: 18
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 6
100%
M: 0 C: 1
100%

Coverage

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.oom;
16:
17: import cz.cvut.kbss.jopa.model.JOPAPersistenceProperties;
18: import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
19: import cz.cvut.kbss.jopa.model.metamodel.Attribute;
20: import cz.cvut.kbss.jopa.model.metamodel.EntityType;
21: import cz.cvut.kbss.jopa.model.metamodel.FieldSpecification;
22: import cz.cvut.kbss.jopa.sessions.validator.IntegrityConstraintsValidator;
23: import cz.cvut.kbss.jopa.utils.EntityPropertiesUtils;
24: import cz.cvut.kbss.jopa.vocabulary.RDF;
25: import cz.cvut.kbss.ontodriver.model.Axiom;
26: import org.slf4j.Logger;
27: import org.slf4j.LoggerFactory;
28:
29: import java.lang.reflect.Field;
30: import java.net.URI;
31: import java.util.Collection;
32: import java.util.HashMap;
33: import java.util.Map;
34:
35: class EntityConstructor {
36:
37: private static final Logger LOG = LoggerFactory.getLogger(EntityConstructor.class);
38:
39: private final ObjectOntologyMapperImpl mapper;
40:
41: EntityConstructor(ObjectOntologyMapperImpl mapper) {
42: this.mapper = mapper;
43: }
44:
45: /**
46: * Creates an instance of the specified {@link EntityType} with the specified identifier and populates its attributes from the specified axioms.
47: *
48: * @param identifier Entity identifier
49: * @param et Entity type
50: * @param descriptor Entity descriptor with context info
51: * @param axioms Axioms from which the instance attribute values should be reconstructed
52: * @param <T> Entity type
53: * @return New instance with populated attributes
54: * @throws InstantiationException If instance cannot be created
55: * @throws IllegalAccessException If the default constructor is not public
56: */
57: <T> T reconstructEntity(URI identifier, EntityType<T> et, Descriptor descriptor,
58: Collection<Axiom<?>> axioms) throws InstantiationException, IllegalAccessException {
59:• assert !axioms.isEmpty();
60:
61:• if (!axiomsContainEntityClassAssertion(axioms, et)) {
62: return null;
63: }
64: final T instance = createEntityInstance(identifier, et);
65: mapper.registerInstance(identifier, instance, descriptor.getContext());
66: populateAttributes(instance, et, descriptor, axioms);
67: validateIntegrityConstraints(instance, et);
68:
69: return instance;
70: }
71:
72: private static boolean axiomsContainEntityClassAssertion(Collection<Axiom<?>> axioms, EntityType<?> et) {
73:• for (Axiom<?> ax : axioms) {
74:• if (MappingUtils.isEntityClassAssertion(ax, et)) {
75: return true;
76: }
77: }
78: return false;
79: }
80:
81: /**
82: * Instantiates an entity of the specified {@link EntityType} with the specified identifier.
83: *
84: * @param identifier Entity identifier
85: * @param et Entity type
86: * @param <T> Entity type
87: * @return Newly created instance with identifier set
88: * @throws InstantiationException If instance cannot be created
89: * @throws IllegalAccessException If the default constructor is not public
90: */
91: <T> T createEntityInstance(URI identifier, EntityType<T> et)
92: throws InstantiationException, IllegalAccessException {
93: final T instance = et.getJavaType().newInstance();
94: EntityPropertiesUtils.setIdentifier(identifier, instance, et);
95: return instance;
96: }
97:
98: private <T> void populateAttributes(final T instance, EntityType<T> et,
99: Descriptor entityDescriptor, Collection<Axiom<?>> axioms)
100: throws IllegalAccessException {
101: final Map<URI, FieldSpecification<? super T, ?>> attributes = indexEntityAttributes(et);
102: final Map<FieldSpecification<? super T, ?>, FieldStrategy<? extends FieldSpecification<? super T, ?>, T>>
103: fieldLoaders = new HashMap<>(
104: et.getAttributes().size());
105:• for (Axiom<?> ax : axioms) {
106:• if (MappingUtils.isEntityClassAssertion(ax, et)) {
107: continue;
108: }
109: final FieldStrategy<? extends FieldSpecification<? super T, ?>, T> fs = getFieldLoader(
110: ax, attributes, fieldLoaders, et, entityDescriptor);
111:• if (fs == null) {
112:• if (!MappingUtils.isClassAssertion(ax)) {
113: LOG.warn("No attribute found for property {}. Axiom {} will be skipped.", ax.getAssertion(), ax);
114: }
115: continue;
116: }
117: fs.addValueFromAxiom(ax);
118: }
119: // We need to build the field values separately because some may be
120: // plural and we have to wait until all values are prepared
121:• for (FieldStrategy<? extends FieldSpecification<?, ?>, ?> fs : fieldLoaders.values()) {
122: fs.buildInstanceFieldValue(instance);
123: }
124: }
125:
126: private static <T> Map<URI, FieldSpecification<? super T, ?>> indexEntityAttributes(EntityType<T> et) {
127: final Map<URI, FieldSpecification<? super T, ?>> atts = new HashMap<>(et.getAttributes().size());
128:• for (Attribute<? super T, ?> at : et.getAttributes()) {
129: atts.put(at.getIRI().toURI(), at);
130: }
131:• if (et.getTypes() != null) {
132: atts.put(URI.create(RDF.TYPE), et.getTypes());
133: }
134: return atts;
135: }
136:
137: private <T> FieldStrategy<? extends FieldSpecification<? super T, ?>, T> getFieldLoader(
138: Axiom<?> ax,
139: Map<URI, FieldSpecification<? super T, ?>> attributes,
140: Map<FieldSpecification<? super T, ?>, FieldStrategy<? extends FieldSpecification<? super T, ?>, T>> loaders,
141: EntityType<T> et, Descriptor desc) {
142: final URI attId = ax.getAssertion().getIdentifier();
143: FieldSpecification<? super T, ?> att = attributes.get(attId);
144:• if (att == null) {
145:• if (et.getProperties() != null) {
146: att = et.getProperties();
147: } else {
148: return null;
149: }
150: }
151:• if (!loaders.containsKey(att)) {
152: loaders.put(att, FieldStrategy.createFieldStrategy(et, att, desc, mapper));
153: }
154: return loaders.get(att);
155: }
156:
157: private <T> void validateIntegrityConstraints(T entity, EntityType<T> et) {
158:• if (shouldSkipICValidationOnLoad()) {
159: return;
160: }
161: IntegrityConstraintsValidator.getValidator().validate(entity, et, true);
162: }
163:
164: private boolean shouldSkipICValidationOnLoad() {
165: return mapper.getConfiguration().is(JOPAPersistenceProperties.DISABLE_IC_VALIDATION_ON_LOAD);
166: }
167:
168: <T> void validateIntegrityConstraints(T entity, FieldSpecification<? super T, ?> fieldSpec,
169: EntityType<T> et) {
170:• if (shouldSkipICValidationOnLoad()) {
171: return;
172: }
173: final Object id = EntityPropertiesUtils.getIdentifier(entity, et);
174: final Object value = EntityPropertiesUtils.getAttributeValue(fieldSpec, entity);
175: IntegrityConstraintsValidator.getValidator().validate(id, fieldSpec, value);
176: }
177:
178: <T> void setFieldValue(T entity, Field field, Collection<Axiom<?>> axioms, EntityType<T> et,
179: Descriptor entityDescriptor) throws IllegalAccessException {
180: final FieldSpecification<? super T, ?> fieldSpec = MappingUtils.getFieldSpecification(field, et);
181:• if (axioms.isEmpty()) {
182: validateIntegrityConstraints(entity, fieldSpec, et);
183: return;
184: }
185: final FieldStrategy<? extends FieldSpecification<? super T, ?>, T> fs = FieldStrategy
186: .createFieldStrategy(et, fieldSpec, entityDescriptor, mapper);
187: axioms.forEach(fs::addValueFromAxiom);
188: fs.buildInstanceFieldValue(entity);
189: validateIntegrityConstraints(entity, fieldSpec, et);
190: }
191: }