Example Using Generic (XML) Resource Objects
Overview
The Resource interface provides a generic way to represent and access domain objects from various backend systems. It is designed to support different data formats and structures by exposing APIs to retrieve properties and child objects.
A common use case for Resource is working with XML data. The CRISP framework includes a default XML implementation, JdomResource, which uses the JDOM library to parse XML.
Mapping a Single XML Element to a Resource Object
Consider the following XML representing a product from a backend system:
<product> <name>NEC MultiSync X431BT</name> <sku>4150349</sku> <description>MultiSync X431BT - 109.22 cm (43 ") , 1920 x 480, 16:4, 500 cd/m², 3000:1, 8 ms</description> <extendedData> <entry> <key>title</key> <value xsi:type="xs:string">NEC MultiSync X431BT</value> </entry> <entry> <key>type</key> <value xsi:type="xs:string">Link</value> </entry> <entry> <key>uri</key> <value xsi:type="xs:string">Incentro-HIC-Site/-/products/4150349</value> </entry> <entry> <key>description</key> <value xsi:type="xs:string">MultiSync X431BT - 109.22 cm (43 ") , 1920 x 480, 16:4, 500 cd/m², 3000:1, 8 ms</value> </entry> </extendedData> </product>
This XML structure maps directly to a Resource object:
- The root XML element becomes the
Resourceobject. - Element attributes are available as primitive string properties.
- Child elements (such as
name,sku, andextendedData) are exposed as childResourceproperties. - Access both primitive and nested properties using
Resource#getValueMap().get(String name). JdomResourcereturns string values or childResourceobjects viagetValueMap(). When usinggetValueMap().get(String name, Class type), it attempts to convert the value to the requested type (for example,String,Number, orResource).JdomResourceimplementsResource#getDefaultValue()to return the text content of the XML element. The methodResource#getDefaultValue(Class type)converts the value to the requested type when possible.
To access properties and child resources after retrieving a single Resource object with ResourceServiceBroker#resolve(...), use the following approach:
ResourceServiceBroker broker = CrispHstServices.getDefaultResourceServiceBroker(HstServices.getComponentManager()); Resource product = resourceServiceBroker.resolve("demoProductCatalogsXml", "/products.xml/sku/12345678901"); String name = (String) ((Resource) product.getValueMap().get("name")).getDefaultValue(); String sku = (String) ((Resource) product.getValueMap().get("sku")).getDefaultValue(); String description = (String) ((Resource) product.getValueMap().get("description")).getDefaultValue(); Resource extendedData = (Resource) product.getValueMap().get("extendedData"); // ...
JdomResource also supports standard XPath expressions in the Resource#getValue(String relPath) method. You can access nested properties using XPath, as shown below:
ResourceServiceBroker broker = CrispHstServices.getDefaultResourceServiceBroker(HstServices.getComponentManager()); Resource product = resourceServiceBroker.resolve("demoProductCatalogsXml", "/products/sku/12345678901"); // Access the "title" property of the "extendedData" child resource using XPath: String title = ((Resource) product.getValue("extendedData/entry[key='description']/value")).getDefaultValue(); // ...
Refer to the Resource JavaDoc for additional details.
Mapping a Collection of XML Elements to Resource Objects
The following XML represents a collection of products:
<data> <products> <product> <name>NEC MultiSync X431BT</name> <sku>4150349</sku> <description>MultiSync X431BT - 109.22 cm (43 ") , 1920 x 480, 16:4, 500 cd/m², 3000:1, 8 ms</description> <extendedData> <entry> <key>title</key> <value xsi:type="xs:string">NEC MultiSync X431BT</value> </entry> <entry> <key>type</key> <value xsi:type="xs:string">Link</value> </entry> <entry> <key>uri</key> <value xsi:type="xs:string">Incentro-HIC-Site/-/products/4150349</value> </entry> <entry> <key>description</key> <value xsi:type="xs:string">MultiSync X431BT - 109.22 cm (43 ") , 1920 x 480, 16:4, 500 cd/m², 3000:1, 8 ms</value> </entry> </extendedData> </product> <product> <name>NEC PA271W</name> <sku>4696003</sku> <description>PA271W, 68.58 cm (27 ") LCD, 2560 x 1440, 6ms, 1000:1, 300cd/m2, 1.073B</description> <extendedData> <entry> <key>title</key> <value xsi:type="xs:string">NEC PA271W</value> </entry> <entry> <key>type</key> <value xsi:type="xs:string">Link</value> </entry> <entry> <key>uri</key> <value xsi:type="xs:string">Incentro-HIC-Site/-/products/4696003</value> </entry> <entry> <key>description</key> <value xsi:type="xs:string">PA271W, 68.58 cm (27 ") LCD, 2560 x 1440, 6ms, 1000:1, 300cd/m2, 1.073B</value> </entry> </extendedData> </product> <!-- SNIP --> </products> </data>
This XML structure can also be mapped to a Resource object, with the root XML element as the entry point.
- Use
Resource#getChildren()to iterate over collections of child resources.
After retrieving a Resource object containing the product collection with ResourceServiceBroker#findResources(...), you can iterate through the products as follows:
ResourceServiceBroker broker = CrispHstServices.getDefaultResourceServiceBroker(HstServices.getComponentManager()); Resource data = resourceServiceBroker.findResources("demoProductCatalogsXml", "/products.xml"); Resource products = ((Resource) data.getValue("products")).getChildren(); for (Resource product : products.getChildren()) { String name = (String) ((Resource) product.getValueMap().get("name")).getDefaultValue(); String sku = (String) ((Resource) product.getValueMap().get("sku")).getDefaultValue(); String description = (String) ((Resource) product.getValueMap().get("description")).getDefaultValue(); // ... }
Pagination with Resource Objects
The Resource interface supports pagination. You can specify an offset and a limit when retrieving children using Resource#getChildren(long offset, long limit). This allows you to fetch a specific page of results:
// ... ResourceServiceBroker broker = CrispHstServices.getDefaultResourceServiceBroker(HstServices.getComponentManager()); Resource data = resourceServiceBroker.findResources("demoProductCatalogsXml", "/products.xml"); // Retrieve the first page of results with a page size of 10. for (Resource lead : ((Resource) data.getValue("products")).getChildren(0, 10)) { String name = (String) ((Resource) product.getValueMap().get("name")).getDefaultValue(); String sku = (String) ((Resource) product.getValueMap().get("sku")).getDefaultValue(); String description = (String) ((Resource) product.getValueMap().get("description")).getDefaultValue(); // ... }
Refer to the Resource interface JavaDoc for additional information on pagination and available methods.