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    package org.apache.camel.impl;
018    
019    import org.apache.camel.CamelContext;
020    import org.apache.camel.Exchange;
021    import org.apache.camel.Message;
022    import org.apache.camel.NoTypeConversionAvailableException;
023    import org.apache.camel.TypeConverter;
024    import org.apache.camel.util.UuidGenerator;
025    
026    /**
027     * A base class for implementation inheritence providing the core
028     * {@link Message} body handling features but letting the derived class deal
029     * with headers.
030     *
031     * Unless a specific provider wishes to do something particularly clever with
032     * headers you probably want to just derive from {@link DefaultMessage}
033     *
034     * @version $Revision: 1290 $
035     */
036    public abstract class MessageSupport implements Message {
037        private static final UuidGenerator DEFALT_ID_GENERATOR = new UuidGenerator();
038        private Exchange exchange;
039        private Object body;
040        private String messageId;
041    
042        public Object getBody() {
043            if (body == null) {
044                body = createBody();
045            }
046            return body;
047        }
048    
049        @SuppressWarnings({"unchecked" })
050        public <T> T getBody(Class<T> type) {
051            return getBody(type, getBody());
052        }
053    
054        protected <T> T getBody(Class<T> type, Object body) {
055            Exchange e = getExchange();
056            if (e != null) {
057                CamelContext camelContext = e.getContext();
058                if (camelContext != null) {
059                    TypeConverter converter = camelContext.getTypeConverter();
060                    try {
061                        // lets first try converting the message itself first
062                        // as for some types like InputStream v Reader its more efficient to do the transformation
063                        // from the Message itself as its got efficient implementations of them, before trying the
064                        // payload
065                        return converter.convertTo(type, e, body);
066                    } catch (NoTypeConversionAvailableException ex) {
067                        // ignore
068                    }
069                    return converter.convertTo(type, this);
070                }
071            }
072            return (T)getBody();
073        }
074    
075        public void setBody(Object body) {
076            this.body = body;
077        }
078    
079        public <T> void setBody(Object value, Class<T> type) {
080            Exchange e = getExchange();
081            if (e != null) {
082                T v = e.getContext().getTypeConverter().convertTo(type, e, value);
083                if (v != null) {
084                    value = v;
085                }
086            }
087            setBody(value);
088        }
089    
090        public Message copy() {
091            Message answer = newInstance();
092            answer.copyFrom(this);
093            return answer;
094        }
095    
096        public void copyFrom(Message that) {
097            setMessageId(that.getMessageId());
098            setBody(that.getBody());
099            getHeaders().putAll(that.getHeaders());
100            getAttachments().putAll(that.getAttachments());
101        }
102    
103        public Exchange getExchange() {
104            return exchange;
105        }
106    
107        public void setExchange(Exchange exchange) {
108            this.exchange = exchange;
109        }
110    
111        /**
112         * Returns a new instance
113         */
114        public abstract Message newInstance();
115    
116        /**
117         * A factory method to allow a provider to lazily create the message body
118         * for inbound messages from other sources
119         *
120         * @return the value of the message body or null if there is no value
121         *         available
122         */
123        protected Object createBody() {
124            return null;
125        }
126    
127        public String getMessageId() {
128            if (messageId == null) {
129                messageId = createMessageId();
130            }
131            return this.messageId;
132        }
133    
134        public void setMessageId(String messageId) {
135            this.messageId = messageId;
136        }
137    
138        /**
139         * Lets allow implementations to auto-create a messageId
140         */
141        protected String createMessageId() {
142            return DEFALT_ID_GENERATOR.generateId();
143        }
144    }