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.Exchange;
020 import org.apache.camel.InvalidPayloadException;
021 import org.apache.camel.Message;
022 import org.apache.camel.TypeConverter;
023 import org.apache.camel.util.UuidGenerator;
024
025 /**
026 * A base class for implementation inheritence providing the core
027 * {@link Message} body handling features but letting the derived class deal
028 * with headers.
029 *
030 * Unless a specific provider wishes to do something particularly clever with
031 * headers you probably want to just derive from {@link DefaultMessage}
032 *
033 * @version $Revision: 789087 $
034 */
035 public abstract class MessageSupport implements Message {
036 private static final UuidGenerator DEFALT_ID_GENERATOR = new UuidGenerator();
037 private Exchange exchange;
038 private Object body;
039 private String messageId;
040
041 public Object getBody() {
042 if (body == null) {
043 body = createBody();
044 }
045 return body;
046 }
047
048 public <T> T getBody(Class<T> type) {
049 return getBody(type, getBody());
050 }
051
052 public Object getMandatoryBody() throws InvalidPayloadException {
053 Object answer = getBody();
054 if (answer == null) {
055 throw new InvalidPayloadException(getExchange(), Object.class, this);
056 }
057 return answer;
058 }
059
060 protected <T> T getBody(Class<T> type, Object body) {
061 // eager same instance type test to avoid the overhead of invoking the type converter
062 // if already same type
063 if (type.isInstance(body)) {
064 return type.cast(body);
065 }
066
067 Exchange e = getExchange();
068 if (e != null) {
069 TypeConverter converter = e.getContext().getTypeConverter();
070
071 // lets first try converting the body itself first
072 // as for some types like InputStream v Reader its more efficient to do the transformation
073 // from the body itself as its got efficient implementations of them, before trying the
074 // message
075 T answer = converter.convertTo(type, getExchange(), body);
076 if (answer != null) {
077 return answer;
078 }
079
080 // fallback to the message itself (e.g. used in camel-http)
081 answer = converter.convertTo(type, getExchange(), this);
082 if (answer != null) {
083 return answer;
084 }
085 }
086
087 // not possible to convert
088 return null;
089 }
090
091 public <T> T getMandatoryBody(Class<T> type) throws InvalidPayloadException {
092 // eager same instance type test to avoid the overhead of invoking the type converter
093 // if already same type
094 if (type.isInstance(body)) {
095 return type.cast(body);
096 }
097
098 Exchange e = getExchange();
099 if (e != null) {
100 TypeConverter converter = e.getContext().getTypeConverter();
101 try {
102 return converter.mandatoryConvertTo(type, e, getBody());
103 } catch (Exception cause) {
104 throw new InvalidPayloadException(e, type, this, cause);
105 }
106 }
107 throw new InvalidPayloadException(e, type, this);
108 }
109
110 public void setBody(Object body) {
111 this.body = body;
112 }
113
114 public <T> void setBody(Object value, Class<T> type) {
115 Exchange e = getExchange();
116 if (e != null) {
117 T v = e.getContext().getTypeConverter().convertTo(type, e, value);
118 if (v != null) {
119 value = v;
120 }
121 }
122 setBody(value);
123 }
124
125 public Message copy() {
126 Message answer = newInstance();
127 answer.copyFrom(this);
128 return answer;
129 }
130
131 public void copyFrom(Message that) {
132 setMessageId(that.getMessageId());
133 setBody(that.getBody());
134 getHeaders().putAll(that.getHeaders());
135 getAttachments().putAll(that.getAttachments());
136 }
137
138 public Exchange getExchange() {
139 return exchange;
140 }
141
142 public void setExchange(Exchange exchange) {
143 this.exchange = exchange;
144 }
145
146 /**
147 * Returns a new instance
148 */
149 public abstract Message newInstance();
150
151 /**
152 * A factory method to allow a provider to lazily create the message body
153 * for inbound messages from other sources
154 *
155 * @return the value of the message body or null if there is no value
156 * available
157 */
158 protected Object createBody() {
159 return null;
160 }
161
162 public String getMessageId() {
163 if (messageId == null) {
164 messageId = createMessageId();
165 }
166 return this.messageId;
167 }
168
169 public void setMessageId(String messageId) {
170 this.messageId = messageId;
171 }
172
173 /**
174 * Lets allow implementations to auto-create a messageId
175 */
176 protected String createMessageId() {
177 return DEFALT_ID_GENERATOR.generateId();
178 }
179 }