Skip to content

Package: MetamodelBuilder

MetamodelBuilder

nameinstructionbranchcomplexitylinemethod
MetamodelBuilder(Configuration)
M: 0 C: 41
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
addInferredClass(Class)
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%
buildMetamodel(PersistenceUnitClassFinder)
M: 0 C: 24
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
entity(Class)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getEntities()
M: 0 C: 15
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
getEntityClass(Class)
M: 0 C: 14
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getInferredClasses()
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%
getNamedQueryManager()
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%
getResultSetMappingManager()
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%
getTypeMap()
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%
getTypeReferenceMap()
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%
hasManagedType(Class)
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$getEntities$0(Map.Entry)
M: 0 C: 10
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getEntities$1(Map, Map.Entry)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
processManagedType(TypeBuilderContext)
M: 0 C: 83
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 18
100%
M: 0 C: 1
100%
processOWLClass(Class)
M: 0 C: 27
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
processSupertypes(Class)
M: 0 C: 37
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
registerTypeReference(Class, Class)
M: 8 C: 16
67%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 0 C: 4
100%
M: 0 C: 1
100%
resolveInheritanceType(EntityTypeImpl)
M: 0 C: 41
100%
M: 1 C: 5
83%
M: 1 C: 3
75%
M: 0 C: 9
100%
M: 0 C: 1
100%
static {...}
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%

Coverage

1: /**
2: * Copyright (C) 2022 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.metamodel;
14:
15: import cz.cvut.kbss.jopa.exception.MetamodelInitializationException;
16: import cz.cvut.kbss.jopa.loaders.PersistenceUnitClassFinder;
17: import cz.cvut.kbss.jopa.model.JOPAPersistenceProperties;
18: import cz.cvut.kbss.jopa.model.TypeReferenceMap;
19: import cz.cvut.kbss.jopa.model.annotations.Inheritance;
20: import cz.cvut.kbss.jopa.query.NamedQueryManager;
21: import cz.cvut.kbss.jopa.query.ResultSetMappingManager;
22: import cz.cvut.kbss.jopa.query.mapper.ResultSetMappingProcessor;
23: import cz.cvut.kbss.jopa.utils.Configuration;
24: import cz.cvut.kbss.jopa.utils.Constants;
25: import org.slf4j.Logger;
26: import org.slf4j.LoggerFactory;
27:
28: import java.lang.reflect.Field;
29: import java.util.*;
30:
31: public class MetamodelBuilder {
32:
33: private static final Logger LOG = LoggerFactory.getLogger(MetamodelBuilder.class);
34:
35: private final NamedNativeQueryProcessor queryProcessor = new NamedNativeQueryProcessor();
36: private final ResultSetMappingProcessor mappingProcessor;
37:
38: private final Map<Class<?>, AbstractIdentifiableType<?>> typeMap = new HashMap<>();
39: private final Set<Class<?>> inferredClasses = new HashSet<>();
40:
41: private final TypeReferenceMap typeReferenceMap = new TypeReferenceMap();
42:
43: private final ConverterResolver converterResolver;
44:
45: private final Configuration configuration;
46:
47: public MetamodelBuilder(Configuration configuration) {
48: this.configuration = configuration;
49: this.mappingProcessor = new ResultSetMappingProcessor(this);
50: this.converterResolver = new ConverterResolver(new Converters(configuration));
51: }
52:
53: /**
54: * Builds persistence unit metamodel based on classes discovered by the specified class finder.
55: *
56: * @param classFinder Holder of information about classes relevant for persistence unit building
57: */
58: public void buildMetamodel(PersistenceUnitClassFinder classFinder) {
59: classFinder.getAttributeConverters().forEach(converterResolver::registerConverter);
60: classFinder.getEntities().forEach(this::processOWLClass);
61: classFinder.getResultSetMappings().forEach(mappingProcessor::buildMapper);
62: }
63:
64: private <X> void processOWLClass(final Class<X> cls) {
65:• if (typeMap.containsKey(cls)) {
66: return;
67: }
68:
69: LOG.debug("Processing OWL class: {}", cls);
70:
71: final TypeBuilderContext<X> et = ManagedClassProcessor.processManagedType(cls);
72: et.setConverterResolver(converterResolver);
73: et.setPuLanguage(configuration.get(JOPAPersistenceProperties.LANG));
74:
75: processManagedType(et);
76: }
77:
78: private <X> void processManagedType(TypeBuilderContext<X> context) {
79: final AbstractIdentifiableType<X> type = context.getType();
80: final Class<X> cls = type.getJavaType();
81: typeMap.put(cls, type);
82:
83: final AbstractIdentifiableType<? super X> supertype = processSupertypes(cls);
84:• if (supertype != null) {
85: type.setSupertype(supertype);
86: }
87: type.setLifecycleListenerManager(new EntityLifecycleCallbackResolver(type).resolve());
88:
89: final ClassFieldMetamodelProcessor<X> fieldProcessor = new ClassFieldMetamodelProcessor<>(context, this);
90:
91:• for (Field f : cls.getDeclaredFields()) {
92: fieldProcessor.processField(f);
93: }
94:
95:• if (type.getPersistenceType() == Type.PersistenceType.ENTITY) {
96: try {
97: type.getIdentifier();
98: } catch (IllegalArgumentException e) {
99: throw new MetamodelInitializationException("Missing identifier field in entity " + cls);
100: }
101: resolveInheritanceType((EntityTypeImpl<X>) type);
102: }
103:
104: queryProcessor.processClass(cls);
105: }
106:
107: private <X> AbstractIdentifiableType<? super X> processSupertypes(Class<X> cls) {
108: final Class<? super X> managedSupertype = ManagedClassProcessor.getManagedSupertype(cls);
109:• if (managedSupertype != null) {
110:• if (typeMap.containsKey(managedSupertype)) {
111: return (AbstractIdentifiableType<? super X>) typeMap.get(managedSupertype);
112: }
113: final TypeBuilderContext<? super X> context = ManagedClassProcessor.processManagedType(managedSupertype);
114: context.setConverterResolver(converterResolver);
115: context.setPuLanguage(configuration.get(JOPAPersistenceProperties.LANG));
116: processManagedType(context);
117: return context.getType();
118: }
119: return null;
120: }
121:
122: private static <X> void resolveInheritanceType(EntityTypeImpl<X> et) {
123: final Class<X> cls = et.getJavaType();
124: final Inheritance inheritance = cls.getDeclaredAnnotation(Inheritance.class);
125:• if (inheritance != null) {
126:• if (et.getSupertype() != null &&
127:• et.getSupertype().getPersistenceType() != Type.PersistenceType.MAPPED_SUPERCLASS) {
128: throw new MetamodelInitializationException("Class " + cls +
129: " cannot declare inheritance strategy, because it already inherits it from its supertype.");
130: }
131: et.setInheritanceType(inheritance.strategy());
132: } else {
133: et.setInheritanceType(Constants.DEFAULT_INHERITANCE_TYPE);
134: }
135: }
136:
137: public Map<Class<?>, ManagedType<?>> getTypeMap() {
138: return Collections.unmodifiableMap(typeMap);
139: }
140:
141: public <X> AbstractIdentifiableType<X> entity(Class<X> cls) {
142: return (AbstractIdentifiableType<X>) typeMap.get(cls);
143: }
144:
145: public Map<Class<?>, EntityType<?>> getEntities() {
146: final Map<Class<?>, EntityType<?>> map = new HashMap<>();
147:• typeMap.entrySet().stream().filter(e -> e.getValue().getPersistenceType() == Type.PersistenceType.ENTITY)
148: .forEach(e -> map.put(e.getKey(), (EntityType<?>) e.getValue()));
149: return map;
150: }
151:
152: public Set<Class<?>> getInferredClasses() {
153: return Collections.unmodifiableSet(inferredClasses);
154: }
155:
156: public NamedQueryManager getNamedQueryManager() {
157: return queryProcessor.getQueryManager();
158: }
159:
160: public ResultSetMappingManager getResultSetMappingManager() {
161: return mappingProcessor.getManager();
162: }
163:
164: void addInferredClass(Class<?> cls) {
165: inferredClasses.add(cls);
166: }
167:
168: @SuppressWarnings("unchecked")
169: <X> ManagedType<X> getEntityClass(Class<X> cls) {
170:• if (!typeMap.containsKey(cls)) {
171: processOWLClass(cls);
172: }
173: return (ManagedType<X>) typeMap.get(cls);
174: }
175:
176: /**
177: * Checks whether the specified class represents a managed type already processed by the metamodel builder.
178: *
179: * @param cls Class to check
180: * @return Managed type existence status
181: */
182: boolean hasManagedType(Class<?> cls) {
183: return typeMap.containsKey(cls);
184: }
185:
186: void registerTypeReference(Class<?> referencedType, Class<?> referringType) {
187:• assert hasManagedType(referencedType);
188:• assert hasManagedType(referringType);
189: typeReferenceMap.addReference(referencedType, referringType);
190: }
191:
192: public TypeReferenceMap getTypeReferenceMap() {
193: return typeReferenceMap;
194: }
195: }