bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Invoking Liquid Data Queries Programmatically

Using Custom Functions

This section describes how to create custom functions in BEA Liquid Data for WebLogicTM. It contains the following sections:

- About Custom Functions

- Defining Custom Functions

- Examples of Custom Functions

About Custom Functions

Liquid Data provides a set of standard functions to use when creating data views and queries. You can also define custom functions in the Liquid Data server repository to use in the Data View Builder or in hand-coded queries. Custom functions, which are implemented as Java methods, allow you to extend the power and functionality of Liquid Data. Queries can invoke custom functions during query execution just as they can standard functions.

A custom function is:

- Implemented in Java code, as described in Step 1: Write the Custom Function Implementation in Java.

You can package Java implementations in a JAR file that is stored in the custom_lib folder of the Liquid Data repository. If any custom functions refer to addition Java libraries that are not stored in the custom_lib folder of the repository, then you must specify those folders in the Liquid Data CLASSPATH that you configure on the General tab in the Liquid Data node of the Administration Console. For more information, see Configuring Liquid Data Server Settings in the Liquid Data Administration Guide.

- Declared as a method in a custom functions library definition (.CFLD) file, as described in Step 2: Create the Custom Functions Library Definition File.

A function library is a collection of one or more declared custom functions that Liquid Data manages as a single unit. Each function library usually corresponds to a Java class file that contains the function implementations. However, the function library can also reference functions that are implemented in several Java class files. You store custom functions library definition files in the custom_functions folder of the Liquid Data repository.

- Registered on the Repository tab in the in the Administration Console, as described in Step 3: Register the Custom Function in the Administration Console.

Once configured as custom functions, descriptions in the Liquid Data server repository will show up as functions available for use in any Data View Builder client or hand-coded XQuery that connects to this server.

- Invoked in a query in the same way that you would invoke a standard function.

Defining Custom Functions

This section describes the sequence of tasks for defining custom functions for use in the Data View Builder. The process of defining custom functions involves the following steps:

- Step 1: Write the Custom Function Implementation in Java

- Step 2: Create the Custom Functions Library Definition File

- Step 3: Register the Custom Function in the Administration Console

Once a custom function is created, declared, and registered, you can invoke them in queries created using the Data View Builder.

Step 1: Write the Custom Function Implementation in Java

To define a custom function, you first write its implementation in Java and then compile it. The custom function implementation can exist in a single or multiple Java class files. A single Java class file can contain implementations of multiple custom functions. You package Java implementation in a JAR file that is stored in the custom_lib folder of the Liquid Data repository.

For examples of custom function implementations, see:

- Implementation of Custom Functions for Simple Types

- Implementation of a Custom Function for a Complex Type

Rules for Writing Custom Function Implementations

When writing a custom function, you must comply with the following rules:

- Declare the custom function as a static method.

- For parameters and returned values, you must use the data types described in Table 7-1.

Correspondence Between XML and Java Data Types

The following table describes the correspondence between XML and Java data types.

Note: For XML data types, the xs prefix corresponds to the XML schema namespace described at the following URL: http://www.w3.org/2001/XMLSchema.

Table 7-1 Relationship Between XML and Java Data Types

XML Data Type | Corresponding Java Data Type
--- | ---
xs:boolean | java.lang.Boolean
xs:byte | java.lang.Byte
xs:short | java.lang.Short
xs:integer | java.lang.Integer
xs:long | java.lang.Long
xs:float | java.lang.float
xs:double | java.lang.double
xs:decimal | java.math.BigDecimal
xs:string | java.lang.String
xs:dateTime | java.util.Calendar
Complex Element Type | org.w3c.dom.Element

Step 2: Create the Custom Functions Library Definition File

After implementing a custom function in Java, you must declare the custom function in a custom functions library definition (CFLD) file. A CFLD file describes each custom function in a structured XML format. You store custom functions library definition files in the custom_functions folder of the Liquid Data repository.

For examples of custom function implementations, see:

- CFLD File That Declares Custom Functions for Simple Types

- CFLD File That Declares the Custom Function for a Complex Type

Contents of a CFLD File

A CFLD file contains the following information:

- Complex element definitions (for custom functions that operate on complex types)

- Custom function signatures

- Custom function implementation bindings—function name, return type, class, method, and any arguments

- Run-time attributes—running the custom function synchronously or asynchronously

Structure of a CFLD File

A CFLD file has the following structure:

Listing 7-1 Structure of a CFLD File

>     <?xml version = "1.0" encoding = "UTF-8"?>

>     <definitions>

>           <types>

>                 <xs:schema> complex types </xs:schema>

>           </types>

>           <functions>

>                 <function name="Name of the function" return_type="Return Type"

>                       class="Implementation class" method="Implementation method"

>                             asynchronous="boolean value"? > *

>                       <argument type="Argument Type" label="Argument label"/> *

>                       <presentation group="Data View Builder Presentation Group" />

>                       <description>Function Description</description>

>                 </function>

>           </functions>

>     </definitions>

Elements and Attributes in a CFLD File

The following table describes the elements in a CFLD file.

Table 7-2 Elements in a CFLD File

Element

Attribute

Description

<types>

Declares any complex data types that a custom function can accept as parameters or return as results, if applicable.

<functions>

Function definitions for all functions.

<function>

Function definition for a single function.

name

Name of the function in the form of prefix:localname. The prefix must be declared in the <types> section.

return type

Return type of the function, which can be either a supported XML simple data type or a complex data type declared in the <types> section.

class

Implementation class.

method

Implementation method.

asynchronous

Optional. Determines whether the method should be executed asynchronously (true) in a separate thread or not (false). Specify true for functions that execute more slowly than other functions.

<argument>

Argument declarations.

type

Type of the argument (simple or complex).

label

Optional. Label for the function that the Data View Builder displays in the list.

<presentation group>

For a group of related custom functions, if specified, defines the label of a custom tab that appears in the Data View Builder.

<description>

Text that describes the function in some detail.

Step 3: Register the Custom Function in the Administration Console

After implementing a custom function and creating the CFLD file, you must register the custom function using the Administration Console. Registration involves the following tasks:

- Adding the JAR and CFLD files for the custom function to the custom_lib folder and custom_functions folder, respectively, in the Liquid Data Server repository.

- Adding the path to the JAR file in the Custom Functions Classpath field on the General tab in the Liquid Data node, if any other JAR is referenced.

- Creating a custom function description for each set of custom functions.

- If security is enabled, assign ACLs to the custom function description and to the JAR and CFLD files in the Liquid Data Server repository.

For detailed instructions, see Configuring Access to Custom Functions in the Liquid Data Administration Guide.

Examples of Custom Functions

This topic provides examples of custom functions that use simple and complex types. It includes the following sections:

- Example That Uses Simple Types

- Example That Uses Complex Types

Example That Uses Simple Types

This example shows how to create, declare and use custom functions that operate on simple types.

Implementation of Custom Functions for Simple Types

The following Java code implements custom functions. These functions implement a simple echo operation that returns its argument back to the caller.

Listing 7-2 Java Code for Custom Functions That Use Simple Types

>     package cf;

>     import java.math.*;

>     import java.util.Date;

>     public class CustomFunctions

>     {

>           public static BigDecimal echoDecimal(BigDecimal v)

>           {

>                 return v;

>           }

>           public static Integer echoInteger(Integer v)

>           {

>                 return v;

>           }

>           public static Float echoFloat(Float v)

>           {

>                 return v;

>           }

>           public static String echoString(String v)

>           {

>                 return v;

>           }

>           public static Boolean echoBoolean(Boolean v)

>           {

>                 return v;

>           }

>           public static Calendar echoDateTime(Calendar v)

>           {

>                 return v;

>           }

>           public static Long echoLong(Long v)

>           {

>                 return v;

>           }

>           public static Short echoShort(Short v)

>           {

>                 return v;

>           }

>           public static Byte echoByte(Byte v)

>           {

>                 return v;

>           }

>           public static Double echoDouble(Double v)

>           {

>                 return v;

>           }

>     }

CFLD File That Declares Custom Functions for Simple Types

The following sample CFLD file declares the custom functions for simple types.

>     <?xml version = "1.0" encoding = "UTF-8"?>

>     <definitions>

>           <types>

>                 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

>                 </xs:schema>

>           </types>

>           <functions>

>                 <function name="echoString" return_type="xs:string"

>                       class="cf.CustomFunctions" method="echoString" >

>                       <argument type="xs:string" />

>                 </function>

>                 <function name="echoBoolean" return_type="xs:boolean"

>                       class="cf.CustomFunctions" method="echoBoolean" >

>                       <argument type="xs:boolean" />

>                 </function>

>                 <function name="echoByte" return_type="xs:byte"

>                       class="cf.CustomFunctions" method="echoByte" >

>                       <argument type="xs:byte" />

>                 </function>

>                 <function name="echoShort" return_type="xs:short"

>                       class="cf.CustomFunctions" method="echoShort" >

>                       <argument type="xs:short" />

>                 </function>

>                 <function name="echoInteger" return_type="xs:integer"

>                       class="cf.CustomFunctions" method="echoInteger" >

>                       <argument type="xs:integer" />

>                 </function>

>                 <function name="echoLong" return_type="xs:long"

>                       class="cf.CustomFunctions" method="echoLong" >

>                       <argument type="xs:long" />

>                 </function>

>                 <function name="echoFloat" return_type="xs:float"

>                       class="cf.CustomFunctions" method="echoFloat" >

>                       <argument type="xs:float" />

>                 </function>

>                 <function name="echoDouble" return_type="xs:double"

>                       class="cf.CustomFunctions" method="echoDouble" >

>                       <argument type="xs:double" />

>                 </function>

>                 <function name="echoDecimal" return_type="xs:decimal"

>                       class="cf.CustomFunctions" method="echoDecimal" >

>                       <argument type="xs:decimal" />

>                 </function>

>                 <function name="echoDateTime" return_type="xs:dateTime"

>                       class="cf.CustomFunctions" method="echoDateTime" >

>                       <argument type="xs:dateTime" />

>                 </function>

>           </functions>

>     </definitions>

Query That Uses the Custom Functions for Simple Types

After the function library is registered in Liquid Data, it can be called from the following query (mycf is the logical name specified in the CFLD file):

>     let

>           $es:=mycf:echoString("hello"),

>           $ebool:=mycf:echoBoolean(xf:true()),

>           $eb:=mycf:echoByte(cast as xs:byte("127")),

>           $eh:=mycf:echoShort(cast as xs:short("32767")),

>           $ei:=mycf:echoInteger(cast as xs:integer("2147483647")),

>           $el:=mycf:echoLong(cast as xs:long("9223372036854775807")),

>           $ef:=mycf:echoFloat(cast as xs:float("1.0")),

>           $ed:=mycf:echoDouble(cast as xs:double("2.0")),

>           $edec:=mycf:echoDecimal(cast as xs:decimal("1.5")),

>           $edateTime:=mycf:echoDateTime(cast as xs:dateTime("1999-05-31 13:20:00.0")),

>     return

>           <echo>

>                 <string>{$es}</string>

>                 <boolean>{$ebool}</boolean>

>                 <byte>{$eb}</byte>

>                 <short>{$eh}</short>

>                 <integer>{$ei}</integer>

>                 <long>{$el}</long>

>                 <float>{$ef}</float>

>                 <double>{$ed}</double>

>                 <decimal>{$edec}</decimal>

>                 <dateTime>{$edateTime}</dateTime>

>           </echo>

Example That Uses Complex Types

This example shows how to create, declare and use a custom function that takes a complex type as a parameter and returns a complex type.

Implementation of a Custom Function for a Complex Type

The following Java code implements a custom function for a complex type. This function simply returns its parameter.

Listing 7-3 Custom Function for a Complex Type

>     package mycf;

>     import org.w3c.dom.Element;

>     public static Element echoElement(Element v)

>     {

>           return v;

>     }

CFLD File That Declares the Custom Function for a Complex Type

The following sample CFLD file declares the custom function for a complex type.

Listing 7-4 CFLD File That Declares the Custom Function for a Complex Type

>     <?xml version = "1.0" encoding = "UTF-8"?>

>     <definitions>

>           <types>

>                 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

>                       <xs:element name = "book">

>                             <xs:complexType>

>                                   <xs:sequence>

>                                         <xs:element ref = "title"/>

>                                         <xs:element ref = "author" maxOccurs = "unbounded"/>

>                                         <xs:element ref = "publisher"/>

>                                         <xs:element ref = "price"/>

>                                   </xs:sequence>

>                             </xs:complexType>

>                       </xs:element>

>                       <xs:element name = "title" type = "xs:string"/>

>                       <xs:element name = "author">

>                             <xs:complexType>

>                                   <xs:sequence>

>                                         <xs:element ref = "last"/>

>                                         <xs:element ref = "first"/>

>                                   </xs:sequence>

>                             </xs:complexType>

>                       </xs:element>

>                       <xs:element name = "publisher" type = "xs:string"/>

>                       <xs:element name = "price" type = "xs:string"/>

>                       <xs:element name = "last" type = "xs:string"/>

>                       <xs:element name = "first" type = "xs:string"/>

>                 </xs:schema>

>           </types>

>           <functions>

>                 <function name="echoBook" return_type="book"

>                       class="mycf.CustomFunctions2" method="echoElement" >

>                       <argument type="book" />

>                 </function>

>           </functions>

>     </definitions>

Query That Uses the Custom Function for a Complex Type

After the function is registered in Liquid Data, it can be called from the following query:

Listing 7-5 Sample Query That Uses the Custom Function for a Complex Type

>     for $b in document("bib")//book

>     let $c:=echoBook($b)

>     return

>     <ans>

>     {

>           for $t in $c/title

>           return $t

>     }

>     </ans>