Hi,

Sorry for bringing this up again, but I have received no feedback at all about 
this topic yet.

The current attachment support in Camel 2.x is essentially a Map<String, 
DataHandler>. As such it can transport the attachment body (in the 
DataHandler), the Content-Type (also in the DataHandler and a String value (the 
map key), which may have different semantics (in camel-mail this is the 
attachment filename, in camel-cxf it is the content-id).

However real-life attachments can have multiple headers (MIME which the 
standard for mail attachment as well as for SOAP attachments supports an 
arbitrary number of those).

As the attachments are part of the camel Message interface (which is one of the 
most central interfaces in Camel), there must be no incompatible change in that 
before Camel 3.0 (but this will take a while till we get this).

For the time being I have evaluated three compatible implementation options in 
https://issues.apache.org/jira/browse/CAMEL-9880 :

Option 1:
Create an Attachment interface that supports headers per attachment. 
Furthermore create a DefaultAttachment implementation which implements the 
Attachment interface and extends the DataHandler class. As these 
DefaultAttachment objects are also DataHandlers they can be put into the map 
provided by the existing Message interface (and its implementation). Components 
that supports this can check whether a DataHandler in the map also implements 
the Attachment interface and can also access the headers in that case.

Advantages:

1.       The Message interface and the DefaultMessage implementation are not 
changed.

2.       The headers are kept with the attachment data, no inconsistencies can 
occur if attachments are added/removed.
Disadvantage:

1.       The whole issue is not very transparent. The user needs to know that 
the DataHandler in the map may also implement the Attachment interface (but the 
API itself does not indicate this).

Option 2:
Define a specifically named header of type Map<String, Map<String, String>> 
that contains the content of all attachment headers. Access is done via new 
methods of the MessageHelper class.

Advantages:

1.       The message interface and the DefaultMessage implementation are not 
changed.

2.       No new interface
Disadvantages:

1.       Access to these headers is rather complex. If it's simplified a little 
via MessageHelper calls, these become a public API to access this.

2.       The whole scheme is rather intransparent. The user needs to know about 
these headers and the naming convention. The API does not give any indication 
about this.

3.       The headers and attachments are separate entities and can become 
inconsistent (e.g. if attachment or headers are removed).

Option 3:
Create an Attachment interface as in option 1 but the DefaultAttachment 
implementation does not implement DataHandler. Therefore the Message interface 
(and the DefaultMessage implementation) are (compatibly) extended in a way that 
provides access to the Attachment objects. The underlying Map for the 
attachments in the DefaultMessage implementation is changed from Map<String, 
DataHandler> to Map<String, Attachment>. The access methods to the old map 
return a Map<String, DataHander> implementation that is backed by the new 
mapped (the the map returned by getAttachments() is still modifiable and all 
modifications work as before).

Advantages:

1.       The way of implementation is rather clean, the API clearly indicates 
how the attachment headers can be accessed.

2.       The headers are kept with the attachment data, no inconsistencies can 
occur if attachments are added/removed
Disadvantages:

1.       The Message interface is extended (in a compatible way). Message 
implementations that do not extend DefaultMessage will break (but there are 
none of those in the Camel codeline).

2.       The changes in Default message (with the map view) introduce some 
additional complexity that may have new bugs.

3.       If someone passes a map to the setAttachments() call that was not 
retrieved by a preceeding getAttachments() call and then modifies the passed 
map, these modifications will be lost (because in that case the 
setAttachments() needs to do a (shallow) copy of the passed map. Note: this is 
likely not working too well with the current implementation, anyway as the 
DefauiltMessage implementation cannot make sure that the passed map is 
LinkedHashMap, so the order of the headers may become random in that case-

What do you think about these approaches. Do you think any of those could go 
into Camel 2.18?

Best regards
Stephan

Reply via email to