KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > metadata > MessageDrivenMetaData


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.metadata;
23
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26
27 import javax.jms.Message JavaDoc;
28 import javax.jms.Session JavaDoc;
29
30 import org.w3c.dom.Element JavaDoc;
31
32 import org.jboss.invocation.InvocationType;
33 import org.jboss.deployment.DeploymentException;
34
35 /**
36  * Provides a container and parser for the metadata of a message driven bean.
37  *
38  * <p>Have to add changes ApplicationMetaData and ConfigurationMetaData.
39  *
40  * @author <a HREF="mailto:sebastien.alborini@m4x.org">Sebastien Alborini</a>
41  * @author <a HREF="mailto:peter.antman@tim.se">Peter Antman</a>
42  * @author <a HREF="mailto:andreas@jboss.org">Andreas Schaefer</a>
43  * @author <a HREF="mailto:adrian@jboss.com">Adrian Brock</a>
44  * @version $Revision: 58228 $
45  */

46 public class MessageDrivenMetaData
47    extends BeanMetaData
48 {
49    // Constants -----------------------------------------------------
50

51    public static final int AUTO_ACKNOWLEDGE_MODE = Session.AUTO_ACKNOWLEDGE;
52    public static final int DUPS_OK_ACKNOWLEDGE_MODE = Session.DUPS_OK_ACKNOWLEDGE;
53    public static final int CLIENT_ACKNOWLEDGE_MODE = Session.CLIENT_ACKNOWLEDGE;
54    public static final byte DURABLE_SUBSCRIPTION = 0;
55    public static final byte NON_DURABLE_SUBSCRIPTION = 1;
56    public static final byte TX_UNSET = 9;
57    public static final String JavaDoc DEFAULT_MESSAGE_DRIVEN_BEAN_INVOKER_PROXY_BINDING = "message-driven-bean";
58
59    public static final String JavaDoc DEFAULT_MESSAGING_TYPE = "javax.jms.MessageListener";
60
61    // Attributes ----------------------------------------------------
62

63    private int acknowledgeMode = AUTO_ACKNOWLEDGE_MODE;
64    private byte subscriptionDurability = NON_DURABLE_SUBSCRIPTION;
65    private byte methodTransactionType = TX_UNSET;
66    private String JavaDoc messagingType = DEFAULT_MESSAGING_TYPE;
67    private String JavaDoc destinationType;
68    private String JavaDoc destinationLink;
69    private String JavaDoc messageSelector;
70    private String JavaDoc destinationJndiName;
71    private String JavaDoc user;
72    private String JavaDoc passwd;
73    private String JavaDoc clientId;
74    private String JavaDoc subscriptionId;
75    /** The activation config properties */
76    private HashMap JavaDoc activationConfigProperties = new HashMap JavaDoc();
77    /** The resource adapter name */
78    private String JavaDoc resourceAdapterName;
79    
80    // Static --------------------------------------------------------
81

82    // Constructors --------------------------------------------------
83

84    public MessageDrivenMetaData(ApplicationMetaData app)
85    {
86       super(app, BeanMetaData.MDB_TYPE);
87    }
88    
89    // Public --------------------------------------------------------
90

91    /**
92     * Get the message acknowledgement mode.
93     *
94     * @return MessageDrivenMetaData.AUTO_ACKNOWLADGE_MODE or
95     * MessageDrivenMetaData.DUPS_OK_AKNOWLEDGE_MODE or
96     * MessageDrivenMetaData.CLIENT_ACKNOWLEDGE_MODE
97     */

98    public int getAcknowledgeMode()
99    {
100       // My interpretation of the EJB and JMS spec leads
101
// me to that CLIENT_ACK is the only possible
102
// solution. A transaction is per session in JMS, and
103
// it is not possible to get access to the transaction.
104
// According to the JMS spec it is possible to
105
// multithread handling of messages (but not session),
106
// but there is NO transaction support for this.
107
// I,e, we can not use the JMS transaction for
108
// message ack: hence we must use manual ack.
109

110       // But for NOT_SUPPORTED this is not true here we
111
// should have AUTO_ACKNOWLEDGE_MODE
112

113       // This is not true for now. For JBossMQ we relly
114
// completely on transaction handling. For JBossMQ, the
115
// ackmode is actually not relevant. We keep it here
116
// anyway, if we find that this is needed for other
117
// JMS provider, or is not good.
118

119       if (getMethodTransactionType() == TX_REQUIRED)
120       {
121          return CLIENT_ACKNOWLEDGE_MODE;
122       }
123       else
124       {
125          return acknowledgeMode;
126       }
127    }
128
129    public void setAcknowledgeMode(String JavaDoc ack)
130    {
131       if( ack == null || ack.equalsIgnoreCase("Auto-acknowledge") ||
132          ack.equalsIgnoreCase("AUTO_ACKNOWLEDGE"))
133       {
134          acknowledgeMode = AUTO_ACKNOWLEDGE_MODE;
135       }
136       else if (ack.equalsIgnoreCase("Dups-ok-acknowledge") ||
137          ack.equalsIgnoreCase("DUPS_OK_ACKNOWLEDGE"))
138       {
139          acknowledgeMode = DUPS_OK_ACKNOWLEDGE_MODE;
140       }
141       else
142       {
143          throw new IllegalStateException JavaDoc("invalid acknowledge-mode: " + ack);
144       }
145    }
146
147    public String JavaDoc getMessagingType()
148    {
149       return messagingType;
150    }
151
152    public void setMessagingType(String JavaDoc messagingType)
153    {
154       this.messagingType = messagingType;
155    }
156
157    public boolean isJMSMessagingType()
158    {
159       return DEFAULT_MESSAGING_TYPE.equals(messagingType);
160    }
161
162    public String JavaDoc getDestinationType()
163    {
164       return destinationType;
165    }
166
167    public void setDestinationType(String JavaDoc destinationType)
168    {
169       this.destinationType = destinationType;
170    }
171
172    public String JavaDoc getDestinationLink()
173    {
174       return destinationLink;
175    }
176
177    public void setDestinationLink(String JavaDoc destinationLink)
178    {
179       this.destinationLink = destinationLink;
180    }
181
182    public String JavaDoc getMessageSelector()
183    {
184       return messageSelector;
185    }
186
187    public void setMessageSelector(String JavaDoc selector)
188    {
189       this.messageSelector = selector;
190       if( messageSelector != null )
191       {
192          //AS Check for Carriage Returns, remove them and trim the selector
193
int i = -1;
194          // Note this only works this way because the search and replace are distinct
195
while( ( i = messageSelector.indexOf( "\r\n" ) ) >= 0 )
196          {
197             // Replace \r\n by a space
198
messageSelector = ( i == 0 ? "" : messageSelector.substring( 0, i ) ) +
199             " " +
200             ( i >= messageSelector.length() - 2 ? "" : messageSelector.substring( i + 2 ) );
201          }
202          i = -1;
203          while( ( i = messageSelector.indexOf( "\r" ) ) >= 0 )
204          {
205             // Replace \r by a space
206
messageSelector = ( i == 0 ? "" : messageSelector.substring( 0, i ) ) +
207             " " +
208             ( i >= messageSelector.length() - 1 ? "" : messageSelector.substring( i + 1 ) );
209          }
210          i = -1;
211          while( ( i = messageSelector.indexOf( "\n" ) ) >= 0 )
212          {
213             // Replace \n by a space
214
messageSelector = ( i == 0 ? "" : messageSelector.substring( 0, i ) ) +
215             " " +
216             ( i >= messageSelector.length() - 1 ? "" : messageSelector.substring( i + 1 ) );
217          }
218          // Finally trim it. This is here because only carriage returns and linefeeds are transformed
219
// to spaces
220
messageSelector = messageSelector.trim();
221          if( "".equals( messageSelector ) )
222          {
223             messageSelector = null;
224          }
225       }
226    }
227
228    public String JavaDoc getDestinationJndiName()
229    {
230       return destinationJndiName;
231    }
232
233    public void setDestinationJndiName(String JavaDoc destinationJndiName)
234    {
235       this.destinationJndiName = destinationJndiName;
236    }
237
238    public String JavaDoc getUser()
239    {
240       return user;
241    }
242
243    public void setUser(String JavaDoc user)
244    {
245       this.user = user;
246    }
247
248    public String JavaDoc getPasswd()
249    {
250       return passwd;
251    }
252
253    public void setPasswd(String JavaDoc passwd)
254    {
255       this.passwd = passwd;
256    }
257
258    public String JavaDoc getClientId()
259    {
260       return clientId;
261    }
262
263    public void setClientId(String JavaDoc clientId)
264    {
265       this.clientId = clientId;
266    }
267
268    public String JavaDoc getSubscriptionId()
269    {
270       return subscriptionId;
271    }
272
273    public void setSubscriptionId(String JavaDoc subscriptionId)
274    {
275       this.subscriptionId = subscriptionId;
276    }
277
278    /**
279     * Check MDB methods TX type, is cached here
280     */

281    public byte getMethodTransactionType()
282    {
283       if (methodTransactionType == TX_UNSET)
284       {
285          Class JavaDoc[] sig = { Message JavaDoc.class };
286          methodTransactionType = getMethodTransactionType("onMessage", sig);
287       }
288       return methodTransactionType;
289    }
290    
291    /**
292     * Check MDB methods TX type, is cached here
293     */

294    public byte getMethodTransactionType(String JavaDoc methodName, Class JavaDoc[] signature)
295    {
296       if (isContainerManagedTx())
297       {
298          if (super.getMethodTransactionType(methodName, signature, null) == MetaData.TX_NOT_SUPPORTED)
299             return TX_NOT_SUPPORTED;
300          else
301             return TX_REQUIRED;
302       }
303       else
304          return TX_UNKNOWN;
305    }
306
307    /**
308     * Overide here, since a message driven bean only ever have one method,
309     * which we might cache.
310     */

311    public byte getMethodTransactionType(String JavaDoc methodName, Class JavaDoc[] params, InvocationType iface)
312    {
313       // A JMS MDB may only ever have one method
314
if (isJMSMessagingType())
315          return getMethodTransactionType();
316       else
317          return getMethodTransactionType(methodName, params);
318    }
319
320    /**
321     * Get the subscription durability mode.
322     *
323     * @return MessageDrivenMetaData.DURABLE_SUBSCRIPTION or
324     * MessageDrivenMetaData.NON_DURABLE_SUBSCRIPTION
325     */

326    public byte getSubscriptionDurability()
327    {
328       return subscriptionDurability;
329    }
330
331    public void setSubscriptionDurability(String JavaDoc subscr)
332    {
333       // Should we do sanity check??
334
if( subscr != null && subscr.equals("Durable") )
335       {
336          subscriptionDurability = DURABLE_SUBSCRIPTION;
337       }
338       else
339       {
340          subscriptionDurability = NON_DURABLE_SUBSCRIPTION;//Default
341
}
342    }
343
344    public String JavaDoc getDefaultConfigurationName()
345    {
346       if (isJMSMessagingType() == false)
347          return ConfigurationMetaData.MESSAGE_INFLOW_DRIVEN;
348       else
349          return ConfigurationMetaData.MESSAGE_DRIVEN_13;
350    }
351
352    /**
353     * Get all the activation config properties
354     *
355     * @return a collection of ActivationConfigPropertyMetaData elements
356     */

357    public HashMap JavaDoc getActivationConfigProperties()
358    {
359       return activationConfigProperties;
360    }
361    
362    /**
363     * Get a particular activation config property
364     *
365     * @param name the name of the property
366     * @return the ActivationConfigPropertyMetaData or null if not found
367     */

368    public ActivationConfigPropertyMetaData getActivationConfigProperty(String JavaDoc name)
369    {
370       return (ActivationConfigPropertyMetaData) activationConfigProperties.get(name);
371    }
372
373    /**
374     * Get the resource adapter name
375     *
376     * @return the resource adapter name or null if none specified
377     */

378    public String JavaDoc getResourceAdapterName()
379    {
380       return resourceAdapterName;
381    }
382
383    public void setResourceAdapterName(String JavaDoc resourceAdapterName)
384    {
385       this.resourceAdapterName = resourceAdapterName;
386    }
387
388    public void importEjbJarXml(Element JavaDoc element) throws DeploymentException
389    {
390       super.importEjbJarXml(element);
391       
392       setMessageSelector(getOptionalChildContent(element, "message-selector"));
393
394       // messaging-type is new to EJB-2.1
395
messagingType = getOptionalChildContent(element, "messaging-type", DEFAULT_MESSAGING_TYPE);
396
397       // destination is optional
398
Element JavaDoc destination = getOptionalChild(element, "message-driven-destination");
399       if (destination != null)
400       {
401          destinationType = getUniqueChildContent(destination, "destination-type");
402          if (destinationType.equals("javax.jms.Topic"))
403          {
404             String JavaDoc subscr = getOptionalChildContent(destination, "subscription-durability");
405             setSubscriptionDurability(subscr);
406          }
407       }
408
409       // look for an EJB21 destination type
410
String JavaDoc ejb21DestinationType = getOptionalChildContent(element, "message-destination-type");
411       if (ejb21DestinationType != null)
412          destinationType = ejb21DestinationType;
413
414       // destination link is optional
415
destinationLink = getOptionalChildContent(element, "message-destination-link");
416       
417       // set the transaction type
418
String JavaDoc transactionType = getUniqueChildContent(element, "transaction-type");
419       if (transactionType.equals("Bean"))
420       {
421          containerManagedTx = false;
422          String JavaDoc ack = getOptionalChildContent(element, "acknowledge-mode");
423          setAcknowledgeMode(ack);
424       }
425       else if (transactionType.equals("Container"))
426       {
427          containerManagedTx = true;
428       }
429       else
430       {
431          throw new DeploymentException
432          ("transaction type should be 'Bean' or 'Container'");
433       }
434       
435       // Set the activation config properties
436
Element JavaDoc activationConfig = getOptionalChild(element, "activation-config");
437       if (activationConfig != null)
438       {
439          Iterator JavaDoc iterator = getChildrenByTagName(activationConfig, "activation-config-property");
440          while (iterator.hasNext())
441          {
442             Element JavaDoc resourceRef = (Element JavaDoc) iterator.next();
443             ActivationConfigPropertyMetaData metaData = new ActivationConfigPropertyMetaData();
444             metaData.importXml(resourceRef);
445             if (activationConfigProperties.containsKey(metaData.getName()))
446                throw new DeploymentException("Duplicate activation-config-property-name: " + metaData.getName());
447             activationConfigProperties.put(metaData.getName(), metaData);
448          }
449       }
450    }
451
452    public void importJbossXml(Element JavaDoc element) throws DeploymentException
453    {
454       super.importJbossXml(element);
455       
456       // set the jndi name, (optional)
457
destinationJndiName = getOptionalChildContent(element, "destination-jndi-name");
458       user = getOptionalChildContent(element, "mdb-user");
459       passwd = getOptionalChildContent(element,"mdb-passwd");
460       clientId = getOptionalChildContent(element,"mdb-client-id");
461       subscriptionId = getOptionalChildContent(element,"mdb-subscription-id");
462       resourceAdapterName = getOptionalChildContent(element,"resource-adapter-name");
463       
464       // Allow activation config properties to be overriden in jboss.xml
465
Element JavaDoc activationConfig = getOptionalChild(element, "activation-config");
466       if (activationConfig != null)
467       {
468          Iterator JavaDoc iterator = getChildrenByTagName(activationConfig, "activation-config-property");
469          while (iterator.hasNext())
470          {
471             Element JavaDoc resourceRef = (Element JavaDoc) iterator.next();
472             ActivationConfigPropertyMetaData metaData = new ActivationConfigPropertyMetaData();
473             metaData.importXml(resourceRef);
474             activationConfigProperties.put(metaData.getName(), metaData);
475          }
476       }
477    }
478    
479    public void defaultInvokerBindings()
480    {
481      this.invokerBindings = new HashMap JavaDoc();
482      this.invokerBindings.put(DEFAULT_MESSAGE_DRIVEN_BEAN_INVOKER_PROXY_BINDING, getJndiName());
483    }
484
485    // Package protected ---------------------------------------------
486

487    // Protected -----------------------------------------------------
488

489    // Private -------------------------------------------------------
490

491    // Inner classes -------------------------------------------------
492
}
493
494
Popular Tags