Some element can have facets that constrain the data they contain.
The facet
element has a attribute as follows:
name
The name
attribute specifies a name of constraint.
The facet
element has a constraint value as element contents.
List 19.4.1.1[grammarFacet.rcdl] is a sample RCDL definition and List 19.4.1.2[grammarFacet.rng] is a sample RELAX NG schema to be used in the sample 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="grammarFacet.rng"/> <operation name="findAccount"> <in name="accountNo" type="token"> <facet name="length">5</facet> </in> <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>
When you use relaxer with -cdl.filer.assert switch,
a filter for assertion, AccountManagerAssertionFilter
shown in
List 19.4.1.3[AccountManagerAssertionFilter.java],
is generated.
This filter checks the condition defined by the postCondition
element
before and after method execution.
import java.rmi.RemoteException; import org.relaxer.runtime.*; public class AccountManagerAssertionFilter extends \ AbstractAccountManagerFilter { /** * @param master */ public AccountManagerAssertionFilter(Object master) { super(master); } /** * Asserts against operation findAccount$AccountManager. * * @param accountNo * @exception RemoteException * @return Account */ public Account findAccount$AccountManager(String accountNo) throws \ RemoteException { IAccountManagerFilter $reference$ = rGetReference$AccountManager(); RVerifyReport $report$ = new RVerifyReport(); RVerifyContext $context$ = new RVerifyContext(); String $message$; try { rAssertInvariants(); $message$ = $context$.isValid(accountNo, "token", "length:5"); if ($message$ != null) { $report$.addError("accountNo", RVerifyReport.INVALID_VALUE, accountNo, \ "token{length:5}", $message$); } if (!$report$.isValid()) { throw (new IllegalArgumentException()); } Account $result$ = $reference$.findAccount$AccountManager(accountNo); rAssertInvariants(); $report$.addError($result$.verify()); if (!$report$.isValid()) { throw (new RAssertionException($report$)); } return ($result$); } catch (RemoteException e) { throw (e); } catch (Exception e) { if (e instanceof RAssertionException) { throw ((RAssertionException)e); } else { throw (new RemoteException(e.getMessage(), e)); } } } /** * Invariant * * @exception RemoteException * @return boolean */ public boolean rIsValidInvariants() throws RemoteException { IAccountManagerFilter $reference$ = rGetReference$AccountManager(); return (true); } /** * Invariant * * @exception RemoteException */ public void rAssertInvariants() throws RemoteException { if (!(rIsValidInvariants())) { throw (new RAssertionException("invariant")); } } }