]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/ServiceMessageListenerAdapter.java
ActiveMQ and Castor integration
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.activemq / src / main / java / org / argeo / slc / jms / ServiceMessageListenerAdapter.java
diff --git a/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/ServiceMessageListenerAdapter.java b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/ServiceMessageListenerAdapter.java
new file mode 100644 (file)
index 0000000..01ca721
--- /dev/null
@@ -0,0 +1,125 @@
+package org.argeo.slc.jms;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.msg.ExecutionAnswer;
+import org.springframework.jms.listener.adapter.MessageListenerAdapter;
+
+public class ServiceMessageListenerAdapter extends MessageListenerAdapter {
+       public final static String DEFAULT_METHOD_NAME_PARAMETER = "action";
+       public final static String BODY_ARGUMENT = "BODY";
+
+       private Map<String, List<String>> methodArguments = new HashMap<String, List<String>>();
+
+       private static String methodNameParameter = DEFAULT_METHOD_NAME_PARAMETER;
+
+       @Override
+       protected Object extractMessage(Message message) throws JMSException {
+               return new ExtractedMessage(message);
+       }
+
+       @Override
+       protected String getListenerMethodName(Message originalMessage,
+                       Object extractedMessage) throws JMSException {
+               return ((ExtractedMessage) extractedMessage).methodName;
+       }
+
+       @Override
+       protected Object[] buildListenerArguments(Object extractedMessage) {
+               return ((ExtractedMessage) extractedMessage).arguments;
+       }
+
+       @Override
+       public void onMessage(Message message, Session session) throws JMSException {
+               try {// hacked and simplified from parent class
+                       // Regular case: find a handler method reflectively.
+                       Object convertedMessage = extractMessage(message);
+                       String methodName = getListenerMethodName(message, convertedMessage);
+
+                       // Invoke the handler method with appropriate arguments.
+                       Object[] listenerArguments = buildListenerArguments(convertedMessage);
+                       Object result = invokeListenerMethod(methodName, listenerArguments);
+                       if (result != null) {
+                               handleResult(result, message, session);
+                       } else {
+                               ExecutionAnswer answer = ExecutionAnswer.ok("Execution of "
+                                               + methodName + " on " + getDelegate() + " succeeeded.");
+                               Message okMessage = getMessageConverter().toMessage(answer,
+                                               session);
+                               sendResponse(session, getResponseDestination(message,
+                                               okMessage, session), okMessage);
+                       }
+               } catch (Exception e) {
+                       if (session == null)
+                               return;
+
+                       StringWriter writer = new StringWriter();
+                       e.printStackTrace(new PrintWriter(writer));
+                       ExecutionAnswer answer = ExecutionAnswer.error(writer.toString());
+                       Message errorMessage = getMessageConverter().toMessage(answer,
+                                       session);
+                       sendResponse(session, getResponseDestination(message, errorMessage,
+                                       session), errorMessage);
+               }
+       }
+
+       protected class ExtractedMessage {
+               private final String methodName;
+               private final Object[] arguments;
+               private final Message originalMessage;
+
+               public ExtractedMessage(Message originalMessage) throws JMSException {
+                       this.originalMessage = originalMessage;
+
+                       if (!originalMessage.propertyExists(methodNameParameter))
+                               throw new SlcException("No property " + methodNameParameter
+                                               + " in incoming message,"
+                                               + " cannot determine service method");
+
+                       methodName = originalMessage.getStringProperty(methodNameParameter);
+
+                       if (!methodArguments.containsKey(methodName)) {// no arg specified
+                               arguments = new Object[0];
+                       } else {
+                               List<String> parameterNames = methodArguments.get(methodName);
+                               List<Object> arguments = new ArrayList<Object>();
+                               int count = 0;
+                               for (String name : parameterNames) {
+                                       if (name.equals(BODY_ARGUMENT)) {
+                                               Object body = getMessageConverter().fromMessage(
+                                                               originalMessage);
+                                               arguments.add(body);
+                                       } else {
+                                               if (!originalMessage.propertyExists(name))
+                                                       throw new SlcException("No property " + name
+                                                                       + " in incoming message,"
+                                                                       + " cannot determine argument #" + count);
+                                               arguments.add(originalMessage.getObjectProperty(name));
+                                       }
+                                       count++;
+                               }
+                               this.arguments = arguments.toArray();
+                       }
+               }
+       }
+
+       public void setMethodArguments(Map<String, List<String>> methodArguments) {
+               this.methodArguments = methodArguments;
+       }
+
+       public static void setMethodNameParameter(String methodNameParameter) {
+               ServiceMessageListenerAdapter.methodNameParameter = methodNameParameter;
+       }
+       
+       
+}