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 */
017package org.apache.camel;
018
019import java.util.Map;
020import java.util.Set;
021import java.util.function.Supplier;
022import javax.activation.DataHandler;
023
024/**
025 * Implements the <a
026 * href="http://camel.apache.org/message.html">Message</a> pattern and
027 * represents an inbound or outbound message as part of an {@link Exchange}.
028 * <p/>
029 * See {@link org.apache.camel.impl.DefaultMessage DefaultMessage} for how headers
030 * is represented in Camel using a {@link org.apache.camel.util.CaseInsensitiveMap CaseInsensitiveMap}.
031 *
032 * @version 
033 */
034public interface Message {
035
036    /**
037     * Returns the id of the message
038     *
039     * @return the message id
040     */
041    String getMessageId();
042
043    /**
044     * Sets the id of the message
045     *
046     * @param messageId id of the message
047     */
048    void setMessageId(String messageId);
049
050    /**
051     * Returns the exchange this message is related to
052     *
053     * @return the exchange
054     */
055    Exchange getExchange();
056
057    /**
058     * Returns true if this message represents a fault
059     *
060     * @return <tt>true</tt> if this is a fault message, <tt>false</tt> for regular messages.
061     */
062    boolean isFault();
063
064    /**
065     * Sets the fault flag on this message
066     *
067     * @param fault the fault flag
068     */
069    void setFault(boolean fault);
070
071    /**
072     * Accesses a specific header
073     *
074     * @param name  name of header
075     * @return the value of the given header or <tt>null</tt> if there is no
076     *         header for the given name
077     */
078    Object getHeader(String name);
079
080    /**
081     * Accesses a specific header
082     *
083     * @param name  name of header
084     * @param defaultValue the default value to return if header was absent
085     * @return the value of the given header or <tt>defaultValue</tt> if there is no
086     *         header for the given name
087     */
088    Object getHeader(String name, Object defaultValue);
089
090    /**
091     * Accesses a specific header
092     *
093     * @param name  name of header
094     * @param defaultValueSupplier the default value supplier used to generate the value to return if header was absent
095     * @return the value of the given header or he value generated by the <tt>defaultValueSupplier</tt> if there is no
096     *         header for the given name
097     */
098    Object getHeader(String name, Supplier<Object> defaultValueSupplier);
099
100    /**
101     * Returns a header associated with this message by name and specifying the
102     * type required
103     *
104     * @param name the name of the header
105     * @param type the type of the header
106     * @return the value of the given header or <tt>null</tt> if there is no header for
107     *         the given name
108     * @throws TypeConversionException is thrown if error during type conversion
109     */
110    <T> T getHeader(String name, Class<T> type);
111
112    /**
113     * Returns a header associated with this message by name and specifying the
114     * type required
115     *
116     * @param name the name of the header
117     * @param defaultValue the default value to return if header was absent
118     * @param type the type of the header
119     * @return the value of the given header or <tt>defaultValue</tt> if there is no header for
120     *         the given name or <tt>null</tt> if it cannot be converted to the given type
121     */
122    <T> T getHeader(String name, Object defaultValue, Class<T> type);
123
124    /**
125     * Returns a header associated with this message by name and specifying the
126     * type required
127     *
128     * @param name the name of the header
129     * @param defaultValueSupplier the default value supplier used to generate the value to return if header was absent
130     * @param type the type of the header
131     * @return the value of the given header or he value generated by the <tt>defaultValueSupplier</tt> if there is no
132     *         header for the given name or <tt>null</tt> if it cannot be converted to the given type
133     */
134    <T> T getHeader(String name, Supplier<Object> defaultValueSupplier, Class<T> type);
135
136    /**
137     * Sets a header on the message
138     *
139     * @param name of the header
140     * @param value to associate with the name
141     */
142    void setHeader(String name, Object value);
143
144    /**
145     * Removes the named header from this message
146     *
147     * @param name name of the header
148     * @return the old value of the header
149     */
150    Object removeHeader(String name);
151
152    /**
153     * Removes the headers from this message
154     *
155     * @param pattern pattern of names
156     * @return boolean whether any headers matched
157     */
158    boolean removeHeaders(String pattern);
159    
160    /**
161     * Removes the headers from this message that match the given <tt>pattern</tt>, 
162     * except for the ones matching one or more <tt>excludePatterns</tt>
163     * 
164     * @param pattern pattern of names that should be removed
165     * @param excludePatterns one or more pattern of header names that should be excluded (= preserved)
166     * @return boolean whether any headers matched
167     */ 
168    boolean removeHeaders(String pattern, String... excludePatterns);
169
170    /**
171     * Returns all of the headers associated with the message.
172     * <p/>
173     * See {@link org.apache.camel.impl.DefaultMessage DefaultMessage} for how headers
174     * is represented in Camel using a {@link org.apache.camel.util.CaseInsensitiveMap CaseInsensitiveMap}.
175     * <p/>
176     * <b>Important:</b> If you want to walk the returned {@link Map} and fetch all the keys and values, you should use
177     * the {@link java.util.Map#entrySet()} method, which ensure you get the keys in the original case.
178     *
179     * @return all the headers in a Map
180     */
181    Map<String, Object> getHeaders();
182
183    /**
184     * Set all the headers associated with this message
185     * <p/>
186     * <b>Important:</b> If you want to copy headers from another {@link Message} to this {@link Message}, then
187     * use <tt>getHeaders().putAll(other)</tt> to copy the headers, where <tt>other</tt> is the other headers.
188     *
189     * @param headers headers to set
190     */
191    void setHeaders(Map<String, Object> headers);
192
193    /**
194     * Returns whether has any headers has been set.
195     *
196     * @return <tt>true</tt> if any headers has been set
197     */
198    boolean hasHeaders();
199
200    /**
201     * Returns the body of the message as a POJO
202     * <p/>
203     * The body can be <tt>null</tt> if no body is set.
204     * <p/>
205     * Notice if the message body is stream based then calling this method multiple times may lead to the stream not being able to be re-read again.
206     * You can enable stream caching and call the {@link StreamCache#reset()} method to reset the stream to be able to re-read again (if possible).
207     * See more details about <a href="http://camel.apache.org/stream-caching.html">stream caching</a>.
208     *
209     * @return the body, can be <tt>null</tt>
210     */
211    Object getBody();
212
213    /**
214     * Returns the body of the message as a POJO
215     * <p/>
216     * Notice if the message body is stream based then calling this method multiple times may lead to the stream not being able to be re-read again.
217     * See more details about <a href="http://camel.apache.org/stream-caching.html">stream caching</a>.
218     *
219     * @return the body, is never <tt>null</tt>
220     * @throws InvalidPayloadException Is thrown if the body being <tt>null</tt> or wrong class type
221     */
222    Object getMandatoryBody() throws InvalidPayloadException;
223
224    /**
225     * Returns the body as the specified type
226     * <p/>
227     * Notice if the message body is stream based then calling this method multiple times may lead to the stream not being able to be re-read again.
228     * You can enable stream caching and call the {@link StreamCache#reset()} method to reset the stream to be able to re-read again (if possible).
229     * See more details about <a href="http://camel.apache.org/stream-caching.html">stream caching</a>.
230     *
231     * @param type the type that the body
232     * @return the body of the message as the specified type, or <tt>null</tt> if no body exists
233     * @throws TypeConversionException is thrown if error during type conversion
234     */
235    <T> T getBody(Class<T> type);
236
237    /**
238     * Returns the mandatory body as the specified type
239     * <p/>
240     * Notice if the message body is stream based then calling this method multiple times may lead to the stream not being able to be re-read again.
241     * You can enable stream caching and call the {@link StreamCache#reset()} method to reset the stream to be able to re-read again (if possible).
242     * See more details about <a href="http://camel.apache.org/stream-caching.html">stream caching</a>.
243     *
244     * @param type the type that the body
245     * @return the body of the message as the specified type, is never <tt>null</tt>.
246     * @throws InvalidPayloadException Is thrown if the body being <tt>null</tt> or wrong class type
247     */
248    <T> T getMandatoryBody(Class<T> type) throws InvalidPayloadException;
249
250    /**
251     * Sets the body of the message
252     *
253     * @param body the body
254     */
255    void setBody(Object body);
256
257    /**
258     * Sets the body of the message as a specific type
259     *
260     * @param body the body
261     * @param type the type of the body
262     */
263    <T> void setBody(Object body, Class<T> type);
264
265    /**
266     * Creates a copy of this message so that it can be used and possibly
267     * modified further in another exchange
268     *
269     * @return a new message instance copied from this message
270     */
271    Message copy();
272
273    /**
274     * Copies the contents of the other message into this message
275     * <p/>
276     * If you need to do a copy and then set a new body,
277     * then use {@link #copyFromWithNewBody(Message, Object)} method instead.
278     *
279     * @param message the other message
280     * @see #copyFromWithNewBody(Message, Object)
281     */
282    void copyFrom(Message message);
283    
284    /**
285     * Copies the contents (except the body) of the other message into this message and uses the provided new body instead
286     *
287     * @param message the other message
288     * @param newBody the new body to use
289     */
290    void copyFromWithNewBody(Message message, Object newBody);
291
292    /**
293     * Copies the attachments of the other message into this message
294     *
295     * @param message the other message
296     */
297    void copyAttachments(Message message);
298
299    /**
300     * Returns the attachment specified by the id
301     *
302     * @param id the id under which the attachment is stored
303     * @return the data handler for this attachment or <tt>null</tt>
304     */
305    DataHandler getAttachment(String id);
306
307    /**
308     * Returns the attachment specified by the id
309     *
310     * @param id the id under which the attachment is stored
311     * @return the attachment or <tt>null</tt>
312     */
313    Attachment getAttachmentObject(String id);
314
315    /**
316     * Returns a set of attachment names of the message
317     *
318     * @return a set of attachment names
319     */
320    Set<String> getAttachmentNames();
321
322    /**
323     * Removes the attachment specified by the id
324     *
325     * @param id   the id of the attachment to remove
326     */
327    void removeAttachment(String id);
328
329    /**
330     * Adds an attachment to the message using the id
331     *
332     * @param id        the id to store the attachment under
333     * @param content   the data handler for the attachment
334     */
335    void addAttachment(String id, DataHandler content);
336
337    /**
338     * Adds an attachment to the message using the id
339     *
340     * @param id        the id to store the attachment under
341     * @param content   the attachment
342     */
343    void addAttachmentObject(String id, Attachment content);
344
345    /**
346     * Returns all attachments of the message
347     *
348     * @return the attachments in a map or <tt>null</tt>
349     */
350    Map<String, DataHandler> getAttachments();
351
352    /**
353     * Returns all attachments of the message
354     *
355     * @return the attachments in a map or <tt>null</tt>
356     */
357    Map<String, Attachment> getAttachmentObjects();
358
359    /**
360     * Set all the attachments associated with this message
361     *
362     * @param attachments the attachments
363     */
364    void setAttachments(Map<String, DataHandler> attachments);
365
366    /**
367     * Set all the attachments associated with this message
368     *
369     * @param attachments the attachments
370     */
371    void setAttachmentObjects(Map<String, Attachment> attachments);
372
373    /**
374     * Returns whether this message has attachments.
375     *
376     * @return <tt>true</tt> if this message has any attachments.
377     */
378    boolean hasAttachments();
379
380    /**
381     * Returns the unique ID for a message exchange if this message is capable
382     * of creating one or <tt>null</tt> if not
383     *
384     * @return the created exchange id, or <tt>null</tt> if not capable of creating
385     * @deprecated will be removed in Camel 3.0. It is discouraged for messages to create exchange ids
386     */
387    @Deprecated
388    String createExchangeId();
389}