Skip to content

Method: scanClasspath(Configuration)

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.jopa.loaders;
19:
20: import cz.cvut.kbss.jopa.exception.MetamodelInitializationException;
21: import cz.cvut.kbss.jopa.model.JOPAPersistenceProperties;
22: import cz.cvut.kbss.jopa.model.annotations.SparqlResultSetMapping;
23: import cz.cvut.kbss.jopa.oom.converter.ConverterWrapper;
24: import cz.cvut.kbss.jopa.utils.Configuration;
25: import cz.cvut.kbss.jopa.utils.ReflectionUtils;
26:
27: import java.util.Map;
28: import java.util.Objects;
29: import java.util.Set;
30: import java.util.stream.Stream;
31:
32: /**
33: * Scans classpath to discover classes relevant to persistence unit building.
34: * <p>
35: * Only classes under the package configured via {@link JOPAPersistenceProperties#SCAN_PACKAGE} are processed.
36: */
37: public class PersistenceUnitClassFinder {
38:
39: private final EntityLoader entityLoader = new EntityLoader();
40: private final ResultSetMappingLoader resultSetMappingLoader = new ResultSetMappingLoader();
41: private final ConverterLoader converterLoader = new ConverterLoader();
42:
43: private boolean scanned = false;
44:
45: /**
46: * Scans application classpath based on the {@link JOPAPersistenceProperties#SCAN_PACKAGE}, looking for classes
47: * relevant for the persistence provider.
48: * <p>
49: * These classes include:
50: * <ul>
51: * <li>Entities, i.e. classes annotated with {@link cz.cvut.kbss.jopa.model.annotations.OWLClass},</li>
52: * <li>Result result mapping classes, i.e. classes annotated with {@link cz.cvut.kbss.jopa.model.annotations.SparqlResultSetMapping}
53: * or {@link cz.cvut.kbss.jopa.model.annotations.SparqlResultSetMappings}</li>
54: * </ul>
55: *
56: * @param configuration Persistence configuration, should contain value for the
57: * {@link JOPAPersistenceProperties#SCAN_PACKAGE} property
58: * @throws IllegalArgumentException If {@link JOPAPersistenceProperties#SCAN_PACKAGE} values is missing
59: */
60: public void scanClasspath(Configuration configuration) {
61: Objects.requireNonNull(configuration);
62: String scanPackageConfig = configuration.get(JOPAPersistenceProperties.SCAN_PACKAGE, "");
63: final String[] toScan = scanPackageConfig.split(",");
64: final ClasspathScanner classpathScanner = resolveClasspathScanner(configuration);
65: classpathScanner.addListener(entityLoader);
66: classpathScanner.addListener(resultSetMappingLoader);
67: classpathScanner.addListener(converterLoader);
68: Stream.of(toScan).map(String::trim).forEach(classpathScanner::processClasses);
69: this.scanned = true;
70: }
71:
72: private static ClasspathScanner resolveClasspathScanner(Configuration config) {
73: try {
74: final String scannerType = config.get(JOPAPersistenceProperties.CLASSPATH_SCANNER_CLASS,
75: DefaultClasspathScanner.class.getName());
76: final Class<?> scannerCls = Class.forName(scannerType);
77: return (ClasspathScanner) ReflectionUtils.instantiateUsingDefaultConstructor(scannerCls);
78: } catch (ClassNotFoundException | cz.cvut.kbss.jopa.exception.InstantiationException e) {
79: throw new MetamodelInitializationException("Unable to instantiate configured ClasspathScanner.", e);
80: }
81: }
82:
83: /**
84: * Gets entity classes found during classpath scanning.
85: *
86: * @return Set of entity classes discovered on classpath
87: */
88: public Set<Class<?>> getEntities() {
89: assert scanned;
90: return entityLoader.getEntities();
91: }
92:
93: /**
94: * Gets {@link SparqlResultSetMapping}s found during classpath scanning.
95: *
96: * @return Set of result set mapping annotations discovered on classpath
97: */
98: public Set<SparqlResultSetMapping> getResultSetMappings() {
99: assert scanned;
100: return resultSetMappingLoader.getMappings();
101: }
102:
103: /**
104: * Gets {@link cz.cvut.kbss.jopa.model.AttributeConverter} implementations found during classpath scanning.
105: * <p>
106: * The converters are wrapped in an internal helper class {@link ConverterWrapper}.
107: *
108: * @return Map of classes to custom converters
109: */
110: public Map<Class<?>, ConverterWrapper<?, ?>> getAttributeConverters() {
111: assert scanned;
112: return converterLoader.getConverters();
113: }
114: }