Web services' bread and butter consists primarily of exchanging XML structures between applications in order to fulfill interoperability requirements. Prior to such exchanges taking place, most XML data undergoes a series of steps that include validation and transformation, many of which are solved using staple XML approaches like Schemas, DTD's, XPath and XSL. Up next we will explore yet another technique developed by OASIS which nicely complements many of the aforementioned procedures, its name: CAM (Content Assembly Mechanism) .
CAM's primary objective is to define, compose and validate XML content through the use of specialized templates which allow the application of contextual business rules to any XML structure. Before we dig into what actually constitutes these contextual business rules and why they are useful, the first thing you should realize about CAM is that its rooted in the same principles as many other validating and transformation techniques you may already be familiar with -- such as using XPath and structures similar to those of Schemas. So in this sense CAM is an easily digestible approach which doesn't require starting a fresh new learning curve.
So what is a contextual business rule for XML? Its an elaborate piece of logic which can be applied to raw XML data prior to being used in an actual Web service or application. Such business rules can in turn be used to enforce a particular XML structure (validate) or transform XML fragments to fit a predetermined form. With that said, let's take a closer look at some of these business rules, including their syntax, how they are declared in a CAM template and an actual XML structure using CAM. Listing 1.1 shows an XML document which makes use of CAM.
Listing 1.1 XML structure using CAM Template <?xml version='1.0'?> <as:CAM CAMlevel="1" version="1.0" xmlns:as="http://www.oasis-open.org/committees/cam" > <as:Header> <as:Description> Sample CAM template for Purchase Order </as:Description> <as:Owner>CAM Example</as:Owner> <as:Version>0.1</as:Version> <as:DateTime>2007-03-06T09:48:00</as:DateTime> <as:Parameters> <as:Parameter name="QuickBooks" values="'true'|'false'" default="false" use="local"/> </as:Parameters> </as:Header> <as:AssemblyStructure> <as:Structure ID="W3C-PO" taxonomy="XML" reference=""> <PurchaseOrder orderDate="%1999-05-20%"> <shipTo type="%US%"> <name>%Alice Smith%</name> <street>%123 Maple Street%</street> <city>%Mill Valley%</city> <state>%CA%</state> <zip>%90952%</zip> </shipTo> <shipDate>%1999-05-25%</shipDate> <comment>% Get these use express shipping %</comment> <Items> <Item pno="%333-333%"> <productName>% Lawnmower, model BUZZ-1 %</productName> <quantity>%1%</quantity> <price>%148.95%</price> <comment>% Please confirm this is the electric model %</comment> </Item> </Items> </PurchaseOrder> </as:Structure> </as:AssemblyStructure> </as:CAM> [End Listing 1.1]
This last XML structure imports the CAM namespace immediately at the top of the document and makes various statements around it using the
as: qualifier. Besides of the use of this special namespace, the only other thing worth mentioning are the
% symbols used to delimit character data within certain XML tags, all of which are used by CAM to identify where content data occurs. Now take a look at Listing 1.2 which illustrates a partial CAM template used to enforce certain rules on the previous document.
Listing 1.2 Partial CAM Template. <as:BusinessUseContext> <as:Rules> <as:default> <as:context> <as:constraint action="makeRepeatable(//Items/Item)"/> <as:constraint action="makeOptional(//Item/comment)"/> <as:constraint action="setLength(//shipTo/state,2)"/> <as:constraint action="setDateMask(//PurchaseOrder/shipDate,YYYY-MM-DD)"/> <as:constraint action="makeOptional(//PurchaseOrder/comment)"/> <as:constraint action="restrictValues(//shipTo/@type,'US'| 'CA'| 'MX', 'US')"/> <as:constraint action="setDateMask(//PurchaseOrder/@orderDate,YYYY-MM-DD)"/> <as:constraint action="setNumberMask(//Item/@pno,###-###)"/> <as:constraint action="setNumberMask(//Item/quantity,###)"/> <as:constraint action="setNumberMask(//Item/price,####.##)"/> <as:constraint condition="//Item/@pno = 123-678" action="restrictValues(//shipTo/state,'WA')"> <as:annotation> <as:documentation type="documentation"> Can only ship item 123-678 to Washington State </as:documentation> </as:annotation> </as:constraint> <as:constraint condition="$QuickBooks = true" action="excludeElement(//Item/comment)" /> </as:context> </as:default> </as:Rules> </as:BusinessUseContext>[End Listing 1.2]
The first thing to realize about these CAM rules is that there syntax is based on XPath -- such as the case of
//Item/@pno, which is XPath lingo for saying the
pno attribute for
Item tags. More importantly, however, are the things these CAM rules achieve. There's the introduction of usage patterns for the XML document -- such as
restrictValues -- to better elaborate conditionals for validating and pruning XML data. Specifically for this case, we find a rule that states if the
//Item/@pno tag value coincides with
123-678. It also validate the tag
WA, and additionally we can also find another rule stating that if the
$QuickBooks variable in the XML document equals
true, CAM should suppress the XML tag
In order to put the previous CAM template and XML document into actual use you will need to install a CAM Engine, which is the software infrastructure required to keep the validating and transformation process ticking. Additionally and in order to reduce the burden of creating CAM templates, an XML editor can also be of help in the development lifecycle of CAM projects. Fortunately, CAM has managed to grow a strong open source community around both these areas and makes available as a free download a Java CAM Engine and CAM editor.
Now, instead of exploring the deployment and usage details for these last two CAM pieces -- many of which are covered in the documentation – let's pose a higher-level question regarding the utility of CAM : is the actual introduction of yet another piece of software -- read CAM engine -- a convenient or even practical approach to the ever growing complexity of SOA initiatives? As it turns out, for those services having constantly changing XML validating or transformation requirements CAM provides a fresh outlook and one which reduces complexity.
The issue with the classical validating and transformation techniques for XML is that in one form or another they are heavily dependent on the underlying programming environment, coming in either the form of specifying processing instructions for applying an XSL stylesheet or simply using application logic to execute validating logic beyond what is supported in XML Schemas. In these scenarios, constant changes in XML validating or transformation requirements can quickly become a burden due to the inherent tight coupling, whereas using an approach like CAM a more loosely coupled architecture is achieved -- the latter of which is a highly coveted SOA characteristic.
Though CAM introduces an additional layer to the possible validation and transformation of XML structures, incorporating such a level of indirection into your Web services projects can be an excellent solution for those SOA initiatives requiring support for elaborate XML content rules Add to this that CAM is developed under the guidance of OASIS, which develops numerous other Web services standards, and you are insured CAM will continue its relevance in and around your Web services projects.
About the author: Daniel Rubio is a software consultant with over 10 years of experience in enterprise software development, having recently founded Mashup Soft, a startup specializing in the use Web services for Mashups. He is a technology enthusiast in all areas related to software platforms and maintains a blog on these topics.