Learning
Community
Open Exchange
Global Masters
InterSystems IRIS Data Platform 2019.4 / Application Development / Using the Native API for Java / Calling ObjectScript Methods and Functions
Previous section   Next section

Calling ObjectScript Methods and Functions

This chapter describes methods that call class methods and functions from ObjectScript classes and routines. They allow Java applications to call your custom ObjectScript classmethods or functions as easily as they call native Java methods. See the following sections for details and examples:
Note:
In some cases, these Native API methods can also be used with InterSystems classes defined in the Class Library. For example, this call returns some system information:
  String currentNameSpace = iris.classMethodString("%SYSTEM.SYS","NameSpace");
Unfortunately, most class library methods return only a status code, passing the actual results back in arguments (which cannot be accessed by the Native API). Best practice is always to call class library methods indirectly, from within a user defined wrapper class. This allows you to use the full power of the class library, and also produces more maintainable code.

Class Method Calls

The Native API methods in this section call user defined ObjectScript class methods, and return values of the type indicated by the method name: classMethodBoolean(), classMethodBytes(), classMethodDouble(), classMethodLong(), classMethodString(), or classMethodVoid() (no return value).
They take String arguments for className and methodName, plus 0 or more method arguments. Trailing arguments may be omitted in argument lists, either by passing fewer than the full number of arguments, or by passing null for trailing arguments. An exception will be thrown if a non-null argument is passed to the right of a null argument.
In addition to these methods, you can use classMethodStatusCode() to retrieve error information when an ObjectScript class method call fails. When called from within a catch clause (as demonstrated at the end of the example below) it will throw a RuntimeException error containing the ObjectScript error status number and message.
Calling ObjectScript class methods with the Native API
The code in this example calls class methods of each supported datatype from ObjectScript test class User.NativeTest (listed immediately after the example). Assume that iris is an existing instance of class IRIS, and is currently connected to the server.
  String className = "User.NativeTest";

  System.out.print("cmBoolean() finds if two numbers are equal (true=1,false=0): ");
  System.out.println(iris.classMethodBoolean(className,"cmBoolean",7,7));

  System.out.print("cmBytes() converts a list of integers into a byte array: ");
  System.out.println(new String(iris.classMethodBytes(className,"cmBytes",72,105,33)));

  System.out.print("cmString() concatenates two strings: ");
  System.out.println(iris.classMethodString(className,"cmString","World"));

  System.out.print("cmLong() returns the total of two numbers: ");
  System.out.println(iris.classMethodLong(className,"cmLong",7,8));

  System.out.print("cmDouble() multiplies a number by 100: ");
  System.out.println(iris.classMethodDouble(className,"cmDouble",7.567));

  System.out.print("cmVoid assigns a value to a global array: ");
  iris.classMethodVoid(className,"cmVoid",67);
  System.out.println("^cmGlobal = "_iris.getInteger("^cmGlobal"));

// Get an error message for a failed method call
  try {
    System.out.println("Calling nonexistent class method \"notLegal\"... ");
    iris.classMethodStatusCode(className,"notLegal");
  } catch (RuntimeException e) {
    System.out.println("Call to class method \"notLegal\" returned error:");
    System.out.println(e.getMessage());
  }

ObjectScript Class User.NativeTest
To run the previous example, this ObjectScript class must be compiled and available on the server:
Class User.NativeTest Extends %Persistent
{
  ClassMethod cmBoolean(cm1 As %Integer,cm2 As %Integer) As %Boolean
  {
   quit (cm1=cm2)
  }
  ClassMethod cmBytes(cm1 As %Integer,cm2 As %Integer, cm3 As %Integer) As %Binary
  {
    quit $CHAR(cm1,cm2,cm3)
  }
  ClassMethod cmString(cm1 As %String) As %String
  {
   quit "Hello "_cm1
  }
  ClassMethod cmLong(cm1 As %Integer, cm2 As %Integer) As %Integer
  {
   quit cm1+cm2
  }
  ClassMethod cmDouble(cm1 As %Double) As %Double
  {
   quit cm1 * 100
  }
  ClassMethod cmVoid(cm1 As %Integer)
  {
   set ^cmGlobal=cm1
   quit
  }
}

Function Calls

The Native API methods in this section call user-defined ObjectScript functions or procedures (see “Callable User-defined Code Modules” in Using ObjectScript), and return a value of the type indicated by the method name: functionBoolean(), functionBytes(), functionDouble(), functionLong(), functionString(), or procedure() (no return value).
They take String arguments for functionName and routineName, plus 0 or more function arguments. Trailing arguments may be omitted in argument lists, either by passing fewer than the full number of arguments, or by passing null for trailing arguments. An exception will be thrown if a non-null argument is passed to the right of a null argument.
Note:
These methods are designed to call functions in user-defined routines. ObjectScript system functions (see “ObjectScript Functions” in the ObjectScript Reference) cannot be called directly from your Java code. However, you can write an ObjectScript wrapper function to call a system function indirectly. For instance, the sample code later in this section includes user-defined function functionBytes(), which returns the value of a call to ObjectScript system function $CHAR.
Calling functions of ObjectScript routines with the Native API
The code in this example calls functions of each supported datatype from ObjectScript routine NativeRoutine (File NativeRoutine.mac, listed immediately after this example). Assume that iris is an existing instance of class IRIS, and is currently connected to the server.
  String routineName = "NativeRoutine";

  System.out.print("funcBoolean() finds if two numbers are equal (true=1,false=0): ");
  System.out.println(iris.functionBool("funcBoolean",routineName,7,7));

  System.out.print("funcBytes() converts a list of integers into a byte array: ");
  System.out.println(new String(iris.functionBytes("funcBytes",routineName,72,105,33)));

  System.out.print("funcString() concatenates two strings: ");
  System.out.println(iris.functionString("funcString",routineName,"World"));

  System.out.print("funcLong() returns the total of two numbers: ");
  System.out.println(iris.functionInt("funcLong",routineName,7,8));

  System.out.print("funcDouble() multiplies a number by 100: ");
  System.out.println(iris.functionDouble("funcDouble",routineName,7.567));

  System.out.print("funcProcedure assigns a value to a global array: ");
  iris.procedure("funcProcedure",routineName,88);
  System.out.println("^funcGlobal = "_iris.getInteger("^funcGlobal"));

ObjectScript Routine NativeRoutine.mac
To run the previous example, this ObjectScript routine must be compiled and available on the server:
funcBoolean(fn1,fn2) public {
   quit (fn1=fn2)
}
funcBytes(fn1,fn2,fn3) public {
    quit $CHAR(fn1,fn2,fn3)
}
funcString(fn1) public {
    quit "Hello "_fn1
}
funcLong(fn1,fn2) public {
    quit fn1+fn2
}
funcDouble(fn1) public {
    quit fn1 * 100
}
funcProcedure(fn1) public {
    set ^funcGlobal=fn1
    quit
}
Previous section   Next section