14 October 2010

Handling comments with SAX

DOM and StAX will readily handle XML comments.
With SAX 2 you will need to register an extra handler, LexicalHandler, to be called for comments and other lexical events (CDATA, DTD, Entities). The JAXP adapter class DefaultHandler2 is an adapter for all SAX2 handlers, including the LexicalHandler.
Here's a little code snippet, that shows how to set up your SAX parser to print comments:

      SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
      parser.setProperty(
        "http://xml.org/sax/properties/lexical-handler",
        new LexicalHandler() {
          public void comment(char[] ch, int start, int length)
            throws SAXException {
            System.out.println(
              "/* comment: " + String.valueOf(ch, start, length) + " */");
          }
          public void startDTD(String name, String publicId, String systemId)
            throws SAXException { }
          public void endDTD() throws SAXException { }
          public void startEntity(String name) throws SAXException { }
          public void endEntity(String name) throws SAXException { }
          public void startCDATA() throws SAXException { }
          public void endCDATA() throws SAXException { } 
        });

10 October 2010

DOM editing validation

The example below adds DOM schema validation while modifying the in-memory DOM. It uses DOM load/save example as a basis.
We are adding a text node instead of a comment now, to generate a schema inconsistency.
The checking kicks off when you call normalizeDocument.
Also compare with the parsing validation example.

// SimpleDOML3MemXSD.java

import com.sun.xml.internal.ws.developer.ValidationErrorHandler;
import org.w3c.dom.*;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.*;

import javax.xml.XMLConstants;
import java.io.OutputStreamWriter;

public class SimpleDOML3MemXSD {

  public static void main(String args[]) {
    Document doc;
    try {
      // Create DOM Document using DOM Level 3 Load
      DOMImplementationLS ls = (DOMImplementationLS) DOMImplementationRegistry.
        newInstance().getDOMImplementation("LS");
      LSParser builder = ls.createLSParser(
        DOMImplementationLS.MODE_SYNCHRONOUS,
        "http://www.w3.org/2001/XMLSchema");
      doc = builder.parseURI(args[0]);
      DOMConfiguration config = doc.getDomConfig();
      // for DTD use XMLConstants.XML_DTD_NS_URI
      config.setParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI);
      config.setParameter("validate", true);
      config.setParameter("error-handler", new StdErrorHandler());
      //Obtain root elements
      Element root = doc.getDocumentElement();

      // Add text (NOT ALLOWED BY SCHEMA)
      Text text = doc.createTextNode("Training text");
      root.appendChild(text);

      //Now validate
      doc.normalizeDocument();

     // Output to standard output; using DOM Level 3 save
      LSOutput target = ls.createLSOutput();
      target.setCharacterStream(new OutputStreamWriter(System.out));
      ls.createLSSerializer().write(doc, target);
    } catch (Exception e) {
      System.out.println(e.getMessage());
      e.printStackTrace();
      System.exit(0);
    }
  }

  private static class StdErrorHandler implements DOMErrorHandler {

    public boolean handleError(DOMError e) {
      String prefix = "Severity ";
      if (e.getLocation().getLineNumber() != -1) {
         prefix = "Line " + e.getLocation().getLineNumber()
          + " column  " + e.getLocation().getColumnNumber()
          + ", severity ";
      }
      System.err.println(
        prefix + e.getSeverity()
          + " issue: " + e.getMessage());
      return true;
    }
  }
}

DOM XML Load validation

The example below adds DOM schema validation when you are parsing the XML input file to the DOM load/save example.
The example also features a DOM Level 3 DOMErrorHandler.
Also compare with the editing validation example.

// SimpleDOML3XSD.java

import org.w3c.dom.*;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.*;

import javax.xml.XMLConstants;
import java.io.OutputStreamWriter;

public class SimpleDOML3LSXSD {

  public static void main(String args[]) {
    Document doc;
    try {

      // Create DOM Document using DOM Level 3 Load
      DOMImplementationLS ls = (DOMImplementationLS) DOMImplementationRegistry.
        newInstance().getDOMImplementation("LS");
      LSParser builder = ls.createLSParser(
        DOMImplementationLS.MODE_SYNCHRONOUS,
        // for DTD use XMLConstants.XML_DTD_NS_URI
        XMLConstants.W3C_XML_SCHEMA_NS_URI);
      DOMConfiguration config = builder.getDomConfig();
      config.setParameter("validate", true);
      config.setParameter("error-handler", new StdErrorHandler());
      doc = builder.parseURI(args[0]);

      // Obtain root elements
      Element root = doc.getDocumentElement();

      // Add comment texts
      Comment comment = doc.createComment("Training text");
      root.appendChild(comment);

      // Output to standard output; using DOM Level 3 save
      LSOutput target = ls.createLSOutput();
      target.setCharacterStream(new OutputStreamWriter(System.out));
      ls.createLSSerializer().write(doc, target);

    } catch (Exception e) {
      System.out.println(e.getMessage());
      e.printStackTrace();
      System.exit(0);
    }
  }

  private static class StdErrorHandler implements DOMErrorHandler {

    public boolean handleError(DOMError e) {
      String prefix = "Severity ";
      if (e.getLocation().getLineNumber() != -1) {
         prefix = "Line " + e.getLocation().getLineNumber()
          + " column  " + e.getLocation().getColumnNumber()
          + ", severity ";
      }
      System.err.println(
        prefix + e.getSeverity()
          + " issue: " + e.getMessage());
      return true;
    }
  }
}

9 October 2010

Load and Save XML with DOM (Level 3)

Prior to DOM Level 3, DOM did not standardize reading and writing XML.
Below is the  SL-385 code 4-2 modified to use the standard DOM level 3 Load and Save (LS) API.
An alternative JAXP (but not DOM standard) way is to read using the JAXP DocumentBuilder and to write using the JAXP transformer (TrAX XSLT).
(I included a comment showing DOM LS writing starting from a DocumentBuilder obrained from JAXP reading as well.)


// SimpleDOML3LS.java
import org.w3c.dom.*;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.*;
import java.io.OutputStreamWriter;

public class SimpleDOML3LS {

  public static void main(String args[]) {
    Document doc;
    try {

      // Create DOM Document using DOM Level 3 Load 
      DOMImplementationLS ls = (DOMImplementationLS) DOMImplementationRegistry.
          newInstance().getDOMImplementation("LS");
      LSParser builder = ls.createLSParser(
        DOMImplementationLS.MODE_SYNCHRONOUS,
        null);
      doc = builder.parseURI(args[0]);

      // Obtain root elements
      Element root = doc.getDocumentElement();

      // Add comment texts
      Comment comment = doc.createComment("Training text");
      root.appendChild(comment);

      // Output to standard output; using DOM Level 3 save

      // If you parsed using a JAXP DocumentBuilder
      // you can also get your LSimplementation from your Document:
      // DOMImplementationLS ls = (DOMImplementationLS) doc.
      //   getImplementation().getFeature("LS","3.0");
      LSOutput target = ls.createLSOutput();
      target.setCharacterStream(new OutputStreamWriter(System.out));
      ls.createLSSerializer().write(doc, target);

    } catch (Exception e) {
      System.out.println(e.getMessage());
      e.printStackTrace();
      System.exit(0);
    }
  }
}
To add newlines/indents to enhance readability of the output, replace in the above example
ls.createLSSerializer().write(doc, target);
with
      LSSerializer serializer = ls.createLSSerializer();
      DOMConfiguration serializerConfig = serializer.getDomConfig();
      serializerConfig.setParameter("format-pretty-print", Boolean.TRUE);
      serializer.write(doc, target);

6 October 2010

Oracle buys Passlogix SSO

You got to eat if you want to grow, and Oracle keeps on festing on other companies.
The last buy is a very rational one, and one that will easily integrate into the company.
Oracle was already reselling Passlogix under its own brand as part of its Identity and access management suite and is in-housing the technology now. Additionally Sun Microsystems, which became a piece of the Oracle pie last year, was partnering with PassLogix for Sun Identity and Access management as well.
Oracle's Identity and Access Management suite, will emerge as of the completest in the market.

3 October 2010

Google adds keyboard search navigation

Google's empire is built on providing an ordinary search utility. Still it keeps finding opportunities for enhancement while keeping it simple.
We already have suggest, a drop down box with search term autocompletion suggestions.
Only last month we got instant search, showing search results as you type.
Both are shown in the picture to the left.

Now Google is adding keyboard navigation, allowing you to move down through results (and to next page) using the arrow keys. Keyboard navigation starts after you hit enter in the search box. The current selected item is indicated by the little blue arrow head to the left. Hit enter again to go to the target page.

You need to be logged in with instant search enabled.

Still, criticists say that the blue arrow could be interpreted as a recommendation of the link to the user. It will point to the first position which is often an advertisement, Google's primary source of revenue.

1 October 2010

jspx document

Minimal solution of list headers JSTL exercise (SL-314-EE6 mod 6 lab 1) without any <%…%>  tags (e.g. for taglib declaration).
The document must be saved in a .jspx file (e.g. index.jspx):

<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <head><title>Header jspx page</title></head>
  <body>
    Request headers:
    <ul>
      <c:forEach var="zheader" items="${header}">
        <li>${zheader}</li>
      </c:forEach>
    </ul>
  </body>                                     
</html>