Recipe10.7.Loading XML Data into Your Application


Recipe 10.7. Loading XML Data into Your Application

Problem

You want an easy way to load XML data into application-scoped objects when your application starts up.

Solution

Use the DigestingPlugIn provided in Struts 1.2.

First, decide on the class that will represent the data. If the data will be used in drop-down lists, a convenient option is to use use the Struts-provided LabelValueBean (org.apache.struts.util.LabelValueBean). Next, create the XML-formatted datafile. The struts-example includes a file called server-types.xml that represents types of electronic mail server types:

<lv-beans>     <lv-bean label="IMAP Protocol" value="imap" />     <lv-bean label="POP3 Protocol" value="pop3" /> </lv-beans>

Create the rules file that controls how the Digester will parse the data into objects. The lvb-digester-rules.xml file shown in Example 10-20, from the struts-example, specifies the parsing rules to create an ArrayList of LabelValueBeans from the server-types.xml file.

Example 10-20. Label value bean Digester rules
<digester-rules>     <object-create-rule pattern="lv-beans"                        classname="java.util.ArrayList"/>     <pattern value="lv-beans/lv-bean">         <object-create-rule classname="org.apache.struts.util.         LabelValueBean" />         <set-properties-rule />         <set-next-rule methodname="add" />     </pattern> </digester-rules>

Finally, add a plug-in declaration to your struts-config.xml for each file to be parsed and loaded:

<plug-in className="org.apache.struts.plugins.DigestingPlugIn">     <set-property property="key"                       value="serverTypes"/>     <set-property property="configPath"                       value="/WEB-INF/server-types.xml"/>     <set-property property="digesterPath"                       value="/WEB-INF/lvb-digester-rules.xml"/> </plug-in>

You can now access the data from an Action or JSP page. The DigestingPlugIn stores the data as a servlet context attribute where the attribute name is the value of the key property.

Discussion

The DigestingPlugIn, a new feature of Struts 1.2, provides an easy way to load static, XML-formatted lookup data into the servlet context. The struts-example application, included with the Struts 1.2 source distribution, uses this plug-in. The examples shown in the Solution are taken from the struts-example. If the data you are loading will be used in drop-down lists, you can store the data as a List of LabelValueBeans. In fact, you can use the lvb-digester-rules.xml shown in Example 10-20 to load any set of XML data that conforms to the following format:

<lv-beans>     <lv-bean label=" Foo "               value=" foo " />     <lv-bean label=" Bar "              value=" bar " />     <lv-bean label=" Baz "              value=" baz " /> </lv-beans>

But you are by no means limited to this format. Using custom Digester rules, you can translate any XML file into an object representation. For example, suppose that you wanted to keep a list of Canadian provinces, including province capitals and date established as an application-scoped object. The object that you want to hold data about each province in is shown in Example 10-21.

Example 10-21. Value object for a province
package com.oreilly.strutsckbk.ch10; public class Province {          public String getCapital( ) {         return capital;     }     public void setCapital(String capital) {         this.capital = capital;     }     public int getEstablished( ) {         return established;     }     public void setEstablished(int established) {         this.established = established;     }     public String getName( ) {         return name;     }     public void setName(String name) {         this.name = name;     }     private String name;     private String capital;     private int established; }

The XML file, WEB-INF/canadian-provinces.xml, containing the data to load is shown in Example 10-22.

Example 10-22. XML InfoSet of Canadian provinces
<provinces>     <province name="Alberta" capital="Edmonton"             founded="1905"/>         <province name="British Columbia" capital="Victoria"             founded="1871"/>         <province name="Manitoba" capital="Winnipeg"             founded="1870"/>         <province name="New Brunswick" capital="Fredericton"             founded="1867"/>         <province name="Newfoundland and Labrador" capital="St. John's"            founded="1949"/>         <province name="Nova Scotia" capital="Halifax"             founded="1867"/>         <province name="Ontario" capital="Toronto"             founded="1867"/>         <province name="Prince Edward Island" capital="Charlottetown"             founded="1873"/>         <province name="Quebec" capital="Quebec City"             founded="1867"/>         <province name="Saskatchewan" capital="Regina"             founded="1905"/>     </provinces>

You create the Digester rules file that will parse the XML data into objects. The WEB-INF/province-digester-rules.xml file is shown in Example 10-23.

Example 10-23. Digester rules for parsing province list
<digester-rules>     <object-create-rule pattern="provinces"                        classname="java.util.ArrayList"/>     <pattern value="provinces/province">         <object-create-rule                  classname="com.oreilly.strutsckbk.ch10.Province" />         <set-properties-rule>             <alias attr-name="founded" prop-name="established"/>         </set-properties-rule>         <set-next-rule methodname="add" />       </pattern> </digester-rules>

First, the object-create-rule element tells the Digester the type of object to create when it encounters a certain pattern. In this case, when the Digester encounters the provinces element, it creates an ArrayList. The next pattern specifies nested province elements. For each of these, the Digester creates an instance of the Province class.

The Digester uses the values of XML attributes to set object property values. The set-properties-rule element defines how XML attributes map to object properties. Unless specified, the Digester maps attributes to properties based on name. If you have an XML attribute with a different name than its corresponding object property, the alias element explicitly defines the mapping. In Example 10-23, all of the attribute names of the province element match the property names of the Province class (except for the founded attribute, which maps to the established property).

You configure the DigestingPlugIn by setting properties that define the servlet context key for the created object, the location of the XML datafile, and the location of the Digester rules file. Table 10-1 shows the properties you can set on the DigestingPlugIn.

Table 10-1. DigestingPlugIn configuration properties

key

The name of the servlet context attribute that the created object will be stored under.

configSource

Indicates how the configPath is interpreted. Accepted values are:


classpath

The configPath is relative to the classpath and will be resolved by the web application's ClassLoader. Practically, this means the file will be stored under the WEB-INF/classes directory.


file

The configPath is relative to the filesystem, typically meaning that the path will be relative to the directory from with the application server was run. If you are running Tomcat, for example, the path will be relative to ${CATALINA_HOME}/bin.


servlet

The configPath is relative to the servlet context. This source can be used when loading the data from a URL. In practice, this allows the file to be collocated with the other configuration files stored in the WEB-INF directory.

The value defaults to servlet if not specified.

configPath

Path to the datafile to be loaded. This value is resolved based on the setting for the configSource element.

digesterSource

Indicates how the digesterPath is interpreted. Accepted values are:


classpath

The digesterPath is relative to the classpath and will be resolved by the web application's ClassLoader. Practically, this means the file will be stored under the WEB-INF/classes directory.


file

The digesterPath is relative to the filesystem, typically meaning the path will be relative to the directory from with the application server was run. If you are running Tomcat, for example, the path will be relative to ${CATALINA_HOME}/bin.


servlet

The digesterPath is relative to the servlet context. This source can be used when loading the data from a URL. In practice, this allows the file to be collocated with the other configuration files stored in the WEB-INF directory.

The value defaults to servlet if not specified.

digesterPath

Path to the XML datafile containing the Digester rules. This value is resolved based on the setting for the digesterSource element.


The loaded data can be accessed from the application-scope. For example, the html:optionsCollection tag can be used to set the label and value for a drop-down as shown in this snippet from the subscription.jsp file of the struts-example:

<html:select property="type">     <html:options collection="serverTypes" property="value"                labelProperty="label"/> </html:select>

See Also

Recipe 10.8 demonstrates how to use the Digester to refresh application-scoped data on demand.

The JavaDocs for the DigestingPlugIn can be found at http://struts.apache.org/api/org/apache/struts/plugins/DigestingPlugIn.html.

The homepage for the Digester can be found at http://jakarta.apache.org/commons/digester/.

O'Reilly's ONJava.com has a good article called "Learning and Using Jakarta Digester" by Phillip K. Janert, Ph.D. at http://www.onjava.com/pub/a/onjava/2002/10/23/digester.html.



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net