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