1/14/2015

esProc Integration & Application: User-defined Functions

Besides the system-provided functions, esProc supports invoking user-defined functions to handle some special operations or the encapsulation of certain computations. This article will briefly explain how to invoke user-defined functions with invoke function and how to use parameters and return the results as needed. 

1. Basic method of invoking user-defined functions

invoke function can be used to invoke static method(s) in a specified user-defined Java class. Take the following Java class test.Calc01 as an example:
package test;
public class Calc01 {
         public static Double distance1(Number loc) {
                    double len = Math.abs(loc.doubleValue());
                   len = Math.round(len*1000)/1000d;
                    return Double.valueOf(len);
         }
}

In this simple class, the static method distance1 computes the distance between a given coordinate and the origin, with the value being rounded to three decimal places. The methods being invoked in esProc must be both static and public. Before invocation, the class of user-defined functions needs to be placed in esProc’s classpath, [installation directory]\esProc\classes path; if invoked in the web server-side, it needs to be placed in WEB-INF/classes path correspondingly. After that, the user-defined functions can be invoked by invoke function in the cellset:

As shown in this example, when using invoke function, first specify the full path of the class being invoked and the static method name and then list the necessary parameters in order. The parameters can be cell values in a cellset and cellset parameters, or can be typed in. After computation, results of A2 and A3 are as follows:

There can be multiple user-defined functions in a single class. Now add another method:
         public static Double distance2(Number loc1, Number loc2) {
                  double len = Math.abs(loc1.doubleValue()-loc2.doubleValue());
                  len = Math.round(len*1000)/1000d;
                  return Double.valueOf(len);
         }
The newly-added distance2 computes the distance between two coordinates in a number axis. As esProc invokes methods by their names, different user-defined functions need to have different method names. Once the class(es) has been place in the application’s classpath, the user-defined functions can be invoked in the same cellset, no matter they are from a single class or multiple classes:

In the invoke function, the number and type of parameters need to match the methods being invoked. Results of A1 and A2 are as follows:

2. Return results as needed

The user-defined functions may or may not return results. For example:
         public static void distance3(Number loc1, Number loc2) {
                    double len = Math.abs(loc1.doubleValue()-loc2.doubleValue());
                    len = Math.round(len*1000)/1000d;
                  System.out.println(Double.toString(len));
         }
When the computation with static method distance3 is completed, the output data will be handled with print spooling and won’t be returned. Such functions are similar to the executable cells in a cellset, in which invoke function can start with >. For example:

Now the output data can be viewed in the console. To access the console, click Tool>Console on the menu bar. The result is as follows:

But if the user-defined functions return results, they need to use data types supported in esProc; otherwise errors may occur during presentation or invocation. Following is the correspondence between commonly-used data types in esProc and those in Java:
       Integer                                          java.lang.Integer
       Long integer                                     java.lang.Long
       Floating point number                             java.lang.Double
       Big decimal                                      java.math.BigInteger
       Real number                                     java.lang.Number
       Boolean                                         java.lang.Boolean
       String                                           java.lang.String
       Date                                           java.sql.Date
       Time                                             java.sql.Time
       Date/time                                        java.sql.TimeStamp
       Sequence                                       com.raqsoft.dm.Sequence
       Table sequence                                 com.raqsoft.dm.Table
In the previous examples, all the returned data are Double object, which corresponds to the floating point number in esProc. User-defined function can return results as needed. For instance, add another two user-defined functions to test.Calc01 and return results of different data types:

         public static String distance4(Number loc1, Number loc2) {
                  double len = Math.abs(loc1.doubleValue()-loc2.doubleValue());
                   len = Math.round(len*1000)/1000d;
                   return Double.toString(len);
         }
         public static Sequence distance5(Number loc1, Number loc2) {
                  double len = Math.abs(loc1.doubleValue()-loc2.doubleValue());
                   len = Math.round(len*1000)/1000d;
                   com.raqsoft.dm.Sequence result = new com.raqsoft.dm.Sequence();
                   result.add(loc1);
                   result.add(loc2);
                   result.add(Double.valueOf(len));
                   return result;
         }
These two static methods are still used to compute the distance between two points in a number axis. distance4 returns the result of string type and distance5 returns the result in a form of a sequence in which the coordinates of the two points and the distance between them are stored. invoke function is still used to invoke the two methods in a cellset:

For the convenience of comparison, A1 calls distance2 used in the previous example. After the code is executed, results of A1~A3 are as follows: 

Notice that the results of A1 and A2 use different data types and are displayed differently. The return results of user-defined functions can be used for later computation.

3.Parameters of sequence type

The parameters used in a user-defined function come from esProc. The correspondence between their data types and the Java objects is the same as that mentioned above. Note that the parameters used during the invocation of user-defined functions need to be consistent with the parameters in the static methods.

A special point worth noting is that the sequence is the most frequently used data type in esProc. Besides returning a sequence as the result, user-defined functions can also use parameters of sequence type. For example:
         public static Double distance6(com.raqsoft.dm.Sequence seq1, com.raqsoft.dm.Sequence seq2) {
                   int len1 = seq1.length();
                   int len2 = seq2.length();
                   double x1 = len1 > 0 ? ((Number) seq1.get(1)).doubleValue(): 0;
                   double x2 = len2 > 0 ? ((Number) seq2.get(1)).doubleValue(): 0;
                   double y1 = len1 > 1 ? ((Number) seq1.get(2)).doubleValue(): 0;
                   double y2 = len2 > 1 ? ((Number) seq2.get(2)).doubleValue(): 0;
                   double len = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
                   len = Math.round(len*1000)/1000d;
                    return Double.valueOf(len);
         }
The user-defined function distance6 computes the distance between two points in a rectangular coordinate system. Coordinates of the two points need to be input using parameters of sequence type during invocation. For example:

After computation, result of A3 is as follows:


No comments:

Post a Comment