Description:
Invoke the static function of class in the package.
Syntax:
invoke(p.c.f,ai,…)
Note:
The function calls the static function f of class c in the package p, which can be omitted. Do not allow overload methods (with the same name but different signatures).
When invoking a user-defined function, you should put the user-defined function class file in the format of .class in the path [esProc install-root directory]/esProc/classes/{p}; if the user-defined function is used at the web side, then you should put the corresponding function in path WEB-INF/classes/{p}.
Parameter:
p |
Package path |
c |
Class name |
f |
Static method name |
ai |
Parameter |
The following lists data types of the parameters passed for the invoke() function and their corresponding parameter data types in Java classes:
Bool |
java.lang.Boolean |
Int |
java.lang.Integer |
Long |
java.lang.Long |
Float |
java.lang.Double |
Decimal |
java.math.BigDecimal |
Date |
java.sql.Date |
Time |
java.sql.Time |
Datetime |
java.sql.Timerstamp |
String |
java.lang.String |
Blob |
byte [] |
Sequence |
Object[] |
Option:
@x |
Convert the sequence type parameter or return value; can be performed recursively |
Example:
I Below is content of JAVA class api.Calc01:
package api;
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);
}
}
Place Calc01.class in path [esProc install-root directory]/esProc/classes/api and invoke function distance1 from the cellset file:
|
A |
|
1 |
-12.34567 |
|
2 |
=invoke(api.Calc01.distance1,A1) |
|
3 |
=invoke(api.Calc01.distance1, -512) |
|
The static method distance1 calculates the distance between a given point and the origin, with the result rounded to 3 decimal places. A method invoked in an esProc cellset file should be both static and public.
II Create a customized class LineReaders for implementing the ILineInput interface so that users can retrieve a various types of data files using the file cursor. The file path can be defined as a parameter to be passed to the customized class. Then the file contents can be retrieved through stream in a row-wise fashion or by skipping certain individual rows; and the cursor can thus be closed in a certain way.
1. Below is a sample program:
package api;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import com.scudata.dm.ILineInput;
import com.scudata.dm.UserUtils;
import com.scudata.dm.cursor.ICursor;
public class LineReaders implements ILineInput {
private String pathName;
private boolean hasTitle;
private BufferedReader bfr;
final String COL_SEP = "\t";
final String encoding = "UTF-8";
String lineTxt = null;
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd ");
String[] rowData;
Object[] datas = new Object[3];
public LineReaders(String pathName,boolean hasTitle) {
this.pathName = pathName;
this.hasTitle=hasTitle;
}
public static LineReaders newInstance(String pathName,boolean hasTitle) {
return new LineReaders(pathName,hasTitle);
}
private BufferedReader getBufferedReader() throws IOException {
if (bfr == null) {
File file = new File(pathName);
if (file.isFile() && file.exists()) { // Check if the file exists
InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// Take the type of character encoding into consideration
bfr = new BufferedReader(read);
}
}
return bfr;
}
//Read an individual row
public Object[] readLine() throws IOException {
BufferedReader bfr = getBufferedReader();
try {
if (!hasTitle) {
datas[0] = "ID";
datas[1] = "BirthDate";
datas[2] = "Name";
}
while ((lineTxt = bfr.readLine()) != null) {
rowData = lineTxt.split(COL_SEP);
if (rowData != null && rowData.length == 3) {
if (hasTitle) {
datas[0] = rowData[0];
datas[1] = rowData[1];
datas[2] = rowData[2];
hasTitle = false;
return datas;
}
datas[0] = Integer.parseInt(rowData[0]);
datas[1] = df.parse(rowData[1]);
datas[2] = rowData[2];
return datas;
}
}
return null;
} catch (EOFException e) {
return null;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return datas;
}
// Convert the ILineInput instance to a cursor
public static ICursor UserUtilsReader(String pathName,boolean hasTitle){
return UserUtils.newCursor(newInstance(pathName,hasTitle), "t");
}
//Skip an individual row
public boolean skipLine() throws IOException{
BufferedReader bfr = getBufferedReader();
try {
String s = bfr.readLine();
if(s!=null){
return true;
}
} catch (EOFException e) {
return false;
}
return false;
}
//Close the cursor
public void close() throws IOException {
if (bfr != null) {
bfr.close();
bfr = null;
}
}
2. Place a LineReaders.class file in the api folder in the [esProc install-root directory]/esProc/classes path.
3. The contents of the file (it uses the character encoding of UTF-8) retrieved by a cursor are as follows:
4. Invoke the customized function with invoke() function in the esProc cellset file:
|
A |
|
1 |
=invoke(api.LineReaders.UserUtilsReader,"D://abc.txt",true) |
Call the customized function. |
2 |
=A1.skip(3) |
3 |
3 |
=A1.fetch() |
|
III Using a sequence type parameter
package api;
public class Calc01 {
public static int sum(Object []vals) {
int result = 0;
for(Object val : vals){
result += ((Number)val).intValue();
}
return result;
}
public static Integer[] sum2(Object []vals){
Integer []result = new Integer[vals.length];
for(int i = 0;i < vals.length; ++i){
result[i] = sum((Object[])vals[i]);
}
return result;
}
}
|
A |
|
1 |
[1,2,3,4] |
|
2 |
=invoke@x(api.Calc01.sum,A1) |
@x option converts the sequence type parameter; the static method sum accumulates members in A1’s sequence.
|
3 |
=invoke@x(api.Calc01.sum, to(100)) |
Calculates the cumulative sum from 1 to 100.
|
4 |
=invoke@x(api.Calc01.sum2,A1.(to(~))) |
@x option converts the sequence type parameter, which is a sequence of sequences.
|