001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: MessageDrivenDesc.java 6220 2005-02-03 08:18:47Z joaninh $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_ejb.deployment.api;
025:
026: import java.util.Iterator;
027: import java.util.List;
028: import java.util.ListIterator;
029:
030: import org.objectweb.jonas_ejb.deployment.xml.ActivationConfig;
031: import org.objectweb.jonas_ejb.deployment.xml.ActivationConfigProperty;
032: import org.objectweb.jonas_ejb.deployment.xml.AssemblyDescriptor;
033: import org.objectweb.jonas_ejb.deployment.xml.JonasMessageDriven;
034: import org.objectweb.jonas_ejb.deployment.xml.MessageDriven;
035: import org.objectweb.jonas_ejb.deployment.xml.MessageDrivenDestination;
036: import org.objectweb.jonas_ejb.lib.BeanNaming;
037:
038: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
039:
040: import org.objectweb.jonas_lib.deployment.xml.JLinkedList;
041:
042: import org.objectweb.util.monolog.api.BasicLevel;
043:
044: /**
045: * Class to hold meta-information related to a message driven bean
046: *
047: * @author Christophe Ney [cney@batisseurs.com] : Initial developer
048: * @author Helene Joanin
049: */
050: public class MessageDrivenDesc extends BeanDesc {
051:
052: public final static int AUTO_ACKNOWLEDGE = 1;
053: public final static int DUPS_OK_ACKNOWLEDGE = 2;
054: protected static final String[] ACKMODE = { null,
055: "AUTO_ACKNOWLEDGE", "DUPS_OK_ACKNOWLEDGE" };
056:
057: public final static int SUBS_DURABLE = 1;
058: public final static int SUBS_NON_DURABLE = 2;
059: protected static final String[] SUBS_DURABILITY = { null,
060: "SUBSCRIPTION_DURABLE", "SUBSCRIPTION_NON_DURABLE" };
061:
062: public final static int DEFAULT_MAX_MESSAGES = 1;
063:
064: protected String selector = null;
065: protected int acknowledgeMode;
066: protected int subscriptionDurability = SUBS_NON_DURABLE;
067: protected Class destinationType = null;
068: protected int txAttribute = MethodDesc.TX_NOT_SET; // for onMessage method
069: protected boolean isTopicDestination = false;
070: protected int transactionType;
071: protected String destinationJndiName = null;
072: protected String destinationLink = null;
073:
074: // Used with JMS Rars
075: protected String destination = null;
076:
077: protected ActivationConfigDesc mdActivationConfigDesc = null;
078:
079: protected ActivationConfigDesc mdJonasActivationConfigDesc = null;
080:
081: /**
082: * package protected constructor used by API
083: */
084: MessageDrivenDesc(ClassLoader classLoader, MessageDriven md,
085: AssemblyDescriptor asd, JonasMessageDriven jMd,
086: JLinkedList jMDRList, String fileName)
087: throws DeploymentDescException {
088:
089: super (classLoader, md, jMd, asd, jMDRList, fileName);
090: mdActivationConfigDesc = new ActivationConfigDesc(md
091: .getActivationConfig());
092: mdJonasActivationConfigDesc = new ActivationConfigDesc(jMd
093: .getActivationConfig());
094:
095: // min-pool-size
096: if (jMd.getMinPoolSize() != null) {
097: String tstr = jMd.getMinPoolSize();
098: Integer tval = new Integer(tstr);
099: poolMin = tval.intValue();
100: }
101:
102: // max-cache-size
103: if (jMd.getMaxCacheSize() != null) {
104: String tstr = jMd.getMaxCacheSize();
105: Integer tval = new Integer(tstr);
106: cacheMax = tval.intValue();
107: }
108:
109: // necessary check
110: if (md.getEjbName() == null) {
111: throw new Error(
112: "No ejb-name specified for a message-driven bean");
113: }
114:
115: // transaction-type
116: if (md.getTransactionType().equals("Bean")) {
117: transactionType = BEAN_TRANSACTION_TYPE;
118: } else if (md.getTransactionType().equals("Container")) {
119: transactionType = CONTAINER_TRANSACTION_TYPE;
120: } else {
121: throw new DeploymentDescException(
122: "Invalid transaction-type content for ejb-name "
123: + ejbName);
124: }
125:
126: // message driven destination
127: if (jMd.getJonasMessageDrivenDestination() != null) {
128: destinationJndiName = jMd
129: .getJonasMessageDrivenDestination().getJndiName();
130: }
131:
132: // Set values can be from old 2.0 way, ActivationConfig in std xml,
133: // or ActivationConfig in jonas xml
134:
135: // message selector
136: selector = md.getMessageSelector();
137: // acknowledge mode
138: if (md.getAcknowledgeMode() == null) {
139: acknowledgeMode = AUTO_ACKNOWLEDGE;
140: } else {
141: if (md.getAcknowledgeMode().equals("Auto-acknowledge")) {
142: acknowledgeMode = AUTO_ACKNOWLEDGE;
143: } else if (md.getAcknowledgeMode().equals(
144: "Dups-ok-acknowledge")) {
145: acknowledgeMode = DUPS_OK_ACKNOWLEDGE;
146: } else {
147: throw new DeploymentDescException(
148: "Invalid acknowledge-mode content for ejb-name "
149: + ejbName);
150: }
151: }
152: MessageDrivenDestination d = md.getMessageDrivenDestination();
153: if (d != null && d.getDestinationType() != null) {
154: if (d.getDestinationType().equals("javax.jms.Queue")) {
155: destinationType = javax.jms.Queue.class;
156: } else if (d.getDestinationType().equals("javax.jms.Topic")) {
157: destinationType = javax.jms.Topic.class;
158: isTopicDestination = true;
159: } else {
160: try {
161: destinationType = classLoader.loadClass(d
162: .getDestinationType());
163: } catch (Exception ex) {
164: throw new DeploymentDescException(
165: "Invalid destination-type for ejb-name "
166: + ejbName);
167: }
168: }
169: if (d.getSubscriptionDurability() != null) {
170: if (destinationType.equals(javax.jms.Queue.class)) {
171: throw new DeploymentDescException(
172: "subscription-durability of message-driven-destination for ejb-name "
173: + ejbName + " defined");
174: }
175: if (d.getSubscriptionDurability().equals("Durable")) {
176: subscriptionDurability = SUBS_DURABLE;
177: } else if (d.getSubscriptionDurability().equals(
178: "NonDurable")) {
179: subscriptionDurability = SUBS_NON_DURABLE;
180: } else {
181: throw new DeploymentDescException(
182: "Invalid subscription-durability content for ejb-name "
183: + ejbName);
184: }
185: } else {
186: // non-durable subscription default value for topic
187: if (destinationType.equals(javax.jms.Topic.class)) {
188: subscriptionDurability = SUBS_NON_DURABLE;
189: }
190: }
191:
192: }
193:
194: destinationLink = md.getMessageDestinationLink();
195:
196: if (mdActivationConfigDesc != null) {
197: configureAC(mdActivationConfigDesc, classLoader);
198: }
199:
200: if (mdJonasActivationConfigDesc != null) {
201: configureAC(mdJonasActivationConfigDesc, classLoader);
202: }
203:
204: if (destinationJndiName == null) {
205: throw new Error(
206: "No destination specified for message-driven bean "
207: + ejbName);
208: }
209:
210: // cache TxAttribute for onMessage and ejbTimeout
211: for (Iterator i = getMethodDescIterator(); i.hasNext();) {
212: MethodDesc methd = (MethodDesc) i.next();
213: if (methd.getMethod().getName().equals("onMessage")) {
214: txAttribute = methd.getTxAttribute();
215: }
216: if (methd.getMethod().getName().equals("ejbTimeout")) {
217: timerTxAttribute = methd.getTxAttribute();
218: ejbTimeoutSignature = BeanNaming.getSignature(
219: getEjbName(), methd.getMethod());
220: }
221: }
222: }
223:
224: /**
225: * Get transaction management type of the message driven.
226: *
227: * @return transaction type value within
228: * BEAN_TRANSACTION_TYPE,CONTAINER_TRANSACTION_TYPE
229: */
230: public int getTransactionType() {
231: return transactionType;
232: }
233:
234: /**
235: * Return the transaction attribute for the onMessage method of Message
236: * driven bean
237: *
238: */
239: public int getTxAttribute() {
240: return txAttribute;
241: }
242:
243: /**
244: * @return true if BEAN_TRANSACTION_TYPE
245: */
246: public boolean isBeanManagedTransaction() {
247: return (transactionType == BeanDesc.BEAN_TRANSACTION_TYPE);
248: }
249:
250: /**
251: * Get the the destination name of the message driven bean.
252: * @return name of the destination of the message driven bean.
253: */
254: public String getDestination() {
255: return (destination);
256: }
257:
258: /**
259: * Get the the destination JNDI name of the message driven bean.
260: *
261: * @return JNDI name of the destination of the message driven bean.
262: */
263: public String getDestinationJndiName() {
264: return (destinationJndiName);
265: }
266:
267: /**
268: * Get the the destination link name of the message driven bean.
269: *
270: * @return link name of the destination of the message driven bean.
271: */
272: public String getDestinationLink() {
273: return (destinationLink);
274: }
275:
276: /**
277: * Get the the destination type of the message driven bean.
278: *
279: * @return type of the destination of the message driven bean.
280: */
281: public Class getDestinationType() {
282: return (destinationType);
283: }
284:
285: /**
286: * Return true if it is a Topic destination
287: */
288: public boolean isTopicDestination() {
289: return (isTopicDestination);
290: }
291:
292: /**
293: * Assessor for existence of a message-selector for the message driven bean
294: *
295: * @return true if message-selector is defined for the bean
296: */
297: public boolean hasSelector() {
298: return (selector != null);
299: }
300:
301: /**
302: * Get the message-selector value of the message driven bean.
303: *
304: * @return value of the message selector return null if no selector
305: */
306: public String getSelector() {
307: return (selector);
308: }
309:
310: /**
311: * Get the acknowledge-mode of the message driven bean.
312: *
313: * @return acknowledge-mode value within AUTO_ACKNOWLEDGE,
314: * DUPS_OK_ACKNOWLEDGE
315: */
316: public int getAcknowledgeMode() {
317: return (acknowledgeMode);
318: }
319:
320: /**
321: * Get the the durability of the subscription of the message driven bean.
322: *
323: * @return durability of the subscription value within SUBS_DURABLE,
324: * SUBS_NON_DURABLE
325: */
326: public int getSubscriptionDurability() {
327: return (subscriptionDurability);
328: }
329:
330: public boolean isSubscriptionDurable() {
331: return (subscriptionDurability == SUBS_DURABLE);
332: }
333:
334: /**
335: * Return true if tx attribute for onMessage is Required
336: */
337: public boolean isRequired() {
338: return (txAttribute == MethodDesc.TX_REQUIRED);
339: }
340:
341: /**
342: * @return the maximum number of messages that can be assigned to a server
343: * session at one time. will be configurable in the future
344: */
345: public int getMaxMessages() {
346: return DEFAULT_MAX_MESSAGES;
347: }
348:
349: /**
350: * check that trans-attribute is valid for bean
351: */
352: protected void checkTxAttribute(MethodDesc md)
353: throws DeploymentDescException {
354: java.lang.reflect.Method m = md.getMethod();
355: if (getTransactionType() == CONTAINER_TRANSACTION_TYPE) {
356: if (md.getTxAttribute() == MethodDesc.TX_NOT_SET) {
357: // trans-attribute not set !
358: // trace a warning and set the tx-attribute with the default value
359: logger.log(BasicLevel.WARN,
360: "trans-attribute missing for method "
361: + m.toString()
362: + " in message driven bean "
363: + getEjbName()
364: + " (set to the default value "
365: + MethodDesc.TX_STR_DEFAULT_VALUE_4_MDB
366: + ")");
367: md
368: .setTxAttribute(MethodDesc.TX_STR_DEFAULT_VALUE_4_MDB);
369: }
370: if ((md.getTxAttribute() != MethodDesc.TX_REQUIRED)
371: && (md.getTxAttribute() != MethodDesc.TX_NOT_SUPPORTED)) {
372: if (!"ejbTimeout".equals(md.getMethod().getName())) {
373: throw new DeploymentDescException(
374: md.getTxAttributeName()
375: + " is not a valid trans-attribute for method "
376: + m.toString()
377: + " in message driven bean "
378: + getEjbName());
379: }
380: }
381: } else {
382: if (md.getTxAttribute() != MethodDesc.TX_NOT_SET) {
383: throw new DeploymentDescException(
384: "trans-attribute for message driven bean "
385: + getEjbName()
386: + " must not be defined (transaction bean managed)");
387: }
388: }
389: }
390:
391: /**
392: * Check that the message diven bean descriptor is valid
393: *
394: * @exception DeploymentDescException
395: * thrown for non-valid bean
396: */
397: public void check() throws DeploymentDescException {
398: super .check();
399: }
400:
401: /**
402: * String representation of the object for test purpose
403: *
404: * @return String representation of this object
405: */
406: public String toString() {
407: StringBuffer ret = new StringBuffer();
408: ret.append(super .toString());
409: ret.append("\ngetTransactionType()="
410: + TRANS[getTransactionType()]);
411: if (hasSelector()) {
412: ret.append("\ngetSelector()=\"" + getSelector() + "\"");
413: }
414: ret.append("\ngetAcknowledgeMode()="
415: + ACKMODE[getAcknowledgeMode()]);
416: if (getDestinationType() != null) {
417: ret.append("\ngetDestinationType()="
418: + getDestinationType().getName());
419: }
420: ret.append("\ngetSubscriptionDurability()="
421: + SUBS_DURABILITY[getSubscriptionDurability()]);
422: ret.append("\ngetDestinationJndiName()="
423: + getDestinationJndiName());
424: return ret.toString();
425: }
426:
427: /**
428: * @return the MessageDriven ActivationConfigDesc object
429: */
430: public ActivationConfigDesc getMdActivationConfigDesc() {
431: return mdActivationConfigDesc;
432: }
433:
434: /**
435: * @return the JOnAS MessageDriven ActivationConfigDesc object
436: */
437: public ActivationConfigDesc getJonasMdActivationConfigDesc() {
438: return mdJonasActivationConfigDesc;
439: }
440:
441: private void configureAC(ActivationConfigDesc ac,
442: ClassLoader curLoader) throws DeploymentDescException {
443: try {
444: List acpl = ac.getActivationConfigPropertyList();
445: for (ListIterator lit = acpl.listIterator(); lit.hasNext();) {
446: ActivationConfigPropertyDesc el = (ActivationConfigPropertyDesc) lit
447: .next();
448: if (el.getActivationConfigPropertyName().equals(
449: "destinationType")) {
450: if (el.getActivationConfigPropertyValue().equals(
451: "javax.jms.Queue")) {
452: destinationType = javax.jms.Queue.class;
453: } else if (el.getActivationConfigPropertyValue()
454: .equals("javax.jms.Topic")) {
455: destinationType = javax.jms.Topic.class;
456: isTopicDestination = true;
457: } else {
458: try {
459: destinationType = curLoader
460: .loadClass(el
461: .getActivationConfigPropertyValue());
462: } catch (Exception ex) {
463: throw new DeploymentDescException(
464: "Invalid destination-type of "
465: + el
466: .getActivationConfigPropertyValue()
467: + "for ejb-name" + ejbName);
468: }
469: }
470: } else if (el.getActivationConfigPropertyName().equals(
471: "messageSelector")) {
472: selector = el.getActivationConfigPropertyValue();
473: } else if (el.getActivationConfigPropertyName().equals(
474: "acknowledgeMode")) {
475: if (el.getActivationConfigPropertyValue().equals(
476: "Auto-acknowledge")) {
477: acknowledgeMode = AUTO_ACKNOWLEDGE;
478: } else if (el.getActivationConfigPropertyValue()
479: .equals("Dups-ok-acknowledge")) {
480: acknowledgeMode = DUPS_OK_ACKNOWLEDGE;
481: }
482: } else if (el.getActivationConfigPropertyName().equals(
483: "subscriptionDurability")) {
484: if (el.getActivationConfigPropertyValue().equals(
485: "Durable")) {
486: subscriptionDurability = SUBS_DURABLE;
487: } else {
488: subscriptionDurability = SUBS_NON_DURABLE;
489: }
490: } else if (el.getActivationConfigPropertyName().equals(
491: "destination")) {
492: destination = el.getActivationConfigPropertyValue();
493: }
494: }
495: } catch (Exception ex) {
496: ex.printStackTrace();
497: }
498: }
499:
500: }
|