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 java.util.HashMap;
020    import java.util.Map;
021    import java.util.Set;
022    import javax.activation.DataHandler;
023    
024    import org.apache.camel.Exchange;
025    import org.apache.camel.util.MessageHelper;
026    
027    /**
028     * The default implementation of {@link org.apache.camel.Message}
029     *
030     * @version $Revision: 789087 $
031     */
032    public class DefaultMessage extends MessageSupport {
033        private Map<String, Object> headers;
034        private Map<String, DataHandler> attachments;
035    
036        @Override
037        public String toString() {
038            return MessageHelper.extractBodyForLogging(this);
039        }
040    
041        public Object getHeader(String name) {
042            return getHeaders().get(name);
043        }
044    
045        public <T> T getHeader(String name, Class<T> type) {
046            Object value = getHeader(name);
047    
048            // eager same instance type test to avoid the overhead of invoking the type converter
049            // if already same type
050            if (type.isInstance(value)) {
051                return type.cast(value);
052            }
053    
054            Exchange e = getExchange();
055            if (e != null) {
056                return e.getContext().getTypeConverter().convertTo(type, e, value);
057            } else {
058                return (T) value;
059            }
060        }
061    
062        public void setHeader(String name, Object value) {
063            if (headers == null) {
064                headers = createHeaders();
065            }
066            headers.put(name, value);
067        }
068    
069        public Object removeHeader(String name) {
070            if (headers != null) {
071                return headers.remove(name);
072            } else {
073                return null;
074            }
075        }
076    
077        public Map<String, Object> getHeaders() {
078            if (headers == null) {
079                headers = createHeaders();
080            }
081            return headers;
082        }
083    
084        public void setHeaders(Map<String, Object> headers) {
085            this.headers = headers;
086        }
087    
088        public DefaultMessage newInstance() {
089            return new DefaultMessage();
090        }
091    
092        /**
093         * A factory method to lazily create the headers to make it easy to create
094         * efficient Message implementations which only construct and populate the
095         * Map on demand
096         *
097         * @return return a newly constructed Map possibly containing headers from
098         *         the underlying inbound transport
099         */
100        protected Map<String, Object> createHeaders() {
101            Map<String, Object> map = new HashMap<String, Object>();
102            populateInitialHeaders(map);
103            return map;
104        }
105    
106        /**
107         * A strategy method populate the initial set of headers on an inbound
108         * message from an underlying binding
109         *
110         * @param map is the empty header map to populate
111         */
112        protected void populateInitialHeaders(Map<String, Object> map) {
113        }
114    
115        /**
116         * A factory method to lazily create the attachments to make it easy to
117         * create efficient Message implementations which only construct and
118         * populate the Map on demand
119         *
120         * @return return a newly constructed Map
121         */
122        protected Map<String, DataHandler> createAttachments() {
123            Map<String, DataHandler> map = new HashMap<String, DataHandler>();
124            populateInitialAttachments(map);
125            return map;
126        }
127    
128        /**
129         * A strategy method populate the initial set of attachments on an inbound
130         * message from an underlying binding
131         *
132         * @param map is the empty attachment map to populate
133         */
134        protected void populateInitialAttachments(Map<String, DataHandler> map) {
135        }
136    
137        public void addAttachment(String id, DataHandler content) {
138            if (attachments == null) {
139                attachments = createAttachments();
140            }
141            attachments.put(id, content);
142        }
143    
144        public DataHandler getAttachment(String id) {
145            return getAttachments().get(id);
146        }
147    
148        public Set<String> getAttachmentNames() {
149            if (attachments == null) {
150                attachments = createAttachments();
151            }
152            return attachments.keySet();
153        }
154    
155        public void removeAttachment(String id) {
156            if (attachments != null && attachments.containsKey(id)) {
157                attachments.remove(id);
158            }
159        }
160    
161        public Map<String, DataHandler> getAttachments() {
162            if (attachments == null) {
163                attachments = createAttachments();
164            }
165            return attachments;
166        }
167    
168        public void setAttachments(Map<String, DataHandler> attachments) {
169            this.attachments = attachments;
170        }
171    
172        public boolean hasAttachments() {
173            if (attachments == null) {
174                attachments = createAttachments();
175            }
176            return this.attachments != null && this.attachments.size() > 0;
177        }
178    
179        /**
180         * Returns true if the headers have been mutated in some way
181         */
182        protected boolean hasPopulatedHeaders() {
183            return headers != null;
184        }
185    
186        public String createExchangeId() {
187            return null;
188        }
189    }