001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  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.apache.activemq.util.oxm;
019    
020    import java.io.Serializable;
021    
022    import javax.jms.JMSException;
023    import javax.jms.Message;
024    import javax.jms.MessageConsumer;
025    import javax.jms.MessageProducer;
026    import javax.jms.ObjectMessage;
027    import javax.jms.Session;
028    import javax.jms.TextMessage;
029    
030    import org.apache.activemq.MessageTransformerSupport;
031    
032    import com.thoughtworks.xstream.XStream;
033    import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
034    
035    /**
036     * Abstract class used as a base for implementing transformers from object to text messages (in XML/JSON format)
037     * and vice versa using.
038     * Supports plugging of custom marshallers
039     */
040    public abstract class AbstractXMLMessageTransformer extends
041                    MessageTransformerSupport {
042    
043        protected MessageTransform transformType;
044    
045        /**
046         * Defines the type of transformation. If XML (default), - producer
047         * transformation transforms from Object to XML. - consumer transformation
048         * transforms from XML to Object. If OBJECT, - producer transformation
049         * transforms from XML to Object. - consumer transformation transforms from
050         * Object to XML. If ADAPTIVE, - producer transformation transforms from
051         * Object to XML, or XML to Object depending on the type of the original
052         * message - consumer transformation transforms from XML to Object, or
053         * Object to XML depending on the type of the original message
054         */
055        public enum MessageTransform {
056            XML, OBJECT, ADAPTIVE
057        };
058    
059    
060        public AbstractXMLMessageTransformer() {
061            this(MessageTransform.XML);
062        }
063    
064        public AbstractXMLMessageTransformer(MessageTransform transformType) {
065            this.transformType = transformType;
066        }
067    
068        public Message consumerTransform(Session session, MessageConsumer consumer, Message message) throws JMSException {
069            switch (transformType) {
070            case XML:
071                return (message instanceof TextMessage) ? textToObject(session, (TextMessage)message) : message;
072            case OBJECT:
073                return (message instanceof ObjectMessage) ? objectToText(session, (ObjectMessage)message) : message;
074            case ADAPTIVE:
075                return (message instanceof TextMessage) ? textToObject(session, (TextMessage)message) : (message instanceof ObjectMessage) ? objectToText(session, (ObjectMessage)message) : message;
076            default:
077            }
078            return message;
079        }
080    
081        public Message producerTransform(Session session, MessageProducer producer, Message message) throws JMSException {
082            switch (transformType) {
083            case XML:
084                return (message instanceof ObjectMessage) ? objectToText(session, (ObjectMessage)message) : message;
085            case OBJECT:
086                return (message instanceof TextMessage) ? textToObject(session, (TextMessage)message) : message;
087            case ADAPTIVE:
088                return (message instanceof TextMessage) ? textToObject(session, (TextMessage)message) : (message instanceof ObjectMessage) ? objectToText(session, (ObjectMessage)message) : message;
089            default:
090            }
091            return message;
092        }
093    
094        public MessageTransform getTransformType() {
095            return transformType;
096        }
097    
098        public void setTransformType(MessageTransform transformType) {
099            this.transformType = transformType;
100        }
101    
102        /**
103         * Transforms an incoming XML encoded {@link TextMessage} to an
104         * {@link ObjectMessage}
105         * 
106         * @param session - JMS session currently being used
107         * @param textMessage - text message to transform to object message
108         * @return ObjectMessage
109         * @throws JMSException
110         */
111        protected ObjectMessage textToObject(Session session, TextMessage textMessage) throws JMSException {
112            Object object = unmarshall(session, textMessage);
113            if (object instanceof Serializable) {
114                ObjectMessage answer = session.createObjectMessage((Serializable)object);
115                copyProperties(textMessage, answer);
116                return answer;
117            } else {
118                throw new JMSException("Object is not serializable: " + object);
119            }
120        }
121    
122        /**
123         * Transforms an incoming {@link ObjectMessage} to an XML encoded
124         * {@link TextMessage}
125         * 
126         * @param session - JMS session currently being used
127         * @param objectMessage - object message to transform to text message
128         * @return XML encoded TextMessage
129         * @throws JMSException
130         */
131        protected TextMessage objectToText(Session session, ObjectMessage objectMessage) throws JMSException {
132            TextMessage answer = session.createTextMessage(marshall(session, objectMessage));
133            copyProperties(objectMessage, answer);
134            return answer;
135        }
136    
137        /**
138         * Marshalls the Object in the {@link ObjectMessage} to a string using XML
139         * encoding
140         */
141        protected abstract String marshall(Session session, ObjectMessage objectMessage) throws JMSException;
142    
143        /**
144         * Unmarshalls the XML encoded message in the {@link TextMessage} to an
145         * Object
146         */
147        protected abstract Object unmarshall(Session session, TextMessage textMessage) throws JMSException;
148    
149    }