001 /** 002 * 003 * Copyright 2005 LogicBlaze, Inc. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 **/ 018 package org.logicblaze.lingo.jms.marshall; 019 020 import org.logicblaze.lingo.LingoInvocation; 021 import org.logicblaze.lingo.jms.Requestor; 022 import org.apache.commons.logging.Log; 023 import org.apache.commons.logging.LogFactory; 024 import org.springframework.remoting.support.RemoteInvocation; 025 import org.springframework.remoting.support.RemoteInvocationResult; 026 027 import javax.jms.JMSException; 028 import javax.jms.Message; 029 import javax.jms.ObjectMessage; 030 031 /** 032 * Represents the strategy of marshalling of requests and responses in and out of JMS messages 033 * 034 * @version $Revision: 1.2 $ 035 */ 036 public class DefaultMarshaller implements Marshaller { 037 038 private static final Log log = LogFactory.getLog(DefaultMarshaller.class); 039 040 private boolean ignoreInvalidMessages; 041 042 public Message createRequestMessage(Requestor requestor, LingoInvocation invocation) throws JMSException { 043 ObjectMessage message = requestor.getSession().createObjectMessage(invocation); 044 appendMessageHeaders(message, requestor, invocation); 045 return message; 046 } 047 048 public RemoteInvocationResult extractInvocationResult(Message message) throws JMSException { 049 handleInvocationResultHeaders(message); 050 if (message instanceof ObjectMessage) { 051 ObjectMessage objectMessage = (ObjectMessage) message; 052 Object body = objectMessage.getObject(); 053 if (body instanceof RemoteInvocationResult) { 054 return (RemoteInvocationResult) body; 055 } 056 } 057 return onInvalidClientMessage(message); 058 } 059 060 public RemoteInvocation readRemoteInvocation(Message message) throws JMSException { 061 handleInvocationHeaders(message); 062 if (message instanceof ObjectMessage) { 063 ObjectMessage objectMessage = (ObjectMessage) message; 064 Object body = objectMessage.getObject(); 065 if (body instanceof RemoteInvocation) { 066 return (RemoteInvocation) body; 067 } 068 } 069 return onInvalidMessage(message); 070 } 071 072 // Properties 073 //------------------------------------------------------------------------- 074 public boolean isIgnoreInvalidMessages() { 075 return ignoreInvalidMessages; 076 } 077 078 /** 079 * Sets whether invalidly formatted messages should be silently ignored or not 080 */ 081 public void setIgnoreInvalidMessages(boolean ignoreInvalidMessages) { 082 this.ignoreInvalidMessages = ignoreInvalidMessages; 083 } 084 085 // Implementation methods 086 //------------------------------------------------------------------------- 087 protected RemoteInvocationResult onInvalidClientMessage(Message message) throws JMSException { 088 throw new JMSException("Invalid response message: " + message); 089 } 090 091 /** 092 * Handle invalid messages by just logging, though a different implementation 093 * may wish to throw exceptions 094 */ 095 protected RemoteInvocation onInvalidMessage(Message message) { 096 String text = "Invalid message will be discarded: " + message; 097 log.info(text); 098 if (!ignoreInvalidMessages) { 099 throw new RuntimeException(text); 100 } 101 return null; 102 } 103 104 /** 105 * A strategy method for derived classes to allow them a plugin point to perform custom header processing 106 */ 107 protected void appendMessageHeaders(Message message, Requestor requestor, LingoInvocation invocation) { 108 } 109 110 111 /** 112 * A strategy method to allow derived classes to process the headers in a special way 113 */ 114 protected void handleInvocationHeaders(Message message) { 115 } 116 117 /** 118 * A strategy method to allow derived classes to process the headers in a special way 119 */ 120 protected void handleInvocationResultHeaders(Message message) { 121 } 122 123 }