-
Notifications
You must be signed in to change notification settings - Fork 14
/
TypesFieldStrategy.java
115 lines (101 loc) · 4.55 KB
/
TypesFieldStrategy.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* Copyright (C) 2016 Czech Technical University in Prague
* <p>
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any
* later version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cz.cvut.kbss.jopa.oom;
import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
import cz.cvut.kbss.jopa.model.metamodel.EntityType;
import cz.cvut.kbss.jopa.model.metamodel.TypesSpecification;
import cz.cvut.kbss.jopa.utils.IdentifierTransformer;
import cz.cvut.kbss.ontodriver.model.Assertion;
import cz.cvut.kbss.ontodriver.model.Axiom;
import java.net.URI;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
public class TypesFieldStrategy<X> extends FieldStrategy<TypesSpecification<? super X, ?>, X> {
private final Set<Object> values = new HashSet<>();
public TypesFieldStrategy(EntityType<X> et, TypesSpecification<? super X, ?> att,
Descriptor descriptor, EntityMappingHelper mapper) {
super(et, att, descriptor, mapper);
}
@Override
void addValueFromAxiom(Axiom<?> ax) {
if (MappingUtils.isEntityClassAssertion(ax, et)) {
return;
}
final Object type =
IdentifierTransformer.transformToIdentifier(ax.getValue().getValue(), attribute.getElementType());
values.add(type);
}
@Override
void buildInstanceFieldValue(Object instance) throws IllegalAccessException {
assert attribute.getJavaField().getType().isAssignableFrom(Set.class);
if (values.isEmpty()) {
return;
}
setValueOnInstance(instance, values);
}
@Override
void buildAxiomValuesFromInstance(X instance, AxiomValueGatherer valueBuilder) throws IllegalAccessException {
final Object val = extractFieldValueFromInstance(instance);
final X original = mapper.getOriginalInstance(instance);
if (val == null) {
if (original == null) {
return;
}
final Set<?> origTypes = (Set<?>) extractFieldValueFromInstance(original);
if (origTypes == null || origTypes.isEmpty()) {
return;
}
valueBuilder.removeTypes(prepareTypes(origTypes), getAttributeContext());
} else {
assert val instanceof Set; // This is verified when the metamodel is built
final Set<?> types = (Set<?>) val;
if (original == null) {
valueBuilder.addTypes(prepareTypes(types), getAttributeContext());
} else {
Set<?> origTypes = (Set<?>) extractFieldValueFromInstance(original);
if (origTypes == null) {
origTypes = Collections.emptySet();
}
extractTypesToAdd(valueBuilder, types, origTypes);
extractTypesToRemove(valueBuilder, types, origTypes);
}
}
}
private void extractTypesToAdd(AxiomValueGatherer valueBuilder, Set<?> types, Set<?> origTypes) {
final Set<URI> toAdd = typesDiff(origTypes, types);
valueBuilder.addTypes(toAdd, getAttributeContext());
}
private Set<URI> typesDiff(Set<?> base, Set<?> difference) {
final Set<URI> addedDiff = new HashSet<>(base.size());
addedDiff.addAll(difference.stream().filter(t -> !base.contains(t)).map(t -> URI.create(t.toString()))
.collect(Collectors.toList()));
return addedDiff;
}
private void extractTypesToRemove(AxiomValueGatherer valueBuilder, Set<?> types, Set<?> origTypes) {
final Set<URI> toRemove = typesDiff(types, origTypes);
valueBuilder.removeTypes(toRemove, getAttributeContext());
}
private Set<URI> prepareTypes(Set<?> types) {
final Set<URI> toAdd = new HashSet<>(types.size());
toAdd.addAll(types.stream().map(t -> URI.create(t.toString())).collect(Collectors.toList()));
return toAdd;
}
@Override
Assertion createAssertion() {
return Assertion.createClassAssertion(attribute.isInferred());
}
}