http://www.dassault.aviation.com/meteo:visibility
new keyword. It will send a meteo
request to the meteoProvider module.meteo
service as an interface of the Jena Jena moduleUAFunction
to implement the http://www.dassault.aviation.com/meteo:visibility
keywordmeteo
service as an interface of the Jena Jena moduleUAFunctionFactory
to the Jena module library<application name="jena"> <deployment> <lib url="JenaModule.jar" /> <lib url="JenaFunctions.jar" /> </deployment> <modules> <module name="jena"> <interfaces> <requestReceived service="owlRequest"/> <requestReceived service="owlObjectRequest" uri="http://dassault-aviation.com/jena" /> <requestReceived service="applyOperations" uri="http://dassault-aviation.com/jena" /> <eventReceived service="saveSchema"/> <requestSend service="meteo" /> </interfaces> </module> </modules> </application>
<properties> <application name="jena"> <module name="jena"> <moduleArrayGroupProperty key="schemas"> <moduleArrayValue> <moduleProperty key="name" value="inav" /> <moduleProperty key="owlData" value="MapGeoSparql.owl.rdf" /> <moduleProperty key="prefixNS" value="inav:" /> <moduleProperty key="customFunctions" value="uaFunctions.xml" /> <moduleProperty key="owlNS" value="http://localhost/INAV#" /> <moduleProperty key="geosparql" value="true" /> </moduleArrayValue> </moduleArrayGroupProperty> <moduleProperty key="debug" value="false" /> <moduleProperty key="commit" value="true" /> </module> </application> ... </properties>The
uaFunctions.xml
only has to declare the path of our factory:<customFunctions> <factoryPath path="JenaFunctions.jar"/> </customFunctions>Now we have to code this factory. Don't worry, it is not as hard as it looks.
JenaFactoryConf: org/da/jena/functions/uaFunction.xmlThe specification of the
uaFunction.xml
file is the following:<customFunctions> <factory name="meteoUAFactory" path="org.da.jena.functions.MeteoUAFactory" prefix="da" namespace="http://www.dassault.aviation.com/meteo"> <uaFunction name="visibility" countArguments="1" /> </factory> </customFunctions>As you can see:
org.da.jena.functions.MeteoUAFactory
is the path of our UAFunctionFactory
visibility
, with only one argument (in our case, it is the Waypoint Label)da:visibility
or http://www.dassault.aviation.com/meteo:visibility
.
UAFunctionFactory
interface, but as explained in the Jena uaFunctions article, it is simpler to extend the AbstractUAFunctionFactory
class: public class MeteoUAFactory extends AbstractUAFunctionFactory { public MeteoUAFactory() { super(); } @Override protected Function createImpl(String fctName) { FunctionKey fkey = UAFunctionFactory.createFunctionKey(fctName); // the complete IRI is http://www.dassault.aviation.com/meteo:visibility if (fkey.getURI().equals("http://www.dassault.aviation.com/meteo")) { switch (fkey.getName()) { case "visibility": return new visibility(); default: return null; } } else { return null; } } }As you see, the only thing the factory must do is return a new instance of the
Function
class implementing the keyword.
UAFunction
interface. Also this function has only one argument, so it must extend the FunctionBase1
class:public class visibility extends FunctionBase1 implements UAFunction { }
init
method to get our factory and the meteo
service:public class visibility extends FunctionBase1 implements UAFunction { private Module module = null; private UAFunctionFactory factory = null; private ServiceInstance meteoService = null; public visibility() { super(); } @Override public void init(Module module, UAFunctionFactory factory) { this.module = module; this.factory = factory; meteoService = module.getService("meteo"); } }
exec
method for the function will return the result of the function invocation. It is called by the Jena engine upon encountering the keyword for the function:public class visibility extends FunctionBase1 implements UAFunction { private Module module = null; private UAFunctionFactory factory = null; private float result = 0; public visibility() { super(); } @Override public NodeValue exec(NodeValue nv) { wpt = nv.getString(); // the waypoint name is a string factory.invokeAndBlock(this, 100); // we block to be sure that the result will be available immediately return NodeValue.makeFloat(result); // the result is a visibility, we decide to return it as a float } }As explained in the Jena uaFunctions article, we need to implement the
invoke
method of the UAFunction
interface, because this is this method which will be called by the factory upon calling factory.invokeAndBlock(this, 100)
:@Override public void invoke() { _ // invoke the meteo service _ meteoService.getData("type").setValue("visibility"); _ meteoService.getData("waypoint").setValue(wpt); _ meteoService.invokeAndBlock(); _ // as the invoke is blocking, we get the result just after the invoke _ String resultS = meteoService.getValueAsString("result"); _ if (resultS.isEmpty()) { _ result = -1; _ } else { _ result = Float.parseFloat(resultS); _ } _ factory.unlock(); // the calling thread is blocked until unlock is called }Now everything is done.
Copyright 2017-2020 Dassault Aviation. All Rights Reserved. Documentation and source under the LGPL v3 licence