KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb3 > mdb > ConsumerContainer


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb3.mdb;
23
24 import java.lang.reflect.InvocationTargetException JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Hashtable JavaDoc;
30 import java.util.Map JavaDoc;
31
32 import javax.ejb.ActivationConfigProperty JavaDoc;
33 import javax.ejb.EJBException JavaDoc;
34 import javax.ejb.MessageDriven JavaDoc;
35 import javax.ejb.Timer JavaDoc;
36 import javax.ejb.TimerService JavaDoc;
37 import javax.ejb.TransactionAttribute JavaDoc;
38 import javax.ejb.TransactionAttributeType JavaDoc;
39 import javax.ejb.TransactionManagement JavaDoc;
40 import javax.ejb.TransactionManagementType JavaDoc;
41 import javax.jms.Connection JavaDoc;
42 import javax.jms.ConnectionConsumer JavaDoc;
43 import javax.jms.Destination JavaDoc;
44 import javax.jms.ExceptionListener JavaDoc;
45 import javax.jms.JMSException JavaDoc;
46 import javax.jms.Message JavaDoc;
47 import javax.jms.MessageListener JavaDoc;
48 import javax.jms.ObjectMessage JavaDoc;
49 import javax.jms.Queue JavaDoc;
50 import javax.jms.QueueConnection JavaDoc;
51 import javax.jms.ServerSessionPool JavaDoc;
52 import javax.jms.Topic JavaDoc;
53 import javax.jms.TopicConnection JavaDoc;
54 import javax.management.MBeanServer JavaDoc;
55 import javax.management.ObjectName JavaDoc;
56 import javax.naming.Context JavaDoc;
57 import javax.naming.NamingException JavaDoc;
58 import javax.transaction.Transaction JavaDoc;
59 import org.jboss.annotation.ejb.AcknowledgementMode;
60 import org.jboss.annotation.ejb.Consumer;
61 import org.jboss.annotation.ejb.DefaultActivationSpecs;
62 import org.jboss.annotation.ejb.Durability;
63 import org.jboss.annotation.ejb.Local;
64 import org.jboss.annotation.ejb.MessageProperties;
65 import org.jboss.annotation.ejb.MessagePropertiesImpl;
66 import org.jboss.annotation.ejb.Producer;
67 import org.jboss.annotation.ejb.Producers;
68 import org.jboss.aop.AspectManager;
69 import org.jboss.aop.MethodInfo;
70 import org.jboss.aop.advice.Interceptor;
71 import org.jboss.aop.joinpoint.Invocation;
72 import org.jboss.aop.joinpoint.InvocationResponse;
73 import org.jboss.aop.joinpoint.MethodInvocation;
74 import org.jboss.aop.util.MethodHashing;
75 import org.jboss.aop.util.PayloadKey;
76 import org.jboss.deployment.DeploymentException;
77 import org.jboss.ejb3.Container;
78 import org.jboss.ejb3.EJBContainer;
79 import org.jboss.ejb3.EJBContainerInvocation;
80 import org.jboss.ejb3.Ejb3Module;
81 import org.jboss.ejb3.ProxyFactoryHelper;
82 import org.jboss.ejb3.ThreadLocalENCFactory;
83 import org.jboss.ejb3.Ejb3Deployment;
84 import org.jboss.ejb3.interceptor.InterceptorInfoRepository;
85 import org.jboss.ejb3.mdb.inflow.JBossMessageEndpointFactory;
86 import org.jboss.ejb3.timerservice.TimedObjectInvoker;
87 import org.jboss.ejb3.timerservice.TimerServiceFactory;
88 import org.jboss.ejb3.tx.TxUtil;
89 import org.jboss.jms.ConnectionFactoryHelper;
90 import org.jboss.jms.asf.ServerSessionPoolFactory;
91 import org.jboss.jms.asf.StdServerSessionPool;
92 import org.jboss.jms.jndi.JMSProviderAdapter;
93 import org.jboss.logging.Logger;
94
95 /**
96  * Comment
97  *
98  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
99  * @version $Revision: 54985 $
100  */

101 public class ConsumerContainer extends MessagingContainer
102 {
103    private static final Logger log = Logger.getLogger(ConsumerContainer.class);
104    
105    protected Class JavaDoc messagingType = null;
106    protected Method JavaDoc ON_MESSAGE;
107    
108    protected ArrayList JavaDoc<ProducerFactory> producers = new ArrayList JavaDoc<ProducerFactory>();
109    
110    /**
111     * Default destination type. Used when no message-driven-destination is given
112     * in ejb-jar, and a lookup of destinationJNDI from jboss.xml is not
113     * successfull. Default value: javax.jms.Topic.
114     */

115    protected final static String JavaDoc DEFAULT_DESTINATION_TYPE = "javax.jms.Topic";
116
117
118    /**
119     * This is needed because API changed from JBoss 4.0.1sp1 to 4.0.2
120     * TODO remove this after 4.0.2 is out.
121     */

122    public static final String JavaDoc CONSUMER_MESSAGE = "CONSUMER_MESSAGE";
123
124
125    public ConsumerContainer(String JavaDoc ejbName, AspectManager manager, ClassLoader JavaDoc cl, String JavaDoc beanClassName,
126                             Hashtable JavaDoc ctxProperties, InterceptorInfoRepository interceptorRepository,
127                             Ejb3Deployment deployment)
128    {
129       super(ejbName, manager, cl, beanClassName, ctxProperties, interceptorRepository, deployment);
130    }
131    
132    public InvocationResponse dynamicInvoke(Invocation invocation) throws Throwable JavaDoc
133    {
134       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
135       EJBContainerInvocation newSi = null;
136       ThreadLocalENCFactory.push(enc);
137       try
138       {
139          Thread.currentThread().setContextClassLoader(classloader);
140          MethodInvocation si = (MethodInvocation) invocation;
141          MethodInfo info = (MethodInfo) methodInterceptors.get(si.getMethodHash());
142          if (info == null)
143          {
144             throw new RuntimeException JavaDoc("Could not resolve beanClass method from proxy call");
145          }
146        
147          Interceptor[] aspects = info.getInterceptors();
148          newSi = new EJBContainerInvocation(info, aspects);
149          newSi.setArguments(si.getArguments());
150          newSi.setMetaData(si.getMetaData());
151          newSi.setAdvisor(this);
152
153          InvocationResponse response = new InvocationResponse(newSi.invokeNext());
154          response.setContextInfo(newSi.getResponseContextInfo());
155          return response;
156       }
157       finally
158       {
159          Thread.currentThread().setContextClassLoader(oldLoader);
160          ThreadLocalENCFactory.pop();
161       }
162    }
163    
164    protected Method JavaDoc getOnMessage()
165    {
166       if (ON_MESSAGE != null)
167          return ON_MESSAGE;
168       
169       try
170       {
171          final Class JavaDoc arg = Message JavaDoc.class;
172          ON_MESSAGE = javax.jms.MessageListener JavaDoc.class.getMethod("onMessage", new Class JavaDoc[]{arg});
173       }
174       catch (Exception JavaDoc e)
175       {
176          e.printStackTrace();
177          throw new ExceptionInInitializerError JavaDoc(e);
178       }
179
180       return ON_MESSAGE;
181    }
182    
183    public Object JavaDoc localInvoke(MethodInfo info, Object JavaDoc[] args) throws Throwable JavaDoc
184    {
185       if (info.getAdvisedMethod().equals(getOnMessage()))
186       {
187          ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
188          ThreadLocalENCFactory.push(enc);
189          
190          try
191          {
192             Message JavaDoc message = (Message JavaDoc)args[0];
193             MethodInvocation invocation = (MethodInvocation) ((ObjectMessage JavaDoc) message).getObject();
194             invocation.getMetaData().addMetaData(CONSUMER_MESSAGE, CONSUMER_MESSAGE, message, PayloadKey.TRANSIENT);
195             return this.dynamicInvoke(invocation);
196          }
197          finally
198          {
199             Thread.currentThread().setContextClassLoader(oldLoader);
200             ThreadLocalENCFactory.pop();
201          }
202       }
203       else
204          return super.localInvoke(info, args);
205    }
206    
207    public Class JavaDoc getMessagingType()
208    {
209       return javax.jms.MessageListener JavaDoc.class;
210    }
211    
212    public MethodInfo getMethodInfo(Method JavaDoc method)
213    {
214       MethodInfo info = new MethodInfo();
215       info.setAdvisor(this);
216       info.setAdvisedMethod(method);
217       info.setUnadvisedMethod(method);
218     
219       return info;
220    }
221  
222    public Map JavaDoc getActivationConfigProperties()
223    {
224       HashMap JavaDoc result = new HashMap JavaDoc();
225       Consumer JavaDoc annotation = (Consumer JavaDoc) resolveAnnotation(Consumer JavaDoc.class);
226       for (ActivationConfigProperty JavaDoc property : annotation.activationConfig())
227       {
228          addActivationSpecProperty(result, property);
229       }
230       
231       DefaultActivationSpecs defaultSpecsAnnotation = (DefaultActivationSpecs)resolveAnnotation(DefaultActivationSpecs.class);
232       if (defaultSpecsAnnotation != null)
233       {
234          for (ActivationConfigProperty JavaDoc property : defaultSpecsAnnotation.value())
235          {
236             addActivationSpecProperty(result, property);
237          }
238       }
239       
240       return result;
241    }
242
243
244    /**
245     * Initialize the container invoker. Sets up a connection, a server session
246     * pool and a connection consumer for the configured destination.
247     * <p/>
248     * Any JMSExceptions produced while initializing will be assumed to be
249     * caused due to JMS Provider failure.
250     *
251     * @throws Exception Failed to initalize.
252     */

253    public void start() throws Exception JavaDoc
254    {
255       super.start();
256       
257       registerProducers();
258    }
259
260    public Class JavaDoc[] getProducerInterfaces(Container container1)
261    {
262       Class JavaDoc beanClass = container1.getBeanClass();
263       Class JavaDoc[] interfaces = beanClass.getInterfaces();
264       if (interfaces.length == 0) throw new RuntimeException JavaDoc("Bean class must implement at least one interface: " + beanClass.getName());
265       if (interfaces.length == 1)
266       {
267          return interfaces;
268       }
269       ArrayList JavaDoc localInterfaces = new ArrayList JavaDoc();
270       for (int i = 0; i < interfaces.length; i++)
271       {
272          if (interfaces[i].isAnnotationPresent(Producer.class))
273          {
274             localInterfaces.add(interfaces[i]);
275          }
276       }
277       Producer annotation = (Producer)resolveAnnotation(Producer.class);
278       if (annotation != null)
279       {
280          Class JavaDoc producer = annotation.producer();
281          if (producer != null)
282             localInterfaces.add(producer);
283       }
284       
285       Producers producersAnnotation = (Producers)resolveAnnotation(Producers.class);
286       if (producersAnnotation != null)
287       {
288          for (Producer producerAnnotation : producersAnnotation.value())
289          {
290             Class JavaDoc producer = producerAnnotation.producer();
291             if (producer != null)
292                localInterfaces.add(producer);
293          }
294       }
295       
296       if (localInterfaces.size() == 0) return null;
297       interfaces = (Class JavaDoc[]) localInterfaces.toArray(new Class JavaDoc[localInterfaces.size()]);
298       return interfaces;
299    }
300
301    protected void registerProducers() throws Exception JavaDoc
302    {
303       Destination JavaDoc dest = (Destination JavaDoc) getInitialContext().lookup(getDestination());
304       Class JavaDoc[] producers = getProducerInterfaces(this);
305       MessageProperties props = (MessageProperties) resolveAnnotation(MessageProperties.class);
306       if (props == null) props = new MessagePropertiesImpl();
307       for (Class JavaDoc producer : producers)
308       {
309          log.debug("Producer: " + producer.getName());
310          ProducerFactory producerFactory = null;
311          if (producer.isAnnotationPresent(Local.class))
312          {
313             producerFactory = new LocalProducerFactory(this, producer, props, dest, getInitialContext(), initialContextProperties);
314          }
315          else
316          {
317             producerFactory = new RemoteProducerFactory(this, producer, props, dest, getInitialContext(), initialContextProperties);
318          }
319          this.producers.add(producerFactory);
320          producerFactory.start();
321       }
322    }
323
324    protected void unregisterProducers() throws Exception JavaDoc
325    {
326       for (ProducerFactory factory : producers)
327       {
328          factory.stop();
329       }
330    }
331    
332    protected void populateActivationSpec()
333    {
334       DefaultActivationSpecs defaultSpecs = (DefaultActivationSpecs) resolveAnnotation(DefaultActivationSpecs.class);
335       if (defaultSpecs != null)
336       {
337          activationSpec.merge(defaultSpecs.value());
338       }
339
340       Consumer JavaDoc md = (Consumer JavaDoc) resolveAnnotation(Consumer JavaDoc.class);
341       activationSpec.merge(md.activationConfig());
342    }
343
344    public void stop() throws Exception JavaDoc
345    {
346       super.stop();
347       unregisterProducers();
348    }
349 }
350
Popular Tags