This section examines
a simple but complete Java program that uses SAS Micro Analytic Service
to call a simple DS2 package method. Comments within the body of the
code explain each step.
The example code performs
the following sequence of steps:
-
Starts SAS Micro Analytic
Service
-
-
-
Creates a new revision
(DS2 package is compiled)
-
Checks for compiler
messages and prints any that are found to the console
-
Retrieves and prints
metadata about the DS2 package
-
Prepares method arguments
-
-
Retrieves and prints
results
-
Prepares a different
set of argument values
-
Calls a different method
of the package
-
Retrieves and prints
results of the second call
-
Shuts down SAS Micro
Analytic Service
The console output from
running the example follows the source code.
package com.sas.mas.test;
import java.util.ArrayList;
import com.sas.mas.TkLight;
import com.sas.mas.tksfParmdef;
import com.sas.mas.tksfValues;
import com.sas.mas.TkLight.Language;
import com.sas.mas.jni.tksfjni;
public class SimpleDS2Example {
/*
This is a simple DS2 package with two methods. The code could have
been read from a file, but is included here for easy reference.
The source code starts with "ds2_options sas" and ends with
with "endpackage." This pattern should be used with all DS2 to be
published to SAS Micro Analytic Service.
Note: each source code line ends with a line-end character.
This best practice facilitates use of the line numbers included in
compiler messages, making it easier to locate syntax errors.
*/
static String DS2 =
"ds2_options sas; \n" +
"package simple_example /overwrite=yes; \n" +
" \n" +
" method str2double (char(12) numericString, in_out double number); \n" +
" number = put( numericString, 8.0); \n" +
" /* Include an undeclared variable to illustrate a compiler warning */ \n" +
" anotherNumber = number; \n" +
" end; \n" +
" \n" +
" method flip_string(varchar(32767) in_string, in_out varchar out_string); \n" +
" /* Reverse the input string and set in output string */ \n" +
" out_string=reverse(in_string); \n" +
" end; \n" +
" \n" +
"endpackage; \n";
/**
* @param parms
*/
public static void main(String[] parms) {
int rc;
String stringToReverse = new String("This is a test...");
String stringToConvert = new String("0.9997");
long userCtx = -1;
long moduleCtx = -1;
// Start SAS Micro Analtyic Service with four threads and
// no logging configuration file location (null second argument)
int threads = 4;
TkLight tk = new tksfjni(threads, null);
System.out.println("*** Simple example of using SAS Micro Analytic Service ***");
// Create a user context.
userCtx = tk.newUserContext("A user context");
if (userCtx <= 0) {
System.out.println(" User context creation failed.");
return;
}
else {
System.out.println(" User context created at " +
tk.getUserContextCreationDateTime(userCtx) + ".");
}
/* Create a module context.
This module context is owned by the user context just created.
The language is specified as DS2. Therefore, all revisions
of the module must be DS2.
The module is named for the DS2 package it represents, or
"simple_example" in this case.
Pass null for the last argument, which specifies the default options.
*/
moduleCtx = tk.newModuleContext(userCtx,
Language.DS2,
"simple_example",
null);
if (moduleCtx <= 0) {
System.out.println(" Module context creation failed.");
tk.term();
return;
}
else {
System.out.println(" Module context created at " +
tk.getModuleContextCreationDateTime(moduleCtx) + ".");
}
/* Publish the DS2 to SAS Micro Analytic Service by calling newRevision().
Pass in the module context ID, the source code String, and an
optional description.
Pass null for the fouth argument, a list of entry points, which
is only used for C modules.
Pass null for the last argument, which specifies default options.
*/
int revision = tk.newRevision(moduleCtx, DS2,
"A simple DS2 example to illustrate SAS Micro Analytic Service usage.",
null, null);
if (revision <= 0) {
System.out.println(" Compilation failed");
String[] messages = tk.getCompilationMessages(moduleCtx);
if (messages.length > 0) {
System.out.println(" Compiler messages:");
for (String msg : messages) {
System.out.println(" " + msg);
}
}
System.out.println(" Revision creation failed.");
tk.term();
return;
}
else {
System.out.println(" Revision " + revision + " created at " +
tk.getRevisionCreationDateTime(moduleCtx, revision)
+ ".");
}
System.out.println(" DS2 Package: " +
tk.getModuleContextDisplayName(moduleCtx));
/* Even successful compilations can produce warning messages from the compiler.
The undeclared variable included in the source code generates such a
warning. However, it will not prevent the code from publishing and executing
properly.
*/
String[] messages = tk.getCompilationMessages(moduleCtx);
if (messages.length > 0) {
System.out.println(" Compiler messages:");
for (String msg : messages) {
System.out.println(" " + msg);
}
}
/* Once published, SAS Micro Analtic Service can be queried for information
about the revision. Here you are asked for the inputs to the str2double
method. Parameter metadata is represented by class tksfParmdef.
*/
ArrayList<tksfParmdef> inputs = tk.getStepInputs(moduleCtx,
revision,
"str2double");
System.out.println(" Input arguments to method 'str2double':");
for (tksfParmdef p : inputs) {
System.out.println(" Input name: '" + p.name + "' type: " +
p.getType());
}
/* Setup arguments to call method "str2double", which has one String input and
one double output.
Note: Setters are being used with implicit indices.
*/
int numArgs = 2;
int numInputs = 1;
tksfValues args = new tksfValues(numArgs, numInputs); // DS2 method arguments
args.setString(stringToConvert);
args.setOutDouble();
String methodName = "str2double";
// Execute the DS2 package method "str2double"
rc = tk.execute(userCtx, moduleCtx, revision, methodName, args);
if (rc != 0) {
System.out.println(" Bad return code from execute:" + rc);
if (rc == 29) {
System.out.println(" Exception occurred during execution of " +
methodName + " in the TK environment.");
}
tk.term();
return;
}
else {
// Print results (Getters are being used with explicit indices.)
System.out.println(" Results of calling str2double:");
System.out.println(" Input String: " + args.getString(0));
System.out.println(" Output double (rounded): " + args.getDouble(1));
}
// Setup arguments to call the method "flip_string", which has one String input
// and one double output. Setters are being used with implicit indices.
numArgs = 2;
numInputs = 1;
args = new tksfValues(numArgs, numInputs); // DS2 method arguments
args.setString(stringToReverse);
args.setOutString();
methodName = "flip_string";
// Execute the DS2 package method "flip_string"
rc = tk.execute(userCtx, moduleCtx, revision, methodName, args);
if (rc != 0) {
System.out.println(" Bad return code from execute:" + rc);
if (rc == 29) {
System.out.println(" Exception occurred during execution of " +
methodName + " in the TK environment.");
}
tk.term();
return;
}
else {
// Print results (Getters are being used with explicit indices.)
System.out.println(" Results of calling flip_string:");
System.out.println(" Input String: " + args.getString(0));
System.out.println(" Output String: " + args.getString(1));
}
System.out.println("*** Simple DS2 example complete ***\n");
// Shutdown
tk.term();
}
}
Here is the console
output from running the example code above:
*** Simple example of using SAS Micro Analytic Service ***
User context created at Tue Apr 07 17:50:28 EDT 2015.
Module context created at Tue Apr 07 17:50:28 EDT 2015.
Revision 1 created at Tue Apr 07 17:50:28 EDT 2015.
DS2 Package: simple_example
Compiler messages:
Line 6: No DECLARE for assigned-to variable anothernumber;
creating it as a global variable of type double.
Input arguments to method 'str2double':
Input name: 'numericString' type: string_t
Results of calling str2double:
Input String: 0.9997
Output double (should round to nearest whole number): 1.0
Results of calling flip_string:
Input String: This is a test...
Output String: ...tset a si sihT
*** Simple DS2 example complete ***