脚本语言和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的脚本语言是很容易的,可以随意使用它。现在我应该使用哪个脚本语言...?