001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb3.entity;
023:
024: import java.net.URL;
025: import java.util.ArrayList;
026: import java.util.List;
027: import java.util.Properties;
028: import javax.naming.InitialContext;
029: import javax.persistence.EntityManager;
030: import javax.persistence.EntityManagerFactory;
031: import javax.persistence.spi.PersistenceProvider;
032: import javax.persistence.spi.PersistenceUnitTransactionType;
033: import org.hibernate.ejb.HibernatePersistence;
034: import org.hibernate.ejb.packaging.PersistenceMetadata;
035: import org.jboss.ejb3.DependencyPolicy;
036: import org.jboss.ejb3.DeploymentUnit;
037: import org.jboss.ejb3.Ejb3Deployment;
038: import org.jboss.ejb3.NonSerializableFactory;
039: import org.jboss.logging.Logger;
040:
041: /**
042: * Comment
043: *
044: * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
045: * @version $Revision: 61833 $
046: */
047: public class PersistenceUnitDeployment {
048: private static final Logger log = Logger
049: .getLogger(PersistenceUnitDeployment.class);
050:
051: protected InitialContext initialContext;
052: protected DeploymentUnit di;
053: protected List<String> explicitEntityClasses = new ArrayList<String>();
054: protected ManagedEntityManagerFactory managedFactory;
055: protected EntityManagerFactory actualFactory;
056: protected URL persistenceXmlUrl;
057: protected PersistenceMetadata xml;
058: protected String kernelName;
059: protected Ejb3Deployment deployment;
060: protected boolean scoped;
061:
062: public PersistenceUnitDeployment(InitialContext initialContext,
063: Ejb3Deployment deployment,
064: List<String> explicitEntityClasses, URL persistenceXmlUrl,
065: PersistenceMetadata metadata, String ear, String jar,
066: boolean isScoped) {
067: this .scoped = isScoped;
068: this .deployment = deployment;
069: this .initialContext = initialContext;
070: this .di = deployment.getDeploymentUnit();
071: this .explicitEntityClasses = explicitEntityClasses;
072: this .persistenceXmlUrl = persistenceXmlUrl;
073: xml = metadata;
074: kernelName = "persistence.units:";
075: String name = getEntityManagerName();
076: if (name == null || name.equals(""))
077: throw new RuntimeException(
078: "Empty string is not allowed for a persistence unit. Fix your persistence.xml file");
079: if (ear != null) {
080: kernelName += "ear=" + ear;
081: if (!ear.endsWith(".ear"))
082: kernelName += ".ear";
083: kernelName += ",";
084: }
085: if (isScoped) {
086: kernelName += "jar=" + jar;
087: if (!jar.endsWith(".jar"))
088: kernelName += ".jar";
089: kernelName += ",";
090: }
091: kernelName += "unitName=" + name;
092: }
093:
094: public static String getDefaultKernelName(String unitName) {
095: int hashIndex = unitName.indexOf('#');
096: if (hashIndex != -1) {
097: String relativePath = unitName.substring(3, hashIndex);
098: String name = unitName.substring(hashIndex + 1);
099: return "persistence.units:jar=" + relativePath + ","
100: + "unitName=" + name;
101: }
102: return "persistence.units:unitName=" + unitName;
103: }
104:
105: public boolean isScoped() {
106: return scoped;
107: }
108:
109: public Ejb3Deployment getDeployment() {
110: return deployment;
111: }
112:
113: protected String getJaccContextId() {
114: return di.getShortName();
115: }
116:
117: public EntityManagerFactory getActualFactory() {
118: return actualFactory;
119: }
120:
121: public PersistenceMetadata getXml() {
122: return xml;
123: }
124:
125: public String getKernelName() {
126: return kernelName;
127: }
128:
129: public String getEntityManagerName() {
130: return xml.getName() == null ? "" : xml.getName();
131: }
132:
133: public ManagedEntityManagerFactory getManagedFactory() {
134: if (managedFactory == null)
135: log.warn("managed factory is null, persistence unit "
136: + kernelName + " has not yet been started");
137: return managedFactory;
138: }
139:
140: public void addDependencies(DependencyPolicy policy) {
141: Properties props = getXml().getProps();
142: if (!props
143: .containsKey("jboss.no.implicit.datasource.dependency")) {
144: if (getXml().getJtaDatasource() != null) {
145: String ds = getXml().getJtaDatasource();
146: policy.addDatasource(ds);
147: }
148: if (getXml().getNonJtaDatasource() != null) {
149: String ds = getXml().getNonJtaDatasource();
150: policy.addDatasource(ds);
151: }
152: }
153: for (Object prop : props.keySet()) {
154: String property = (String) prop;
155: if (property.startsWith("jboss.depends")) {
156: policy.addDependency(props.getProperty(property));
157: }
158: }
159:
160: }
161:
162: public void start() throws Exception {
163: log.info("Starting persistence unit " + kernelName);
164:
165: Properties props = new Properties();
166: props.putAll(di.getDefaultPersistenceProperties());
167: props.put(HibernatePersistence.JACC_CONTEXT_ID,
168: getJaccContextId());
169:
170: PersistenceUnitInfoImpl pi = new PersistenceUnitInfoImpl();
171: pi.setClassLoader(di.getClassLoader());
172:
173: ArrayList<URL> jarFiles = new ArrayList<URL>();
174: pi.setJarFiles(jarFiles);
175: pi.setPersistenceProviderClassName(HibernatePersistence.class
176: .getName());
177: log.debug("Found persistence.xml file in EJB3 jar");
178: props.putAll(xml.getProps());
179: pi.setManagedClassnames(xml.getClasses());
180: pi.setPersistenceUnitName(xml.getName());
181: pi.setMappingFileNames(xml.getMappingFiles());
182: pi.setExcludeUnlistedClasses(xml.getExcludeUnlistedClasses());
183: pi.setPersistenceUnitRootUrl(di.getUrl());
184: // PersistenceUnitTransactionType transactionType = PersistenceUnitTransactionType.JTA;
185: // if ("RESOURCE_LOCAL".equals(xml.getTransactionType()))
186: // transactionType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
187: PersistenceUnitTransactionType transactionType = xml
188: .getTransactionType();
189: pi.setTransactionType(transactionType);
190:
191: for (String jar : xml.getJarFiles()) {
192: jarFiles.add(deployment.getDeploymentUnit().getRelativeURL(
193: jar));
194: }
195:
196: if (xml.getProvider() != null)
197: pi.setPersistenceProviderClassName(xml.getProvider());
198: if (explicitEntityClasses.size() > 0) {
199: List<String> classes = pi.getManagedClassNames();
200: if (classes == null)
201: classes = explicitEntityClasses;
202: else
203: classes.addAll(explicitEntityClasses);
204: pi.setManagedClassnames(classes);
205: }
206: if (xml.getJtaDatasource() != null) {
207: pi.setJtaDataSource((javax.sql.DataSource) initialContext
208: .lookup(xml.getJtaDatasource()));
209: } else if (transactionType == PersistenceUnitTransactionType.JTA) {
210: throw new RuntimeException(
211: "You have not defined a jta-data-source for a JTA enabled persistence context named: "
212: + xml.getName());
213: }
214: if (xml.getNonJtaDatasource() != null) {
215: pi
216: .setNonJtaDataSource((javax.sql.DataSource) initialContext
217: .lookup(xml.getNonJtaDatasource()));
218: } else if (transactionType == PersistenceUnitTransactionType.RESOURCE_LOCAL) {
219: throw new RuntimeException(
220: "You have not defined a non-jta-data-source for a RESOURCE_LOCAL enabled persistence context named: "
221: + xml.getName());
222: }
223: pi.setProperties(props);
224:
225: if (pi.getPersistenceUnitName() == null) {
226: throw new RuntimeException(
227: "you must specify a name in persistence.xml");
228: }
229:
230: Class providerClass = Thread.currentThread()
231: .getContextClassLoader().loadClass(
232: pi.getPersistenceProviderClassName());
233:
234: // EJBTHREE-893
235: if (!pi.getProperties().containsKey(
236: "hibernate.session_factory_name")) {
237: pi.getProperties().put("hibernate.session_factory_name",
238: kernelName);
239: }
240:
241: PersistenceProvider pp = (PersistenceProvider) providerClass
242: .newInstance();
243: actualFactory = pp
244: .createContainerEntityManagerFactory(pi, null);
245:
246: managedFactory = new ManagedEntityManagerFactory(actualFactory,
247: kernelName);
248:
249: String entityManagerJndiName = (String) props
250: .get("jboss.entity.manager.jndi.name");
251: if (entityManagerJndiName != null) {
252: EntityManager injectedManager = new TransactionScopedEntityManager(
253: managedFactory);
254: NonSerializableFactory.rebind(initialContext,
255: entityManagerJndiName, injectedManager);
256: }
257: String entityManagerFactoryJndiName = (String) props
258: .get("jboss.entity.manager.factory.jndi.name");
259: if (entityManagerFactoryJndiName != null) {
260: EntityManagerFactory injectedFactory = new InjectedEntityManagerFactory(
261: managedFactory);
262: NonSerializableFactory.rebind(initialContext,
263: entityManagerFactoryJndiName, injectedFactory);
264: }
265: }
266:
267: public void stop() throws Exception {
268: log.info("Stopping persistence unit " + kernelName);
269:
270: String entityManagerJndiName = (String) xml.getProps().get(
271: "jboss.entity.manager.jndi.name");
272: if (entityManagerJndiName != null) {
273: NonSerializableFactory.unbind(initialContext,
274: entityManagerJndiName);
275: }
276: String entityManagerFactoryJndiName = (String) xml.getProps()
277: .get("jboss.entity.manager.factory.jndi.name");
278: if (entityManagerFactoryJndiName != null) {
279: NonSerializableFactory.unbind(initialContext,
280: entityManagerFactoryJndiName);
281: }
282: managedFactory.destroy();
283: }
284:
285: }
|