Powered by SmartDoc

The cdl option

The cdl option enables Relaxer to generate a component implementation for Java defined by Relaxer Component Definition Language (RCDL).

Parameters

The cdl option takes no parameters. Specifing the cdl option indicates that you want to use the CDL generator.

Artifact

Relaxer generates various artifacts from the RCDL or RIDL defitions, as follows:

INTERFACE works with replaceable part of file names. This string is substituted with an interface name from the RCDL definition.

The URComponent is a helper class for the Relaxer eomponent.

The IINTERFACE is a java interface for the API of the Relaxer component.

The IINTERFACEService is a java interface for the SPI of the Relaxer component.

The IINTERFACEFilter is a Java interface for filter objects.

The AbstractINTERFACEFilter is an abstract base class for filter objects.

The INTERFACEForwardProxy and the INTERFACEContainer are classes used by Relaxer internally at runtime.

The AbstractINTERFACEService is an abstract base class for service providers.

The INTERFACEService.java.INTERFACE is a prototype for the service provider.

The INTERFACEBean is a JavaBeans to be used by application programs.

The INTERFACECommand is a front-end command to be used by the end user.

Example

List 18.2.3.1[cdl.rcdl] is a sample RCDL definition, and List 18.2.3.2[cdl.rng] is a sample RELAX NG schema used by the RCDL definition.

cdl.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="cdl.rng"/>
    <operation name="findAccount">
      <in name="accountNo" type="token"/>
      <out label="account"/>
    </operation>
  </interface>
</component>
cdl.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 the Relaxer with the cdl option is as follows:

$ relaxer -cdl cdl.rcdl

As a result, Relaxer generates 17 files, as follows:

List 18.2.3.3[IAccountManager.java] is the 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.2.3.4[IAccountManagerService.java] is the IAccountManagerService which is a Java interface to be used as an SPI.

IAccountManagerService.java
import java.rmi.*;

public interface IAccountManagerService extends IAccountManager {
}

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

Implementation of the method in the class throws java.lang.UnsupportedOperationException. It is stub code that the souce code can be compile.

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 then create a findAccount method. Finally, the service provider AccountManagerService is implemented, as shown in List 18.2.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));
	}
    }
}

Compilation of AccountManagerCommand is as follows. No special compile options are needed.

$ javac AccountManagerCommand.java

Execution of AccountManagerCommand is as shown here:

$ java AccountManagerCommand -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>

The -findAccount, followed by a12345, indicates that you want to invoke a findAccount method with the parameter a12345.

As a result, the command outputs an XML document produced by the service provider.