The cdl.filter.assert option takes one of the following values as a parameter.
The cdl.filter.assert option generates filter implementations for the component.
The cdl option generates base classes as follows:
In addition to these base classes, the cdl.filter option related classes shown below are generated.
The cdl.filter option adds no additional methods to Relaxer objects.
List 6.2.3.1[cdlFilterAssert.rcdl] is a sample RCDL definition, and List 6.2.3.2[cdlFilterAssert.rng] is a sample RELAX NG schema used by the RCDL definition.
<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="cdlFilterAssert.rng"/> <operation name="findAccount"> <in name="accountNo" type="token"/> <out label="account"/> </operation> </interface> </component>
<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 option is as follows:
$ relaxer -cdl -cdl.filter.assert cdlFilter.rcdl
As a result, Relaxer generates 18 files as follows:
AccountManagerLogingFilter
is a filter object for
logging.
List 6.2.3.3[IAccountManager.java] shows IAccountManager
which is a Java interface to be used as an API.
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 6.2.3.4[IAccountManagerService.java]
shows IAccountManagerService
which is a Java interface
to be used as an SPI.
import java.rmi.*; public interface IAccountManagerService extends IAccountManager { }
To complete the component,
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 6.2.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
.
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 6.2.3.6[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 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
means invoking a findAccount
method
with a parameter a12345
.
As a result, the command outputs an XML document produced by the service provider.