]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/ServiceMessageListenerAdapter.java
Introduce JMS based notifications
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.activemq / src / main / java / org / argeo / slc / jms / ServiceMessageListenerAdapter.java
1 package org.argeo.slc.jms;
2
3 import java.io.PrintWriter;
4 import java.io.StringWriter;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9
10 import javax.jms.JMSException;
11 import javax.jms.Message;
12 import javax.jms.Session;
13
14 import org.argeo.slc.SlcException;
15 import org.argeo.slc.msg.ExecutionAnswer;
16 import org.springframework.jms.listener.adapter.MessageListenerAdapter;
17
18 public class ServiceMessageListenerAdapter extends MessageListenerAdapter {
19 public final static String DEFAULT_METHOD_NAME_PARAMETER = "action";
20 public final static String BODY_ARGUMENT = "BODY";
21
22 private Map<String, List<String>> methodArguments = new HashMap<String, List<String>>();
23
24 private static String methodNameParameter = DEFAULT_METHOD_NAME_PARAMETER;
25
26 @Override
27 protected Object extractMessage(Message message) throws JMSException {
28 return new ExtractedMessage(message);
29 }
30
31 @Override
32 protected String getListenerMethodName(Message originalMessage,
33 Object extractedMessage) throws JMSException {
34 return ((ExtractedMessage) extractedMessage).methodName;
35 }
36
37 @Override
38 protected Object[] buildListenerArguments(Object extractedMessage) {
39 return ((ExtractedMessage) extractedMessage).arguments;
40 }
41
42 @Override
43 public void onMessage(Message message, Session session) throws JMSException {
44 try {// hacked and simplified from parent class
45 // Regular case: find a handler method reflectively.
46 Object convertedMessage = extractMessage(message);
47 String methodName = getListenerMethodName(message, convertedMessage);
48
49 // Invoke the handler method with appropriate arguments.
50 Object[] listenerArguments = buildListenerArguments(convertedMessage);
51 Object result = invokeListenerMethod(methodName, listenerArguments);
52 if (result != null) {
53 handleResult(result, message, session);
54 } else {
55 ExecutionAnswer answer = ExecutionAnswer.ok("Execution of "
56 + methodName + " on " + getDelegate() + " succeeeded.");
57 Message okMessage = getMessageConverter().toMessage(answer,
58 session);
59 sendResponse(session, getResponseDestination(message,
60 okMessage, session), okMessage);
61 }
62 } catch (Exception e) {
63 if (session == null)
64 return;
65
66 StringWriter writer = new StringWriter();
67 e.printStackTrace(new PrintWriter(writer));
68 ExecutionAnswer answer = ExecutionAnswer.error(writer.toString());
69 Message errorMessage = getMessageConverter().toMessage(answer,
70 session);
71 sendResponse(session, getResponseDestination(message, errorMessage,
72 session), errorMessage);
73 }
74 }
75
76 protected class ExtractedMessage {
77 private final String methodName;
78 private final Object[] arguments;
79 private final Message originalMessage;
80
81 public ExtractedMessage(Message originalMessage) throws JMSException {
82 this.originalMessage = originalMessage;
83
84 if (!originalMessage.propertyExists(methodNameParameter))
85 throw new SlcException("No property " + methodNameParameter
86 + " in incoming message,"
87 + " cannot determine service method");
88
89 methodName = originalMessage.getStringProperty(methodNameParameter);
90
91 if (!methodArguments.containsKey(methodName)) {// no arg specified
92 arguments = new Object[0];
93 } else {
94 List<String> parameterNames = methodArguments.get(methodName);
95 List<Object> arguments = new ArrayList<Object>();
96 int count = 0;
97 for (String name : parameterNames) {
98 if (name.equals(BODY_ARGUMENT)) {
99 Object body = getMessageConverter().fromMessage(
100 originalMessage);
101 arguments.add(body);
102 } else {
103 if (!originalMessage.propertyExists(name))
104 throw new SlcException("No property " + name
105 + " in incoming message,"
106 + " cannot determine argument #" + count);
107 arguments.add(originalMessage.getObjectProperty(name));
108 }
109 count++;
110 }
111 this.arguments = arguments.toArray();
112 }
113 }
114 }
115
116 public void setMethodArguments(Map<String, List<String>> methodArguments) {
117 this.methodArguments = methodArguments;
118 }
119
120 public static void setMethodNameParameter(String methodNameParameter) {
121 ServiceMessageListenerAdapter.methodNameParameter = methodNameParameter;
122 }
123
124
125 }