KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > connectors > inflow > MessageEndpointInvocationHandler


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

24 package com.sun.enterprise.connectors.inflow;
25
26 import com.sun.ejb.MessageBeanListener;
27 import com.sun.ejb.MessageBeanProtocolManager;
28 import com.sun.enterprise.J2EETransactionManager;
29 import com.sun.enterprise.Switch;
30 import com.sun.enterprise.connectors.ConnectorConstants;
31 import com.sun.logging.LogDomains;
32 import java.lang.reflect.InvocationHandler JavaDoc;
33 import java.lang.reflect.Method JavaDoc;
34 import java.lang.reflect.Proxy JavaDoc;
35 import java.util.logging.Level JavaDoc;
36 import java.util.logging.Logger JavaDoc;
37 import com.sun.enterprise.Switch;
38 import com.sun.enterprise.admin.monitor.callflow.*;
39
40 /**
41  * This class handles the implementation of two interfaces:
42  * 1) javax.resource.spi.endpoint.MessageEndpoint;
43  * 2) any message listener type (e.g. javax.jms.MessageListener,
44  * OR javax.xml.messaging.OnewayListener)
45  *
46  * @author Qingqing Ouyang
47  */

48
49 public final class MessageEndpointInvocationHandler
50     implements InvocationHandler JavaDoc {
51
52     private MessageBeanListener listener_;
53     private boolean beforeDeliveryCalled = false;
54
55     private boolean throwTransactedExceptions_ = true;
56     private MessageBeanProtocolManager messageBeanPM_;
57
58     private static String JavaDoc MESSAGE_ENDPOINT
59     = "javax.resource.spi.endpoint.MessageEndpoint";
60
61     private static String JavaDoc THROW_TRANSACTED_EXCEPTIONS_PROP
62         = "resourceadapter.throw.transacted.exceptions";
63
64     private static Logger JavaDoc logger =
65     LogDomains.getLogger(LogDomains.RSR_LOGGER);
66     
67     private Agent callFlowAgent = Switch.getSwitch().getCallFlowAgent();
68     
69     /**
70      * Constructs a MessageEndpointInvocationHandler.
71      *
72      * @param listener <code>MessageBeanListener</code> to deliver messages.
73      * @param pm Protocol object to MDB container.
74      */

75     public MessageEndpointInvocationHandler(MessageBeanListener listener,
76                                             MessageBeanProtocolManager pm) {
77         this.listener_ = listener;
78         this.messageBeanPM_ = pm;
79
80     throwTransactedExceptions_ =
81         ConnectorConstants.THROW_TRANSACTED_EXCEPTIONS;
82
83         if( throwTransactedExceptions_ != true ) {
84             logger.info(ConnectorConstants.THROW_TRANSACTED_EXCEPTIONS_PROP +
85                     " set to false");
86         }
87
88     }
89
90     /**
91      * Invokes the method
92      *
93      * @param proxy Object
94      * @param method <code>Method</code> to be executed.
95      * @param args Arguments
96      * @throws Throwable.
97      */

98     public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args)
99         throws Throwable JavaDoc {
100
101         // NOTE : be careful with "args" parameter. It is null
102
// if method signature has 0 arguments.
103

104         String JavaDoc methodClassName = method.getDeclaringClass().getName();
105         String JavaDoc methodName = method.getName();
106         Object JavaDoc returnValue = null;
107
108         if (logger.isLoggable(Level.FINEST)) {
109             
110             String JavaDoc msg = "Invoking method [" + methodName
111                 + "] from class [" + methodClassName + "]";
112             logger.log(Level.FINEST, msg);
113         }
114
115         // delegate the beforeDelivery and afterDelivery calls
116
// to the MDB container
117
if (MESSAGE_ENDPOINT.equals(methodClassName)) {
118
119             if ("beforeDelivery".equals(methodName)) {
120                 Method JavaDoc onMessageMethod = (Method JavaDoc) args[0];
121                 beforeDeliveryCalled = true;
122                 listener_.beforeMessageDelivery(onMessageMethod, false);
123
124             } else if ("afterDelivery".equals(methodName)) {
125                 beforeDeliveryCalled = false; //reset
126
listener_.afterMessageDelivery();
127                 
128             } else if ("release".equals(methodName)) {
129         messageBeanPM_.destroyMessageBeanListener(listener_);
130             } else {
131                 logger.log(Level.SEVERE, "endpointfactory.method_not_defined",
132                         new Object JavaDoc[] {methodName, MESSAGE_ENDPOINT});
133                 throw new RuntimeException JavaDoc(methodName);
134             }
135             
136         } else if ("java.lang.Object".equals(methodClassName)) {
137             returnValue = invokeJavaObjectMethod(this, method, args);
138             
139         } else { //the rest are considered methods for message delivery
140

141             //RA did not call beforeDelivery, handle it here
142
if (!beforeDeliveryCalled) {
143                 J2EETransactionManager txManager =
144                     Switch.getSwitch().getTransactionManager();
145                 boolean txImported = (txManager.getTransaction() != null);
146                 listener_.beforeMessageDelivery(method, txImported);
147             }
148             
149             try {
150                 //returnValue = listener_.deliverMessage(method, args);
151

152                 // Notify Call Flow Agent.
153
try{
154                     callFlowAgent.requestStart(
155                             RequestType.REMOTE_ASYNC_MESSAGE);
156                     callFlowAgent.startTime(
157                             ContainerTypeOrApplicationType.EJB_CONTAINER);
158                     // This is an opportunity to provide callerIPAddress and
159
// remote user name. But since this information is not
160
// currently available. So, we don't call
161
// callFlowAgent.setRequestInfo().
162
} catch (Exception JavaDoc ex){
163                     logger.log(Level.WARNING, "Call Flow Agent threw exception" + ex);
164                 }
165     
166                 returnValue = listener_.deliverMessage(args);
167             } catch (Throwable JavaDoc ex) {
168                 if( messageBeanPM_.isDeliveryTransacted(method) ) {
169                     if( throwTransactedExceptions_ ) {
170                         throw ex;
171                     } else {
172                         logger.log(Level.INFO, "Resource adapter eating " +
173                                    " transacted exception", ex);
174                     }
175                 } else {
176                     throw ex;
177                 }
178             } finally {
179
180             // Send end notification to call flow agent
181
try{
182                     callFlowAgent.endTime();
183                     callFlowAgent.requestEnd();
184                 } catch (Exception JavaDoc ex){
185                     logger.log(Level.WARNING, "Call Flow Agent threw exception" + ex);
186                 }
187     
188                 //assume that if the RA didn't call beforeDelivery, it
189
//would not call afterDelivery. o.w. it will be hard to
190
//to determine when to pair the afterDelivery call.
191
if (!beforeDeliveryCalled) {
192                     listener_.afterMessageDelivery();
193                 }
194                 beforeDeliveryCalled = false;
195             }
196         }
197         return returnValue;
198     }
199
200     /**
201      * This is the same implementation in
202      * com.sun.ejb.container.InvocationHandlerUtil
203      * Need to abstract out at some point.
204      */

205     private Object JavaDoc invokeJavaObjectMethod(
206             InvocationHandler JavaDoc handler, Method JavaDoc method, Object JavaDoc[] args)
207         throws RuntimeException JavaDoc {
208
209         Object JavaDoc returnValue = null;
210         
211         // Can only be one of :
212
// boolean java.lang.Object.equals(Object)
213
// int java.lang.Object.hashCode()
214
// String java.lang.Object.toString()
215
//
216
// Optimize by comparing as few characters as possible.
217

218         switch( method.getName().charAt(0) ) {
219             case 'e' :
220                 Object JavaDoc other = Proxy.isProxyClass(args[0].getClass()) ?
221                     Proxy.getInvocationHandler(args[0]) : args[0];
222                 returnValue = new Boolean JavaDoc(handler.equals(other));
223                 break;
224             case 'h' :
225                 returnValue = new Integer JavaDoc(handler.hashCode());
226                 break;
227             case 't' :
228                 returnValue = handler.toString();
229                 break;
230             default :
231                 throw new RuntimeException JavaDoc(method.getName());
232         }
233
234         return returnValue;
235     }
236 }
237     
238
Popular Tags