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  UAFunctionFactoryvisibility, 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