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.injection;
023:
024: import java.lang.reflect.AccessibleObject;
025: import java.lang.reflect.Field;
026: import java.lang.reflect.Method;
027: import java.util.Map;
028: import javax.naming.NameNotFoundException;
029: import javax.persistence.EntityManagerFactory;
030: import javax.persistence.PersistenceUnit;
031: import javax.persistence.PersistenceUnits;
032:
033: import org.hibernate.SessionFactory;
034: import org.jboss.annotation.IgnoreDependency;
035: import org.jboss.ejb3.entity.InjectedEntityManagerFactory;
036: import org.jboss.ejb3.entity.InjectedSessionFactory;
037: import org.jboss.ejb3.entity.ManagedEntityManagerFactory;
038: import org.jboss.ejb3.entity.PersistenceUnitDeployment;
039: import org.jboss.logging.Logger;
040: import org.jboss.metamodel.descriptor.EnvironmentRefGroup;
041: import org.jboss.metamodel.descriptor.PersistenceUnitRef;
042:
043: /**
044: * Searches bean class for all @Inject and create Injectors
045: *
046: * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
047: * @version $Revision: 60233 $
048: */
049: public class PersistenceUnitHandler implements InjectionHandler {
050: private static final Logger log = Logger
051: .getLogger(PersistenceUnitHandler.class);
052:
053: public void loadXml(EnvironmentRefGroup xml,
054: InjectionContainer container) {
055: if (xml == null)
056: return;
057: if (xml.getPersistenceUnitRefs() == null)
058: return;
059:
060: for (PersistenceUnitRef ref : xml.getPersistenceUnitRefs()) {
061: String encName = "env/" + ref.getRefName();
062: // we add injection target no matter what. enc injection might be overridden but
063: // XML injection cannot be overriden
064: Class injectionType = InjectionUtil.injectionTarget(
065: encName, ref, container, container
066: .getEncInjections());
067: if (container.getEncInjectors().containsKey(encName))
068: return;
069: container.getEncInjectors().put(
070: encName,
071: new PuEncInjector(encName, injectionType, ref
072: .getUnitName(), "<persistence-unit-ref>"));
073: try {
074: addPUDependency(ref.getUnitName(), container);
075: } catch (NameNotFoundException e) {
076: throw new RuntimeException(
077: "Illegal <persistence-unit-ref> of "
078: + ref.getRefName() + " :"
079: + e.getMessage());
080: }
081: }
082: }
083:
084: public void handleClassAnnotations(Class clazz,
085: InjectionContainer container) {
086: PersistenceUnits resources = container.getAnnotation(
087: PersistenceUnits.class, clazz);
088: if (resources != null) {
089: for (PersistenceUnit ref : resources.value()) {
090: handleClassAnnotation(ref, container, clazz);
091: }
092: }
093: PersistenceUnit pu = container.getAnnotation(
094: PersistenceUnit.class, clazz);
095: if (pu != null) {
096: handleClassAnnotation(pu, container, clazz);
097: }
098: }
099:
100: private static void handleClassAnnotation(PersistenceUnit ref,
101: InjectionContainer container, Class clazz) {
102: String encName = ref.name();
103: if (encName == null || encName.equals("")) {
104: throw new RuntimeException(
105: "JBoss requires name() for class level @PersistenceUnit");
106: }
107: encName = "env/" + encName;
108: if (container.getEncInjectors().containsKey(encName))
109: return;
110: container.getEncInjectors().put(
111: encName,
112: new PuEncInjector(encName, null, ref.unitName(),
113: "@PersistenceUnit"));
114: try {
115: addPUDependency(ref.unitName(), container);
116: } catch (NameNotFoundException e) {
117: throw new RuntimeException("Illegal @PersistenceUnit on "
118: + clazz.getName() + " of unitname "
119: + ref.unitName() + " :" + e.getMessage());
120: }
121: }
122:
123: public static void addPUDependency(String unitName,
124: InjectionContainer container) throws NameNotFoundException {
125: PersistenceUnitDeployment deployment = null;
126: // look in EAR first
127: deployment = container.getPersistenceUnitDeployment(unitName);
128: if (deployment != null) {
129: container.getDependencyPolicy().addDependency(
130: deployment.getKernelName());
131: log
132: .debug("***** adding PU dependency from located persistence unit: "
133: + deployment.getKernelName());
134: return;
135: }
136: // probably not deployed yet.
137: // todo not sure if we should do this in JBoss 5
138: log
139: .debug("******* could not find PU dependency so adding a default: "
140: + PersistenceUnitDeployment
141: .getDefaultKernelName(unitName));
142: container.getDependencyPolicy().addDependency(
143: PersistenceUnitDeployment
144: .getDefaultKernelName(unitName));
145: }
146:
147: public static ManagedEntityManagerFactory getManagedEntityManagerFactory(
148: InjectionContainer container, String unitName)
149: throws NameNotFoundException {
150: ManagedEntityManagerFactory factory;
151: PersistenceUnitDeployment deployment = container
152: .getPersistenceUnitDeployment(unitName);
153: if (deployment != null) {
154: factory = deployment.getManagedFactory();
155: } else {
156: throw new NameNotFoundException(
157: "Unable to find persistence unit: " + unitName
158: + " for deployment: "
159: + container.getIdentifier());
160: }
161: return factory;
162: }
163:
164: public static EntityManagerFactory getEntityManagerFactory(
165: PersistenceUnit ref, InjectionContainer container)
166: throws NameNotFoundException {
167: return getEntityManagerFactory(ref.unitName(), container);
168: }
169:
170: public static Object getFactory(Class type, String unitName,
171: InjectionContainer container) throws NameNotFoundException {
172: if (type != null
173: && type.getName()
174: .equals(SessionFactory.class.getName()))
175: return getSessionFactory(unitName, container);
176: return getEntityManagerFactory(unitName, container);
177: }
178:
179: public static EntityManagerFactory getEntityManagerFactory(
180: String unitName, InjectionContainer container)
181: throws NameNotFoundException {
182: ManagedEntityManagerFactory managedFactory;
183: PersistenceUnitDeployment deployment = container
184: .getPersistenceUnitDeployment(unitName);
185: if (deployment != null) {
186: managedFactory = deployment.getManagedFactory();
187: } else {
188: return null;
189: }
190: return new InjectedEntityManagerFactory(managedFactory);
191: }
192:
193: private static SessionFactory getSessionFactory(String ref,
194: InjectionContainer container) throws NameNotFoundException {
195: ManagedEntityManagerFactory managedFactory;
196: PersistenceUnitDeployment deployment = container
197: .getPersistenceUnitDeployment(ref);
198: if (deployment != null) {
199: managedFactory = deployment.getManagedFactory();
200: } else {
201: return null;
202: }
203: return new InjectedSessionFactory(managedFactory);
204: }
205:
206: public void handleMethodAnnotations(Method method,
207: InjectionContainer container,
208: Map<AccessibleObject, Injector> injectors) {
209: PersistenceUnit ref = method
210: .getAnnotation(PersistenceUnit.class);
211: if (ref == null)
212: return;
213: if (!method.getName().startsWith("set"))
214: throw new RuntimeException(
215: "@PersistenceUnit can only be used with a set method: "
216: + method);
217: String encName = ref.name();
218: if (encName == null || encName.equals("")) {
219: encName = InjectionUtil.getEncName(method);
220: } else {
221: encName = "env/" + encName;
222: }
223: if (!container.getEncInjectors().containsKey(encName)) {
224: container.getEncInjectors().put(
225: encName,
226: new PuEncInjector(encName, method
227: .getParameterTypes()[0], ref.unitName(),
228: "@PersistenceUnit"));
229: try {
230: if (!method.isAnnotationPresent(IgnoreDependency.class))
231: addPUDependency(ref.unitName(), container);
232: } catch (NameNotFoundException e) {
233: throw new RuntimeException(
234: "Illegal @PersistenceUnit on " + method + " :"
235: + e.getMessage());
236: }
237: }
238:
239: injectors.put(method, new JndiMethodInjector(method, encName,
240: container.getEnc()));
241: }
242:
243: public void handleFieldAnnotations(Field field,
244: InjectionContainer container,
245: Map<AccessibleObject, Injector> injectors) {
246: PersistenceUnit ref = field
247: .getAnnotation(PersistenceUnit.class);
248: if (ref == null)
249: return;
250: String encName = ref.name();
251: if (encName == null || encName.equals("")) {
252: encName = InjectionUtil.getEncName(field);
253: } else {
254: encName = "env/" + encName;
255: }
256: if (!container.getEncInjectors().containsKey(encName)) {
257: container.getEncInjectors().put(
258: encName,
259: new PuEncInjector(encName, field.getType(), ref
260: .unitName(), "@PersistenceUnit"));
261: try {
262: if (!field.isAnnotationPresent(IgnoreDependency.class))
263: addPUDependency(ref.unitName(), container);
264: } catch (NameNotFoundException e) {
265: throw new RuntimeException(
266: "Illegal @PersistenceUnit on " + field + " :"
267: + e.getMessage());
268: }
269: }
270:
271: injectors.put(field, new JndiFieldInjector(field, encName,
272: container.getEnc()));
273: }
274: }
|