Skip to content

Method: toAxiomValue(Object)

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.oom;
19:
20: import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
21: import cz.cvut.kbss.jopa.model.metamodel.EntityType;
22: import cz.cvut.kbss.jopa.model.metamodel.TypesSpecification;
23: import cz.cvut.kbss.jopa.utils.EntityPropertiesUtils;
24: import cz.cvut.kbss.jopa.utils.IdentifierTransformer;
25: import cz.cvut.kbss.ontodriver.model.*;
26:
27: import java.net.URI;
28: import java.util.Collection;
29: import java.util.Collections;
30: import java.util.HashSet;
31: import java.util.Set;
32: import java.util.stream.Collectors;
33:
34: class TypesFieldStrategy<X> extends FieldStrategy<TypesSpecification<? super X, ?>, X> {
35:
36: private final Set<Object> values = new HashSet<>();
37:
38: TypesFieldStrategy(EntityType<X> et, TypesSpecification<? super X, ?> att, Descriptor descriptor,
39: EntityMappingHelper mapper) {
40: super(et, att, descriptor, mapper);
41: }
42:
43: @Override
44: void addAxiomValue(Axiom<?> ax) {
45: if (MappingUtils.isEntityClassAssertion(ax, et)) {
46: return;
47: }
48: final Object type =
49: IdentifierTransformer.transformToIdentifier(ax.getValue().getValue(), attribute.getElementType());
50: values.add(type);
51: }
52:
53: @Override
54: boolean hasValue() {
55: return !values.isEmpty();
56: }
57:
58: @Override
59: void buildInstanceFieldValue(Object instance) {
60: assert attribute.getJavaField().getType().isAssignableFrom(Set.class);
61: setValueOnInstance(instance, values);
62: }
63:
64: @Override
65: void buildAxiomValuesFromInstance(X instance, AxiomValueGatherer valueBuilder) {
66: final Object val = extractFieldValueFromInstance(instance);
67: final X original = mapper.getOriginalInstance(instance);
68: if (val == null) {
69: if (original == null) {
70: return;
71: }
72: final Set<?> origTypes = (Set<?>) extractFieldValueFromInstance(original);
73: if (origTypes == null || origTypes.isEmpty()) {
74: return;
75: }
76: valueBuilder.removeTypes(prepareTypes(origTypes), getAttributeWriteContext());
77: } else {
78: assert val instanceof Set; // This is verified when the metamodel is built
79: final Set<?> types = (Set<?>) val;
80: if (original == null) {
81: valueBuilder.addTypes(prepareTypes(types), getAttributeWriteContext());
82: } else {
83: Set<?> origTypes = (Set<?>) extractFieldValueFromInstance(original);
84: if (origTypes == null) {
85: origTypes = Collections.emptySet();
86: }
87: extractTypesToAdd(valueBuilder, types, origTypes);
88: extractTypesToRemove(valueBuilder, types, origTypes);
89: }
90: }
91: }
92:
93: private void extractTypesToAdd(AxiomValueGatherer valueBuilder, Set<?> types, Set<?> origTypes) {
94: final Set<URI> toAdd = typesDiff(origTypes, types);
95: valueBuilder.addTypes(toAdd, getAttributeWriteContext());
96: }
97:
98: private static Set<URI> typesDiff(Set<?> base, Set<?> difference) {
99: final Set<URI> addedDiff = new HashSet<>(base.size());
100: addedDiff.addAll(difference.stream().filter(t -> !base.contains(t)).map(t -> URI.create(t.toString()))
101: .toList());
102: return addedDiff;
103: }
104:
105: private void extractTypesToRemove(AxiomValueGatherer valueBuilder, Set<?> types, Set<?> origTypes) {
106: final Set<URI> toRemove = typesDiff(types, origTypes);
107: valueBuilder.removeTypes(toRemove, getAttributeWriteContext());
108: }
109:
110: private static Set<URI> prepareTypes(Set<?> types) {
111: final Set<URI> toAdd = new HashSet<>(types.size());
112: toAdd.addAll(types.stream().map(t -> URI.create(t.toString())).toList());
113: return toAdd;
114: }
115:
116: @Override
117: Set<Axiom<?>> buildAxiomsFromInstance(X instance) {
118: final Object val = extractFieldValueFromInstance(instance);
119: assert val == null || val instanceof Set;
120: final Set<?> types = (Set<?>) val;
121: if (val == null || ((Set<?>) val).isEmpty()) {
122: return Collections.emptySet();
123: } else {
124: final NamedResource subject = NamedResource.create(EntityPropertiesUtils.getIdentifier(instance, et));
125: final Assertion assertion = createAssertion();
126: return types.stream().map(t -> new AxiomImpl<>(subject, assertion, new Value<>(URI.create(t.toString()))))
127: .collect(Collectors.toSet());
128: }
129: }
130:
131: @Override
132: Collection<Value<?>> toAxiomValue(Object value) {
133: return Collections.singleton(new Value<>(URI.create(value.toString())));
134: }
135:
136: @Override
137: Assertion createAssertion() {
138: return Assertion.createClassAssertion(attribute.isInferred());
139: }
140: }