Powered by SmartDoc

The cdl.jaxm option

The cdl.jaxm option generates a JAXM component from the RCDL or RIDL definition.

Parameters

The cdl.jaxm option takes one of the following values as a parameter.

true
Generates a JAXM component.
false
Does not generates a JAXM component.

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

Artifact

The cdl.jaxm option generates a JAXM component from the RCDL or RIDL definition.

The cdl option generates base classes as follows:

In addition to these base classes, the cdl.jaxm option related classes shown below are generated.

The JAXMINTERFACE and the JAXMINTERFACEServlet are important for programmars.

The JAXMINTERFACE is a JavaBeans to be used as a front-end against a application program. Because of this the JAXMINTERFACE implements the API interface IINTERFACE. Application programs uses the JAXMINTERFACE immdiately.

The JAXMINTERFACEServlet is a JAXM servlet. This object are executed as a JAXM server.

The INTERFACERemote, The INTERFACEClient are used internally.

The cdl.jaxm option adds no additional methods to Relaxer objects.

Example

List 18.7.3.1[cdlJaxm.rcdl] is a sample RCDL definition, and List 18.7.3.2[cdlJaxm.rng] is a sample RELAX NG schema used by the RCDL definition.

cdlJaxm.rcdl
<component xmlns="http://www.relaxer.org/xmlns/cdl"
           namespace="http://example.com/account"
           name="backOffice">
  <interface namespace="http://example.com/account" name="accountManager">
<grammar namespace="http://example.com/account" location="cdlJaxm.rng"/>
    <operation name="findAccount">
      <in name="accountNo" type="token"/>
      <out label="account"/>
    </operation>
  </interface>
</component>
cdlJaxm.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>

Execution of Relaxer with the cdl.jaxm option is as follows. The cdl option must be used together.

$ relaxer -cdl -cdl.jaxm cdlJaxm.rcdl

As a result, Relaxer generates 23 files:

JAXM-related classes are the IAccountManagerRemote.

The JAXM specific classes are the UJAXM, the JAXMAccountManager, the JAXMAccountManagerClient, and the JAXMAccountManagerServlet.

List 18.7.3.3[IAccountManager.java] shows IAccountManager which is a java interface to be used as an API.

IAccountManager.java
import java.rmi.*;

public interface IAccountManager extends Remote {
    /**
     * Application interface of the operation findAccount.
     *
     * @param accountNo
     * @exception RemoteException
     * @return Account
     */
    Account findAccount(String accountNo) throws RemoteException;
}

List 18.7.3.4[IAccountManagerService.java] shows IAccountManagerService which is a Java interface to be used as an SPI.

IAccountManagerService.java
import java.rmi.*;

public interface IAccountManagerService extends IAccountManager {
}

To complete this component, you must develop a service provider. For this purpose, Relaxer generates a prototype of the service provider. In the example, AccountManagerService in List 18.7.3.5[AccountManagerService.java.AccountManager] is the prototype of the service provider. AccountManagerService extends AbstractAccountManagerService which is the abstract base class for the service provider. Therefore, the AccountManagerService implicitly implements the SPI IAccountManagerService.

AccountManagerService.java.AccountManager
import java.rmi.RemoteException;

public class AccountManagerService extends AbstractAccountManagerService {

    /**
     * Implementation of a operation findAccount.
     *
     * @param accountNo
     * @exception RemoteException
     * @return Account
     */
    public Account findAccount(String accountNo) throws RemoteException {
        throw (new UnsupportedOperationException());
    }
}

Copy the file "AccountManagerService.java" and write a findAccount method. The service provider AccountManagerService is shown in List 18.7.3.6[AccountManagerService.java].

AccountManagerService.java
import java.rmi.RemoteException;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;

public class AccountManagerService extends AbstractAccountManagerService {

    /**
     * Implementation of a operation findAccount.
     *
     * @param accountNo
     * @exception RemoteException
     * @return Account
     */
    public Account findAccount(String accountNo) throws RemoteException {
	try {
	    Account account = new Account();
	    account.setAccountNo(accountNo);
	    account.setBalance(10000);
	    account.setOwner("XML Taro");
	    account.setAddress(
		new Address("<address zip='123'>Yokohama</address>")
	    );
	    Phone phone1 = new Phone();
	    phone1.setArea("123");
	    phone1.setContent("456-7890");
	    account.addPhone(phone1);
	    Phone phone2 = new Phone("<phone area='090'>123-4567</phone>");
	    account.addPhone(phone2);
	    return (account);
	} catch (IOException e) {
	    throw (new RemoteException(e.getMessage(), e));
	} catch (SAXException e) {
	    throw (new RemoteException(e.getMessage(), e));
	} catch (ParserConfigurationException e) {
	    throw (new RemoteException(e.getMessage(), e));
	}
    }
}

The List 18.7.3.7[web.xml.backOffice] is a prototype of deployment descriptor for the J2EE Web component. Though the prototype only has enough information for a deployment descriptor, you can use it as is.

web.xml.backOffice
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application \
    2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
  <display-name>backOffice</display-name>
  <servlet>
    <servlet-name>accountManager</servlet-name>
    <servlet-class>JAXMAccountManagerServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>accountManager</servlet-name>
    <url-pattern>/accountManager</url-pattern>
  </servlet-mapping>
</web-app>

The file web.xml.backOffice defines the following:

You must compile both client-side and server-side programs. The client-side program is AccountManagerCommand and the server-side program is JAXMAccountManagerServlet.

Compilation of AccountManagerCommand and JAXMAccountManagerServlet are as shown below. JAXM-related JAR files must be specified on the command line.

$ javac -classpath ".;jaxm-api.jar;saaj-api.jar" \
    AccountManagerCommand.java
$ javac -classpath ".;jaxm-api.jar;saaj-api.jar;j2ee.jar" \
    JAXMAccountManagerServlet.java

Creating Web component

To make a JAXM component, you must package parts of the component as a J2EE WAR file.

Suppose you have a root directory for packaging called /tmp/backOffice.

Create directory named /tmp/backOffice and /tmp/backOffice/WEB-INF as follows:

$ mkdir /tmp/backOffice
$ mkdir /tmp/backOffice/WEB-INF
$ mkdir /tmp/backOffice/WEB-INF/classes

Copy the class files to the the classes directory in the WEB-INF directory using this command:

$ cp *.class /tmp/backOffice/WEB-INF/classes

In the example, we use web.xml.backOffice, generated by Relaxer, as it is used for web.xml, a deployment descriptor for a J2EE Web component. Copy the file web.xml.backOffice as web.xml with this command:

$ cp jaxm-jar.xml.backOffice /tmp/backOffice/WEB-INF/web.xml

Finally, pack all the parts together with the JAR command.

$ cd /tmp/backOffice
$ jar cvf /tmp/backOffice.war .

As a result, the WAR file backOffice.war is created in the directory /tmp.

Deployment

To execute a Web application, you must deploy the application to a Web server.

Execution

Execution of AccountManagerCommand is shown here:

$ java -classpath \
    ".;jaxm-api.jar;saaj-api.jar;saaj-ri.jar;commons-logging.jar;mail.jar;activation.jar;dom4j.jar" \
    AccountManagerCommand --jaxm \
    http://localhost:8080/backOffice/accountManager -findAccount \
    a12345
<account accountNo="a12345"><balance>10000</balance><owner>XML \
    Taro</owner><address zip="123">Yokohama</address><phone \
    area="123">456-7890</phone><phone \
    area="090">123-4567</phone></account>

Following parameters are for AccountManagerCommand. The --jaxm option specifies using JAXM to access the target component.

The -findAccount followed by a12345 means invoking a findAccount method with a parameter a12345.

As a result, the command outputs an XML document which is sent back from the component via SOAP transport.