Lucas writes in to ask a question about my undocumented example application number 20, where I show an example of using the built-in writeXML() method of the ADF business components framework to produce an XML document for Department and its nested Employees and JobHistory information. He asked whether it would be possible to create a transient attribute of the Department view object and have that transient attribute return the XML document. His attempts to achieve this were running into ClassCastExceptions.
The thought is perfectly valid, but I am going to guess that the ClassCastExceptions are a result of trying to refer to the value of the attribute using an EL expression in the page that returns a binding object instead of just the raw attribute value.
I downloaded the sample in question, and added a transient attribute named DepartmentXML of type org.w3c.dom.Document to its Departments view object. I checked the box to generate the view row class, and in the DepartmentsViewRowImpl.java class, I implemented the getDepartmentXML() getter method like this:
public Document getDepartmentXML() { HashMap h = new HashMap(); h.put("test.model.DepartmentsView", new String[]{"DepartmentId", "DepartmentName", "EmployeesView", "JobHistoryView"}); h.put("test.model.EmployeesView", new String[]{"EmployeeId", "FirstName", "LastName", "Email", "EmployeesView"}); h.put("test.model.JobHistoryView", new String[]{"StartDate","StartDate"}); Node n = writeXML(XMLInterface.XML_OPT_LIMIT_RANGE,h); Document d = n.getOwnerDocument(); n = ((XMLDocument)d).adoptNode(n); d.appendChild(n); return (Document)d; }
With this in place, calling getDepartmentXML() on any row in the Departments view will return an XML document that has a structure like this:
<DepartmentsViewRow> <DepartmentId>80</DepartmentId> <DepartmentName>Sales</DepartmentName> <EmployeesView> <EmployeesViewRow> <EmployeeId>145</EmployeeId> <FirstName>John</FirstName> <LastName>Russell</LastName> <Email>JRUSSEL</Email> <EmployeesView> <EmployeesViewRow> <EmployeeId>150</EmployeeId> <FirstName>Peter</FirstName> <LastName>Tucker</LastName> <Email>PTUCKER</Email> </EmployeesViewRow> </EmployeesView> </EmployeesViewRow> </EmployeesView> <JobHistoryView> <JobHistoryViewRow> <StartDate>1998-03-24</StartDate> <StartDate>1998-03-24</StartDate> </JobHistoryViewRow> </JobHistoryView> </DepartmentsViewRow>
Then, I dropped the "DepartmentXML" attribute to a JSP page from the Data Control palette to create a value binding for it in my JSP page. After adding in the taglib directive for the JSTL XML tag library, I was able to refer to iterate over the XML document using the <x:forEach> tag by doing the following two things:
-
Get the document into a page-scope variable <c:set var="voxml" value="${bindings.DepartmentXML.attributeValue}"/>
-
Iterate the document in the voxml variable like this: <x:forEach select="$voxml/DepartmentsViewRow">
The thing to notice is the use of the attributeValue property of the binding. An EL expression like ${bindings.DepartmentXML} would be valid and legal, but it refers to the Control Value binding object, and not to its value (in this case, the XMLDocument).
2:46:18 PM
|