返回首页

脚本语言和COBOL
作者斯蒂芬Gennard的名义发表。
脚本语言与其他语言的使用增加了在过去几年中,从一个简单的互操作性的情况下,脚本代码的重用,允许你的代码进行定制,通过使用外部脚本。所有这一切都是真实的世界,我已经看到了客户使用的例子。
语言之间的互操作性是非常重要的其他语言一样多的COBOL环境。一些平台,如微软的。NET与他们CLR让所有语言都有一个共同的基础设施的生活变得更轻松;即,指令集和虚拟机(MSIL和CLR)伴随着一个基类库,让你开始。
,如Sun公司的虚拟机(JVM)环境提供了两种不同的方法与Java的互操作性,首先是通过JNI / JNA的,第二个是生产字节码运行在VM是。
虽然微焦点COBOL编译器不支持JVM字节码或生成Java源代码,它支持通过面向对象的调用动词调用的类/方法。
这个机制是非常简单易用,你只需要让我们的对象的COBOL运行时知道类是一个Java类。这可以通过配售美元的JAVA类和保证类本身的名称前可以找到JVM通常是通过增加额外的目录或jar文件CLASSPATH环境变量。
使用Java 6.0和JSR 223,支持基于Java的脚本语言提供了通过封装的javax.script。
Java有一个从AWK脚本语言XSLT的财富。我的最爱是,{A1}。
java.net网站有一个全面的脚本语言列表 - {A2}。
使用脚本包,你首先需要创建一个ScriptEngineManager,然后用它来创建一个特定的您选择的脚本语言的ScriptEngine对象,并使用它。
例如:创建一个ScriptEngineManager对象。检索经理的ScriptEngine对象。评估使用的ScriptEngine对象的脚本。
在COBOL,这是很简单:

*> ooctrl(+p) required for COM and Java classes

*> ooctrl(-f) used to preserve case of method names for Java

$set ooctrl(+p) ooctrl(-f)



class-control.

   cls-Script-EngineManager is

       class "$JAVA$javax.script.ScriptEngineManager"

   cls-Script-Engine is

       class "$JAVA$javax.script.ScriptEngine"

   cls-object is

       class "$JAVA$java.lang.Object"

   cls-System is

       class "$JAVA$java.lang.System"     

   cls-PrintStream is

       class "$JAVA$java.io.PrintStream"

  .



working-storage section.

01 ws-obj-sem     object reference cls-Script-EngineManager.

01 ws-javascript  object reference cls-Script-Engine.

01 ws-obj         object reference cls-object.



01 ws-pout        object reference cls-PrintStream.

procedure division.

 invoke cls-Script-EngineManager "new" 

     returning ws-obj-sem

 end-invoke



 invoke ws-obj-sem "getEngineByName" using

     "JavaScript" returning ws-javascript 

 end-invoke



 invoke ws-javascript "eval" using

     z"print('Hello, world!')"

     returning ws-obj

 end-invoke



 if ws-obj not equal null

  invoke cls-System "getout" returning ws-pout

  invoke ws-pout "println"   using ws-obj

  invoke ws-pout "finalize"  returning ws-pout

  invoke ws-obj "finalize"   returning ws-obj

 end-if



$if NO-FINALIZE not defined

 invoke ws-obj-sem "finalize"    returning ws-obj-sem

 invoke ws-javascript "finalize" returning ws-javascript

$end

stop run.

实际正在执行的JavaScript包含的调用语句,这简直是:{C}
要使用上面的例子中,我们首先需要对代码进行编译和运行它..这是做了如下:
C:\jscripting\HelloWorld>cobol cbljscript.cbl int(); 

Micro Focus Net Express V5

Version 6.0.00059  Copyright (C) 1984-2009 Micro Focus (IP) Limited.

URN AXCGG/AA0/00000 

* Checking complete with no errors - starting code generation

* Generating cbljscript

* Data:         848     Code:        1992     Literals:         904



C:\jscripting\HelloWorld>runm cbljscript 

Micro Focus Net Express V6.0.00059                          

RUN TIME ENVIRONMENT Copyright (C) 1984-2009 Micro Focus (IP) Limited.

URN AXCGG/AA0/00000                                                             

Hello, world!

这仅仅是开始,是需要另一种语言的互操作性的下一块是通过参数和脚本的能力。幸运的是,对于我们来说,对JSR组巧妙章有"放"和"得"的方法,使我们能够简单地把一个名字参数并得到更新或新的参数。
所以考虑的例子中,我们需要设置一个参数称为"消息"的脚本,然后读取一个参数叫做'replyMessage"后已执行的脚本。要做到这一点的JavaScript:
/* Do some insanity checking! */

if (typeof(message) == 'undefined')

{

    message = "ERROR - 'message' has not been setup"

}



println(message)



replyMessage = "Hello from javascript"

要设置的消息参数,我们只是需要做的:
*> Put a variable in engine, so the javascript

*> can use it.

invoke ws-javascript "put" using

   z"message"

   z"Hello World from COBOL!"

end-invoke

然后脚本执行后,我们只需要使用'get'的方法..
*> get a variable in engine

  invoke ws-javascript "get" using

     z"replyMessage"

     returning ws-message

  end-invoke



*> now display the replyMessage if it is available

  if ws-message not equal null

    invoke ws-pout "println"   using ws-message

  else

    display "Javascript did not set a replyMessage var"

完成的COBOL下面的例子使用JavaScript的一个侧面的文件,代码如下:
*> ooctrl(+p) required for COM and Java classes

*> ooctrl(-f) used to preserve case of method names for Java

$set ooctrl(+p) ooctrl(-f)



class-control.

   cls-Script-EngineManager is

       class "$JAVA$javax.script.ScriptEngineManager"

   cls-Script-Engine is

       class "$JAVA$javax.script.ScriptEngine"

   cls-object is

       class "$JAVA$java.lang.Object"

   cls-System is

       class "$JAVA$java.lang.System"     

   cls-PrintStream is

       class "$JAVA$java.io.PrintStream"

   cls-FileReader is

       class "$JAVA$java.io.FileReader"

  .



working-storage section.

01 ws-file        object reference cls-FileReader.

01 ws-obj-sem     object reference cls-Script-EngineManager.

01 ws-javascript  object reference cls-Script-Engine.

01 ws-obj         object reference cls-object.

01 ws-message     object reference cls-object.



01 ws-pout        object reference cls-PrintStream.

procedure division.

*> setup ws-pout to be System.out object

 invoke cls-System "getout" returning ws-pout



*> Setup a FileReader object for the external helloworld.js file

 invoke cls-FileReader "new" using

      z"helloworld.js"

      returning ws-file

 end-invoke



*> Create a new script manager

 invoke cls-Script-EngineManager "new" 

     returning ws-obj-sem

 end-invoke



*> Find the javascript engine

 invoke ws-obj-sem "getEngineByName" using

     "JavaScript" returning ws-javascript 

 end-invoke



*> Put a variable in engine, so the javascript

*> can use it.

 invoke ws-javascript "put" using

    z"message"

    z"Hello World from COBOL!"

 end-invoke



*> do some javascript stuff!

 invoke ws-javascript "eval" using

    ws-file

    returning ws-obj-sem

 end-invoke



*> get a variable in engine

 invoke ws-javascript "get" using

    z"replyMessage"

    returning ws-message

 end-invoke



*> now display the replyMessage if it is available

 if ws-message not equal null

   invoke ws-pout "println"   using ws-message

 else

   display "Javascript did not set a replyMessage var"

 end-if





*> cleanup code, not strickly needed for the example but

*> its good practice, to do it.

$if NO-FINALIZE not defined

 if ws-message not equal null

    invoke ws-message "finalize" returning ws-message

 end-if

 if ws-pout not equal null

    invoke ws-pout "finalize"    returning ws-pout

 end-if

 invoke ws-obj-sem "finalize"    returning ws-obj-sem

 invoke ws-javascript "finalize" returning ws-javascript

$end



stop run.
C:\jscripting\HelloWorld3>cobol cbljscript.cbl int(); 

Micro Focus Net Express V5

Version 6.0.00059  Copyright (C) 1984-2009 Micro Focus (IP) Limited.

URN AXCGG/AA0/00000 

* Checking complete with no errors - starting code generation

* Generating cbljscript

* Data:         888     Code:        2528     Literals:        1296



C:\jscripting\HelloWorld3>runm cbljscript 

Micro Focus Net Express V6.0.00059                          

RUN TIME ENVIRONMENT Copyright (C) 1984-2009 Micro Focus (IP) Limited.

URN AXCGG/AA0/00000                                                             

Hello World from COBOL!

Hello from javascript

正如你可以看到从上面的代码,设置的参数是很容易做到,但有时我们只想执行一个脚本语言功能,如:
function testMessage(msg)

{

    print("testMessage : " + msg);

}

我们已经创建了使用脚本引擎ScriptEngine的对象可能会实现一个可选的接口称为javax.script.Invocable;我们如果脚本引擎使用的是不提供这种接口,则称为invokeFunction(..)方法可以使用​​。
为了减少COBOL代码的大小,我作为一个简单的代理层编码在Java中的简单utils的类,代码非常简单,但不使其更容易 COBOL的使用invokeFunction()方法。
import javax.script.*;



public class utils {

    public static Invocable getInvocable(ScriptEngine obj) {

        return (Invocable)obj;

    }



    public static Object invokeFunction(ScriptEngine obj, 



           String function, Object p1) 

           throws ScriptException, NoSuchMethodException {

        Invocable iObj = getInvocable(obj);

        return iObj.invokeFunction(function, p1);

    }

}

然后从COBOL方面,我们可以使用上面的invokeFunction。
例如:
*> invoke a function with one parameter

invoke cls-utils "invokeFunction" using

 ws-javascript

 z"testMessage"

 z"Hello to function testMessage from COBOL"

这给了我们下面的输出,在执行时:
C:\jscripting\InvokeFunction>runm cbljscript

Micro Focus Net Express V6.0.00059

RUN TIME ENVIRONMENT Copyright (C) 1984-2009 Micro Focus (IP) Limited.

URN AXCGG/AA0/00000



testMessage : Hello to function testMessage from COBOL

完成的示例如下:
*> ooctrl(+p) required for COM and Java classes

*> ooctrl(-f) used to preserve case of method names for Java

$set ooctrl(+p) ooctrl(-f)



class-control.

   cls-Script-EngineManager is

       class "$JAVA$javax.script.ScriptEngineManager"

   cls-Script-Engine is

       class "$JAVA$javax.script.ScriptEngine"

   cls-object is

       class "$JAVA$java.lang.Object"

   cls-System is

       class "$JAVA$java.lang.System"     

   cls-PrintStream is

       class "$JAVA$java.io.PrintStream"

   cls-FileReader is

       class "$JAVA$java.io.FileReader"

   cls-Utils is

       class "$JAVA$utils"



  .



working-storage section.

01 ws-file        object reference cls-FileReader.

01 ws-obj-sem     object reference cls-Script-EngineManager.

01 ws-javascript  object reference cls-Script-Engine.

01 ws-message     object reference cls-object.



01 ws-pout        object reference cls-PrintStream.

procedure division.

*> setup ws-pout to be System.out object

 invoke cls-System "getout" returning ws-pout



*> Setup a FileReader object for the external helloworld.js file

 invoke cls-FileReader "new" using

      z"helloworld.js"

      returning ws-file

 end-invoke



*> Create a new script manager

 invoke cls-Script-EngineManager "new" 

     returning ws-obj-sem

 end-invoke



*> Find the javascript engine

 invoke ws-obj-sem "getEngineByName" using

     "JavaScript" returning ws-javascript 

 end-invoke



*> do some javascript function

 invoke ws-javascript "eval" using

    ws-file

    returning ws-obj-sem

 end-invoke



*> invoke a function with one parameter

 invoke cls-utils "invokeFunction" using

    ws-javascript

    z"testMessage"

    z"Hello to function testMessage from COBOL"

    returning ws-message

 end-invoke



*> cleanup code, not strickly needed for the example but

*> its good practice, to do it.

$if NO-FINALIZE not defined

 if ws-file not equal null

    invoke ws-file "finalize" returning ws-file

 end-if

 if ws-message not equal null

    invoke ws-message "finalize" returning ws-message

  end-if

 if ws-pout not equal null

    invoke ws-pout "finalize"    returning ws-pout

 end-if

 if ws-obj-sem not equal null

    invoke ws-obj-sem "finalize"    returning ws-obj-sem

 end-if

 if ws-javascript not equal null

    invoke ws-javascript "finalize" returning ws-javascript

 end-if

$end



stop run.
结论
从COBOL使用Java的脚本语言是很容易的,可以随意使用它。现在我应该使用哪个脚本语言...?

回答

评论会员: 时间:2