Skip to content

Method: getSet(String)

1: /**
2: * Copyright (C) 2016 Czech Technical University in Prague
3: * <p>
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: * <p>
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.model.metamodel;
16:
17: import java.lang.reflect.Modifier;
18: import java.util.*;
19: import java.util.stream.Collectors;
20:
21: public abstract class AbstractIdentifiableType<X> implements IdentifiableType<X> {
22:
23: private final Class<X> javaType;
24:
25: private Identifier identifier;
26:
27: private AbstractIdentifiableType<? super X> supertype;
28:
29: private final Set<AbstractIdentifiableType<? extends X>> subtypes = new HashSet<>(2);
30:
31: private TypesSpecification<X, ?> directTypes;
32:
33: private PropertiesSpecification<X, ?, ?, ?> properties;
34:
35: private final Map<String, Attribute<X, ?>> declaredAttributes = new HashMap<>();
36:
37: private EntityLifecycleListenerManager lifecycleListenerManager = EntityLifecycleListenerManager.empty();
38:
39: AbstractIdentifiableType(Class<X> javaType) {
40: this.javaType = javaType;
41: }
42:
43: void addDeclaredAttribute(final String name, final Attribute<X, ?> a) {
44: declaredAttributes.put(name, a);
45: }
46:
47: void setSupertype(AbstractIdentifiableType<? super X> supertype) {
48: assert supertype != null;
49: this.supertype = supertype;
50: supertype.addSubtype(this);
51: }
52:
53: private void addSubtype(AbstractIdentifiableType<? extends X> subtype) {
54: subtypes.add(subtype);
55: }
56:
57: void addDirectTypes(TypesSpecification<X, ?> a) {
58: this.directTypes = a;
59: }
60:
61: void addOtherProperties(PropertiesSpecification<X, ?, ?, ?> a) {
62: this.properties = a;
63: }
64:
65: public void setIdentifier(final Identifier identifier) {
66: this.identifier = identifier;
67: }
68:
69: @Override
70: public boolean hasSingleIdAttribute() {
71: return true; // We do not support id classes
72: }
73:
74: @Override
75: public <Y> SingularAttribute<X, Y> getDeclaredVersion(Class<Y> type) {
76: // TODO
77: throw new UnsupportedOperationException();
78: }
79:
80: @Override
81: public AbstractIdentifiableType<? super X> getSupertype() {
82: return supertype;
83: }
84:
85: /**
86: * Whether this managed type has any managed subtypes (entities or mapped superclasses).
87: *
88: * @return {@code true} when managed subtypes exist, {@code false} otherwise
89: */
90: public boolean hasSubtypes() {
91: return !subtypes.isEmpty();
92: }
93:
94: /**
95: * Whether the Java type represented by this type is an abstract class.
96: *
97: * @return {@code true} if the represented Java type is abstract, {@code false} otherwise
98: */
99: public boolean isAbstract() {
100: return Modifier.isAbstract(javaType.getModifiers());
101: }
102:
103: public Set<AbstractIdentifiableType<? extends X>> getSubtypes() {
104: return Collections.unmodifiableSet(subtypes);
105: }
106:
107: @Override
108: public <Y> SingularAttribute<? super X, Y> getVersion(Class<Y> type) {
109: // TODO
110: throw new UnsupportedOperationException();
111: }
112:
113: @Override
114: public boolean hasVersionAttribute() {
115: return false;
116: }
117:
118: @Override
119: public Set<Attribute<? super X, ?>> getAttributes() {
120: final Set<Attribute<? super X, ?>> attributes = new HashSet<>(declaredAttributes.values());
121: if (supertype != null) {
122: attributes.addAll(supertype.getAttributes());
123: }
124: return attributes;
125: }
126:
127: @Override
128: public Attribute<? super X, ?> getAttribute(String name) {
129: Objects.requireNonNull(name);
130: if (declaredAttributes.containsKey(name)) {
131: return declaredAttributes.get(name);
132: }
133: if (supertype != null) {
134: return supertype.getAttribute(name);
135: }
136: throw new IllegalArgumentException("Attribute " + name + " is not present in type " + this.toString());
137: }
138:
139: @Override
140: public CollectionAttribute<? super X, ?> getCollection(String name) {
141: return getCollection(name, Object.class);
142: }
143:
144: @Override
145: public <E> CollectionAttribute<? super X, E> getCollection(String name, Class<E> elementType) {
146: return getPluralAttribute("Collection", name, elementType, CollectionAttribute.class);
147: }
148:
149: private <E, R extends PluralAttribute<? super X, ?, E>> R getPluralAttribute(String type, String name,
150: Class<E> elementType,
151: Class<R> attType) {
152: final Attribute<? super X, ?> a = getAttribute(name);
153:
154: checkPluralAttribute(a, type, name, elementType, attType, false);
155: return attType.cast(a);
156: }
157:
158: private <E, R extends PluralAttribute<? super X, ?, E>> void checkPluralAttribute(Attribute<? super X, ?> att,
159: String type, String name,
160: Class<E> elementType,
161: Class<R> attType,
162: boolean declared) {
163: if (!attType.isAssignableFrom(att.getClass())) {
164: throw pluralAttNotFound(type, name, elementType, declared);
165: }
166:
167: final PluralAttribute<? super X, ?, E> colAtt = (PluralAttribute<? super X, ?, E>) att;
168: if (!elementType.isAssignableFrom(colAtt.getBindableJavaType())) {
169: throw pluralAttNotFound(type, name, elementType, declared);
170: }
171: }
172:
173: private IllegalArgumentException pluralAttNotFound(String type, String name, Class<?> elementType,
174: boolean declared) {
175: return new IllegalArgumentException(type + " attribute " + name + " with element type " + elementType +
176: " is not " + (declared ? "declared" : "present") + " in type " + this);
177: }
178:
179: @Override
180: public <E> ListAttribute<? super X, E> getList(String name, Class<E> elementType) {
181: return getPluralAttribute("List", name, elementType, ListAttribute.class);
182: }
183:
184: @Override
185: public ListAttribute<? super X, ?> getList(String name) {
186: return getList(name, Object.class);
187: }
188:
189: @Override
190: public <K, V> MapAttribute<? super X, K, V> getMap(String name, Class<K> keyType, Class<V> valueType) {
191: throw new UnsupportedOperationException();
192: }
193:
194: @Override
195: public MapAttribute<? super X, ?, ?> getMap(String name) {
196: return getMap(name, Object.class, Object.class);
197: }
198:
199: @Override
200: public <E> SetAttribute<? super X, E> getSet(String name, Class<E> elementType) {
201: return getPluralAttribute("Set", name, elementType, SetAttribute.class);
202: }
203:
204: @Override
205: public SetAttribute<? super X, ?> getSet(String name) {
206: return getSet(name, Object.class);
207: }
208:
209: @Override
210: public Set<PluralAttribute<? super X, ?, ?>> getPluralAttributes() {
211: final Set<PluralAttribute<? super X, ?, ?>> plurals = new HashSet<>();
212: plurals.addAll(getDeclaredPluralAttributes());
213: if (supertype != null) {
214: plurals.addAll(supertype.getPluralAttributes());
215: }
216: return plurals;
217: }
218:
219: @Override
220: public Set<SingularAttribute<? super X, ?>> getSingularAttributes() {
221: final Set<SingularAttribute<? super X, ?>> singulars = new HashSet<>();
222: singulars.addAll(getDeclaredSingularAttributes());
223: if (supertype != null) {
224: singulars.addAll(supertype.getSingularAttributes());
225: }
226: return singulars;
227: }
228:
229: @Override
230: public <Y> SingularAttribute<? super X, Y> getSingularAttribute(String name, Class<Y> type) {
231: final Attribute<? super X, ?> a = getAttribute(name);
232:
233: if (a.isCollection()) {
234: throw singularAttNotFound(name, type, false);
235: }
236: assert a instanceof SingularAttribute;
237: if (!type.isAssignableFrom(a.getJavaType())) {
238: throw singularAttNotFound(name, type, false);
239: }
240:
241: return (SingularAttribute<? super X, Y>) a;
242: }
243:
244: private IllegalArgumentException singularAttNotFound(String name, Class<?> type, boolean declared) {
245: return new IllegalArgumentException(
246: "Singular attribute " + name + " of type " + type + " is not " + (declared ? "declared" : "present") +
247: " in type " + this);
248: }
249:
250: @Override
251: public SingularAttribute<? super X, ?> getSingularAttribute(String name) {
252: return getSingularAttribute(name, Object.class);
253: }
254:
255: @Override
256: public Set<Attribute<X, ?>> getDeclaredAttributes() {
257: return new HashSet<>(declaredAttributes.values());
258: }
259:
260: @Override
261: public Set<PluralAttribute<X, ?, ?>> getDeclaredPluralAttributes() {
262: return declaredAttributes.values().stream().filter(Attribute::isCollection)
263: .map(a -> (PluralAttribute<X, ?, ?>) a).collect(Collectors.toSet());
264: }
265:
266: @Override
267: public Set<SingularAttribute<X, ?>> getDeclaredSingularAttributes() {
268: return declaredAttributes.values().stream().filter(att -> !att.isCollection()).map(
269: a -> (SingularAttribute<X, ?>) a).collect(Collectors.toSet());
270: }
271:
272: @Override
273: public Attribute<X, ?> getDeclaredAttribute(String name) {
274: if (declaredAttributes.containsKey(name)) {
275: return declaredAttributes.get(name);
276: }
277: throw new IllegalArgumentException("Attribute " + name + " is not declared in type " + name);
278: }
279:
280: @Override
281: public <E> CollectionAttribute<X, E> getDeclaredCollection(String name, Class<E> elementType) {
282: return getDeclaredPluralAttribute("Collection", name, elementType, CollectionAttribute.class);
283: }
284:
285: private <E, R extends PluralAttribute<? super X, ?, E>> R getDeclaredPluralAttribute(String type, String name,
286: Class<E> elementType,
287: Class<R> attType) {
288: final Attribute<? super X, ?> a = getDeclaredAttribute(name);
289:
290: checkPluralAttribute(a, type, name, elementType, attType, true);
291: return attType.cast(a);
292: }
293:
294: @Override
295: public CollectionAttribute<X, ?> getDeclaredCollection(String name) {
296: return getDeclaredCollection(name, Object.class);
297: }
298:
299: @Override
300: public <E> ListAttribute<X, E> getDeclaredList(String name, Class<E> elementType) {
301: return getDeclaredPluralAttribute("List", name, elementType, ListAttribute.class);
302: }
303:
304: @Override
305: public ListAttribute<X, ?> getDeclaredList(String name) {
306: return getDeclaredList(name, Object.class);
307: }
308:
309: @Override
310: public <K, V> MapAttribute<X, K, V> getDeclaredMap(String name, Class<K> keyType, Class<V> valueType) {
311: throw new UnsupportedOperationException();
312: }
313:
314: @Override
315: public MapAttribute<X, ?, ?> getDeclaredMap(String name) {
316: return getDeclaredMap(name, Object.class, Object.class);
317: }
318:
319: @Override
320: public <E> SetAttribute<X, E> getDeclaredSet(String name, Class<E> elementType) {
321: return getDeclaredPluralAttribute("Set", name, elementType, SetAttribute.class);
322: }
323:
324: @Override
325: public SetAttribute<X, ?> getDeclaredSet(String name) {
326: return getDeclaredSet(name, Object.class);
327: }
328:
329: @Override
330: public <Y> SingularAttribute<X, Y> getDeclaredSingularAttribute(String name, Class<Y> type) {
331: final Attribute<X, ?> a = getDeclaredAttribute(name);
332:
333: if (a.isCollection()) {
334: throw singularAttNotFound(name, type, true);
335: }
336: if (!type.isAssignableFrom(a.getJavaType())) {
337: throw singularAttNotFound(name, type, true);
338: }
339:
340: return (SingularAttribute<X, Y>) a;
341: }
342:
343: @Override
344: public SingularAttribute<X, ?> getDeclaredSingularAttribute(String name) {
345: return getDeclaredSingularAttribute(name, Object.class);
346: }
347:
348: @Override
349: public TypesSpecification<? super X, ?> getTypes() {
350: if (directTypes != null) {
351: return directTypes;
352: }
353: return supertype != null ? supertype.getTypes() : null;
354: }
355:
356: @Override
357: public PropertiesSpecification<? super X, ?, ?, ?> getProperties() {
358: if (properties != null) {
359: return properties;
360: }
361: return supertype != null ? supertype.getProperties() : null;
362: }
363:
364: @Override
365: public Set<FieldSpecification<? super X, ?>> getFieldSpecifications() {
366: final Set<FieldSpecification<? super X, ?>> specs = new HashSet<>(getAttributes());
367: final TypesSpecification<? super X, ?> types = getTypes();
368: if (types != null) {
369: specs.add(types);
370: }
371: final PropertiesSpecification<? super X, ?, ?, ?> props = getProperties();
372: if (props != null) {
373: specs.add(props);
374: }
375: return specs;
376: }
377:
378: @Override
379: public FieldSpecification<? super X, ?> getFieldSpecification(String fieldName) {
380: if (declaredAttributes.containsKey(fieldName)) {
381: return declaredAttributes.get(fieldName);
382: }
383: if (directTypes != null && directTypes.getName().equals(fieldName)) {
384: return directTypes;
385: } else if (properties != null && properties.getName().equals(fieldName)) {
386: return properties;
387: }
388: if (supertype != null) {
389: return supertype.getFieldSpecification(fieldName);
390: }
391: throw new IllegalArgumentException("Field " + fieldName + " is not present in type " + this);
392: }
393:
394: @Override
395: public Identifier getIdentifier() {
396: if (identifier != null) {
397: return identifier;
398: }
399: if (supertype != null) {
400: return supertype.getIdentifier();
401: }
402: // This shouldn't happen, because every entity has to contain an identifier, otherwise metamodel building fails
403: throw new IllegalArgumentException("Identifier attribute is not present in type " + this);
404: }
405:
406: @Override
407: public Class<X> getJavaType() {
408: return javaType;
409: }
410:
411: public EntityLifecycleListenerManager getLifecycleListenerManager() {
412: return lifecycleListenerManager;
413: }
414:
415: public void setLifecycleListenerManager(EntityLifecycleListenerManager lifecycleListenerManager) {
416: this.lifecycleListenerManager = lifecycleListenerManager;
417: }
418: }