Skip to content

Method: EntityConstructor(ObjectOntologyMapperImpl)

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.jopa.oom;
16:
17: import cz.cvut.kbss.jopa.CommonVocabulary;
18: import cz.cvut.kbss.jopa.model.JOPAPersistenceProperties;
19: import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
20: import cz.cvut.kbss.jopa.model.metamodel.Attribute;
21: import cz.cvut.kbss.jopa.model.metamodel.EntityType;
22: import cz.cvut.kbss.jopa.model.metamodel.FieldSpecification;
23: import cz.cvut.kbss.jopa.sessions.validator.IntegrityConstraintsValidator;
24: import cz.cvut.kbss.jopa.utils.EntityPropertiesUtils;
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: <T> T reconstructEntity(URI primaryKey, EntityType<T> et, Descriptor descriptor,
46: Collection<Axiom<?>> axioms) throws InstantiationException, IllegalAccessException {
47: assert !axioms.isEmpty();
48:
49: if (!axiomsContainEntityClassAssertion(axioms, et)) {
50: return null;
51: }
52: final T instance = createEntityInstance(primaryKey, et, descriptor);
53: populateAttributes(instance, et, descriptor, axioms);
54: validateIntegrityConstraints(instance, et);
55:
56: return instance;
57: }
58:
59: private boolean axiomsContainEntityClassAssertion(Collection<Axiom<?>> axioms, EntityType<?> et) {
60: for (Axiom<?> ax : axioms) {
61: if (MappingUtils.isEntityClassAssertion(ax, et)) {
62: return true;
63: }
64: }
65: return false;
66: }
67:
68: private <T> T createEntityInstance(URI primaryKey, EntityType<T> et, Descriptor descriptor)
69: throws InstantiationException, IllegalAccessException {
70: final T instance = et.getJavaType().newInstance();
71: EntityPropertiesUtils.setPrimaryKey(primaryKey, instance, et);
72: mapper.registerInstance(primaryKey, instance, descriptor.getContext());
73: return instance;
74: }
75:
76: private <T> void populateAttributes(final T instance, EntityType<T> et,
77: Descriptor entityDescriptor, Collection<Axiom<?>> axioms)
78: throws IllegalAccessException {
79: final Map<URI, FieldSpecification<? super T, ?>> attributes = indexEntityAttributes(et);
80: final Map<FieldSpecification<? super T, ?>, FieldStrategy<? extends FieldSpecification<? super T, ?>, T>>
81: fieldLoaders = new HashMap<>(
82: et.getAttributes().size());
83: for (Axiom<?> ax : axioms) {
84: if (MappingUtils.isEntityClassAssertion(ax, et)) {
85: continue;
86: }
87: final FieldStrategy<? extends FieldSpecification<? super T, ?>, T> fs = getFieldLoader(
88: ax, attributes, fieldLoaders, et, entityDescriptor);
89: if (fs == null) {
90: if (!MappingUtils.isClassAssertion(ax)) {
91: LOG.warn("No attribute found for property {}. Axiom {} will be skipped.", ax.getAssertion(), ax);
92: }
93: continue;
94: }
95: fs.addValueFromAxiom(ax);
96: }
97: // We need to build the field values separately because some may be
98: // plural and we have to wait until all values are prepared
99: for (FieldStrategy<? extends FieldSpecification<?, ?>, ?> fs : fieldLoaders.values()) {
100: fs.buildInstanceFieldValue(instance);
101: }
102: }
103:
104: private <T> Map<URI, FieldSpecification<? super T, ?>> indexEntityAttributes(EntityType<T> et) {
105: final Map<URI, FieldSpecification<? super T, ?>> atts = new HashMap<>(et.getAttributes()
106: .size());
107: for (Attribute<? super T, ?> at : et.getAttributes()) {
108: atts.put(at.getIRI().toURI(), at);
109: }
110: if (et.getTypes() != null) {
111: atts.put(URI.create(CommonVocabulary.RDF_TYPE), et.getTypes());
112: }
113: return atts;
114: }
115:
116: private <T> FieldStrategy<? extends FieldSpecification<? super T, ?>, T> getFieldLoader(
117: Axiom<?> ax,
118: Map<URI, FieldSpecification<? super T, ?>> attributes,
119: Map<FieldSpecification<? super T, ?>, FieldStrategy<? extends FieldSpecification<? super T, ?>, T>> loaders,
120: EntityType<T> et, Descriptor desc) {
121: final URI attId = ax.getAssertion().getIdentifier();
122: FieldSpecification<? super T, ?> att = attributes.get(attId);
123: if (att == null) {
124: if (et.getProperties() != null) {
125: att = et.getProperties();
126: } else {
127: return null;
128: }
129: }
130: if (!loaders.containsKey(att)) {
131: loaders.put(att, FieldStrategy.createFieldStrategy(et, att,
132: desc.getAttributeDescriptor(att), mapper));
133: }
134: return loaders.get(att);
135: }
136:
137: private <T> void validateIntegrityConstraints(T entity, EntityType<T> et) {
138: if (shouldSkipICValidationOnLoad()) {
139: return;
140: }
141: IntegrityConstraintsValidator.getValidator().validate(entity, et, true);
142: }
143:
144: private boolean shouldSkipICValidationOnLoad() {
145: return mapper.getConfiguration().is(JOPAPersistenceProperties.DISABLE_IC_VALIDATION_ON_LOAD);
146: }
147:
148: private <T> void validateIntegrityConstraints(T entity, FieldSpecification<? super T, ?> fieldSpec,
149: EntityType<T> et) {
150: if (shouldSkipICValidationOnLoad()) {
151: return;
152: }
153: final Object id = EntityPropertiesUtils.getPrimaryKey(entity, et);
154: final Object value = EntityPropertiesUtils.getAttributeValue(fieldSpec, entity);
155: IntegrityConstraintsValidator.getValidator().validate(id, fieldSpec, value);
156: }
157:
158: <T> void setFieldValue(T entity, Field field, Collection<Axiom<?>> axioms, EntityType<T> et,
159: Descriptor entityDescriptor) throws IllegalArgumentException, IllegalAccessException {
160: final FieldSpecification<? super T, ?> fieldSpec = MappingUtils.getFieldSpecification(field, et);
161: final FieldStrategy<? extends FieldSpecification<? super T, ?>, T> fs = FieldStrategy
162: .createFieldStrategy(et, fieldSpec,
163: entityDescriptor.getAttributeDescriptor(fieldSpec), mapper);
164: axioms.forEach(fs::addValueFromAxiom);
165: fs.buildInstanceFieldValue(entity);
166: validateIntegrityConstraints(entity, fieldSpec, et);
167: }
168: }