Powered by SmartDoc

The java.pattern.visitor option

The java.pattern.visitor option adds a visitor facility for Relaxer objects.

The visitor facility, which is a kind of Visitor pattern from the GoF's Design Pattern book, enables a facility to traverse object structure.

Parameters

The java.pattern.visitor option takes one of the following values as a parameter:

true
Enables a visitor facility.
false
Disables a visitor facility.

The default configuration is false. No parameter implies that the parameter is true.

Artifacts

The java.pattern.visitor option generates additional classes as follows:

The java.pattern.visitor option adds the following methods to Relaxer objects.

Example

List 7.20.3.1[javaPatternVisitor.rng] is a sample schema for the java.pattern.visitor option.

javaPatternVisitor.rng
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <start>
    <ref name="account"/>
  </start>
  <define name="account">
    <element name="account">
      <attribute name="accountNo">
        <data type="token"/>
      </attribute>
      <element name="balance">
        <data type="int"/>
      </element>
      <element name="owner">
        <data type="token"/>
      </element>
      <ref name="address"/>
      <zeroOrMore>
        <ref name="phone"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="address">
    <element name="address">
      <attribute name="zip">
        <data type="token"/>
      </attribute>
      <text/>
    </element>
  </define>
  <define name="phone">
    <element name="phone">
      <attribute name="area">
        <data type="token"/>
      </attribute>
        <data type="token"/>
    </element>
  </define>
</grammar>

Build

Execution of Relaxer with the java.pattern.visitor option is as follows:

$ relaxer -java -java.pattern.visitor javaPatternVisitor.rng

Because the Java generator is a default generator, execution of Relaxer as shown below has the same effect:

$ relaxer -java.pattern.visitor javaPatternVisitor.rng

As a result, Relaxer generates 11 files:

The IRNode is a interface for the composite pattern. The composite pattern is used automatically when the visitor pattern is used.

The IRVisitable, the URVisitor, the IRVisitor, and the RVisitorBase are the visitor pattern specific classes.

List 7.20.3.1.1[JavaPatternVisitor.java] is a sample program for the java.pattern.visitor option.

JavaPatternVisitor.java
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;

public class JavaPatternVisitor {
    public static void main(String[] args)
	throws IOException, SAXException, ParserConfigurationException {

	String uri = args[0];
	Account account = makeAccount(uri);
	printAccount(account);
	visitAccount(account);
    }

    private static Account makeAccount(String uri)
	throws IOException, SAXException, ParserConfigurationException {

	System.out.println("*** makeAccount ***");
	Account account = new Account(uri);
	return (account);
    }

    private static void printAccount(Account account) {
	System.out.println("*** printAccount ***");
	String accountNo = account.getAccountNo();
	long balance = account.getBalance();
	String owner = account.getOwner();
	System.out.println("AccountNo:" + accountNo);
	System.out.println("Balance:" + balance);
	System.out.println("Owner:" + owner);
	Address address = account.getAddress();
	if (address != null) {
	    String zip = address.getZip();
	    String place = address.getContent();
	    System.out.println("Address: [" + zip + "] " + place);
	}
	Phone[] phones = account.getPhone();
	for (int i = 0;i < phones.length;i++) {
	    Phone phone = phones[i];
	    String area = phone.getArea();
	    String number = phone.getContent();
	    System.out.println("Phone: [" + area + "] " + number);
	}
    }

    private static void showAccount(Account account) {
	System.out.println("*** showAccount ***");
	System.out.println("XML:" + account);
    }

    private static void visitAccount(Account account) {
	System.out.println("*** visitAccount ***");
	PrintVisitor visitor = new PrintVisitor();
	URVisitor.traverse(account, visitor);
    }
}

In the JavaPatternVisitor, the visitor class PrintVisitor as shown in List 7.20.3.1.2[PrintVisitor.java] is used.

PrintVisitor.java
public class PrintVisitor extends RVisitorBase {
    public boolean enter(Account account) {
	System.out.println("enter - Account");
	String accountNo = account.getAccountNo();
	long balance = account.getBalance();
	String owner = account.getOwner();
	System.out.println("AccountNo:" + accountNo);
	System.out.println("Balance:" + balance);
	System.out.println("Owner:" + owner);
        return (true);
    }

    public void leave(Account account) {
	System.out.println("leave - Account");
    }

    public boolean enter(Address address) {
	System.out.println("enter - Address");
	String zip = address.getZip();
	String place = address.getContent();
	System.out.println("Address: [" + zip + "] " + place);
        return (true);
    }

    public void leave(Address address) {
	System.out.println("leave - Address");
    }

    public boolean enter(Phone phone) {
	System.out.println("enter - Phone");
	String area = phone.getArea();
	String number = phone.getContent();
	System.out.println("Phone: [" + area + "] " + number);
        return (true);
    }

    public void leave(Phone phone) {
	System.out.println("leave - Phone");
    }
}

Compilation of JavaPatternVisitor.java is shown here:

$ javac JavaPatternVisitor.java

Execution

List 7.20.3.2.1[javapatternVisitor.xml] is an XML document for testing.

javapatternVisitor.xml
<account accountNo="12345">
  <balance>102030</balance>
  <owner>XML Taro</owner>
  <address zip="213">Yokohama</address>
  <phone area="123">456-7890</phone>
  <phone area="090">123-4567</phone>
</account>

Execution of the JavaPatternVisitor class is shown here:

$ java JavaPatternVisitor javaPatternVisitor.xml
AccountNo:12345
Balance:102030
Owner:XML Taro
XML:<account xmlns="http://example.com/account" \
    accountNo="12345"><balance>102030</balance><owner>XML \
    Taro</owner></account>