Java XML Functionality


XML provides basic support for processing XML documents. Developers have been parsing XML with Java for years . However, for the first time, the XML libraries are part of the J2SE library, which makes them a standardized set of Java platform APIs.

The XML libraries offer many powerful features, such as navigating with XPath, transforming one XML document to another one with a different schema, and, my favorite, displaying and styling a document with Extensible Stylesheet Language Transformations (XSLT). For this chapter, however, the discussion is confined to using XML for the assignment.

These are the three main packages you are likely to need if you use XML:

  • javax.xml.parsers Contains classes for processing XML documents through Document Object Model (DOM) or Simple API for XML (SAX).

  • javax.xml.transform.dom Contains classes for transforming an XML document parsed with DOM using XSL Transformations (XSLT).

  • javax.xml.transform.sax Contains classes for transforming an XML document parsed with SAX using XSLT.

  • javax.xml.transform.stream This package contains the StreamResult class (which holds the output of a transformation) and the StreamSource class (which holds the transformation source in the form of a stream of XML Markup).

The difference between DOM and SAX is how the parser converts the XML document. Using DOM, the parser creates an object in memory that represents the entire XML document as an object tree. DOM makes it easy to reference any part of the document; DOM does to XML what RandomAccessFile does to files. This contrasts with SAX, which is an API that facilitates sequential, event-driven access to the document. As the parser marches through the document, the parser calls certain methods in response to certain events (e.g., the end of tag event method). These methods are treated as events that you respond to. The advantage of DOM is random access, but it uses more resources. The advantage of SAX is speed, but it allows sequential access only.

Many candidates initialize their application by processing the parameters the user provides at the command line. This approach is certainly reasonable and the path of least resistance. However, some candidates prefer the more professional approach of initializing an application through a XML configuration file.

To demonstrate J2SE's new XML functionality, Listing 8.2 demonstrates how to grab application settings from a configuration file that is an XML document. It is in this configuration file where the user can store your project's initial settings. These settings are defined when the application is installed and, if applicable , reconfigured later.

Listing 8.2 shows that when your application is started or restarted, the configuration settings are read from this XML document. These are the steps for initializing your application using a configuration file formatted as an XML document:

  1. Create a DOM object.

  2. Open the configuration file.

  3. Parse the XML by walking the tree.

  4. Process the configuration parameters.

  5. Initialize your application with these parameters.

If you choose to go this route, be sure to include instructions in the README.TXT file about how the evaluator should edit the configuration file. For example, the application must know the path to the database file supplied with the assignment you downloaded. The evaluator must add this path to the configuration file or the application won't work.

graphics/note_icon.gif

Most candidates use command-line options to configure their project's database binary file location, local/remote mode operation, and, for remote mode, the RMI server's address and port. However, the command line is not the only way. You can justify using a configuration file because it makes the application more robust and easier to use.


Listing 8.2 A Sample Configuration File Handler
 import java.io.File; import java.io.IOException; import java.util.ArrayList; import org.w3c.dom.Document; import org.w3c.dom.DOMException; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.w3c.dom.Element; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; public class ConfigureApplication {     //the initialization parameters:     String app_name;     String app_client_class;     String app_server_class;     String app_database_class;     String welcome_file;     String design_file;     String help_file;     String mode;     String db_path;     String root_path;     String security_role;     String nodeName;     String nodeText;     int lastType = 0;     public static void main(String[] args)     {         //get filename and pass that to parser         String filename = "configuration.xml";         if(args.length>0) filename = args[0];         ConfigureApplication application =                                 new ConfigureApplication();         application.configure(filename);     }     public void configure(String filename)     {         try         {   //get SAX factory             DocumentBuilderFactory factory =                       DocumentBuilderFactory.newInstance();             factory.setIgnoringComments(true);             //load document             Document doc = factory.newDocumentBuilder()                                 .parse(new File(filename));             //parse document, set initialization parameters             processChild(doc);             //now configure application with initialization parameters             configureApplication();         } catch (SAXException saxe)         {             System.out.println(saxe);         } catch (ParserConfigurationException pce)         {             System.out.println(pce);         } catch (IOException e)         {             System.out.println(e);         }     }     //traverse the DOM tree     private void processChild(Node node)     {         int type = node.getNodeType();         if(type==Node.ELEMENT_NODE)         {             lastType = type;             nodeName = node.getNodeName();         }         //extract text         if(type==Node.TEXT_NODE)         {             String text = node.getNodeValue().trim();             //skip if empty or not succeeding element             if (lastType == Node.ELEMENT_NODE                  && text.length() > 0)             {   //you have key-value pair, assign to parameter                 loadParameter(nodeName, text);                 lastType = type;             }         }         for(Node child = node.getFirstChild();             child != null;             child = child.getNextSibling())         {             //we like recursion             processChild(child);         }     }     //initialize application     //printing is eye candy only     public void configureApplication()     {         String name;         String desc;         String value;         System.out.println("name="+app_name);         System.out.println("client="+app_client_class);         System.out.println("server="+app_server_class);         System.out.println("database="+app_database_class);         System.out.println("welcome="+welcome_file);         System.out.println("design="+design_file);         System.out.println("help="+help_file);         System.out.println("mode="+mode);         System.out.println("db path="+db_path);         System.out.println("root path="+root_path);         System.out.println("security role="+security_role);     }     ////match nodeName with parameter name and assign nodeText to it     public void loadParameter(String nodeName, String nodeText)     {         //switch replacement, see note at bottom         //find initialization parameter and assign new value         switch_(nodeName);         {                 if(case_("app-name"))             {                 app_name = nodeText;                 break_();  //exit switch             }                                   if(case_("app-client-class"))             {                 app_client_class = nodeText;                 break_();  //exit switch             }                                   if(case_("app-server-class"))             {                 app_server_class = nodeText;                 break_();  //exit switch             }                                     if(case_("app-database-class"))             {                 app_database_class = nodeText;                 break_();  //exit switch             }                               if(case_("welcome-file"))             {                 welcome_file = nodeText;                 break_();  //exit switch             }                              if(case_("design-file"))             {                 design_file = nodeText;                 break_();  //exit switch             }                            if(case_("help-file"))             {                 help_file = nodeText;                 break_();  //exit switch             }                       if(case_("mode"))             {                 mode = nodeText;                 break_();  //exit switch             }                          if(case_("db-path"))             {                 db_path = nodeText;                 break_();  //exit switch             }                            if(case_("root-path"))             {                 root_path = nodeText;                 break_();  //exit switch             }                                if(case_("security-role"))             {                 security_role = nodeText;                 break_();  //exit switch             }                    if(default_())             {                 //process default condition             }         }     } /*********SWITCH REPLACEMENT START*****************/ //The switch is limited to byte, short, char, or int. //This switch is an improvement that handles objects.     Object switch_expression;     boolean stop = false;     boolean match = false;     boolean is_default = false;     void switch_(Object item)     {        switch_expression = item;     }     boolean case_(Object item)     {         if (stop) return false;         if (match) return true;         //can customize behavior with a         //custom comparator here, perhaps         //myComparator(item, switch_expression).         if  (item.equals(switch_expression)) match = true;         return match;     }     //required to reset switch     boolean default_()     {         match = false;         if (stop)         {             stop = false;             return false;         }         stop = false;         return true;     }     void break_()     {        stop = true;     } /*********SWITCH REPLACEMENT END *****************/ } 

Using Listing 8.2, you can configure your project with the following configuration file:

 <?xml version="1.0" encoding="ISO-8859-1"?> <application>     <app-name>Super Bowl Reservation System</app-name>     <app-client-class>myPackage.client.Client         </app-client-class>     <app-server-class>myPackage.server.RemoteServer </app-server-class>     <app-database-class>myPackage.database.Database </app-database-class>     <welcome-file>README.TXT</welcome-file>     <design-file>DESIGN_CHOICES.TXT</design-file>     <help-file>index.jsp</help-file>     <mode>local</mode>     <db-path>myDatabase.bin</db-path>     <root-path>c:\programs\football\</root-path>     <security-role>regular user</security-role> </application> 

The preceding configuration file is one possibility. You can certainly add more settings. For example, you could save the details of the last reservation. Then when the examiner restarts your application, voil details of the last reservation are shown. Running the program on the preceding configuration file produces the following output:

 name=Super Bowl Reservation System client=myPackage.client.Client server=myPackage.server.RemoteServer database=myPackage.database.Database welcome=README.TXT design=DESIGN_CHOICES.TXT help=index.jsp mode=local db path=database.bin root path=c:\programs\football\ security role=regular user 

Listing 8.1 produced a log in XML format. By changing the filename and the tags to scan for in Listing 8.2, you can show this log to the user. For example, you could add a menu item for the user to select having a session log displayed in a dialog box.

graphics/caution_icon.gif

Listing 8.1 creates a file and places it in the application's root directory, the directory from where the application is run. Should you choose to display the log, Listing 8.2 will find it as is. However, if you move the log, make sure Listing 8.2 uses the new path.




JavaT 2 Developer Exam CramT 2 (Exam CX-310-252A and CX-310-027)
JavaT 2 Developer Exam CramT 2 (Exam CX-310-252A and CX-310-027)
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 187

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