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 org.jboss.metamodel.descriptor.PersistenceContextRef;
025: import org.jboss.logging.Logger;
026: import org.jboss.annotation.IgnoreDependency;
027: import org.jboss.metamodel.descriptor.EnvironmentRefGroup;
028:
029: import javax.naming.NameNotFoundException;
030: import javax.persistence.PersistenceContext;
031: import javax.persistence.PersistenceContextType;
032: import javax.persistence.PersistenceContexts;
033: import java.lang.reflect.AccessibleObject;
034: import java.lang.reflect.Field;
035: import java.lang.reflect.Method;
036: import java.util.Map;
037:
038: /**
039: * Searches bean class for all
040: *
041: * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
042: * @version $Revision: 60233 $
043: * @Inject and create Injectors
044: */
045: public class PersistenceContextHandler implements InjectionHandler {
046: private static final Logger log = Logger
047: .getLogger(PersistenceContextHandler.class);
048:
049: public void loadXml(EnvironmentRefGroup xml,
050: InjectionContainer container) {
051: if (xml == null)
052: return;
053: if (xml.getPersistenceContextRefs() == null)
054: return;
055: for (PersistenceContextRef ref : xml
056: .getPersistenceContextRefs()) {
057: String encName = "env/" + ref.getRefName();
058: // we add injection target no matter what. enc injection might be overridden but
059: // XML injection cannot be overriden
060: Class injectionType = InjectionUtil.injectionTarget(
061: encName, ref, container, container
062: .getEncInjections());
063:
064: if (container.getEncInjectors().containsKey(encName))
065: continue;
066: // add it to list of
067: String error = "unable to load <persistence-context-ref> for unitName: "
068: + ref.getUnitName()
069: + " <ref-name>: "
070: + ref.getRefName();
071: PersistenceContextType type = ref
072: .getPersistenceContextType();
073: String unitName = ref.getUnitName();
074: container.getEncInjectors().put(
075: encName,
076: new PcEncInjector(encName, unitName, type,
077: injectionType, error));
078: try {
079: PersistenceUnitHandler.addPUDependency(ref
080: .getUnitName(), container);
081: } catch (NameNotFoundException e) {
082: throw new RuntimeException(
083: "Illegal <persistence-context-ref> of "
084: + ref.getRefName() + " :"
085: + e.getMessage());
086: }
087: }
088: }
089:
090: public void handleClassAnnotations(Class clazz,
091: InjectionContainer container) {
092: PersistenceContexts resources = container.getAnnotation(
093: PersistenceContexts.class, clazz);
094: if (resources != null) {
095: for (PersistenceContext ref : resources.value()) {
096: loadPersistenceContextClassAnnotation(ref, container,
097: clazz);
098: }
099: }
100: PersistenceContext pc = container.getAnnotation(
101: PersistenceContext.class, clazz);
102:
103: if (pc != null) {
104: loadPersistenceContextClassAnnotation(pc, container, clazz);
105: }
106:
107: }
108:
109: private static void loadPersistenceContextClassAnnotation(
110: PersistenceContext ref, InjectionContainer container,
111: Class clazz) {
112: String encName = ref.name();
113: if (encName == null || encName.equals("")) {
114: throw new RuntimeException(
115: "JBoss requires name() for class level @PersistenceContext");
116: }
117: encName = "env/" + ref.name();
118: if (container.getEncInjectors().containsKey(encName))
119: return;
120:
121: String error = "Unable to load class-level @PersistenceContext("
122: + ref.unitName() + ") on " + container.getIdentifier();
123: container.getEncInjectors().put(
124: encName,
125: new PcEncInjector(encName, ref.unitName(), ref.type(),
126: null, error));
127: try {
128: PersistenceUnitHandler.addPUDependency(ref.unitName(),
129: container);
130: } catch (NameNotFoundException e) {
131: throw new RuntimeException("Illegal @PersistenceUnit on "
132: + clazz.getName() + " of unitname "
133: + ref.unitName() + " :" + e.getMessage());
134: }
135: }
136:
137: public void handleMethodAnnotations(Method method,
138: InjectionContainer container,
139: Map<AccessibleObject, Injector> injectors) {
140: PersistenceContext ref = method
141: .getAnnotation(PersistenceContext.class);
142: if (ref == null)
143: return;
144: if (!method.getName().startsWith("set"))
145: throw new RuntimeException(
146: "@PersistenceUnit can only be used with a set method: "
147: + method);
148:
149: String encName = ref.name();
150: if (encName == null || encName.equals("")) {
151: encName = InjectionUtil.getEncName(method);
152: } else {
153: encName = "env/" + ref.name();
154: }
155: if (!container.getEncInjectors().containsKey(encName)) {
156: try {
157: if (!method.isAnnotationPresent(IgnoreDependency.class))
158: PersistenceUnitHandler.addPUDependency(ref
159: .unitName(), container);
160: } catch (NameNotFoundException e) {
161: throw new RuntimeException(
162: "Illegal @PersistenceUnit on " + method + " :"
163: + e.getMessage());
164: }
165: String error = "@PersistenceContext(name='" + encName
166: + "',unitName='" + ref.unitName() + "') on EJB: "
167: + container.getIdentifier()
168: + " failed to inject on method "
169: + method.toString();
170: container.getEncInjectors().put(
171: encName,
172: new PcEncInjector(encName, ref.unitName(), ref
173: .type(), method.getParameterTypes()[0],
174: error));
175: }
176: injectors.put(method, new JndiMethodInjector(method, encName,
177: container.getEnc()));
178: }
179:
180: public void handleFieldAnnotations(Field field,
181: InjectionContainer container,
182: Map<AccessibleObject, Injector> injectors) {
183: PersistenceContext ref = field
184: .getAnnotation(PersistenceContext.class);
185: if (ref == null)
186: return;
187:
188: String encName = ref.name();
189: if (encName == null || encName.equals("")) {
190: encName = InjectionUtil.getEncName(field);
191: } else {
192: encName = "env/" + ref.name();
193: }
194: if (!container.getEncInjectors().containsKey(encName)) {
195: try {
196: if (!field.isAnnotationPresent(IgnoreDependency.class))
197: PersistenceUnitHandler.addPUDependency(ref
198: .unitName(), container);
199: } catch (NameNotFoundException e) {
200: throw new RuntimeException(
201: "Illegal @PersistenceUnit on " + field + " :"
202: + e.getMessage());
203: }
204: String error = "@PersistenceContext(name='" + encName
205: + "',unitName='" + ref.unitName() + "') on EJB: "
206: + container.getIdentifier()
207: + " failed to inject on field " + field.toString();
208: container.getEncInjectors().put(
209: encName,
210: new PcEncInjector(encName, ref.unitName(), ref
211: .type(), field.getType(), error));
212: }
213: injectors.put(field, new JndiFieldInjector(field, encName,
214: container.getEnc()));
215: }
216: }
|