Skip to content

Method: unwrap(Class)

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.model;
19:
20: import cz.cvut.kbss.jopa.loaders.PersistenceUnitClassFinder;
21: import cz.cvut.kbss.jopa.model.metamodel.EntityType;
22: import cz.cvut.kbss.jopa.model.metamodel.Metamodel;
23: import cz.cvut.kbss.jopa.model.query.Query;
24: import cz.cvut.kbss.jopa.model.query.criteria.CriteriaBuilder;
25: import cz.cvut.kbss.jopa.sessions.ServerSession;
26: import cz.cvut.kbss.jopa.utils.Configuration;
27: import cz.cvut.kbss.jopa.utils.EntityPropertiesUtils;
28: import cz.cvut.kbss.ontodriver.OntologyStorageProperties;
29: import cz.cvut.kbss.ontodriver.config.OntoDriverProperties;
30:
31: import java.util.*;
32: import java.util.concurrent.ConcurrentHashMap;
33: import java.util.function.Consumer;
34:
35: public class EntityManagerFactoryImpl implements EntityManagerFactory, PersistenceUnitUtil {
36:
37: private volatile boolean open = true;
38:
39: private final Set<AbstractEntityManager> em;
40: private final Configuration configuration;
41: private final OntologyStorageProperties storageProperties;
42:
43: private volatile ServerSession serverSession;
44:
45: private volatile MetamodelImpl metamodel;
46:
47: private final Consumer<EntityManagerFactoryImpl> closeListener;
48:
49: public EntityManagerFactoryImpl(final Map<String, String> properties,
50: Consumer<EntityManagerFactoryImpl> closeListener) {
51: this.em = Collections.newSetFromMap(new ConcurrentHashMap<>());
52: this.configuration = new Configuration(properties != null ? properties : Collections.emptyMap());
53: this.closeListener = closeListener;
54: this.storageProperties = initStorageProperties();
55: initMetamodel();
56: }
57:
58: private OntologyStorageProperties initStorageProperties() {
59: return OntologyStorageProperties.driver(configuration.get(JOPAPersistenceProperties.DATA_SOURCE_CLASS))
60: .ontologyUri(configuration.get(JOPAPersistenceProperties.ONTOLOGY_URI_KEY))
61: .physicalUri(
62: configuration.get(JOPAPersistenceProperties.ONTOLOGY_PHYSICAL_URI_KEY))
63: .username(configuration.get(OntoDriverProperties.DATA_SOURCE_USERNAME))
64: .password(configuration.get(OntoDriverProperties.DATA_SOURCE_PASSWORD))
65: .build();
66: }
67:
68: private void initMetamodel() {
69: this.metamodel = new MetamodelImpl(configuration);
70: metamodel.build(new PersistenceUnitClassFinder());
71: }
72:
73: @Override
74: public void close() {
75: ensureOpen();
76: synchronized (this) {
77: if (!open) {
78: return;
79: }
80:
81: em.stream().filter(EntityManager::isOpen).forEach(EntityManager::close);
82: em.clear();
83: if (serverSession != null) {
84: serverSession.close();
85: this.serverSession = null;
86: }
87: this.metamodel = null;
88: this.open = false;
89: }
90: closeListener.accept(this);
91: }
92:
93: @Override
94: public EntityManager createEntityManager() {
95: return this.createEntityManager(Collections.emptyMap());
96: }
97:
98: @Override
99: public EntityManager createEntityManager(Map<String, String> map) {
100: ensureOpen();
101:
102: final Map<String, String> newMap = new HashMap<>(map);
103:
104: newMap.putAll(configuration.getProperties());
105:
106: initServerSession();
107:
108: final AbstractEntityManager c = new EntityManagerImpl(this, new Configuration(newMap), this.serverSession);
109:
110: em.add(c);
111: return c;
112: }
113:
114: private void ensureOpen() {
115: if (!open) {
116: throw new IllegalStateException("The entity manager factory is closed.");
117: }
118: }
119:
120: /**
121: * Initializes the server session if necessary.
122: */
123: private synchronized void initServerSession() {
124: if (serverSession == null) {
125: this.serverSession = new ServerSession(storageProperties, configuration, metamodel);
126: }
127: }
128:
129: @Override
130: public CriteriaBuilder getCriteriaBuilder() {
131: ensureOpen();
132: initServerSession();
133: return serverSession.getCriteriaBuilder();
134: }
135:
136: /**
137: * The server session should by initialized by now, but to make sure, there is default initialization with an empty
138: * properties map.
139: *
140: * @return The ServerSession for this factory.
141: */
142: public ServerSession getServerSession() {
143: return serverSession;
144: }
145:
146: @Override
147: public boolean isOpen() {
148: return open;
149: }
150:
151: @Override
152: public Map<String, String> getProperties() {
153: ensureOpen();
154: return configuration.getProperties();
155: }
156:
157: @Override
158: public Metamodel getMetamodel() {
159: ensureOpen();
160: return metamodel;
161: }
162:
163: @Override
164: public PersistenceUnitUtil getPersistenceUnitUtil() {
165: ensureOpen();
166: return this;
167: }
168:
169: @Override
170: public void addNamedQuery(String name, Query query) {
171: ensureOpen();
172: throw new UnsupportedOperationException("Not supported, yet.");
173: }
174:
175: @Override
176: public <T> T unwrap(Class<T> cls) {
177: ensureOpen();
178:• if (cls.isAssignableFrom(this.getClass())) {
179: return cls.cast(this);
180: }
181: return serverSession.unwrap(cls);
182: }
183:
184: @Override
185: public Object getIdentifier(Object entity) {
186: Objects.requireNonNull(entity);
187: final EntityType<?> et = getMetamodel().entity(entity.getClass());
188: return EntityPropertiesUtils.getFieldValue(et.getIdentifier().getJavaField(), entity);
189: }
190:
191: @Override
192: public boolean isLoaded(Object entity, String attributeName) {
193: Objects.requireNonNull(entity);
194: Objects.requireNonNull(attributeName);
195: for (final AbstractEntityManager emi : em) {
196: if (emi.isLoaded(entity, attributeName)) {
197: return true;
198: }
199: }
200: return false;
201: }
202:
203:
204: @Override
205: public boolean isLoaded(Object entity) {
206: Objects.requireNonNull(entity);
207: return em.stream().anyMatch(emi -> emi.isLoaded(entity));
208: }
209:
210: @Override
211: public Cache getCache() {
212: ensureOpen();
213: initServerSession();
214: return serverSession.getLiveObjectCache();
215: }
216:
217: void entityManagerClosed(AbstractEntityManager manager) {
218: assert manager != null;
219: em.remove(manager);
220: }
221: }