diff options
Diffstat (limited to 'files/zh-cn/mozilla/projects/rhino/embedding_tutorial/index.html')
-rw-r--r-- | files/zh-cn/mozilla/projects/rhino/embedding_tutorial/index.html | 221 |
1 files changed, 0 insertions, 221 deletions
diff --git a/files/zh-cn/mozilla/projects/rhino/embedding_tutorial/index.html b/files/zh-cn/mozilla/projects/rhino/embedding_tutorial/index.html deleted file mode 100644 index b7cf0168f5..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/embedding_tutorial/index.html +++ /dev/null @@ -1,221 +0,0 @@ ---- -title: 'Tutorial: Embedding Rhino' -slug: Mozilla/Projects/Rhino/Embedding_tutorial -translation_of: Mozilla/Projects/Rhino/Embedding_tutorial ---- -<p>Embedding Rhino can be done simply with good results. With more effort on the part of the embedder, the objects exposed to scripts can be customized further.</p> -<p>This tutorial leads you through the steps from a simple embedding to more customized, complex embeddings. Fully compilable examples are provided along the way.</p> -<p>The examples live in the <code>rhino/examples</code> directory in the distribution and in <code>mozilla/js/rhino/examples</code> in cvs. This document will link to them using <a href="http://lxr.mozilla.org/">lxr</a>.</p> -<p>In this document, JavaScript code will be in <span class="java_js_code">green</span>, Java code will be in <span class="java_js_code">green,</span> and shell logs will be in <span class="shell_logs_code">purple</span>.</p> -<h2 id="In_this_document">In this document:</h2> -<ul class="toc"> - <li><a href="#runScript">RunScript: A simple embedding</a> - <ul> - <li><a href="#enteringContext">Entering a Context</a></li> - <li><a href="#initializing">Initializing standard objects</a></li> - <li><a href="#collecting">Collecting the arguments</a></li> - <li><a href="#evaluating">Evaluating a script</a></li> - <li><a href="#print">Printing the result</a></li> - <li><a href="#exit">Exiting the Context</a></li> - </ul> - </li> - <li><a href="#expose">Expose Java APIs</a> - <ul> - <li><a href="#useJava">Using Java APIs</a></li> - <li><a href="#implementingInterfaces">Implementing interfaces</a></li> - <li><a href="#addJava">Adding Java objects</a></li> - </ul> - </li> - <li><a href="#usingJSObjs">Using JavaScript objects from Java</a> - <ul> - <li><a href="#usingJSvars">Using JavaScript variables</a></li> - <li><a href="#callingJSfuns">Calling JavaScript functions</a></li> - </ul> - </li> - <li><a href="#javaScriptHostObjects">JavaScript host objects</a> - <ul> - <li><a href="#definingHostObjects">Defining Host Objects</a></li> - <li><a href="#counter">Counter example</a> - <ul> - <li><a href="#counterCtors">Counter's constructors</a></li> - <li><a href="#classname">Class name</a></li> - <li><a href="#dynamic">Dynamic properties</a></li> - <li><a href="#definingMethods">Defining JavaScript "methods"</a></li> - <li><a href="#addingCounter">Adding Counter to RunScript</a></li> - </ul> - </li> - </ul> - </li> -</ul> -<h2 id="RunScript_A_simple_embedding"><a id="runScript" name="runScript">RunScript: A simple embedding</a></h2> -<p>About the simplest embedding of Rhino possible is the <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/RunScript.java">RunScript example</a>. All it does it read a script from the command line, execute it, and print a result.</p> -<p>Here's an example use of RunScript from a shell command line:</p> -<pre class="code shell_logs_code">$ java RunScript "Math.cos(Math.PI)" --1 -$ java RunScript "function f(x){return x+1} f(7)" -8 -</pre> -<p>Note that you'll have to have both the Rhino classes and the RunScript example class file in the classpath. Let's step through the body of <code>main</code> one line at time.</p> -<h3 id="Entering_a_Context"><a id="enteringContext" name="enteringContext">Entering a Context</a></h3> -<p>The code</p> -<pre class="code java_js_code">Context cx = Context.enter(); -</pre> -<p>Creates and enters a <code>Context</code>. A <code>Context</code> stores information about the execution environment of a script.</p> -<h3 id="Initializing_standard_objects"><a name="initializing">Initializing standard objects</a></h3> -<p>The code</p> -<pre class="code java_js_code">Scriptable scope = cx.initStandardObjects(); -</pre> -<p>Initializes the standard objects (<code>Object</code>, <code>Function</code>, etc.) This must be done before scripts can be executed. The <var>null</var> parameter tells <code>initStandardObjects</code> to create and return a scope object that we use in later calls.</p> -<h3 id="Collecting_the_arguments"><a id="collecting" name="collecting">Collecting the arguments</a></h3> -<p>This code is standard Java and not specific to Rhino. It just collects all the arguments and concatenates them together.</p> -<pre class="code java_js_code">String s = ""; -for (int i=0; i < args.length; i++) { - s += args[i]; -} -</pre> -<h3 id="Evaluating_a_script"><a id="evaluating" name="evaluating">Evaluating a script</a></h3> -<p>The code</p> -<pre class="code java_js_code">Object result = cx.evaluateString(scope, s, "<cmd>", 1, null); -</pre> -<p>uses the Context <code>cx</code> to evaluate a string. Evaluation of the script looks up variables in <var>scope</var>, and errors will be reported with the filename <code><cmd></code> and line number 1.</p> -<h3 id="Printing_the_result"><a id="print" name="print">Printing the result</a></h3> -<p>The code</p> -<pre class="code java_js_code">System.out.println(cx.toString(result)); -</pre> -<p>prints the result of evaluating the script (contained in the variable <var>result</var>). <var>result</var> could be a string, JavaScript object, or other values. The <code>toString</code> method converts any JavaScript value to a string.</p> -<h3 id="Exiting_the_Context"><a id="exit" name="exit">Exiting the Context</a></h3> -<p>The code</p> -<pre class="code java_js_code">} finally { - Context.exit(); -} -</pre> -<p>exits the Context. This removes the association between the Context and the current thread and is an essential cleanup action. There should be a call to <code>exit</code> for every call to <code>enter</code>. To make sure that it is called even if an exception is thrown, it is put into the finally block corresponding to the try block starting after <code>Context.enter()</code>.</p> -<h2 id="Expose_Java_APIs"><a id="expose" name="expose">Expose Java APIs</a></h2> -<h3 id="Using_Java_APIs"><a id="useJava" name="useJava">Using Java APIs</a></h3> -<p>No additional code in the embedding needed! The JavaScript feature called - <i> - LiveConnect</i> - allows JavaScript programs to interact with Java objects:</p> -<pre class="code shell_logs_code">$ java RunScript "java.lang.System.out.println(3)" -3.0 -undefined -</pre> -<h3 id="Implementing_interfaces"><a id="implementingInterfaces" name="implementingInterfaces">Implementing interfaces</a></h3> -<p>Using Rhino, JavaScript objects can implement arbitrary Java interfaces. There's no Java code to write -- it's part of Rhino's LiveConnect implementation. For example, we can see how to implement java.lang.Runnable in a Rhino shell session:</p> -<pre class="code shell_logs_code">js> obj = { run: function() { print("hi"); } } -[object Object] -js> obj.run() -hi -js> r = new java.lang.Runnable(obj); -[object Object] -js> t = new java.lang.Thread(r) -Thread[Thread-0,5,main] -js> t.start() -hi -</pre> -<h3 id="Adding_Java_objects"><a id="addJava" name="addJava">Adding Java objects</a></h3> -<p>The next example is <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/RunScript2.java">RunScript2</a>. This is the same as RunScript, but with the addition of two extra lines of code:</p> -<pre class="code java_js_code">Object wrappedOut = Context.javaToJS(System.out, scope); -ScriptableObject.putProperty(scope, "out", wrappedOut); -</pre> -<p>These lines add a global variable <code>out</code> that is a JavaScript reflection of the <code>System.out</code> variable:</p> -<pre class="code shell_logs_code">$ java RunScript2 "out.println(42)" -42.0 -undefined -</pre> -<h2 id="Using_JavaScript_objects_from_Java"><a id="usingJSObjs" name="usingJSObjs">Using JavaScript objects from Java</a></h2> -<p>After evaluating a script it's possible to query the scope for variables and functions, extracting values and calling JavaScript functions. This is illustrated in the <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/RunScript3.java">RunScript3</a> example. This example adds the ability to print the value of variable <var>x</var> and the result of calling function <code>f</code>. Both <var>x</var> and <var>f</var> are expected to be defined by the evaluated script. For example,</p> -<pre class="code shell_logs_code">$ java RunScript3 "x = 7" -x = 7 -f is undefined or not a function. -$ java RunScript3 "function f(a) { return a; }" -x is not defined. -f("my args") = my arg -</pre> -<h3 id="Using_JavaScript_variables"><a id="usingJSvars" name="usingJSvars">Using JavaScript variables</a></h3> -<p>To print out the value of <var>x</var>, we add the following code:</p> -<pre class="code java_js_code">Object x = scope.get("x", scope); -if (x == Scriptable.NOT_FOUND) { - System.out.println("x is not defined."); -} else { - System.out.println("x = " + Context.toString(x)); -} -</pre> -<h3 id="Calling_JavaScript_functions"><a id="callingJSfuns" name="callingJSfuns">Calling JavaScript functions</a></h3> -<p>To get the function <var>f</var>, call it, and print the result, we add this code:</p> -<pre class="code java_js_code">Object fObj = scope.get("f", scope); -if (!(fObj instanceof Function)) { - System.out.println("f is undefined or not a function."); -} else { - Object functionArgs[] = { "my arg" }; - Function f = (Function)fObj; - Object result = f.call(cx, scope, scope, functionArgs); - String report = "f('my args') = " + Context.toString(result); - System.out.println(report); -} -</pre> -<h2 id="JavaScript_host_objects"><a id="javaScriptHostObjects" name="javaScriptHostObjects">JavaScript host objects</a></h2> -<h3 id="Defining_Host_Objects"><a id="definingHostObjects" name="definingHostObjects">Defining Host Objects</a></h3> -<p>Custom host objects can implement special JavaScript features like dynamic properties.</p> -<h3 id="Counter_example"><a id="counter" name="counter">Counter example</a></h3> -<p>The <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/Counter.java">Counter example</a> is a simple host object. We'll go through it method by method below.</p> -<p>It's easy to try out new host object classes in the shell using its built-in <code>defineClass</code> function. We'll see how to add it to RunScript later. (Note that because the <code>java -jar</code> option preempts the rest of the classpath, we can't use that and access the <code>Counter</code> class.)</p> -<pre class="code shell_logs_code">$ java -cp "js.jar;examples" org.mozilla.javascript.tools.shell.Main -js> defineClass("Counter") -js> c = new Counter(7) -[object Counter] -js> c.count -7 -js> c.count -8 -js> c.count -9 -js> c.resetCount() -js> c.count -0 -</pre> -<h3 id="Counter's_constructors"><a id="counterCtors" name="counterCtors">Counter's constructors</a></h3> -<p>The zero-argument constructor is used by Rhino runtime to create instances. For the counter example, no initialization work is needed, so the implementation is empty.</p> -<pre class="code java_js_code">public Counter () { } -</pre> -<p>The method <code>jsConstructor</code> defines the JavaScript constructor that was called with the expression <code>new Counter(7)</code> in the JavaScript code above.</p> -<pre class="code java_js_code">public void jsConstructor(int a) { count -= a; } -</pre> -<h3 id="Class_name"><a id="classname" name="classname">Class name</a></h3> -<p>The class name is defined by the <code>getClassName</code> method. This is used to determine the name of the constructor.</p> -<pre class="code java_js_code">public String getClassName() { return "Counter"; -} -</pre> -<h3 id="Dynamic_properties"><a id="dynamic" name="dynamic">Dynamic properties</a></h3> -<p>Dynamic properties are defined by methods beginning with <code>jsGet_</code> or <code>jsSet_</code>. The method <code>jsGet_count</code> defines the - <i> - count</i> - property.</p> -<pre class="code java_js_code">public int jsGet_count() { return count++; -} -</pre> -<p>The expression <code>c.count</code> in the JavaScript code above results in a call to this method.</p> -<h3 id="Defining_JavaScript_methods"><a id="definingMethods" name="definingMethods">Defining JavaScript "methods"</a></h3> -<p>Methods can be defined using the <code>jsFunction_ prefix</code>. Here we define <code>resetCount</code> for JavaScript.</p> -<pre class="code java_js_code">public void jsFunction_resetCount() { count -= 0; } -</pre> -<p>The call <code>c.resetCount()</code> above calls this method.</p> -<h3 id="Adding_Counter_to_RunScript"><a id="addingCounter" name="addingCounter">Adding Counter to RunScript</a></h3> -<p>Now take a look at the <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/RunScript4.java">RunScript4 example</a>. It's the same as RunScript except for two additions. The method <code>ScriptableObject.defineClass</code> uses a Java class to define the Counter "class" in the top-level scope:</p> -<pre class="code java_js_code">ScriptableObject.defineClass(scope, Counter.class); -</pre> -<p>Now we can reference the <code>Counter</code> object from our script:</p> -<pre class="code shell_logs_code">$ java RunScript4 "c = new Counter(3); c.count; -c.count;" -</pre> -<p>It also creates a new instance of the <code>Counter</code> object from within our Java code, constructing it with the value 7, and assigning it to the top-level variable <code>myCounter</code>:</p> -<pre class="code java_js_code">Object[] arg = { new Integer(7) }; -Scriptable myCounter = cx.newObject(scope, "Counter", arg); -scope.put("myCounter", scope, myCounter); -</pre> -<p>Now we can reference the <code>myCounter</code> object from our script:</p> -<pre class="code shell_logs_code">$ java RunScript3 'RunScript4 'myCounter.count; myCounter.count' -8 -</pre> |