Java methods invoked by JavaObject.InvokeMethod and JavaObject.InvokeStaticMethod can reference OScript objects and call OScript scripts and built-in functions through the OScriptObject class. This requires the current thread being an OScript thread, i.e. the Java method has to be invoked through JavaObject. Also the OScriptObject and OPeer objects created in the OScript thread or passed from the OScript layer can NOT be used in other threads.
This feature is available since Livelink 10.0.0.
Java code can call OScript built-in functions through the OScriptObject.runScript method. This feature opens up OScript builtin types to the Java layer. For example, with this feature, you can access Livelink system configuration information by calling CAPI.IniGet or put a log message in the thread logs with echo.
// Java Code. OScriptObject.runScript( "echo", "This message goes to thread log" );
This example calls the echo builtin method and puts a message in the thread log if logging is enabled.
// Java Code. String result = (String) OScriptObject.runScript( "$Kernel.SystemPreferences.GetPref", "general", "port" );
This example reads the Livelink port from the opentext.ini file.
// Java Code. public static void testBuiltin( OScriptObject prgCtx ) throws Exception { try { OScriptObject dapiCtx = (OScriptObject) prgCtx.invokeScript( "DSession" ); ODAPISession dapiSess = (ODAPISession) dapiCtx.getFeature( "fSession" ); if ( null == dapiSess ) { throw new NullPointerException( "dapiSess is null" ); } // Get Enterprise workspace. ODAPINode result = (ODAPINode) OScriptObject.runScript( "DAPI.GetNodeByID", dapiSess, 2000 ); sLogger.log( Level.INFO, "DAPI.GetNodeByID result: " + result.pNAME() ); } catch( Exception e ) { sLogger.log( Level.SEVERE, "Caught Exception", e ); throw e; } }
This example takes a prgCtx parameter passed from the OScript layer and calls the DAPI.GetNodeByID built-in function to get the Enterprise Workspace node. To run this example, you need to invoke the above method with JavaObject.InvokeStaticMethod.
Java code can call both global and object scripts with the OScriptObject.runScript and OScriptObject.invokeScript method. Use the OScriptObject.runScript method to call global scripts. Use the OScriptObject.invokeScript method to call scripts of an OScriptObject. This feature opens up OScript scripts to the Java layer. For example, with this feature, you can get the sub-nodes of a node with the $LLIAPI.NodeUtil.ListNodes script or update opentext.ini file with the $Kernel.SystemPreferences.AddPref script.
// Java Code. public static Map<String,Object> testScript( OScriptObject prgCtx ) throws Exception { Map<String,Object> result = null; ArrayList<Integer> args = new ArrayList<Integer>( 1 ); // Enterprise workspace is 2000. args.add( 2000 ); try { // List nodes in the Enterprise workspace. result = (Map<String,Object>) OScriptObject.runScript( "$LLIAPI.NodeUtil.ListNodes", prgCtx, "(ParentID=:A1)", args ); Boolean ok = (Boolean) result.get( "OK" ); if ( ok.booleanValue() ) { RecArray contents = (RecArray) result.get( "Contents" ); Record r; // Loops through the child nodes and write out the node name. for ( int i = 0; i < contents.size(); ++i ) { r = (Record) contents.getRecord( i ); sLogger.log( Level.INFO, "child node name: " + r.get( "Name" ) ); } } else { sLogger.log( Level.SEVERE, "ListNodes error message: " + result.get( "ErrMsg" ) ); sLogger.log( Level.SEVERE, "ListNodes api error: " + result.get( "ApiError" ) ); } } catch( Exception e ) { sLogger.log( Level.SEVERE, "Caught Exception", e ); throw e; } return result; }
This example takes a prgCtx parameter passed from the OScript layer and calls $LLIAPI.NodeUtil.ListNodes to get the sub-nodes in the Enterprise Workspace. It then loops through the contents and logs the name of each node. To run this example, you need to invoke the above method with JavaObject.InvokeStaticMethod.
// Java Code. public static String testScript2( OScriptObject prgCtx ) throws Exception { String retval = "zzz not found"; try { OScriptObject uSession = (OScriptObject) prgCtx.invokeScript( "USession" ); Integer userID = (Integer) uSession.getFeature( "fUserId" ); sLogger.log( Level.INFO, "UserID is " + userID ); retval = "The current login User: " + userID; // Get Admin user's name. Map<String,Object> status = (Map<String,Object>) OScriptObject.runScript( "$LLIAPI.UsersPkg.NameGetByID", uSession, 1000 ); sLogger.log( Level.INFO, String.valueOf( status ) ); sLogger.log( Level.INFO, (String) status.get( "Name" ) ); } catch( Exception e ) { sLogger.log( Level.SEVERE, "Caught Exception", e ); throw e; } return retval; }
This example takes a prgCtx parameter passed from the OScript layer and calls the "USession" script of the prgCtx object to get the user session. It then uses the user session to get the current login userID and the Admin user's name. To run this example, you need to invoke the above method with JavaObject.InvokeStaticMethod.
Java code can access the features of an OScriptObject with the OScriptObject.getFeature method. The feature name is case insensitive just like in OScript.
// Java Code. OScriptObject uSession = (OScriptObject) prgCtx.invokeScript( "USession" ); Integer userID = (Integer) uSession.getFeature( "fUserId" );
This example is a snippet from Example 4. It accesses the fUserId feature of the uSession object.
In order to use JavaObject, Livelink JVM has to be started. However, unlike Livelink service, Livelink Builder does not start the JVM by default. To start the JVM in Livelink Builder, add "-loadjavavm" in the Target field of the Livelink Builder's program shortcut.