Skip to content

Commit fe3b8a0

Browse files
committed
documentation and refactoring
1 parent ae1549e commit fe3b8a0

10 files changed

Lines changed: 333 additions & 344 deletions

File tree

site/advanced/extend.md

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,15 @@
1515
used by the BASIC program.
1616

1717
For example we can have the following class in an application:
18-
19-
%{snippet|id=testExtensionClass|file=src/test/java/com/scriptbasic/TestEngine.java}
2018

19+
```
20+
public static class TestExtensionClass {
21+
@Function(alias = "javaFunction", classification = java.lang.Long.class, requiredVersion = 1)
22+
public static Long fiftyFive() {
23+
return 55L;
24+
}
25+
}
26+
```
2127
This class contains a single `static` method that is very simple: it only returns a `Long` value: 55. This method
2228
is annotated with the annotation `@Function` that signals for the registering process that this method is a candidate
2329
for being called from BASIC.
@@ -27,7 +33,14 @@
2733

2834
The declared function can be called after that from BASIC the following way:
2935

30-
%{snippet|id=testExtensionMethod|file=src/test/java/com/scriptbasic/TestEngine.java}
36+
```
37+
EngineApi engine = EngineApi.getEngine();
38+
engine.registerExtension(TestExtensionClass.class);
39+
engine.load("Sub aPie\nreturn javaFunction()\nEndSub\n");
40+
engine.execute();
41+
Long z = (Long) engine.getSubroutine("aPie").call();
42+
Assert.assertEquals((Long) 55L, z);
43+
```
3144

3245
Note that extension methods should be `static`. If a non-static method is annotated in the registered class using the
3346
annotation `@Function` then the registering process will throw exception. The return value and the arguments can be
@@ -56,7 +69,7 @@
5669
For more information on how to use the `BasicArrayValue` have a look at the
5770
[JavaDoc API](../apidocs/com/scriptbasic/executors/rightvalues/BasicArrayValue.md).
5871

59-
* alias
72+
## alias
6073

6174
The `alias` of a method is the name of the BASIC function. In the example above the `alias` "javaFunction" is used and accordingly
6275
this name is used in the BASIC program. If the annotation parameter `alias` is not used then the actual name of the Java
@@ -69,7 +82,7 @@
6982
Another use of the parameter `alias` is to define a BASIC friendly name to the method that is more appealing or more
7083
common for the BASIC programmers.
7184

72-
* requiredVersion
85+
## requiredVersion
7386

7487
`requiredVersion` is an integer value denoting the required version of the embedding interface of ScriptBasic.
7588
In the current version `1.0.3` of ScriptBasic for Java this is 1. The default version for this parameter is 1.
@@ -80,7 +93,7 @@
8093

8194
For more information on the differences between the versions see the page [versions](./requiredVersion.md).
8295

83-
* substitueClass
96+
## substitueClass
8497

8598
Using the annotations you can register methods that are in different classes. It can happen that the class you want to make
8699
usable by the BASIC program is defined in a package that you import into your project and you do not have the source code or
@@ -93,15 +106,15 @@
93106
`com.scriptbasic.utility.RuntimeUtility` where this annotation is used to declare some of the methods of the class
94107
`java.lang.Math` usable from BASIC.
95108

96-
* substitueMethod
109+
## substitueMethod
97110

98111
Using this annotation you can specify an alternate method instead of the one annotated. In this case the actual
99112
name, parameters, return type of the method annotated is ignored and the one specified in the annotation is used. You can
100113
use this annotation along with `substituteClass` or without that. In the latter case you can give alternative names
101114
of the same method. The names, which are the names of the Java methods or are defined in the annotation `alias` are
102115
interchangeably used in the BASIC program.
103116

104-
* classification
117+
## classification
105118

106119
Classification helps the security system of ScriptBasic for Java. You can classify a method into several groups.
107120
These classification groups classify the nature of the method and help the installation to decide if the invocation

site/advanced/index.md

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
1-
```
2-
jScriptBasic Project Documentation
3-
```
4-
Peter Verhas
5-
```
6-
2012-08-22
7-
```
8-
9-
How to embed ScriptBasic for Java
1+
# How to embed ScriptBasic for Java
102

11-
In this document you will find a detailed description how to embed ScriptBasic for Java into
12-
different types of applications.
3+
In this document you will find a detailed description how to embed ScriptBasic for Java into
4+
different types of applications.
135

146
* [ How to embed ScriptBasic for Java using the JSR233](./jsr223tutorial.md) standard way.
157

site/advanced/jsr223tutorial.md

Lines changed: 105 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,56 @@
1-
```
2-
jScriptBasic Project Documentation
3-
```
4-
Peter Verhas
5-
```
6-
2012-08-22
7-
```
8-
9-
How to embed ScriptBasic for Java using the JSR223 standard interface
10-
11-
The JSR223 interface defines a few
12-
{{{http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/}interfaces and classes}}
13-
that are implemented by ScriptBasic for Java. If you
14-
want to embed ScriptBasic for Java into your application in a standard way
15-
you can do that using these interfaces and classes that are defined in the Java runtime.
16-
17-
The descriptions in this document are very general and most of the statements are true unaltered if we talk about
18-
some other scripting language.
19-
20-
To embed any scripting language into your application first you have to have the JAR file of the interpreter on the
21-
classpath. In case of ScriptBasic for Java it is the `jscriptbasic-x.y.z.jar` file. Your code need
22-
not depend on the actual implementation. You need not have this jar file at hand during compile time. You only need
23-
it during run time.
24-
25-
When you need the interpreter during run time your code has to get an instance of the `javax.script.ScriptEngineManager`
26-
some way, for example creating a new one using the operator `new`:
27-
28-
----
1+
## How to embed ScriptBasic for Java using the JSR223 standard interface
2+
3+
The JSR223 interface defines a few
4+
[interfaces and classes](http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/)
5+
that are implemented by ScriptBasic for Java. If you
6+
want to embed ScriptBasic for Java into your application in a standard way
7+
you can do that using these interfaces and classes that are defined in the Java runtime.
8+
9+
The descriptions in this document are very general and most of the statements are true unaltered if we talk about
10+
some other scripting language.
11+
12+
To use anz scripting language you have to have the implementation of the interpreter.
13+
In case of ScriptBasic for Java it is the `jscriptbasic-x.y.z.jar` file.
14+
Since the interfaces defined in JSR223 are included in the standard JDK the interpreter implementation is not a
15+
compilation time dependency. You can compile any program that wants to use some JSR223 compliant interpreter without
16+
the actual implementation of it. When you run your code, however, the jar file should be included into the classpath.
17+
18+
When you need the interpreter during run time your code has to get an instance of the `javax.script.ScriptEngineManager`
19+
some way, for example creating a new one using the operator `new`:
20+
21+
```
2922
ScriptEngineManager sem = new ScriptEngineManager();
30-
----
23+
```
24+
25+
As you can see from the package `javax.script` this class is part of the JDK.
3126

32-
If you use Sprint or some other DI framework, or container you can get the instance of the manager injected into your code.
33-
When you have the instance you can use the next step is to get an interpreter engine.
27+
If you use Sprint or some other DI framework, or container you can get the instance of the manager injected into your code.
28+
When you have the instance you can use the next step to get an interpreter engine.
3429

35-
----
30+
```
3631
ScriptEngine se = sem.getEngineByExtension(extension);
37-
----
38-
39-
This engine should be used to execute the script. In the line above we asked the manager to select an interpreter for us
40-
based on the extension of the script file name. This is only one possibility. You can ask the manager to give you a script
41-
engine based on the name of the interpreted language or by the mime type of the script (in case you read the script from a
42-
http stream and not from a file). When you ask the manager to give you an interpreter to a script based on the extension
43-
of the script file you have to provide the extension without the dot. Thus you have to specify `sb` or `bas` as
44-
argument to the method `getEngineByExtension()` and NOT `.sb` or `.bas`.
45-
46-
The script engine manager uses the standard Java service locator facility to load and find the appropriate script engine.
47-
This means that at first it loads all `META-INF/services/javax.script.ScriptEngineFactory` resource files that are
48-
loadable from the classpath. If you copied the jar file of ScriptBasic for Java onto the classpath then it will find the
49-
file packaged with this name into this JAR file. The manager will use this file along with the other resources from the
50-
runtime and the JAR files on the classpath and will read the content of each. The content of the file in case of
51-
ScriptBasic for Java is
52-
53-
----
32+
```
33+
34+
This engine should be used to execute the script. In the line above we asked the manager to select an interpreter for us
35+
based on the extension of the script file name. This is only one possibility. You can ask the manager to give you an
36+
interpreter
37+
based on the name of the interpreted language or by the mime type of the script (in case you read the script from a
38+
http stream and not from a file or from some other obscure source that does not represent any name and file extension).
39+
40+
When you ask the manager to give you an interpreter to a script based on the extension
41+
of the script file you have to provide the extension without the dot. Thus you have to specify `sb` or `bas` as
42+
argument to the method `getEngineByExtension()` and NOT `.sb` or `.bas`.
43+
44+
The script engine manager uses the standard Java service locator facility to load and find the appropriate script engine.
45+
This means that at first it loads all `META-INF/services/javax.script.ScriptEngineFactory` resource files that are
46+
loadable from the classpath. If you copied the jar file of ScriptBasic for Java onto the classpath then it will find the
47+
file packaged with this name into this JAR file. The manager will use this file along with the other resources from the
48+
runtime and the JAR files on the classpath and will read the content of each. The content of the file in case of
49+
ScriptBasic for Java is
50+
51+
```
5452
com.scriptbasic.javax.script.ScriptEngineFactory
55-
----
53+
```
5654

5755
This is the fully qualified name of the Java class in ScriptBasic for Java that implements the `javax.script.ScriptEngineFactory`
5856
interface of the Java runtime. The script engine factory can be queried about the mime types, names of scripting languages and
@@ -63,87 +61,88 @@ com.scriptbasic.javax.script.ScriptEngineFactory
6361
When you have the scripting engine you can use it to execute a script. The easiest way to do that is to call the `eval`
6462
method of the engine:
6563

66-
----
64+
```
6765
se.eval("print \"hello world\"");
68-
----
66+
```
6967

7068
Note that this method may throw `javax.script.ScriptException` therefore it is better to surround the call using a
7169
`try`/`catch` block.
7270

73-
To make something more complex than just executing a script, you can define a context that the script runs in. Using the
74-
context you can provide input to the script, get output from the script (standard output, and error output) and you can
75-
also access variables. You can set global BASIC variables before starting the script and you can read the values of the global
76-
variables after the script was executed.
77-
78-
To have a context the engine should be used:
71+
To make something more complex than just executing a script, you can define a context that the script runs in. Using the
72+
context you can provide input to the script, get output from the script (standard output, and error output) and you can
73+
also access variables. You can set global BASIC variables before starting the script and you can read the values of the global
74+
variables after the script was executed.
75+
76+
To have a context the engine should be used:
7977

80-
----
78+
```
8179
ScriptContext context = se.getContext();
82-
----
80+
```
8381

84-
This call will return a context that you can manipulate before starting your script. To set the input and the output
85-
you should have `PrintWriter` and `InputStreamReader` objects. The following code just wraps the Java standard
86-
`System.out`, `System.err` and `System.in` to the scripting engine context:
82+
This call will return a context that you can manipulate before starting your script. To set the input and the output
83+
you should have `PrintWriter` and `InputStreamReader` objects. The following code just wraps the Java standard
84+
`System.out`, `System.err` and `System.in` to the scripting engine context:
8785

88-
----
86+
```
8987
PrintWriter outWriter = new PrintWriter(System.out);
9088
context.setWriter(outWriter);
9189
PrintWriter errorWriter = new PrintWriter(System.err);
9290
context.setErrorWriter(errorWriter);
9391
context.setReader(new InputStreamReader(System.in));
9492
Reader reader = new FileReader(basicProgramFileName);
95-
----
96-
97-
Note that in the current version the interpreter does not provide any mean to write the error output or to
98-
read the standard input. Later versions will provide features for that.
93+
```
9994

100-
To set/get the global variables you should use the so called bindings of the context, that binds the values to the
101-
names of the global variables.
102-
103-
The standard JSR223 defines two bindings: one engine scope and one global scope bindings. The values bound in the global scope
104-
binding are available for all scripts. The values bound in the engine scope are available only to the scripts executed by the engine.
95+
Note that in the current version the interpreter does not provide any mean to write the error output or to
96+
read the standard input. Later versions will provide features for that.
97+
98+
To set/get the global variables you should use the so called bindings of the context, that binds the values to the
99+
names of the global variables.
100+
101+
The standard JSR223 defines two bindings: one engine scope and one global scope bindings. The values bound in the global scope
102+
binding are available for all scripts. The values bound in the engine scope are available only to the scripts executed by the engine.
105103

106-
To get one of the scopes you have to 'get' it from the context:
104+
To get one of the scopes you have to 'get' it from the context:
107105

108-
----
106+
```
109107
Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
110-
----
108+
```
111109

112-
and you can use `put` to store values into the bindings.
110+
and you can use `put` to store values into the bindings.
113111

114-
----
112+
```
115113
bindings.put("B", Integer.valueOf(13));
116114
bindings.put("A", null);
117-
----
115+
```
118116

119-
To get the value of a global variable after the execution of the script you should call `get` on the bindings:
117+
To get the value of a global variable after the execution of the script you should call `get` on the bindings:
120118

121-
----
119+
```
122120
Long z = (Long) bindings.get("A");
123-
----
121+
```
124122

125-
When a ScriptBasic script starts in Java the interpreter first copies the values from the global scope to the global variables table
126-
of the interpreter. After this the interpreter copies the values from the engine scope to the variables table of the interpreter.
127-
It also implies that if a variable is defined in the global and in the engine scope then the one defined in the engine scope
128-
will override the value of the one defined in the global scope.
123+
assuming that the type of the value in the variable `A` is `Long`. If you do not 'put' any value into the bindings
124+
before the execution for the global variable `A` then you will not get back the value of the global variable from
125+
the binding after the execution.
129126

130-
When the interpretation of the script is finished the interpreter overwrites the values of the engine scope binding and the
131-
the global binding with the values of the same name from the interpreter variables table. It does not copy any new value into the
132-
bindings table. If you have a global variable `A` as in the example above you have to put it into the bindings before the
133-
interpreter starts to have the final value in the bindings at the end of the execution. If you have the value defined both in the
134-
global and in the engine binding then both will have the final value of the global variable, even though only the engine scope
135-
is used in the scope as input.
136-
137-
If the execution of the script throws exception then the values are NOT copied into the bindings.
138-
139-
Later versions will develop other features of the JSR223 interface, like calling subroutines of a BASIC script repeatedly.
140-
141-
Some extra features, like executing a script that includes other scripts from disk, or from database, or some other script
142-
repository needs the use of the native interface of ScriptBasic.
143-
144-
145-
146-
147-
148-
149-
127+
When a ScriptBasic script starts in Java the interpreter first copies the values from the global scope to the global variables table
128+
of the interpreter. After this the interpreter copies the values from the engine scope to the variables table of the interpreter.
129+
It also implies that if a variable is defined in the global and in the engine scope then the one defined in the engine scope
130+
will override the value of the one defined in the global scope.
131+
132+
When the interpretation of the script is finished the interpreter overwrites the values of the engine scope binding and the
133+
the global binding with the values of the same name from the interpreter variables table. It does not create any new binding.
134+
If a binding, for example does not contain the key`A` then the interpreter will not create that key even if there is a
135+
global BASIC variable named `A`. If you need the value of a global variable after the execution of the BASIC program
136+
you have to set its value in the bindings before the execution of the program to something. If it is `undef` then set it
137+
to `null`.
138+
139+
If you have the value defined both in the
140+
global and in the engine binding then both will have the final value of the global variable, even though only the engine scope
141+
is used in the scope as input.
142+
143+
If the execution of the script throws exception then the values are NOT copied into the bindings.
144+
145+
Later versions will develop other features of the JSR223 interface, like calling subroutines of a BASIC script repeatedly.
146+
147+
Some extra features, like executing a script that includes other scripts from disk, or from database, or some other script
148+
repository needs the use of the native interface of ScriptBasic.

src/main/java/com/scriptbasic/api/script/ScriptEngineFactory.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ public class ScriptEngineFactory implements javax.script.ScriptEngineFactory {
3333
// standard scripting interface does not provide any mean to define a
3434
// specific interface for the different engine instances that may
3535
// concurrently exist in the JVM
36-
private Configuration config = FactoryUtility
37-
.getConfiguration(SingletonFactoryFactory.getFactory());
36+
private Configuration config = FactoryUtility.getConfiguration(SingletonFactoryFactory.getFactory());
3837

3938
/**
4039
* The constructor reads the configuration and fills the constants that are

src/main/java/com/scriptbasic/configuration/BasicConfiguration.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
* date July 23, 2012
1818
*/
1919
public class BasicConfiguration implements Configuration {
20-
private static final Logger LOG = LoggerFactory
21-
.getLogger();
20+
private static final Logger LOG = LoggerFactory.getLogger();
2221
private final Map<String, List<String>> lists = new HashMap<>();
2322
Factory factory;
2423
Properties configProperties;

src/main/java/com/scriptbasic/hooks/SimpleHook.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* date Aug 3, 2012
2727
*
2828
*/
29-
public class SimpleHook implements InterpreterHook {
29+
public abstract class SimpleHook implements InterpreterHook {
3030

3131
private InterpreterHook next;
3232
private ExtendedInterpreter interpreter;

src/main/java/com/scriptbasic/interfaces/ExtendedInterpreter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ void registerJavaMethod(String alias, Class<?> klass, String methodName,
213213
* {@code java.lang.Math} and accepts one argument, which is {@code double}
214214
*
215215
* @param klass
216-
* @param mehodName
216+
* @param methodName
217217
* @return
218218
* @throws ExecutionException
219219
*/

0 commit comments

Comments
 (0)