KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployment > EjbMessageBeanDescriptor


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.deployment;
24
25 import javax.ejb.TimedObject JavaDoc;
26 import javax.jms.Session JavaDoc;
27 import java.lang.reflect.Method JavaDoc;
28 import com.sun.enterprise.util.LocalStringManagerImpl;
29 import java.util.*;
30 import java.util.logging.Level JavaDoc;
31
32 import com.sun.enterprise.deployment.types.MessageDestinationReferencer;
33 import com.sun.enterprise.deployment.xml.EjbTagNames;
34 import com.sun.enterprise.deployment.xml.TagNames;
35
36     /**
37     * Objects of this kind represent the deployment information describing a
38     * single message driven Ejb.
39     */

40
41 public final class EjbMessageBeanDescriptor extends EjbDescriptor
42     implements MessageDestinationReferencer {
43
44     private static final boolean debug = false;
45
46     /** The Session type String.*/
47     public static final String JavaDoc TYPE = "Message-driven";
48
49     private static LocalStringManagerImpl localStrings =
50         new LocalStringManagerImpl(EjbMessageBeanDescriptor.class);
51
52     private String JavaDoc messageListenerType = "javax.jms.MessageListener";
53
54     // These are the method objects from the
55
// *message-bean implementation class* that implement the
56
// Message Listener interface methods or ejbTimeout method.
57
private Collection beanClassTxMethods = null;
58
59     // *Optional* type of destination from which message bean consumes.
60
private String JavaDoc destinationType = null;
61
62     // The following properties are used for processing of EJB 2.0
63
// JMS-specific deployment descriptor elements.
64
private static final String JavaDoc DURABLE_SUBSCRIPTION_PROPERTY =
65         "subscriptionDurability";
66     private static final String JavaDoc DURABLE =
67         EjbTagNames.JMS_SUBSCRIPTION_IS_DURABLE;
68     private static final String JavaDoc NON_DURABLE =
69         EjbTagNames.JMS_SUBSCRIPTION_NOT_DURABLE;
70
71     private static final String JavaDoc ACK_MODE_PROPERTY =
72         "acknowledgeMode";
73     private static final String JavaDoc AUTO_ACK =
74         EjbTagNames.JMS_AUTO_ACK_MODE;
75     private static final String JavaDoc DUPS_OK_ACK =
76         EjbTagNames.JMS_DUPS_OK_ACK_MODE;
77
78     private static final String JavaDoc MESSAGE_SELECTOR_PROPERTY =
79         "messageSelector";
80
81     private String JavaDoc durableSubscriptionName = null;
82
83     private String JavaDoc connectionFactoryName = null;
84     private String JavaDoc resourceAdapterMid = null;
85
86     // Holds *optional* information about the destination to which
87
// we are linked.
88
private MessageDestinationReferencerImpl msgDestReferencer;
89
90     // activationConfig represents name/value pairs that are
91
// set by the assembler of an MDB application; those properties
92
// are not resource adapter vendor dependent.
93
private ActivationConfigDescriptor activationConfig;
94     
95     // runtimeActivationConfig represents name/value pairs that are
96
// set by the deployer of an MDB application; those properties
97
// are resource adapter vendor dependent.
98
private ActivationConfigDescriptor runtimeActivationConfig;
99     
100     /**
101      * Default constructor.
102      */

103     public EjbMessageBeanDescriptor() {
104         msgDestReferencer = new MessageDestinationReferencerImpl(this);
105         this.activationConfig = new ActivationConfigDescriptor();
106         this.runtimeActivationConfig = new ActivationConfigDescriptor();
107     }
108     
109     /**
110     * The copy constructor.
111     */

112     
113     public EjbMessageBeanDescriptor(EjbMessageBeanDescriptor other) {
114         super(other);
115         this.messageListenerType = other.messageListenerType;
116         this.beanClassTxMethods = null;
117         this.durableSubscriptionName = other.durableSubscriptionName;
118         this.msgDestReferencer = new MessageDestinationReferencerImpl(this);
119         this.activationConfig =
120             new ActivationConfigDescriptor(other.activationConfig);
121         this.runtimeActivationConfig =
122             new ActivationConfigDescriptor(other.runtimeActivationConfig);
123         this.destinationType = other.destinationType;
124     }
125
126
127     /**
128      * Returns the type of this bean - always "Message-driven".
129      */

130     public String JavaDoc getType() {
131         return TYPE;
132     }
133
134     public void setContainerTransactionFor(MethodDescriptor methodDescriptor, ContainerTransaction containerTransaction) {
135         Vector allowedTxAttributes = getPossibleTransactionAttributes();
136         if( allowedTxAttributes.contains(containerTransaction) ) {
137             super.setContainerTransactionFor
138                 (methodDescriptor, containerTransaction);
139          }
140          else {
141              throw new IllegalArgumentException JavaDoc(localStrings.getLocalString(
142                  "enterprise.deployment.msgbeantxattrnotvalid",
143            "Invalid transaction attribute for message-driven bean"));
144          }
145     }
146
147     /**
148      * Sets my type
149      */

150     public void setType(String JavaDoc type) {
151     throw new IllegalArgumentException JavaDoc(localStrings.getLocalString(
152            "enterprise.deployment.exceptioncannotsettypeofmsgdrivenbean",
153            "Cannot set the type of a message-drive bean"));
154     }
155
156     public void setMessageListenerType(String JavaDoc messagingType) {
157         messageListenerType = messagingType;
158
159         // Clear message listener methods so transaction methods will be
160
// recomputed using new message listener type;
161
beanClassTxMethods = null;
162     }
163
164     public String JavaDoc getMessageListenerType() {
165         return messageListenerType;
166     }
167
168     public Set getTxBusinessMethodDescriptors() {
169          
170         ClassLoader JavaDoc classLoader = getEjbBundleDescriptor().getClassLoader();
171         Set methods = new HashSet();
172
173         try {
174             addAllInterfaceMethodsIn
175                 (methods, classLoader.loadClass(messageListenerType),
176                  MethodDescriptor.EJB_BEAN);
177
178             if (isTimedObject()) {
179                 methods.add(getEjbTimeoutMethod());
180             }
181
182         } catch (Throwable JavaDoc t) {
183             _logger.log(Level.SEVERE,"enterprise.deployment.backend.methodClassLoadFailure",new Object JavaDoc [] {"(EjbDescriptor.getBusinessMethodDescriptors())"});
184                                                            
185         throw new RuntimeException JavaDoc(t);
186     }
187          
188         return methods;
189     }
190
191     public Set getSecurityBusinessMethodDescriptors() {
192     throw new IllegalArgumentException JavaDoc(localStrings.getLocalString(
193            "enterprise.deployment.exceptioncannotgetsecbusmethodsinmsgbean",
194                    "Cannot get business method for security for message-driven bean."));
195     }
196
197     /**
198      * This returns the message listener onMessage method from the
199      * *message listener interface* itself, as opposed to the method
200      * from the ejb class that implements it.
201      */

202     public Method JavaDoc[] getMessageListenerInterfaceMethods(ClassLoader JavaDoc classLoader)
203         throws NoSuchMethodException JavaDoc {
204                              
205         Method JavaDoc[] methods;
206         try {
207             Class JavaDoc messageListenerClass =
208                 classLoader.loadClass(messageListenerType);
209             methods = messageListenerClass.getDeclaredMethods();
210             if( methods.length == 0 ) {
211                 throw new NoSuchMethodException JavaDoc
212                     ("MessageListener interface " + messageListenerType +
213                      " must declare at least one method");
214             }
215         } catch(Exception JavaDoc e) {
216             NoSuchMethodException JavaDoc nsme = new NoSuchMethodException JavaDoc();
217             nsme.initCause(e);
218             throw nsme;
219         }
220         return methods;
221     }
222
223     public Vector getPossibleTransactionAttributes() {
224         Vector txAttributes = new Vector();
225         txAttributes.add(new ContainerTransaction
226             (ContainerTransaction.REQUIRED, ""));
227         txAttributes.add(new ContainerTransaction
228             (ContainerTransaction.NOT_SUPPORTED, ""));
229         if( isTimedObject() ) {
230             txAttributes.add(new ContainerTransaction
231                 (ContainerTransaction.REQUIRES_NEW, ""));
232         }
233         return txAttributes;
234     }
235
236     public boolean hasMessageDestinationLinkName() {
237         return (msgDestReferencer.getMessageDestinationLinkName() != null);
238     }
239
240     //
241
// Implementations of MessageDestinationReferencer methods.
242
//
243

244     public boolean isLinkedToMessageDestination() {
245         return msgDestReferencer.isLinkedToMessageDestination();
246     }
247     
248     /**
249      * @return the name of the message destination to which I refer
250      */

251     public String JavaDoc getMessageDestinationLinkName() {
252         return msgDestReferencer.getMessageDestinationLinkName();
253     }
254
255     /**
256      * Sets the name of the message destination to which I refer.
257      */

258     public void setMessageDestinationLinkName(String JavaDoc linkName) {
259         msgDestReferencer.setMessageDestinationLinkName(linkName);
260     }
261
262     public MessageDestinationDescriptor setMessageDestinationLinkName
263         (String JavaDoc linkName, boolean resolveLink) {
264         return msgDestReferencer.setMessageDestinationLinkName
265             (linkName, resolveLink);
266     }
267
268     public MessageDestinationDescriptor resolveLinkName() {
269         return msgDestReferencer.resolveLinkName();
270     }
271         
272     public boolean ownedByMessageDestinationRef() {
273         return false;
274     }
275
276     public MessageDestinationReferenceDescriptor getMessageDestinationRefOwner
277         () {
278         return null;
279     }
280
281     /**
282      * True if the owner is a message-driven bean.
283      */

284     public boolean ownedByMessageBean() {
285         return true;
286     }
287
288     /**
289      * Get the descriptor for the message-driven bean owner.
290      */

291     public EjbMessageBeanDescriptor getMessageBeanOwner() {
292         return this;
293     }
294         
295     /**
296      * @return the message destination to which I refer. Can be NULL.
297     */

298     public MessageDestinationDescriptor getMessageDestination() {
299         return msgDestReferencer.getMessageDestination();
300     }
301
302     /**
303      * @param messageDestiation the message destination to which I refer.
304      */

305     public void setMessageDestination(MessageDestinationDescriptor newMsgDest) {
306         msgDestReferencer.setMessageDestination(newMsgDest);
307     }
308
309     //
310
// ActivationConfig
311
//
312

313     /**
314      * @return Set of EnvironmentProperty elements.
315      */

316     public Set getActivationConfigProperties() {
317         return activationConfig.getActivationConfig();
318     }
319     
320     public String JavaDoc getActivationConfigValue(String JavaDoc name) {
321         for(Iterator iter = activationConfig.getActivationConfig().iterator();
322             iter.hasNext();) {
323             EnvironmentProperty next = (EnvironmentProperty) iter.next();
324             if( next.getName().equals(name) ) {
325                 return (String JavaDoc) next.getValue();
326             }
327         }
328         return null;
329     }
330
331     public void putActivationConfigProperty(EnvironmentProperty prop) {
332         // remove first an existing property with the same name
333
removeActivationConfigPropertyByName(prop.getName());
334         activationConfig.getActivationConfig().add(prop);
335     }
336
337     public void removeActivationConfigProperty(EnvironmentProperty prop) {
338         for(Iterator iter = activationConfig.getActivationConfig().iterator();
339             iter.hasNext();) {
340             EnvironmentProperty next = (EnvironmentProperty) iter.next();
341             if( next.getName().equals(prop.getName()) &&
342                 next.getValue().equals(prop.getValue()) ) {
343                 iter.remove();
344                 break;
345             }
346         }
347     }
348
349     public void removeActivationConfigPropertyByName(String JavaDoc name) {
350         for(Iterator iter = activationConfig.getActivationConfig().iterator();
351             iter.hasNext();) {
352             EnvironmentProperty next = (EnvironmentProperty) iter.next();
353             if( next.getName().equals(name) ) {
354                 iter.remove();
355                 break;
356             }
357         }
358     }
359
360     /**
361      * @return Set of EnvironmentProperty elements.
362      */

363     public Set getRuntimeActivationConfigProperties() {
364         return runtimeActivationConfig.getActivationConfig();
365     }
366     
367     public String JavaDoc getRuntimeActivationConfigValue(String JavaDoc name) {
368         for(Iterator iter =
369                 runtimeActivationConfig.getActivationConfig().iterator();
370             iter.hasNext();) {
371             EnvironmentProperty next = (EnvironmentProperty) iter.next();
372             if( next.getName().equals(name) ) {
373                 return (String JavaDoc) next.getValue();
374             }
375         }
376         return null;
377     }
378
379     public void putRuntimeActivationConfigProperty(EnvironmentProperty prop) {
380         runtimeActivationConfig.getActivationConfig().add(prop);
381     }
382
383     public void removeRuntimeActivationConfigProperty(EnvironmentProperty prop) {
384         for(Iterator iter =
385                 runtimeActivationConfig.getActivationConfig().iterator();
386             iter.hasNext();) {
387             EnvironmentProperty next = (EnvironmentProperty) iter.next();
388             if( next.getName().equals(prop.getName()) &&
389                 next.getValue().equals(prop.getValue()) ) {
390                 iter.remove();
391                 break;
392             }
393         }
394
395     }
396
397     public void removeRuntimeActivationConfigPropertyByName(String JavaDoc name) {
398         for(Iterator iter =
399                 runtimeActivationConfig.getActivationConfig().iterator();
400             iter.hasNext();) {
401             EnvironmentProperty next = (EnvironmentProperty) iter.next();
402             if( next.getName().equals(name) ) {
403                 iter.remove();
404                 break;
405             }
406         }
407     }
408
409     public boolean hasQueueDest() {
410         return ( (destinationType != null) &&
411                  (destinationType.equals("javax.jms.Queue")) );
412     }
413
414     public boolean hasTopicDest() {
415         return ( (destinationType != null) &&
416                  (destinationType.equals("javax.jms.Topic")) );
417     }
418
419     public boolean hasDestinationType() {
420         return (destinationType != null);
421     }
422
423     public String JavaDoc getDestinationType() {
424         return destinationType;
425     }
426     
427     public void setDestinationType(String JavaDoc destType) {
428         destinationType = destType;
429     }
430
431     public boolean hasDurableSubscription() {
432         String JavaDoc value = getActivationConfigValue(DURABLE_SUBSCRIPTION_PROPERTY);
433         return ( (value != null) && value.equals(DURABLE) );
434     }
435
436     public void setHasDurableSubscription(boolean durable) {
437         if( durable ) {
438             EnvironmentProperty durableProp =
439                 new EnvironmentProperty(DURABLE_SUBSCRIPTION_PROPERTY,
440                                         DURABLE, "");
441             putActivationConfigProperty(durableProp);
442         } else {
443             removeActivationConfigPropertyByName(DURABLE_SUBSCRIPTION_PROPERTY);
444         }
445         super.changed();
446     }
447
448
449     public void setHasQueueDest() {
450         destinationType = "javax.jms.Queue";
451         setHasDurableSubscription(false);
452         super.changed();
453     }
454
455     public void setHasTopicDest() {
456         destinationType = "javax.jms.Topic";
457         super.changed();
458     }
459     
460     public void setSubscriptionDurability(String JavaDoc subscription) {
461         if (subscription.equals(DURABLE)) {
462             setHasDurableSubscription(true);
463         }
464         else if (subscription.equals(NON_DURABLE)) {
465             setHasDurableSubscription(false);
466         } else {
467             throw new IllegalArgumentException JavaDoc
468                 ("Invalid subscription durability string : " + subscription);
469         }
470     }
471
472     public boolean hasJmsMessageSelector() {
473         return ( getActivationConfigValue(MESSAGE_SELECTOR_PROPERTY) != null );
474     }
475
476     public void setJmsMessageSelector(String JavaDoc selector) {
477         
478         if( (selector == null) || (selector.trim().equals("")) ) {
479             removeActivationConfigPropertyByName(MESSAGE_SELECTOR_PROPERTY);
480         } else {
481             EnvironmentProperty msgSelectorProp =
482                 new EnvironmentProperty(MESSAGE_SELECTOR_PROPERTY,selector,"");
483             putActivationConfigProperty(msgSelectorProp);
484         }
485
486         super.changed();
487     }
488
489     public String JavaDoc getJmsMessageSelector() {
490     return getActivationConfigValue(MESSAGE_SELECTOR_PROPERTY);
491     }
492
493     public int getJmsAcknowledgeMode() {
494         String JavaDoc ackModeStr = getActivationConfigValue(ACK_MODE_PROPERTY);
495         return ( (ackModeStr != null) && ackModeStr.equals(DUPS_OK_ACK) ) ?
496             Session.DUPS_OK_ACKNOWLEDGE : Session.AUTO_ACKNOWLEDGE;
497     }
498     
499     public String JavaDoc getJmsAcknowledgeModeAsString() {
500         return getActivationConfigValue(ACK_MODE_PROPERTY);
501     }
502     
503     public void setJmsAcknowledgeMode(int acknowledgeMode) {
504         String JavaDoc ackModeValue = (acknowledgeMode == Session.AUTO_ACKNOWLEDGE) ?
505             AUTO_ACK : DUPS_OK_ACK;
506         EnvironmentProperty ackModeProp =
507             new EnvironmentProperty(ACK_MODE_PROPERTY, ackModeValue, "");
508         putActivationConfigProperty(ackModeProp);
509
510         super.changed();
511     }
512     
513     public void setJmsAcknowledgeMode(String JavaDoc acknowledgeMode) {
514         if (AUTO_ACK.equals(acknowledgeMode)) {
515             setJmsAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
516         } else {
517             if (DUPS_OK_ACK.equals(acknowledgeMode)) {
518                 setJmsAcknowledgeMode(Session.DUPS_OK_ACKNOWLEDGE);
519             } else {
520                 throw new IllegalArgumentException JavaDoc
521                     ("Invalid jms acknowledge mode : " + acknowledgeMode);
522             }
523         }
524     }
525
526     public String JavaDoc getDurableSubscriptionName() {
527         return durableSubscriptionName;
528     }
529
530     public void setDurableSubscriptionName(String JavaDoc durableSubscriptionName) {
531         this.durableSubscriptionName = durableSubscriptionName;
532         super.changed();
533     }
534
535     public String JavaDoc getConnectionFactoryName() {
536         return connectionFactoryName;
537     }
538
539     /**
540      * Connection factory is optional. If set to null,
541      * hasConnectionFactory will return false.
542      */

543     public void setConnectionFactoryName(String JavaDoc connectionFactory) {
544         connectionFactoryName = connectionFactory;
545     }
546
547     public boolean hasConnectionFactory() {
548         return (connectionFactoryName != null);
549     }
550
551     public String JavaDoc getResourceAdapterMid() {
552         return resourceAdapterMid;
553     }
554
555     /**
556      * resource-adapter-mid is optional. It is set when
557      * a resource adapter is responsible for delivering
558      * messages to the message-driven bean. If not set,
559      * hasResourceAdapterMid will return false.
560      */

561     public void setResourceAdapterMid(String JavaDoc resourceAdapterMid) {
562         this.resourceAdapterMid = resourceAdapterMid;
563     }
564
565     public boolean hasResourceAdapterMid() {
566         return (resourceAdapterMid != null);
567     }
568
569     /**
570      */

571     public Vector getMethods(ClassLoader JavaDoc classLoader) {
572         // @@@
573
return new Vector();
574     }
575
576     /**
577      * @return a collection of MethodDescriptor for methods which
578      * may have a assigned security attribute.
579      */

580     protected Collection getTransactionMethods(ClassLoader JavaDoc classLoader) {
581         Vector txMethods = new Vector();
582
583         if( beanClassTxMethods == null ) {
584             try {
585                 beanClassTxMethods = new HashSet();
586                 Class JavaDoc ejbClass = classLoader.loadClass(this.getEjbClassName());
587                 Method JavaDoc interfaceMessageListenerMethods[] =
588                     getMessageListenerInterfaceMethods(classLoader);
589                 for(int i = 0; i < interfaceMessageListenerMethods.length;
590                     i++) {
591                     Method JavaDoc next = interfaceMessageListenerMethods[i];
592                     // Convert method objects from MessageListener interface
593
// to method objects from ejb class
594
Method JavaDoc nextBeanMethod = ejbClass.getMethod
595                         (next.getName(), next.getParameterTypes());
596                     beanClassTxMethods.add(new MethodDescriptor(nextBeanMethod, MethodDescriptor.EJB_BEAN));
597                 }
598                 if( isTimedObject() ) {
599                     beanClassTxMethods.add(getEjbTimeoutMethod());
600                 }
601             }
602             catch(Exception JavaDoc e) {
603                 NoSuchMethodError JavaDoc nsme = new NoSuchMethodError JavaDoc(localStrings.getLocalString("enterprise.deployment.noonmessagemethod", "", new Object JavaDoc[] {
604                     getEjbClassName(), getMessageListenerType() }));
605                 nsme.initCause(e);
606                 throw nsme;
607             }
608         }
609         txMethods.addAll(beanClassTxMethods);
610
611         return txMethods;
612     }
613
614     /**
615      * Sets the transaction type for this bean.
616      * Must be either BEAN_TRANSACTION_TYPE or CONTAINER_TRANSACTION_TYPE.
617      */

618     public void setTransactionType(String JavaDoc transactionType) {
619     boolean isValidType = (BEAN_TRANSACTION_TYPE.equals(transactionType) ||
620                 CONTAINER_TRANSACTION_TYPE.equals(transactionType));
621                 
622     if (!isValidType && this.isBoundsChecking()) {
623         throw new IllegalArgumentException JavaDoc(localStrings.getLocalString(
624                                        "enterprise.deployment.exceptionmsgbeantxtypenotlegaltype",
625                                        "{0} is not a legal transaction type for a message-driven bean", new Object JavaDoc[] {transactionType}));
626     } else {
627         super.transactionType = transactionType;
628         super.setMethodContainerTransactions(new Hashtable());
629         super.changed();
630     }
631     }
632
633     public void setActivationConfigDescriptor(ActivationConfigDescriptor desc) {
634         activationConfig = desc;
635     }
636
637     // NOTE : This method should only be used by the XML processing logic.
638
// All access to activation config properties should be done
639
// through the other accessors on the message bean descriptor.
640
public ActivationConfigDescriptor getActivationConfigDescriptor() {
641         return activationConfig;
642     }
643
644     public void setRuntimeActivationConfigDescriptor(ActivationConfigDescriptor
645                                                      desc) {
646         runtimeActivationConfig = desc;
647         
648     }
649
650     // NOTE : This method should only be used by the XML processing logic.
651
// All access to activation config properties should be done
652
// through the other accessors on the message bean descriptor.
653
public ActivationConfigDescriptor getRuntimeActivationConfigDescriptor() {
654         return runtimeActivationConfig;
655     }
656
657     /**
658     * Returns a formatted String of the attributes of this object.
659     */

660     public void print(StringBuffer JavaDoc toStringBuffer) {
661     super.print(toStringBuffer);
662     toStringBuffer.append("Message-driven descriptor : ").append(
663             activationConfig.getActivationConfig()).append(
664             runtimeActivationConfig.getActivationConfig());
665     }
666 }
667
Popular Tags