So I've got work completed for SWITCHYARD-710, which is a prerequisite for SWITCHYARD-703. There are a handful of changes, all of which warrant explanation, but the last of which (#4) might require discussion:
- A new enumeration exists for the purpose of configuring the SOAPContextMapper. It is called SOAPHeadersType, and contains the values CONFIG, VALUE, DOM and XML. If in the <soap.binding> configuration element, you have a child <contextMapper> element, you can now specifiy a soapHeadersType attribute (again with values "CONFIG, "VALUE", "DOM" or "XML"). The default is VALUE, and the text content value of the soap header will be used for the context property value. However, if you specify DOM, then the entire DOM object representing that soap header element will be stored as the context property value. If you specify XML, the XML String representation of the soap header element is used, and if you specify CONFIG an org.switchyard.config.Configuration object is used (this could be desirable since it's API is much easier than DOM's API).
- To support #1, the schemas for the soap, camel and hornetq bindings had to change, since the soapHeadersType attribute only makes sense for soap. The benefit is that now each binding has it's own inherited definition of this element, with soap extending it with this additional attribute.
- Previously, a hack existed in our core/common module contiaining "ContextMapperInfo" and "MessageComposerInfo" interfaces. This is because the ContextMapper and MessageComposer classes existed in our core/api module, but the model classes existed in core/config, so the "Info" classes were there for compilation visibility. Yuck. So what I've done is removed the "Info" classes from core/common and moved the implementations from core/api into a new module: components/common/composer (right next to components/common/rules). This makes core/api and core/common trimmer and much cleaner, and makes sense to be in components/common/composer since the composer classes are only required by components/soap, components/hornetq and components/camel.
- A proposal on this thread was that when extracting SOAPHeaderElements from within the SOAPContextMapper, the context property names used should be prefixed with something like "soapheader_". I wasn't a big fan of the idea of kludging meta-information inside the name of a property itself, so I came up with the idea of context property labels. I added the following methods to org.switchyard.Property: getLabels():Set<String>, addLabels(String...):Property, removeLabels(String...):Property, hasLabel(String):boolean. Labels are trimmed, can never be null, and always stored and compared case-insensitive. Now Properties can have meta-information about where they originiated from. Properties from the SOAPContextMapper can have labels "soap_message_header" or "soap_message_mime_header", Properties from CamelContextMapper can have labels "camel_exchange_property" or "camel_message_header", and Properties from HornetQContextMapper can have label "hornetq_message_property". You can see an example of these labels being set here. With this change, the code proposed here for resolving SWITCHYARD-704 becomes cleaner and not hardcoded. Instead of the RiftsawBPELExchangeHandler adding a header if p.getName().startsWith("soapheader_"), it can add it if p.hasLabel(SOAPComposition.SOAP_MESSAGE_HEADER).