Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

A trivial use case would be adding a 'replace' function that is callable from a DFDL expression. In the DFDL Schema, we might call  call something like the below; where transformedElem will contain "Hello_World", if someElement resolves to "Hello World". 

...

Code Block
languagejava
@UserDefinedFunctionIdentification(
	name = "replace", 
	namespacenamespaceURI = "urn:example:com:ext:udfunction:stringfunctions" 
)
public class Replace {
	public String evaluate(String orig, String pre, String post) {
		//implementation...
	}
}

...

Another use case would be implementing the normalization of elevation above Mean-Sea-Level (MSL) to Height-Above-Ellipsoid (HAE) for Link16F1 data. In the DFDL schema, we might call something like the below; where the functions will return the result of the conversion.

Code Block
xmlns:mhdf="http://extOther.UDFunction.ElevationConversions.com"
...
dfdl:outputValueCalc="{ mhdf:convert_to_hae(../lat, ../lon, ../msl) }"

The function userDefinedFunction class would look something like the below

Code Block
languagejava
@UserDefinedFunctionIdentification(
	name = "convert_to_hae", 
	namespacenamespaceURI = "http://extOther.UDFunction.ElevationConversions.com" 
)
public class MSLConversions {
	public double evaluate(double latitude, double longitude, double msl) {
		//implementation..
	}
}

...

The Daffodil solution will use a combination of JAVA's ServiceLoader and Reflection APIs.

Daffodil Provided

...

Classes

Daffodil will provide a UserDefinedFunction interface, a UserDefinedFunctionProvider abstract class, a  UserDefinedFunctionIdentification annotation class, and two exception classes: UserDefinedFunctionFatalException and UserDefinedFunctionProcessingError.

Each UDF must implement the UserDefinedFunction interface. This marks it as a UDf UDF to Daffodil and gives it some properties such as Serializability.

...

The UserDefinedFunctionProcessingError exception can be thrown when an implementer wishes to throw a recoverable error that'll induce backtracking. The UserDefinedFunctionFatalException exception can be thrown to halt processing all together and abort Daffodil.

...

The implementer will be expected to implement at least 2 two classes: a provider class and at least one UDF class.

...

The UDF classes will contain the functionality of the UDF embodied in an evaluate method. The UDF class will be expected to implement an evaluate method as well as apply the Daffodil provided UserDefinedFunctionIdentification annotation to the class . Because the parameter types and the return types of the evaluate function are dependent on the functionality, and we really only care about the name, we will not provide an abstract function for it. Each function that the implementer wishes to expose must implement the UserDefinedFunction interface, contain an evaluate function, and have the UserDefinedFunctionIdentification annotation. See Use Cases/Examples 135859640 for a sample UDF class.

Daffodil Service Loader

...

MockDaffodil.jar contains a Scala app, that also contains a JAVA class that uses ServiceLoader. It needs UDFunctionProviderImpl.jar & UDFunctionProvider.jar

https://github.com/apache/incubator-daffodil/pull/279/commits/53ae92f43a31623f4aa1544db96d3bab0112b46f


View file
nameHAEMSLConversions.jar
height250
View file
nameMockDaffodil.jar
height250
View file
nameUDFunctionProvider.jar
height250
View file
nameUDFunctionProviderImpl.jar
height250