Building Your Own Path

Custom XPath in SOA Suite 11g

ManPathUsually between standard XPath functions, BPEL extension functions and Oracle extension functions you have more than enough functionality, but sometimes you will need a little bit more.  In this entry I will show how to add a new custom XPath function, in this case we will add a function to return the current system time in millis as a string.

To implement a custom XPath function we need to implement a particular interface in Java and provide a descriptor file to tell SOA how the custom Java code is mapped to an XPath function.

The Custom XPath Function

I created a Java project in JDeveloper and added the “SOA Runtime” library to the project because that includes the interface I need to implement.  I then created a class and implemented the functionality I needed as a static Java method.  The XSLT processor needs the custom XPath function to be implemented as a static Java method with a particular signature as shown below:

public static Object getCurrentTimeMillis(
                              IXPathContext iXPathContext,
                              List list
                              ) throws XPathFunctionException {
  return String.valueOf(System.currentTimeMillis());
}

The name of the method can be anything but it must be static and take the given parameters.  The list parameter is a list of parameters passed to the XPath function.  In this case we are not using any parameters.  The iXPathContext provides access to useful functions to convert namespace prefixes to URIs and access the type of calling component and variables.

The rest of SOA Suite requires the custom XPath expression to be in a class that implements a specific interface - oracle.fabric.common.xml.xpath.IXPathFunction.  I implemented this interface by returning the result from my static function implemented for XSLT as shown below:

public Object call(
                   IXPathContext iXPathContext,
                   List list
                   ) throws XPathFunctionException {
  return getCurrentTimeMillis(iXPathContext, list);
}

Note that the method name must be “call” and non-static because we are implementing an interface.  Otherwise the signature is the same as the one we implemented for the XSLT processor and so we can just call that static method.

We can now compile the Java class file to verify that all is well.

The Descriptor File

We now need to create a descriptor to describe to SOA Suite and the XSLT processor what custom function we have created.  We do this by creating a file called “ext-soa-xpath-functions-config.xml” in the “META-INF” directory which has the following content:

<?xml version="1.0" encoding="UTF-8"?>
<soa-xpath-functions
  xmlns="http://xmlns.oracle.com/soa/config/xpath"
xmlns:blog="http://www.oracle.com/XSL/Transform/java/antony.blog.XPathGetCurrentTimeMillis">
  <function name="blog:getCurrentTimeMillis">
    <className>antony.blog.XPathGetCurrentTimeMillis</className>
    <return type="string"/>
    <desc>returns the current system time in milliseconds</desc>
    <detail>Returns time in milliseconds as reported by
            java.lang.System.currentTimeMillis().
            It is returned as a string to keep full fidelity.</detail>
  </function>
</soa-xpath-functions>

The namespace for the function must be “http://www.oracle.com/XSL/Transform/java/” followed by the full classname of the impementing class, in my case “antony.blog.XPathGetCurrentTimeMillis”.  This is required by the XSLT processor.  The namespace prefix can be anything you like, I chose “blog”.

The function name can be anything but it must have a namespace prefix.  The className is the implementing class “antony.blog.XPathGetCurrentTimeMillis”.

Valid “type” values for “return” are shown in the table below:

Configuration Type Java Method Return Types
string java.lang.String
boolean boolean
number int, float or double
node-set oracle.xml.parser.v2.XMLNodeList
tree oracle.xml.parser.v2.XML

Finally we can provide a brief description in “desc” and a more expansive explanation in “detail”.

Creating a JAR File

The custom XPath function is now complete and we need to package it up as a jar file.  I used the JDeveloper project property Deployment to create a new jar file deployment profile.  I added the source path to the “Contributers” to include the META-INF directory and then in the “Filters” I filtered out the “.java” file.  Our custom XPath function is now packaged and ready to register.

Registering with JDeveloper

Before using the custom function in JDeveloper it needs to be registered.  To do this in JDeveloper we go to the “SOA” section in “Preferences” and add the newly created jar file.  To make JDeveloper see the file we then need to restart JDeveloper.  After doing this we will see the XPath function appears in the “User Defined Extension Functions” in the expression builder.

CustomXPathJDev

Registering with SOA Suite

To use the custom function in SOA Suite we need to add it to the SOA extension libraries.  We do this by copying the jar file to the $ORACLE_SOA_HOME/soa/modules/oracle.soa.ext_11.1.1 directory on the SOA Suite installation.  We then run ant in that directory (setting JAVA_HOME if necessary) by executing $FMW_HOME/modules/org.apache.ant_1.7.1/bin/ant.

[oracle@soa.ext_11.1.1]$ ../../../../modules/org.apache.ant_1.7.1/bin/ant
Buildfile: build.xml

create-manifest-jar:
     [echo] Creating oracle.soa.ext at …/FMW/Oracle_SOA/soa/modules/oracle.soa.ext_11.1.1/oracle.soa.ext.jar…

BUILD SUCCESSFUL
Total time: 1 second

We then need to restart the SOA Suite to get it to recognise the change.

Testing

Finally we can create a test composite and deploy it to the SOA Server to test our new XPath functions behave as we expect.  I created a composite that first does an assign from the new functoin in a mediator and then passes the result onto a BPEL 1.1 process that also does an assign, followed a call to a BPEL 2.0 process that does an assign followed by an XSL transformation.  Finally the result is returned so that I can verify everything is fine.

CustomXPathTest

Loose Ends

We have not examined how we can pass parameters to an XPath function (using the “params” element in the descriptor, nor have we looked at how to handle XML results.  Those are subjects for another blog entry.  It is also possible to register the XPath function with just a subset of components by using different descriptor files.  However in most cases I suspect that making the function available in all components and XSLT is what is wanted.

So go and enjoy creating some custom XPath functions, your only problem is finding functionality that is not already available in XPath!

References

Sample code used above is available here as 2 JDeveloper projects.

The Oracle documentation covers this material

Comments:

Thanks for the nice blog. I have a question regarding creation of the .jar file. I created the .jar file with the steps mentioned in this blog.(I have created a function to use in my transformation and added the appropriate XML in META-INF directory) when i try to attach the same via Tools-> preferences-> SOA -> User defiled function jar files, i encounter the following error. "The function JAR file you selected is not a valid user-defined function JAR file" I am using Jdev 11.1.1.5.0. Any pointers?
thx, Dwarak

Posted by Dwarak on July 30, 2011 at 12:59 AM MDT #

hi ,

I followed all the steps given by you to create custom xslt function .

I am getting following error while adding JAR file to JDeveloper .

"The function JAR file you selected is not a valid user-defined function JAR file".

I am using JDeveloper 11.1.1.3.

Please help me .

Posted by Surfraz on February 19, 2012 at 01:06 AM MST #

Surfraz it looks like you don't have the XML descriptor file in the right location.

Posted by Antony on March 13, 2012 at 07:53 AM MDT #

Post a Comment:
Comments are closed for this entry.
About

Musings on Fusion Middleware and SOA Picture of Antony Antony works with customers across the US and Canada in implementing SOA and other Fusion Middleware solutions. Antony is the co-author of the SOA Suite 11g Developers Cookbook, the SOA Suite 11g Developers Guide and the SOA Suite Developers Guide.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today