17.2 The Manipulation Class

Java Servlet Programming, 2nd Edition > 17. XMLC > 17.2 The Manipulation Class

 
< BACKCONTINUE >

17.2 The Manipulation Class

Once you have compiled your HTML file into a Java-based XML representation, the next step is to write what's called a manipulation class . This class creates an instance of the document, modifies its content, and outputs the document to its final destination. Example 17-3 demonstrates a simple manipulation class for our Hello page. Notice that it's a standalone program. The manipulation class tends to be a servlet or a class called by a servlet, but it doesn't have to be. XMLC has no dependencies on the Servlet API.

Example 17-3. The Manipulation Class for the Hello Page
import java.io.*; import org.w3c.dom.*; import org.w3c.dom.html.*; import org.enhydra.xml.io.DOMFormatter; public class HelloManipulation {   public static void main(String[] args) {     // Some pseudodynamic content     String username = "Mark Diekhans";     int numMessages = 43;     // Create the DOM tree     Hello hello = new Hello();     // Set the title, using a standard DOM method     hello.setTitle("Hello XMLC!");     // Set the value for "greeting"     hello.setTextGreeting("Hello, " + username);     // Set the value for "messages"     hello.setTextMessages("" + numMessages);     try {       DOMFormatter formatter = new DOMFormatter();  // can be heavily tweaked       formatter.write(hello, System.out);     }     catch (IOException e) {       e.printStackTrace();     }   } }

The class first sets the pseudodynamic values to be added to the page: the username, and number of messages. Then it creates an instance of the Hello class that holds the contents of the HTML document. If the hello instance were output at this point, it would generate a faithful representation of the original HTML file. The manipulation class then proceeds to set the page title, the value for the greeting, and the value for the number of messages. It sets the greeting and number of messages using the accessor methods added by XMLC. It sets the title using a standard DOM method. There are many interesting accessor methods standard to the HTML DOM classes such as getApplets( ), getImages( ), getLinks( ), getForms( ), getAnchors( ), and so on. For more information on the capabilities of the DOM classes, see the documentation bundled with XMLC. Finally, the manipulation class uses an org.enhydra.xml.io.DOMFormatter to write the hello instance to System.out. The DOMFormatter can accept an OutputOptions class in its constructor to tweak how the XML is output, but for standard web browsers the default behavior works fine and produces:

<HTML><HEAD><TITLE>Hello XMLC!</TITLE></HEAD><BODY><H2><SPAN id='Greeting'>Hello,  Mark Diekhans</SPAN></H2>You have <SPAN id='Messages'>43</SPAN> new messages. </BODY><!-- hello.html --></HTML>

Notice the mock-up values have been replaced with new values and that all extraneous whitespace has been removed for efficiency. Also notice the comment has been placed at the end of the file. That's a harmless Xerces bug.

To run the manipulation class yourself you'll need to make sure the xmlc.jar file containing the XMLC classes can be found in your classpath (or your server's classpath if calling XMLC from a servlet). Be aware that xmlc.jar contains several supporting packages that can cause conflicts if you have installed different versions of these same packages. With XMLC 1.2b1, watch out for external collisions with Apache Xerces 1.0.2, SAX 1.0, DOM Level 2, GNU RegExp 1.0.8, and JTidy 26jul1999. Package collisions can result in cryptic error messages. For example, when running xmlc the compiler might report the XMLC-generated class is abstract and can't be instantiated because the class does not define a particular method from a particular class. The true problem: you have a mismatch between DOM versions. The solution is to make sure the newest version comes first in the classpath. This works as long as package versions are backward compatible.

17.2.1 Modifying a List

Now let's move on to a more advanced operation, modifying a list. First, we create the prototype page containing a mock-up list as shown in Example 17-4.

Example 17-4. A Mock-up List of Languages
<!-- snoop.html --> <HTML><HEAD><TITLE>XMLC Snoop</TITLE></HEAD> <H1>Client Locales</H1> <UL> <LI >en <LI >es <LI >jp </UL> </BODY></HTML>

In production use this list would be part of a much larger page but it doesn't matter to XMLC at all. We compile the page using the XMLC compiler, and we specify -delete-class mockup to have the elements marked mockup automatically removed during the compile phase:

% xmlc -class Snoop -keep -delete-class mockup -methods snoop.html public org.w3c.dom.html.HTMLLIElement getElementLocale();

Notice only one accessor method was added to the document: getElementLocale( ) was added to return the <ID> element marked locale as an HTMLLIElement object. The manipulation class to dynamically alter this document is given in Example 17-5.

Example 17-5. The Manipulation Class for the List of Languages
import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import org.w3c.dom.*; import org.w3c.dom.html.*; import org.enhydra.xml.io.DOMFormatter; public class SnoopManipulation extends HttpServlet {   public void doGet(HttpServletRequest req, HttpServletResponse res)                                 throws ServletException, IOException {     res.setContentType("text/html");     PrintWriter out = res.getWriter();     // Get some dynamic data to display     Enumeration locales = req.getLocales();     // Create the DOM tree     Snoop snoop = new Snoop();     // Get the first "prototype" list item     // The rest were removed during the xmlc compile     HTMLLIElement item = snoop.getElementLocale();     // Get the prototype's parent so we can manage the children     Node parent = item.getParentNode();     // Loop over the locales adding a node for each     while (locales.hasMoreElements()) {       Locale loc = (Locale)locales.nextElement();       HTMLLIElement newItem = (HTMLLIElement) item.cloneNode(true);       Text text = snoop.createTextNode(loc.toString());       newItem.replaceChild(text, newItem.getLastChild());       parent.insertBefore(newItem, null);     }     // Remove the prototype item     parent.removeChild(item);     // Output the document     DOMFormatter formatter = new DOMFormatter();  // can be heavily tweaked     formatter.write(snoop, out);   } }

The interesting part of this servlet is the while loop. For each locale the servlet clones the prototype item, changes the text held by the clone, and inserts the clone to the end of the list. After the while loop the servlet removes the prototype item, leaving the list full of clones containing the actual data. The result is shown in Figure 17-1.[3]

[3] Beware of classpath interactions when running this example. We have XML libraries needed by XMLC, JDOM, and possibly the server itself. Satisfying the XML library version requirements of all three components without conflict can involve a fair amount of black magic and isn't always possible.

Figure 17-1. English (U.S.), Vietnamese, and Thai Locale Abbreviations

With this example we can see that one of the difficulties of XMLC is dealing with the less-than-intuitive DOM object model. There are some tricks to using DOM. For example, you see here that String content can only be created using the factory method createTextNode( ) called on the document to which the text will be added, and once you have the content created, the model for adding the text to the document requires adding the text as a child node of its containing element and removing the existing child. Under consideration is that a future version of XMLC may include support for the much easier to use JDOM object model. Also, toolkits being developed for XMLC layer on top of the DOM and abstract away some of its more cumbersome requirements.


Last updated on 3/20/2003
Java Servlet Programming, 2nd Edition, © 2001 O'Reilly

< BACKCONTINUE >


Java servlet programming
Java Servlet Programming (Java Series)
ISBN: 0596000405
EAN: 2147483647
Year: 2000
Pages: 223

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