11 Developing and Deploying Custom XPath Functions

This chapter discusses how to implement a function in Java as a Java XPath Class, deploy an XPath/XSL function in JDeveloper and deploy an XPath/XSL function in application servers.

This chapter includes the following sections:

11.1 Implementing a Function in Java as a Java XPath Class

Since the custom function can be invoked either as an XPath or XSL function, the implementation class must take care of both. For this reason, the hosting class must have at least:

  • A public static method with the same name as the function name.

    This method is used by the XSL function invocation. Currently, optional parameters on custom functions are not supported when registering with JDeveloper. For this reason, it is recommended to avoid functions with optional parameters.

  • A public static inner class which implements oracle.fabric.common.xml.xpath.IXPathFunction

    This interface has the method:

    Object call (IXPathContext context, List args) throws XPathFunctionException that gets called by service engines when the XPath function is invoked. When the function is called, the runtime engine passes the XPathContext and list of arguments passed to the function. IXPathContext enables you to get access to the BPEL variable values within the execution context. The implementation of this method should naturally delegate to the public static method representing the function.

    Example 11-1 illustrates a custom function implementation to get the current date. The implementation takes care of supporting both XSL and XPath. The function also has an optional parameter to show how overloaded methods are implemented:

    Example 11-1 Custom Function Implementation to Get the Current Date

    package oracle.apps.aia.core;•
    import java.text.SimpleDateFormat; 
    import java.util.Date; import 
    java.util.List;
    import oracle.fabric.common.xml.xpath.IXPathContext;
    import oracle.fabric.common.xml.xpath.IXPathFunction;
    import oracle.fabric.common.xml.xpath.XPathFunctionException;
    public class DateUtils
    {
    public static class GetCurrentDateFunction implements IXPathFunction
    {
    public Object call(IXPathContext context, List args) 
    throws XPathFunctionException
    {
    if (args.size() == 1)
    {
    String mask = (String) args.get(0); 
    if(mask==null || mask.equals(""))
    mask = "yyyy-MM-dd"; 
    return getCurrentDate(mask);
    }
    throw new XPathFunctionException("must pass one argument.");
    }
    }
    public static String getCurrentDate(String formatMask)
    {
    SimpleDateFormat df = new SimpleDateFormat(formatMask) 
    String s = df. format (new Date()); 
    return s;
    }
    . . .
    }
    

11.1.1 Naming Standards for Custom XPath Functions

These naming standards are enforced:

  • Function name

  • Function implementation class

  • Function implementation method

  • Function inner class

  • Function namespace

  • Function namespace prefix

11.1.1.1 Function Name

The function name must follow the standard Java method naming standards where the name should be Lower-Camel-Case.

Example: getCurrentDate, getEBMHeaderValue, ...

11.1.1.2 Function Implementation Class

You can have one or more function implemented in the same class. The class name must follow the Java class naming standard where it should be Upper-Camel-Case and convey the functionality of the functions it implements.

Example: EBMHeaderUtils, RoutingUtils, ...

11.1.1.3 Function Implementation Method

The implementation class will have a method for each XPath function. The method should be named the same as the function name. The parameter's data types should match the function parameter data types. If there are optional parameters in the function, you should have a different overloaded method to handle the extra optional parameters.

Example: getCurrentDate, getEBMHeaderValue, ...

11.1.1.4 Function Inner Class

There should be an inner-class for each XPath function named exactly as the Upper-Camel-Case of the function with a 'Function' suffix. The inner class is only needed to access the XPath function from BPEL. The inner class will have to implement the com.oracle.bpel.xml.XPath.IXPathFunction interface.

Example: GetESBHeaderValueFunction, ...

11.1.1.5 Function Namespace

For the function to appear in both the BPEL expression builder wizard and the XSL Mapper, the namespace must start with: http://www.oracle.com/XSL/Transform/java/ then followed by the fully qualified name of the Java class, which implements the function.

Example:

http://www.oracle.com/XSL/Transform/java/oracle.apps.aia.core.ebmheader.EBMHeaderUtils

http://www.oracle.com/XSL/Transform/java/oracle.apps.aia.order.route.RoutingUtils

11.1.1.6 Function Namespace Prefix

The namespace prefix must be a readable abbreviation based on functionality.

Example: ebh for GetEBMHeaderValueFunction.

11.1.2 Supported Data Types

The XPath 1.0 and XSL 1.0 data types are supported as return or input parameters to the function, as shown in Table 11-1:

Table 11-1 Supported Data Types for XPath Functions

XPath 1.0/XSL 1.0 Java

Node-set

XMLNodeList

Boolean

boolean

String

String

Number

Int, float, double,...

Tree

XMLDocumentFragment


11.2 Deploying the XPath/XSL Function in JDeveloper

Custom functions should be registered in JDeveloper to be able to show them with BPEL expression builder and in the XSL Mapper. To do that, provide a User Defined Extension Functions config file [ext-soa-xpath-functions-config.xml], as shown in Example 11-2, and register it with JDeveloper through FilePreferencesXSL Map.

Example 11-2 User Defined Extension Functions Config File

<?xml version="1.0" encoding="UTF-8"?>
<soa-xpath-functions xmlns=http://xmlns.oracle.com/soa/config/xpath xmlns:utl="http://www.oracle.com/XSL/Transform/java/oracle.apps.aia.core.DateUtils"
<function name="utl:getCurrentDate">
 <className>oracle.xpath.CustomFunction</className>
 <return type="string"/>
 <params>
  <param name="formatMask" type="string"/> 
 <params>
</function> 
<function ...>
 . . .
</function> 
</functions>

The implementation classes must be zipped/jared and dropped at:. $SOA_HOME/soa/modules/oracle.soa.ext_11.x.x/classes folder. This way, these classes will be placed in the classpath of WebLogic server.

11.3 Deploying the XPath/XSL Function in the Application Server

The Java XPath function should be registered with the application server. This is done by adding an entry in the ext-soa-xpath-functions-config.xml file, which is found at: $SOA_HOME/soa/modules/oracle.soa.ext_11.x.x/classes\META-INF. This file contains the list and descriptions of all XPath functions defined in the system.

Each function entry in this file has this information:

  • <function>: Has the name attribute that defines XPath function name.

  • <classname>: Defines the XPath implementation class name. In this case, it is the inner class name.

  • <return>: Used to define return type.

  • <params>:

    • All the parameters required by the function.

    • <param name="formatMask" type="string"/>

    • For each of the parameter passed specify the name and the data type of the input.

<function name="utl:getCurrentDate">
 <className>oracle.xpath.CustomFunction</className>
 <return type="string"/>
 <params>
  <param name="formatMask" type="string"/> 
 <params>
</function> 

The implementation classes must be dropped at: $SOA_HOME/soa/modules/oracle.soa.ext_11.x.x/classes folder. This way, these classes will be placed in the classpath of the SOA container and available to the classloader.