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    }