KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > inflow > JBossMessageEndpointFactory


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.ejb.plugins.inflow;
23
24 import java.lang.reflect.Method JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Iterator JavaDoc;
29
30 import javax.ejb.EJBMetaData JavaDoc;
31 import javax.management.ObjectName JavaDoc;
32 import javax.resource.spi.ActivationSpec JavaDoc;
33 import javax.resource.spi.UnavailableException JavaDoc;
34 import javax.resource.spi.endpoint.MessageEndpoint JavaDoc;
35 import javax.resource.spi.endpoint.MessageEndpointFactory JavaDoc;
36 import javax.transaction.xa.XAResource JavaDoc;
37
38 import org.jboss.deployment.DeploymentException;
39 import org.jboss.ejb.Container;
40 import org.jboss.ejb.EJBProxyFactory;
41 import org.jboss.ejb.MessageDrivenContainer;
42 import org.jboss.invocation.Invocation;
43 import org.jboss.invocation.InvocationType;
44 import org.jboss.invocation.InvokerInterceptor;
45 import org.jboss.metadata.ActivationConfigPropertyMetaData;
46 import org.jboss.metadata.InvokerProxyBindingMetaData;
47 import org.jboss.metadata.MessageDestinationMetaData;
48 import org.jboss.metadata.MessageDrivenMetaData;
49 import org.jboss.metadata.MetaData;
50 import org.jboss.mx.util.JMXExceptionDecoder;
51 import org.jboss.proxy.GenericProxyFactory;
52 import org.jboss.system.ServiceMBeanSupport;
53 import org.w3c.dom.Element JavaDoc;
54 import org.w3c.dom.Node JavaDoc;
55 import org.w3c.dom.NodeList JavaDoc;
56
57 import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
58
59 /**
60  * EJBProxyFactory for inflow message driven beans
61  *
62  * @jmx:mbean extends="org.jboss.system.ServiceMBean"
63  *
64  * @author <a HREF="mailto:adrian@jboss.com">Adrian Brock</a> .
65  * @version <tt>$Revision: 37459 $</tt>
66  */

67 public class JBossMessageEndpointFactory
68    extends ServiceMBeanSupport
69    implements EJBProxyFactory, MessageEndpointFactory JavaDoc, JBossMessageEndpointFactoryMBean
70 {
71    // Constants -----------------------------------------------------
72

73    // Attributes ----------------------------------------------------
74

75    /** Whether trace is enabled */
76    protected boolean trace = log.isTraceEnabled();
77    
78    /** Our container */
79    protected MessageDrivenContainer container;
80    
81    /** Our meta data */
82    protected MessageDrivenMetaData metaData;
83    
84    /** The invoker binding */
85    protected String JavaDoc invokerBinding;
86    
87    /** The invoker meta data */
88    protected InvokerProxyBindingMetaData invokerMetaData;
89    
90    /** The activation properties */
91    protected HashMap JavaDoc properties = new HashMap JavaDoc();
92    
93    /** The proxy factory */
94    protected GenericProxyFactory proxyFactory = new GenericProxyFactory();
95    
96    /** The messaging type class */
97    protected Class JavaDoc messagingTypeClass;
98    
99    /** The resource adapter name */
100    protected String JavaDoc resourceAdapterName;
101    
102    /** The resource adapter object name */
103    protected ObjectName JavaDoc resourceAdapterObjectName;
104    
105    /** The activation spec */
106    protected ActivationSpec JavaDoc activationSpec;
107    
108    /** The interceptors */
109    protected ArrayList JavaDoc interceptors;
110    
111    /** The interfaces */
112    protected Class JavaDoc[] interfaces;
113    
114    /** The next proxy id */
115    protected SynchronizedInt nextProxyId = new SynchronizedInt(0);
116    
117    // Static --------------------------------------------------------
118

119    /** The signature for createActivationSpec */
120    protected String JavaDoc[] createActivationSpecSig = new String JavaDoc[]
121    {
122       Class JavaDoc.class.getName(),
123       Collection JavaDoc.class.getName()
124    };
125    
126    /** The signature for activate/deactivateEndpint */
127    protected String JavaDoc[] activationSig = new String JavaDoc[]
128    {
129       MessageEndpointFactory JavaDoc.class.getName(),
130       ActivationSpec JavaDoc.class.getName()
131    };
132          
133    // Constructors --------------------------------------------------
134

135    // Public --------------------------------------------------------
136

137    /**
138     * Get the message driven container
139     *
140     * @return the container
141     */

142    public MessageDrivenContainer getContainer()
143    {
144       return container;
145    }
146    
147    /**
148     * Display the configuration
149     *
150     * @jmx:managed-attribute
151     *
152     * @return the configuration
153     */

154    public String JavaDoc getConfig()
155    {
156       return toString();
157    }
158    
159    // MessageEndpointFactory implementation -------------------------
160

161    public MessageEndpoint JavaDoc createEndpoint(XAResource JavaDoc resource) throws UnavailableException JavaDoc
162    {
163       trace = log.isTraceEnabled();
164       
165       if (getState() != STARTED && getState() != STARTING)
166          throw new UnavailableException JavaDoc("The container is not started");
167       
168       HashMap JavaDoc context = new HashMap JavaDoc();
169       context.put(MessageEndpointInterceptor.MESSAGE_ENDPOINT_FACTORY, this);
170       context.put(MessageEndpointInterceptor.MESSAGE_ENDPOINT_XARESOURCE, resource);
171
172       String JavaDoc ejbName = container.getBeanMetaData().getContainerObjectNameJndiName();
173
174       if (trace)
175          log.trace("createEndpoint " + this + " xaResource=" + resource);
176       
177       MessageEndpoint JavaDoc endpoint = (MessageEndpoint JavaDoc) proxyFactory.createProxy
178       (
179          ejbName + "@" + nextProxyId.increment(),
180          container.getServiceName(),
181          InvokerInterceptor.getLocal(),
182          null,
183          null,
184          interceptors,
185          container.getClassLoader(),
186          interfaces,
187          context
188       );
189       
190       if (trace)
191          log.trace("Created endpoint " + endpoint + " from " + this);
192
193       return endpoint;
194    }
195
196    public boolean isDeliveryTransacted(Method JavaDoc method) throws NoSuchMethodException JavaDoc
197    {
198       boolean result = false;
199       int transType = metaData.getMethodTransactionType(method.getName(), method.getParameterTypes(), InvocationType.LOCAL);
200       if (transType == MetaData.TX_REQUIRED)
201          result = true;
202       if (trace)
203          log.trace("isDeliveryTransacted " + container.getBeanMetaData().getContainerObjectNameJndiName() + " method=" + method + " result=" + result);
204       return result;
205    }
206    
207    // ServiceMBeanSupport overrides ---------------------------------
208

209    protected void startService() throws Exception JavaDoc
210    {
211       // Lets take a reference to our metadata
212
metaData = (MessageDrivenMetaData) container.getBeanMetaData();
213       // Resolve the message listener
214
resolveMessageListener();
215       // Resolve the resource adapter
216
resolveResourceAdapter();
217       // Create the activation config
218
createActivationSpec();
219       // Set up proxy parameters
220
setupProxyParameters();
221       // Activate
222
activate();
223    }
224    
225    protected void stopService() throws Exception JavaDoc
226    {
227       // Deactivate
228
deactivate();
229    }
230    
231    // EJBProxyFactory implementation --------------------------------
232

233    public boolean isIdentical(Container container, Invocation mi)
234    {
235       throw new Error JavaDoc("Not valid for MessageDriven beans");
236    }
237    
238    public Object JavaDoc getEJBHome()
239    {
240       throw new Error JavaDoc("Not valid for MessageDriven beans");
241    }
242    
243    public EJBMetaData JavaDoc getEJBMetaData()
244    {
245       throw new Error JavaDoc("Not valid for MessageDriven beans");
246    }
247    
248    public Collection JavaDoc getEntityCollection(Collection JavaDoc c)
249    {
250       throw new Error JavaDoc("Not valid for MessageDriven beans");
251    }
252    
253    public Object JavaDoc getEntityEJBObject(Object JavaDoc id)
254    {
255       throw new Error JavaDoc("Not valid for MessageDriven beans");
256    }
257    
258    public Object JavaDoc getStatefulSessionEJBObject(Object JavaDoc id)
259    {
260       throw new Error JavaDoc("Not valid for MessageDriven beans");
261    }
262    
263    public Object JavaDoc getStatelessSessionEJBObject()
264    {
265       throw new Error JavaDoc("Not valid for MessageDriven beans");
266    }
267    
268    public void setInvokerBinding(String JavaDoc binding)
269    {
270       this.invokerBinding = binding;
271    }
272    
273    public void setInvokerMetaData(InvokerProxyBindingMetaData imd)
274    {
275       this.invokerMetaData = imd;
276    }
277    
278    // ContainerService implementation -------------------------------
279

280    /**
281     * Set the container for which this is an invoker to.
282     *
283     * @param container The container for which this is an invoker to.
284     */

285    public void setContainer(final Container container)
286    {
287       this.container = (MessageDrivenContainer) container;
288    }
289    
290    // Object overrides ----------------------------------------------
291

292    /**
293     * Return a string representation of the current config state.
294     */

295    public String JavaDoc toString()
296    {
297       StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(100);
298       buffer.append(super.toString());
299       buffer.append("{ resourceAdapter=").append(resourceAdapterObjectName);
300       buffer.append(", messagingType=").append(messagingTypeClass.getName());
301       buffer.append(", ejbName=").append(container.getBeanMetaData().getContainerObjectNameJndiName());
302       buffer.append(", activationConfig=").append(properties.values());
303       buffer.append(", activationSpec=").append(activationSpec);
304       buffer.append("}");
305       return buffer.toString();
306    }
307    
308    // Protected -----------------------------------------------------
309

310    /**
311     * Resolve message listener class
312     *
313     * @throws DeploymentException for any error
314     */

315    protected void resolveMessageListener() throws DeploymentException
316    {
317       String JavaDoc messagingType = metaData.getMessagingType();
318       try
319       {
320          messagingTypeClass = GetTCLAction.getContextClassLoader().loadClass(messagingType);
321       }
322       catch (Exception JavaDoc e)
323       {
324          DeploymentException.rethrowAsDeploymentException("Could not load messaging-type class " + messagingType, e);
325       }
326    }
327
328    /**
329     * Resolve the resource adapter name
330     *
331     * @return the resource adapter name
332     * @throws DeploymentException for any error
333     */

334    protected String JavaDoc resolveResourceAdapterName() throws DeploymentException
335    {
336       return metaData.getResourceAdapterName();
337    }
338
339    /**
340     * Resolve the resource adapter
341     *
342     * @throws DeploymentException for any error
343     */

344    protected void resolveResourceAdapter() throws DeploymentException
345    {
346       resourceAdapterName = resolveResourceAdapterName();
347       try
348       {
349          resourceAdapterObjectName = new ObjectName JavaDoc("jboss.jca:service=RARDeployment,name='" + resourceAdapterName + "'");
350          int state = ((Integer JavaDoc) server.getAttribute(resourceAdapterObjectName, "State")).intValue();
351          if (state != STARTED)
352             throw new DeploymentException("The resource adapter is not started " + resourceAdapterName);
353       }
354       catch (Exception JavaDoc e)
355       {
356          DeploymentException.rethrowAsDeploymentException("Cannot locate resource adapter deployment " + resourceAdapterName, e);
357       }
358    }
359    
360    /**
361     * Set up the proxy parametrs
362     *
363     * @throws DeploymentException
364     */

365    protected void setupProxyParameters() throws DeploymentException
366    {
367       // Set the interfaces
368
interfaces = new Class JavaDoc[] { MessageEndpoint JavaDoc.class, messagingTypeClass };
369       
370       // Set the interceptors
371
interceptors = new ArrayList JavaDoc();
372       Element JavaDoc proxyConfig = invokerMetaData.getProxyFactoryConfig();
373       Element JavaDoc endpointInterceptors = MetaData.getOptionalChild(proxyConfig, "endpoint-interceptors", null);
374       if (endpointInterceptors == null)
375          throw new DeploymentException("No endpoint interceptors found");
376       else
377       {
378          NodeList JavaDoc children = endpointInterceptors.getElementsByTagName("interceptor");
379          for (int i = 0; i < children.getLength(); ++i)
380          {
381             Node JavaDoc currentChild = children.item(i);
382             if (currentChild.getNodeType() == Node.ELEMENT_NODE)
383             {
384                Element JavaDoc interceptor = (Element JavaDoc) children.item(i);
385                String JavaDoc className = MetaData.getElementContent(interceptor);
386                try
387                {
388                   Class JavaDoc clazz = container.getClassLoader().loadClass(className);
389                   interceptors.add(clazz);
390                }
391                catch (Throwable JavaDoc t)
392                {
393                   DeploymentException.rethrowAsDeploymentException("Error loading interceptor class " + className, t);
394                }
395             }
396          }
397       }
398    }
399    
400    /**
401     * Add activation config properties
402     *
403     * @throws DeploymentException for any error
404     */

405    protected void augmentActivationConfigProperties() throws DeploymentException
406    {
407       // Allow activation config properties from invoker proxy binding
408
Element JavaDoc proxyConfig = invokerMetaData.getProxyFactoryConfig();
409       Element JavaDoc activationConfig = MetaData.getOptionalChild(proxyConfig, "activation-config");
410       if (activationConfig != null)
411       {
412          Iterator JavaDoc iterator = MetaData.getChildrenByTagName(activationConfig, "activation-config-property");
413          while (iterator.hasNext())
414          {
415             Element JavaDoc resourceRef = (Element JavaDoc) iterator.next();
416             ActivationConfigPropertyMetaData metaData = new ActivationConfigPropertyMetaData();
417             metaData.importXml(resourceRef);
418             if (properties.containsKey(metaData.getName()) == false)
419                properties.put(metaData.getName(), metaData);
420          }
421       }
422       
423       // Message Destination Link
424
String JavaDoc link = metaData.getDestinationLink();
425       if (link != null)
426       {
427          link = link.trim();
428          if (link.length() > 0)
429          {
430             if (properties.containsKey("destination"))
431                log.warn("Ignoring message-destination-link '" + link + "' when the destination " +
432                   "is already in the activation-config.");
433             else
434             {
435                MessageDestinationMetaData destinationMetaData = container.getMessageDestination(link);
436                if (destinationMetaData == null)
437                   throw new DeploymentException("Unresolved message-destination-link '" + link + "' no message-destination in ejb-jar.xml");
438                String JavaDoc jndiName = destinationMetaData.getJNDIName();
439                if (jndiName == null)
440                   throw new DeploymentException("The message-destination '" + link + "' has no jndi-name in jboss.xml");
441                properties.put("destination", jndiName);
442             }
443          }
444       }
445    }
446    
447    /**
448     * Create the activation spec
449     *
450     * @throws DeploymentException for any error
451     */

452    protected void createActivationSpec() throws DeploymentException
453    {
454       properties = new HashMap JavaDoc(metaData.getActivationConfigProperties());
455       augmentActivationConfigProperties();
456       
457       Object JavaDoc[] params = new Object JavaDoc[]
458       {
459          messagingTypeClass,
460          properties.values()
461       };
462       try
463       {
464          activationSpec = (ActivationSpec JavaDoc) server.invoke(resourceAdapterObjectName, "createActivationSpec", params, createActivationSpecSig);
465       }
466       catch (Throwable JavaDoc t)
467       {
468          t = JMXExceptionDecoder.decode(t);
469          DeploymentException.rethrowAsDeploymentException("Unable to create activation spec ra=" + resourceAdapterObjectName +
470                " messaging-type=" + messagingTypeClass.getName() + " properties=" + metaData.getActivationConfigProperties(), t);
471       }
472    }
473    
474    /**
475     * Activate
476     *
477     * @throws DeploymentException for any error
478     */

479    protected void activate() throws DeploymentException
480    {
481       Object JavaDoc[] params = new Object JavaDoc[] { this, activationSpec };
482       try
483       {
484          server.invoke(resourceAdapterObjectName, "endpointActivation", params, activationSig);
485       }
486       catch (Throwable JavaDoc t)
487       {
488          t = JMXExceptionDecoder.decode(t);
489          DeploymentException.rethrowAsDeploymentException("Endpoint activation failed ra=" + resourceAdapterObjectName +
490                " activationSpec=" + activationSpec, t);
491       }
492    }
493    
494    /**
495     * Deactivate
496     */

497    protected void deactivate()
498    {
499       Object JavaDoc[] params = new Object JavaDoc[] { this, activationSpec };
500       try
501       {
502          server.invoke(resourceAdapterObjectName, "endpointDeactivation", params, activationSig);
503       }
504       catch (Throwable JavaDoc t)
505       {
506          t = JMXExceptionDecoder.decode(t);
507          log.warn("Endpoint activation failed ra=" + resourceAdapterObjectName +
508                " activationSpec=" + activationSpec, t);
509       }
510    }
511    
512    // Package Private -----------------------------------------------
513

514    // Private -------------------------------------------------------
515

516    // Inner Classes -------------------------------------------------
517
}
518
Popular Tags