2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org
.argeo
.slc
.jms
;
19 import java
.io
.PrintWriter
;
20 import java
.io
.StringWriter
;
21 import java
.util
.ArrayList
;
22 import java
.util
.HashMap
;
23 import java
.util
.List
;
26 import javax
.jms
.JMSException
;
27 import javax
.jms
.Message
;
28 import javax
.jms
.Session
;
30 import org
.argeo
.slc
.SlcException
;
31 import org
.argeo
.slc
.msg
.ExecutionAnswer
;
32 import org
.springframework
.jms
.listener
.adapter
.MessageListenerAdapter
;
34 public class ServiceMessageListenerAdapter
extends MessageListenerAdapter
{
35 public final static String DEFAULT_METHOD_NAME_PARAMETER
= "action";
36 public final static String BODY_ARGUMENT
= "BODY";
38 private Map
<String
, List
<String
>> methodArguments
= new HashMap
<String
, List
<String
>>();
40 private static String methodNameParameter
= DEFAULT_METHOD_NAME_PARAMETER
;
43 protected Object
extractMessage(Message message
) throws JMSException
{
44 return new ExtractedMessage(message
);
48 protected String
getListenerMethodName(Message originalMessage
,
49 Object extractedMessage
) throws JMSException
{
50 return ((ExtractedMessage
) extractedMessage
).methodName
;
54 protected Object
[] buildListenerArguments(Object extractedMessage
) {
55 return ((ExtractedMessage
) extractedMessage
).arguments
;
59 public void onMessage(Message message
, Session session
) throws JMSException
{
60 try {// hacked and simplified from parent class
61 // Regular case: find a handler method reflectively.
62 Object convertedMessage
= extractMessage(message
);
63 String methodName
= getListenerMethodName(message
, convertedMessage
);
65 // Invoke the handler method with appropriate arguments.
66 Object
[] listenerArguments
= buildListenerArguments(convertedMessage
);
67 Object result
= invokeListenerMethod(methodName
, listenerArguments
);
69 handleResult(result
, message
, session
);
71 ExecutionAnswer answer
= ExecutionAnswer
.ok("Execution of "
72 + methodName
+ " on " + getDelegate() + " succeeeded.");
73 Message okMessage
= getMessageConverter().toMessage(answer
,
75 sendResponse(session
, getResponseDestination(message
,
76 okMessage
, session
), okMessage
);
78 } catch (Exception e
) {
82 StringWriter writer
= new StringWriter();
83 e
.printStackTrace(new PrintWriter(writer
));
84 ExecutionAnswer answer
= ExecutionAnswer
.error(writer
.toString());
85 Message errorMessage
= getMessageConverter().toMessage(answer
,
87 sendResponse(session
, getResponseDestination(message
, errorMessage
,
88 session
), errorMessage
);
92 protected class ExtractedMessage
{
93 private final String methodName
;
94 private final Object
[] arguments
;
95 // private final Message originalMessage;
97 public ExtractedMessage(Message originalMessage
) throws JMSException
{
98 // this.originalMessage = originalMessage;
100 if (!originalMessage
.propertyExists(methodNameParameter
))
101 throw new SlcException("No property " + methodNameParameter
102 + " in incoming message,"
103 + " cannot determine service method");
105 methodName
= originalMessage
.getStringProperty(methodNameParameter
);
107 if (!methodArguments
.containsKey(methodName
)) {// no arg specified
108 arguments
= new Object
[0];
110 List
<String
> parameterNames
= methodArguments
.get(methodName
);
111 List
<Object
> arguments
= new ArrayList
<Object
>();
113 for (String name
: parameterNames
) {
114 if (name
.equals(BODY_ARGUMENT
)) {
115 Object body
= getMessageConverter().fromMessage(
119 if (!originalMessage
.propertyExists(name
))
120 throw new SlcException("No property " + name
121 + " in incoming message,"
122 + " cannot determine argument #" + count
);
123 arguments
.add(originalMessage
.getObjectProperty(name
));
127 this.arguments
= arguments
.toArray();
132 public void setMethodArguments(Map
<String
, List
<String
>> methodArguments
) {
133 this.methodArguments
= methodArguments
;
136 public static void setMethodNameParameter(String methodNameParameter
) {
137 ServiceMessageListenerAdapter
.methodNameParameter
= methodNameParameter
;