Skip to content

Method: isManagedType(Class)

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.exception.MetamodelInitializationException;
18: import cz.cvut.kbss.jopa.model.IRI;
19: import cz.cvut.kbss.jopa.model.annotations.MappedSuperclass;
20: import cz.cvut.kbss.jopa.model.annotations.OWLClass;
21: import cz.cvut.kbss.jopa.model.lifecycle.LifecycleEvent;
22:
23: import java.lang.reflect.Method;
24: import java.lang.reflect.Modifier;
25:
26: /**
27: * Utility methods for processing managed types for metamodel construction.
28: */
29: class ManagedClassProcessor {
30:
31: private ManagedClassProcessor() {
32: }
33:
34: static <T> AbstractIdentifiableType<T> processManagedType(Class<T> cls) {
35: final AbstractIdentifiableType<T> type;
36: if (isEntityType(cls)) {
37: type = processEntityType(cls);
38: } else if (isMappedSuperclassType(cls)) {
39: type = processMappedSuperclassType(cls);
40: } else {
41: throw new MetamodelInitializationException("Type " + cls + " is not a managed type.");
42: }
43: resolveLifecycleHooks(type);
44: return type;
45: }
46:
47: private static <T> EntityTypeImpl<T> processEntityType(Class<T> cls) {
48: final OWLClass c = cls.getDeclaredAnnotation(OWLClass.class);
49: assert c != null;
50:
51: checkForNoArgConstructor(cls);
52:
53: return new EntityTypeImpl<>(cls.getSimpleName(), cls, IRI.create(c.iri()));
54: }
55:
56: private static <T> void checkForNoArgConstructor(Class<T> cls) {
57: try {
58: cls.getDeclaredConstructor();
59: } catch (NoSuchMethodException e) {
60: throw new MetamodelInitializationException("Class " + cls + " is missing required no-arg constructor.");
61: }
62: }
63:
64: private static <T> MappedSuperclassTypeImpl<T> processMappedSuperclassType(Class<T> cls) {
65: assert cls.getDeclaredAnnotation(MappedSuperclass.class) != null;
66:
67: return new MappedSuperclassTypeImpl<>(cls);
68: }
69:
70: static <T> Class<? super T> getManagedSupertype(Class<T> cls) {
71: if (cls.getSuperclass() != null && isManagedType(cls.getSuperclass())) {
72: return cls.getSuperclass();
73: }
74: return null;
75: }
76:
77: private static boolean isManagedType(Class<?> cls) {
78:• return isEntityType(cls) || isMappedSuperclassType(cls);
79: }
80:
81: private static boolean isEntityType(Class<?> cls) {
82: return cls.getDeclaredAnnotation(OWLClass.class) != null;
83: }
84:
85: private static boolean isMappedSuperclassType(Class<?> cls) {
86: return cls.getDeclaredAnnotation(MappedSuperclass.class) != null;
87: }
88:
89: private static <T> void resolveLifecycleHooks(AbstractIdentifiableType<T> type) {
90: final Class<T> cls = type.getJavaType();
91: for (Method m : cls.getDeclaredMethods()) {
92: for (LifecycleEvent hookType : LifecycleEvent.values()) {
93: if (m.getDeclaredAnnotation(hookType.getAnnotation()) != null) {
94: verifyCallbackNotAlreadyDefined(type, hookType);
95: verifyListenerSignature(type, m);
96: type.addLifecycleListener(hookType, m);
97: }
98: }
99: }
100: }
101:
102: private static <T> void verifyCallbackNotAlreadyDefined(AbstractIdentifiableType<T> type, LifecycleEvent hookType) {
103: if (type.hasDeclaredLifecycleListener(hookType)) {
104: throw MetamodelInitializationException.multipleListenersForSameLifecycleEvent(type.getJavaType(), hookType);
105: }
106: }
107:
108: private static <T> void verifyListenerSignature(AbstractIdentifiableType<T> type, Method listener) {
109: if (listener.getParameterCount() > 0) {
110: throw MetamodelInitializationException.invalidArgumentsForLifecycleListener(type.getJavaType(), listener);
111: }
112: if (!listener.getReturnType().equals(Void.TYPE)) {
113: throw MetamodelInitializationException.invalidReturnTypeForLifecycleListener(type.getJavaType(), listener);
114: }
115: if (Modifier.isFinal(listener.getModifiers()) || Modifier.isStatic(listener.getModifiers())) {
116: throw MetamodelInitializationException.invalidLifecycleListenerModifier(type.getJavaType(), listener);
117: }
118: }
119: }