Calling OScript from Java

Introduction

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.

Calling OScript built-in functions in Java

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.

Example 1.

        // 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.

Example 2.

        // Java Code.
        String result = (String) OScriptObject.runScript( "$Kernel.SystemPreferences.GetPref", "general", "port" );

This example reads the Livelink port from the opentext.ini file.

Example 3.

        // 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.

Calling OScript scripts in Java

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.

Example 4.

        // 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.

Example 5.

        // 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.

Accessing the features of an OScriptObject

Java code can access the features of an OScriptObject with the OScriptObject.getFeature method. The feature name is case insensitive just like in OScript.

Example 6.

        // 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.

Enable Java in Livelink Builder

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.

Deploy Java Code in Livelink

Notes