001: /**
002: *
003: * Licensed to the Apache Software Foundation (ASF) under one or more
004: * contributor license agreements. See the NOTICE file distributed with
005: * this work for additional information regarding copyright ownership.
006: * The ASF licenses this file to You under the Apache License, Version 2.0
007: * (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package org.apache.openejb.test.mdb;
018:
019: import javax.jms.Connection;
020: import javax.jms.ConnectionFactory;
021: import javax.jms.JMSException;
022: import javax.jms.Message;
023: import javax.jms.MessageListener;
024: import javax.jms.MessageProducer;
025: import javax.jms.ObjectMessage;
026: import javax.jms.Session;
027: import javax.naming.InitialContext;
028: import javax.naming.NamingException;
029: import java.io.Serializable;
030: import java.lang.reflect.InvocationTargetException;
031: import java.lang.reflect.Method;
032: import java.util.Map;
033: import java.util.TreeMap;
034:
035: public class MdbInvoker implements MessageListener {
036: private final Map<String, Method> signatures = new TreeMap<String, Method>();
037: private final Object target;
038: private Connection connection;
039: private Session session;
040: private ConnectionFactory connectionFactory;
041:
042: public MdbInvoker(ConnectionFactory connectionFactory, Object target)
043: throws JMSException {
044: this .target = target;
045: this .connectionFactory = connectionFactory;
046: for (Method method : target.getClass().getMethods()) {
047: String signature = MdbUtil.getSignature(method);
048: signatures.put(signature, method);
049: }
050: }
051:
052: public synchronized void destroy() {
053: MdbUtil.close(session);
054: session = null;
055: MdbUtil.close(connection);
056: connection = null;
057: }
058:
059: private synchronized Session getSession() throws JMSException {
060: connection = connectionFactory.createConnection();
061: connection.start();
062: boolean isBeanManagedTransaction = false;
063:
064: try {
065: new InitialContext().lookup("java:comp/UserTransaction");
066: isBeanManagedTransaction = true;
067: } catch (NamingException e) {
068: }
069:
070: if (isBeanManagedTransaction) {
071: session = connection.createSession(false,
072: Session.AUTO_ACKNOWLEDGE);
073: } else {
074: session = connection.createSession(true,
075: Session.SESSION_TRANSACTED);
076: }
077: return session;
078: }
079:
080: public void onMessage(Message message) {
081: if (!(message instanceof ObjectMessage))
082: return;
083:
084: try {
085: Session session = getSession();
086: if (session == null)
087: throw new IllegalStateException(
088: "Invoker has been destroyed");
089:
090: if (message == null)
091: throw new NullPointerException(
092: "request message is null");
093: if (!(message instanceof ObjectMessage))
094: throw new IllegalArgumentException(
095: "Expected a ObjectMessage request but got a "
096: + message.getClass().getName());
097: ObjectMessage responseMessage = (ObjectMessage) message;
098: Serializable object = responseMessage.getObject();
099: if (object == null)
100: throw new NullPointerException(
101: "object in ObjectMessage is null");
102: if (!(object instanceof Map)) {
103: if (message instanceof ObjectMessage)
104: throw new IllegalArgumentException(
105: "Expected a Map contained in the ObjectMessage request but got a "
106: + object.getClass().getName());
107: }
108: Map request = (Map) object;
109:
110: String signature = (String) request.get("method");
111: if (signature == null)
112: throw new NullPointerException(
113: "method property is null");
114: Method method = signatures.get(signature);
115: if (method == null)
116: throw new IllegalArgumentException("no such method "
117: + signature + "; known methods are "
118: + signatures.keySet());
119: Object[] args = (Object[]) request.get("args");
120:
121: boolean exception = false;
122: Object result = null;
123: try {
124: result = method.invoke(target, args);
125: } catch (IllegalAccessException e) {
126: result = e;
127: exception = true;
128: } catch (InvocationTargetException e) {
129: result = e.getCause();
130: if (result == null)
131: result = e;
132: exception = true;
133: }
134:
135: MessageProducer producer = null;
136: try {
137: // create response
138: Map<String, Object> response = new TreeMap<String, Object>();
139: if (exception) {
140: response.put("exception", "true");
141: }
142: response.put("return", result);
143:
144: // create response message
145: ObjectMessage resMessage = session
146: .createObjectMessage();
147: resMessage.setJMSCorrelationID(responseMessage
148: .getJMSCorrelationID());
149: resMessage.setObject((Serializable) response);
150:
151: // send response message
152: producer = session.createProducer(responseMessage
153: .getJMSReplyTo());
154: producer.send(resMessage);
155: // System.out.println("\n" +
156: // "***************************************\n" +
157: // "Sent response message: " + responseMessage + "\n" +
158: // " response map: " + response + "\n" +
159: // " to queue: " + message.getJMSReplyTo() + "\n" +
160: // "***************************************\n\n");
161: } catch (Exception e) {
162: e.printStackTrace();
163: } finally {
164: MdbUtil.close(producer);
165: destroy();
166: }
167: } catch (Throwable e) {
168: e.printStackTrace();
169: }
170: }
171: }
|