Constructs service call routes from an XML descriptor. XRouteManager caches
routes so that they can be resused once constructed.
The startup properties file lists the datasets file in its ModelData entry.
e.g.
UseWindow=false
ClientWidth=800
ClientHeight=600
StartPackage=net.xoetrope.myPackage
StartClass=myStartScreen
Title=My Application
StyleFile=myStyles.txt
ModelData=datasets.xml
CenterWin=false
XDataSourceClass=net.xoetrope.xlib.data.XLibDataSource
The dataset then points to a datasource, usually called routes.xml.
<?xml version="1.0" encoding="UTF-8"?>
<DataSources>
<DataSource name="Tables" type="database" filename="tables.xml"/>
<DataSource name="ListValues" filename="staticdata.xml"/>
<DataSource name="Routes" type="routing" filename="routes.xml"/>
<DataSource name="Services" type="service" filename="services.xml"/>
</DataSources>
This XML
file describes each named route as a series of layers with separate entries
for the client (local) and server (remote) sides.
<?xml version="1.0" encoding="UTF-8"?>
<Routes>
<route name="myRemoteService">
<layer class="net.xoetrope.service.XHttpClientServiceProxy" url="http://localhost:8080/xserviceservlet" urlEncode="false"/>
</route>
<route name="myCalculationService">
<layer class="net.xoetrope.service.test.CalcTestService"/>
</route>
</Routes>
The route manager is used in conjunction with the XServiceModelNode as the
following fragement of test code looking up and invoking shows:
XRouteManager routeMgr = XRouteManager.getInstance();
XServiceModelNode node = new XServiceModelNode();
try {
node.setupService( "getName", routeMgr.getRoute( "myCalculationService" ), null );
Object result = node.get();
assertTrue( result.toString().compareTo( CalcTestService.class.getName() ) == 0 );
...
Normally this method of invoking a service would not be used as the services
can more easily be invoked by looking up the XServiceModelNode in the overall
XModel. The nodes in the XModel are configured via the Services
datasource as follow:
<?xml version="1.0" encoding="UTF-8"?>
<Services>
<service name="calcVolume" route="remote" processor="net.xoetrope.service.test.CalcTestService">
<arg name="roomWidth" type="double"/>
<arg name="roomLength" type="double"/>
<arg name="roomHeight" type="double"/>
<return type="double"/>
</service>
<service name="calcRepayments" route="remote">
<arg name="term" type="int" mandatory="true"/>
<arg name="value" type="double" mandatory="true"/>
<arg name="deposit" type="double" mandatory="false"/>
</service>
<service name="getName" route="calcRoute">
<return type="String"/>
</service>
<service name="getNumber" route="calcRoute">
<return type="int"/>
</service>
</Services>
The service can then be invoked via the model as in the following example.
try {
XServiceModelNode node = (XServiceModelNode)XModel.getInstance().get( "calcVolume" );
node.setAttribValue( 0, new Double( 3.9 ));
node.setAttribValue( 1, new Double( 4.6 ));
node.setAttribValue( 2, new Double( 2.5 ));
Object result = node.get();
assertTrue( result instanceof Double );
assertTrue( ((Double)result).doubleValue() == 101.0 );
}
catch ( Exception ex ) {
ex.printStackTrace();
}
Note that on the server side of a remote call the services may need to be
implemented in the reverse order and in a slightly different order i.e. the
server side will have to provide an implementation of the service.
Copyright (c) Xoetrope Ltd. 2001-2003
$Revision: 1.1 $
|