Skip to content

Package: AbstractIdentifiableType

AbstractIdentifiableType

nameinstructionbranchcomplexitylinemethod
AbstractIdentifiableType(Class)
M: 0 C: 23
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
addDeclaredAttribute(String, Attribute)
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
addDirectTypes(TypesSpecification)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
addLifecycleListener(LifecycleEvent, Method)
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
addOtherProperties(PropertiesSpecification)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
addSubtype(AbstractIdentifiableType)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
checkPluralAttribute(Attribute, String, String, Class, Class, boolean)
M: 0 C: 28
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
getAttribute(String)
M: 0 C: 39
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
getAttributes()
M: 0 C: 18
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
getCollection(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getCollection(String, Class)
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getDeclaredAttribute(String)
M: 0 C: 27
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getDeclaredAttributes()
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getDeclaredCollection(String)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getDeclaredCollection(String, Class)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getDeclaredList(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getDeclaredList(String, Class)
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getDeclaredMap(String)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getDeclaredMap(String, Class, Class)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getDeclaredPluralAttribute(String, String, Class, Class)
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getDeclaredPluralAttributes()
M: 0 C: 12
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
getDeclaredSet(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getDeclaredSet(String, Class)
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getDeclaredSingularAttribute(String)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getDeclaredSingularAttribute(String, Class)
M: 6 C: 21
78%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 1 C: 5
83%
M: 0 C: 1
100%
getDeclaredSingularAttributes()
M: 0 C: 12
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
getDeclaredVersion(Class)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getFieldSpecification(String)
M: 0 C: 59
100%
M: 1 C: 11
92%
M: 1 C: 6
86%
M: 0 C: 9
100%
M: 0 C: 1
100%
getFieldSpecifications()
M: 0 C: 26
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
getIdentifier()
M: 0 C: 25
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
getJavaType()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getLifecycleListeners(LifecycleEvent)
M: 0 C: 26
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
getList(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getList(String, Class)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getMap(String)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getMap(String, Class, Class)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getPluralAttribute(String, String, Class, Class)
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getPluralAttributes()
M: 0 C: 20
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
getProperties()
M: 0 C: 15
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getSet(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getSet(String, Class)
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getSingularAttribute(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getSingularAttribute(String, Class)
M: 10 C: 25
71%
M: 2 C: 4
67%
M: 2 C: 2
50%
M: 1 C: 6
86%
M: 0 C: 1
100%
getSingularAttributes()
M: 0 C: 20
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
getSubtypes()
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getSupertype()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getTypes()
M: 0 C: 15
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getVersion(Class)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
hasDeclaredLifecycleListener(LifecycleEvent)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
hasLifecycleListeners(LifecycleEvent)
M: 0 C: 16
100%
M: 1 C: 5
83%
M: 1 C: 3
75%
M: 0 C: 1
100%
M: 0 C: 1
100%
hasSingleIdAttribute()
M: 0 C: 2
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
hasSubtypes()
M: 0 C: 8
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
hasVersionAttribute()
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
isAbstract()
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getDeclaredPluralAttributes$0(Attribute)
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getDeclaredSingularAttributes$1(Attribute)
M: 1 C: 6
86%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getDeclaredSingularAttributes$2(Attribute)
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
pluralAttNotFound(String, String, Class, boolean)
M: 0 C: 30
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
setIdentifier(Identifier)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
setSupertype(AbstractIdentifiableType)
M: 4 C: 10
71%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 4
100%
M: 0 C: 1
100%
singularAttNotFound(String, Class, boolean)
M: 0 C: 28
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
static {...}
M: 0 C: 1
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

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