Skip to content

Method: EntityDescriptor(boolean)

1: /**
2: * Copyright (C) 2020 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.jopa.model.descriptors;
14:
15: import cz.cvut.kbss.jopa.model.metamodel.Attribute;
16: import cz.cvut.kbss.jopa.model.metamodel.Attribute.PersistentAttributeType;
17: import cz.cvut.kbss.jopa.model.metamodel.FieldSpecification;
18: import cz.cvut.kbss.jopa.utils.ErrorUtils;
19:
20: import java.lang.reflect.Field;
21: import java.net.URI;
22: import java.util.*;
23: import java.util.Map.Entry;
24:
25: /**
26: * Describes an entity.
27: * <p>
28: * Each attribute has a descriptor associated with it.
29: */
30: public class EntityDescriptor extends AbstractDescriptor {
31:
32: private final Map<Field, Descriptor> fieldDescriptors;
33:
34: public EntityDescriptor() {
35: this.fieldDescriptors = new HashMap<>();
36: }
37:
38: /**
39: * Allows to configure where object property assertions should be stored
40: *
41: * @param assertionsInSubjectContext Whether object property assertions are stored in the subject's. Defaults to
42: * {@code true}. If {@code false}, object property assertions are stored in the
43: * object's context
44: * @see #areAssertionsInSubjectContext()
45: */
46: public EntityDescriptor(boolean assertionsInSubjectContext) {
47: super(assertionsInSubjectContext);
48: this.fieldDescriptors = new HashMap<>();
49: }
50:
51: public EntityDescriptor(URI context) {
52: super(context);
53: this.fieldDescriptors = new HashMap<>();
54: }
55:
56: public EntityDescriptor(Set<URI> contexts) {
57: this();
58: this.contexts.addAll(Objects.requireNonNull(contexts));
59: }
60:
61: public EntityDescriptor(URI context, boolean assertionsInSubjectContext) {
62: super(context, assertionsInSubjectContext);
63: this.fieldDescriptors = new HashMap<>();
64: }
65:
66: @Override
67: public EntityDescriptor addAttributeDescriptor(FieldSpecification<?, ?> attribute, Descriptor descriptor) {
68: Objects.requireNonNull(attribute, ErrorUtils.getNPXMessageSupplier("attribute"));
69: Objects.requireNonNull(descriptor, ErrorUtils.getNPXMessageSupplier("descriptor"));
70:
71: fieldDescriptors.put(attribute.getJavaField(), descriptor);
72: return this;
73: }
74:
75: @Override
76: public EntityDescriptor addAttributeContext(FieldSpecification<?, ?> attribute, URI context) {
77: Objects.requireNonNull(attribute, ErrorUtils.getNPXMessageSupplier("attribute"));
78:
79: fieldDescriptors.putIfAbsent(attribute.getJavaField(),
80: createDescriptor(attribute, context != null ? Collections.singleton(context) : Collections.emptySet()));
81: fieldDescriptors.get(attribute.getJavaField()).addContext(context);
82: return this;
83: }
84:
85: @Override
86: public EntityDescriptor setLanguage(String languageTag) {
87: super.setLanguage(languageTag);
88: fieldDescriptors.values().forEach(d -> d.setLanguage(languageTag));
89: return this;
90: }
91:
92: @Override
93: public EntityDescriptor setAttributeLanguage(FieldSpecification<?, ?> attribute, String languageTag) {
94: Objects.requireNonNull(attribute);
95:
96: fieldDescriptors.putIfAbsent(attribute.getJavaField(), createDescriptor(attribute, getContexts()));
97: fieldDescriptors.get(attribute.getJavaField()).setLanguage(languageTag);
98: return this;
99: }
100:
101: @Override
102: public Descriptor getAttributeDescriptor(FieldSpecification<?, ?> attribute) {
103: Objects.requireNonNull(attribute);
104: Descriptor d = fieldDescriptors.get(attribute.getJavaField());
105: if (d == null) {
106: d = createDescriptor(attribute, getContexts());
107: if (hasLanguage()) {
108: d.setLanguage(getLanguage());
109: }
110: }
111: return d;
112: }
113:
114: @Override
115: public Set<URI> getAttributeContexts(FieldSpecification<?, ?> attribute) {
116: Objects.requireNonNull(attribute);
117: final Descriptor attDescriptor = getAttributeDescriptor(attribute);
118: return attDescriptor.overridesAssertionContext() || !assertionsInSubjectContext ?
119: attDescriptor.getContexts() : getContexts();
120: }
121:
122: @Override
123: public Collection<Descriptor> getAttributeDescriptors() {
124: return Collections.unmodifiableCollection(fieldDescriptors.values());
125: }
126:
127: private static AbstractDescriptor createDescriptor(FieldSpecification<?, ?> att, Set<URI> contexts) {
128: if (att instanceof Attribute) {
129: final Attribute<?, ?> attSpec = (Attribute<?, ?>) att;
130: if (attSpec.getPersistentAttributeType() == PersistentAttributeType.OBJECT) {
131: if (attSpec.isCollection()) {
132: return new ObjectPropertyCollectionDescriptor(contexts, att);
133: } else {
134: return new EntityDescriptor(contexts);
135: }
136: }
137: }
138: return new FieldDescriptor(contexts, att);
139: }
140:
141: @Override
142: public boolean equals(Object o) {
143: if (this == o) {
144: return true;
145: }
146: if (!(o instanceof EntityDescriptor)) {
147: return false;
148: }
149: if (!super.equals(o)) {
150: return false;
151: }
152:
153: EntityDescriptor that = (EntityDescriptor) o;
154:
155: if (fieldDescriptors.size() != that.fieldDescriptors.size()) {
156: return false;
157: }
158: for (Entry<Field, Descriptor> e : fieldDescriptors.entrySet()) {
159: if (e.getValue() == null) {
160: if (that.fieldDescriptors.containsKey(e.getKey()) && that.fieldDescriptors.get(e.getKey()) != null) {
161: return false;
162: }
163: } else {
164: if (e.getValue() == this && that.fieldDescriptors.get(e.getKey()) == that) {
165: continue;
166: }
167: if (!e.getValue().equals(that.fieldDescriptors.get(e.getKey()))) {
168: return false;
169: }
170: }
171: }
172: return true;
173: }
174:
175: @Override
176: public int hashCode() {
177: int result = super.hashCode();
178: result = 31 * result + fieldDescriptors.entrySet().stream()
179: .map(e -> e.getKey().hashCode() ^
180: (e.getValue() == this ? 0 :
181: e.getValue().hashCode())).reduce(0, Integer::sum);
182: return result;
183: }
184: }