[redbridge~redbridge:d031959c] integrating three projects, embed API, jsr223, and bsf
- From: yokolet@kenai.com
- To: commits@redbridge.kenai.com
- Subject: [redbridge~redbridge:d031959c] integrating three projects, embed API, jsr223, and bsf
- Date: Sat, 12 Sep 2009 21:06:11 +0000
Project: redbridge
Repository: redbridge
Revision: d031959c70f50eee9c4eeab82fb4ba9d5ac7d9fa
Author: yokolet
Date: 2009-09-12 21:05:32 UTC
Link:
Log Message:
------------
integrating three projects, embed API, jsr223, and bsf
integrating three projects, embed API, jsr223, and bsf
Revisions:
----------
2283245490416d02298b2d367d8886671f619326
d031959c70f50eee9c4eeab82fb4ba9d5ac7d9fa
Modified Paths:
---------------
test/org/jruby/embed/jsr223/JRubyEngineTest.java
test/ruby/block-param-scope.rb
test/ruby/calendar.rb
test/ruby/count_down.rb
test/ruby/norman_window_dimensions.rb
test/ruby/norman_window_dimensions2.rb
test/ruby/position_function.rb
test/ruby/sphere.rb
test/ruby/tree.rb
test/ruby/tree_given_localvars.rb
src/org/jruby/embed/bsf/BsfJRubyEngine.properties
src/org/jruby/embed/jruby-embed.properties
src/org/jruby/embed/jsr223/Jsr223JRubyEngine.properties
test/org/jruby/embed/jsr223/JRubyEngineFactoryTest.java
Added Paths:
------------
src/org/jruby/embed/Attribute.java
src/org/jruby/embed/BiVariable.java
src/org/jruby/embed/BiVariableMap.java
src/org/jruby/embed/EmbedRubyObjectAdapter.java
src/org/jruby/embed/EmbedRubyObjectAdapterImpl.java
src/org/jruby/embed/EvalUnitWrapper.java
src/org/jruby/embed/LocalContextProvider.java
src/org/jruby/embed/LocalContextScope.java
src/org/jruby/embed/LocalVariableBehavior.java
src/org/jruby/embed/PathType.java
src/org/jruby/embed/ScriptingContainer.java
src/org/jruby/embed/bsf/BsfJRubyEngine.properties
src/org/jruby/embed/bsf/JRubyEngine.java
src/org/jruby/embed/internal/AbstractLocalContextProvider.java
src/org/jruby/embed/internal/CallMethodType.java
src/org/jruby/embed/internal/LocalContext.java
src/org/jruby/embed/internal/SingleThreadLocalContextProvider.java
src/org/jruby/embed/internal/SingletonLocalContextProvider.java
src/org/jruby/embed/internal/ThreadSafeLocalContextProvider.java
src/org/jruby/embed/io/ReaderInputStream.java
src/org/jruby/embed/io/WriterOutputStream.java
src/org/jruby/embed/jruby-embed.properties
src/org/jruby/embed/util/PropertyName.java
src/org/jruby/embed/util/RubyVersionChecker.java
src/org/jruby/embed/util/SystemPropertyCatcher.java
src/org/jruby/embed/variable/AbstractVariable.java
src/org/jruby/embed/variable/ClassVariable.java
src/org/jruby/embed/variable/Constant.java
src/org/jruby/embed/variable/GlobalVariable.java
src/org/jruby/embed/variable/InstanceVariable.java
src/org/jruby/embed/variable/LocalGlobalVariable.java
src/org/jruby/embed/variable/PersistentLocalVariable.java
src/org/jruby/embed/variable/TransientLocalVariable.java
src/org/jruby/embed/variable/VariableInterceptor.java
test/org/jruby/embed/BiVariableMapTest.java
test/org/jruby/embed/CallMethodTest.java
test/org/jruby/embed/CompileTest.java
test/org/jruby/embed/GetInstanceTest.java
test/org/jruby/embed/Greetings.java
test/org/jruby/embed/IoTest.java
test/org/jruby/embed/MultipleScriptsRunner.java
test/org/jruby/embed/PropertyNameTest.java
test/org/jruby/embed/QuadraticFormula.java
test/org/jruby/embed/QuadraticFormulaNoArg.java
test/org/jruby/embed/RunScriptletTest.java
test/org/jruby/embed/ScriptingContainerTest.java
test/org/jruby/embed/ScriptsRunnerTest.java
test/org/jruby/embed/Writable.java
test/org/jruby/embed/bsf/JRubyEngineTest.java
test/ruby/calendar2.rb
test/ruby/greetings_globalvars.rb
test/ruby/greetings_imple.rb
test/ruby/greetings_instancevars.rb
test/ruby/greetings_localvars.rb
test/ruby/hello_bye.rb
test/ruby/iteration.rb
test/ruby/quadratic_formula.rb
test/ruby/quadratic_formula_class.rb
test/ruby/quadratic_formula_globalvars.rb
test/ruby/quadratic_formula_instancevars.rb
test/ruby/quadratic_formula_localvars.rb
test/ruby/quiet.rb
test/ruby/radioactive_decay.rb
test/ruby/simple_output.rb
test/ruby/three_times.rb
Diffs:
------
diff --git a/src/org/jruby/embed/Attribute.java
b/src/org/jruby/embed/Attribute.java
new file mode 100644
index 0000000..f60702f
--- /dev/null
+++ b/src/org/jruby/embed/Attribute.java
@@ -0,0 +1,67 @@
+/**
+ * **** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2009 Yoko Harada <yokolet@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the
"LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ * **** END LICENSE BLOCK *****
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.jruby.embed;
+
+/**
+ * Predefined keys for an attribute map that ScriptingContainer has.
+
+ * Usage example:
+ * <pre>
+ * ScriptingContainer container = new ScriptingContainer();
+ * container.setAttribute(Attribute.BASE_DIR,
System.getProperty("user.dir");</pre>
+ *
+ * @author Yoko Harada <yokolet@gmail.com>
+ */
+public enum Attribute {
+ /**
+ * A key used by an attribute map to set a reader
+ */
+ READER,
+
+ /**
+ * A key used by an attribute map to set a writer
+ */
+ WRITER,
+
+ /**
+ * A key used by an attribute map to set an error writer
+ */
+ ERROR_WRITER,
+
+ /**
+ * A key used by an attribute map to set a base directory
+ */
+ BASE_DIR
+}
diff --git a/src/org/jruby/embed/BiVariable.java
b/src/org/jruby/embed/BiVariable.java
new file mode 100644
index 0000000..73ff8f0
--- /dev/null
+++ b/src/org/jruby/embed/BiVariable.java
@@ -0,0 +1,117 @@
+/**
+ * **** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2009 Yoko Harada <yokolet@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the
"LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ * **** END LICENSE BLOCK *****
+ */
+package org.jruby.embed;
+
+import org.jruby.Ruby;
+import org.jruby.runtime.builtin.IRubyObject;
+
+/**
+ * Represents bidirectional, both Java and Ruby, variables. Users don't
instantiate
+ * BiVariable type objects. Instead, users can get this type object from
+ * {@link BiVariableMap} after a variable is set to the map. Users can set
variables
+ * in Java program explicitly through put() methods in {@link
ScriptingContainer}
+ * and {@link BiVariableMap} or equivalents. However, variables in Ruby
scripts are
+ * set in the map implicitly. When varibles and constants
+ * are used in the script, thoses are automatically saved in the map
converting to this type.
+ *
+ * @author Yoko Harada <yokolet@gmail.com>
+ */
+public interface BiVariable {
+ /**
+ * Defines a type correspond to Ruby's variables and constant types.
+ */
+ public enum Type {
+ Constant, GlobalVariable, ClassVariable, InstanceVariable,
LocalVariable
+ }
+
+ /**
+ * Returns one of the Ruby's variables or constant types defined by Type.
+ *
+ * @return a type that corresponds to Ruby's variables and constant
types.
+ */
+ public Type getType();
+
+ /**
+ * Returns a name of the variable this object holds. The name follows
Ruby's
+ * naming rule.
+ *
+ * @return a name of the variable
+ */
+ public String getName();
+
+ /**
+ * Returns a value of the variable this object holds in Java type.
+ *
+ * @return a value in Java type.
+ */
+ public Object getJavaObject();
+
+ /**
+ * Sets a Java object as a value of this object. At the same time,
+ * an equivalent Ruby object is set automatically.
+ *
+ * @param runtime is used to convert a Java object to Ruby object.
+ * @param javaObject is a variable value to be set.
+ */
+ public void setJavaObject(Ruby runtime, Object javaObject);
+
+ /**
+ * Injects a variable value to a parsed Ruby script. This method is
invoked
+ * during EvalUnit#run() is executed. Users don't use this method.
+ *
+ * @param runtime is environment where a variable injection occurs
+ * @param receiver is the instance that will have variable injection.
+ */
+ public void inject(Ruby runtime, IRubyObject receiver);
+
+ /**
+ * Returns a value of the variable this object holds in
+ * a org.jruby.runtime.builtin.IRubyObject type.
+ *
+ * @return a value in IRubyObject type.
+ */
+ public IRubyObject getRubyObject();
+
+ /**
+ * Sets a org.jruby.runtime.builtin.IRubyObject type, Ruby object as a
value
+ * of this object. At the same time, an equivalent Java object is set
automatically.
+ *
+ * @param runtime is environment where a variable injection occurs
+ * @param rubyObject is a variable value to be set.
+ */
+ public void setRubyObject(IRubyObject rubyObject);
+
+ /**
+ * Removes this object from {@link BiVariableMap}.
+ *
+ * @param runtime enviroment where a variabe is removed.
+ */
+ public void remove(Ruby runtime);
+}
diff --git a/src/org/jruby/embed/BiVariableMap.java
b/src/org/jruby/embed/BiVariableMap.java
new file mode 100644
index 0000000..1722a50
--- /dev/null
+++ b/src/org/jruby/embed/BiVariableMap.java
@@ -0,0 +1,444 @@
+/**
+ * **** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2009 Yoko Harada <yokolet@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the
"LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ * **** END LICENSE BLOCK *****
+ */
+package org.jruby.embed;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.jruby.Ruby;
+import org.jruby.embed.variable.VariableInterceptor;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.scope.ManyVarsDynamicScope;
+
+/**
+ * Hash table base implementation of the java.util.Map internface. Keys of
this map
+ * should be String, and values should be {@link BiVariable} type object.
+ * This map does not permit null or empty key. Each operation of this class
is not
+ * synchronized; however, {@link ScriptingContainer} creates a map for every
thread.
+ * Thus, operations are thread-safe unless users use this map by methods in
+ * {@link ScriptingContainer}:
+ * <pre>
+ * ScriptingContainer container = new ScriptingContainer();
+ * Map map = container.getVarMap();
+ * map.put("@coefficient", new Float(3.14));</pre>
+ *
+ * @author Yoko Harada <yokolet@gmail.com>
+ */
+public class BiVariableMap<K, V> implements Map<K, V> {
+ private Ruby runtime;
+ private List<String> varNames;
+ private List<BiVariable> variables;
+ private VariableInterceptor interceptor;
+
+ /**
+ * Constructs an empy map. Users do not instantiate this map. The map is
created
+ * internally.
+ *
+ * @param runtime is environment where variables are used to execute
Ruby scripts.
+ */
+ public BiVariableMap(Ruby runtime) {
+ this(runtime, LocalVariableBehavior.TRANSIENT);
+ }
+
+
+ /**
+ * Constructs an empy map. Users do not instantiate this map. The map is
created
+ * internally.
+ *
+ * @param runtime is environment where variables are used to execute
Ruby scripts.
+ * @param behavior is one of variable behaviors defined in
VariableBehavior.
+ */
+ public BiVariableMap(Ruby runtime, LocalVariableBehavior behavior) {
+ this.runtime = runtime;
+ varNames = Collections.synchronizedList(new ArrayList<String>());
+ variables = Collections.synchronizedList(new
ArrayList<BiVariable>());
+ interceptor = new VariableInterceptor(behavior);
+ }
+
+ /**
+ * Returns a list of all names in this map.
+ *
+ * @return a List of all names.
+ */
+ public List<String> getNames() {
+ return varNames;
+ }
+
+ /**
+ * Returns a list of all values in this map.
+ *
+ * @return a List of all values.
+ */
+ public List<BiVariable> getVariables() {
+ return variables;
+ }
+
+ /**
+ * Returns a list of all values in this map.
+ *
+ * @return a List of all values.
+ */
+ public VariableInterceptor getVariableInterceptor() {
+ return interceptor;
+ }
+
+ /**
+ * Returns a map whose value is a Java object not a BiVariable type
object.
+ *
+ * @return a Map of key and value pair, in which values are simple Java
objects.
+ */
+ public Map getMap() {
+ Map m = new HashMap();
+ for (BiVariable v : variables) {
+ m.put(v.getName(), v.getJavaObject());
+ }
+ return m;
+ }
+
+ /**
+ * Returns the number of key-value mappings in this map.
+ *
+ * @return the number of key-value mappings in this map
+ */
+ public int size() {
+ return varNames.size();
+ }
+
+ /**
+ * Returns <tt>true</tt> if this map contains no key-value mappings.
+ *
+ * @return <tt>true</tt> if this map contains no key-value mappings
+ */
+ public boolean isEmpty() {
+ return varNames.isEmpty();
+ }
+
+ private void checkKey(Object key) {
+ if (key == null) {
+ throw new NullPointerException("key is null");
+ }
+ if (!(key instanceof String)) {
+ throw new ClassCastException("key is NOT String");
+ }
+ if (((String)key).length() == 0) {
+ throw new IllegalArgumentException("key is empty");
+ }
+ }
+
+ /**
+ * Returns <tt>true</tt> if this map contains a mapping for the specified
+ * key.
+ *
+ * @param key is a key to be tested its presense
+ * @return <tt>true</tt> if this map contains a mapping for the
specified key
+ */
+ public boolean containsKey(Object key) {
+ checkKey(key);
+ return varNames.contains((String)key);
+ }
+
+ /**
+ * Returns <tt>true</tt> if this map maps one or more keys to the
+ * specified value.
+ *
+ * @param value is a Java object to be tested it presense
+ * @return Returns <tt>true</tt> if this map maps one or more keys to the
+ * specified value.
+ */
+ public boolean containsValue(Object value) {
+ Iterator itr = variables.iterator();
+ while (itr.hasNext()) {
+ BiVariable v = (BiVariable)itr.next();
+ if (value == v.getJavaObject()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the value in simple Java object to which the specified key is
mapped,
+ * or {@code null} if this map contains no mapping for the key.
+ *
+ * @param key is the key whose associated value is to be returned
+ * @return the value in simple Java object to which the specified key is
mapped, or
+ * {@code null} if this map contains no mapping for the key
+ */
+ public V get(Object key) {
+ if (containsKey(key)) {
+ return (V)getVariable((String)key).getJavaObject();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value in BiVariable type to which the specified key is
mapped,
+ * or {@code null} if this map contains no mapping for the key.
+ *
+ * @param key is the key whose associated BiVariable object is to be
returned
+ * @return the BiVariable type object to which the specified key is
mapped, or
+ * {@code null} if this map contains no mapping for the key
+ */
+ public BiVariable getVariable(String key) {
+ if (containsKey(key)) {
+ int index = varNames.indexOf(key);
+ return variables.get(index);
+ } else {
+ return null;
+ }
+ }
+
+ public void setVariable(BiVariable var) {
+ if (var == null) {
+ return;
+ }
+ String key = var.getName();
+ BiVariable old = getVariable(key);
+ if (old != null) {
+ old.setJavaObject(runtime, var.getJavaObject());
+ } else {
+ varNames.add(key);
+ variables.add(var);
+ }
+ }
+
+ /**
+ * Associates the specified value with the specified key in this map.
+ * The values is a simple Java object. If the map previously contained a
mapping for
+ * the key, the old value is replaced by the specified value.
+ *
+ * @param key the key with which the specified value is to be associated
+ * @param value a simple Java object to be associated with the specified
key
+ * @return the previous value associated with <tt>key</tt>, or
+ * <tt>null</tt> if there was no mapping for <tt>key</tt>.
+ */
+ public V put (K key, V value) {
+ String name = (String)key;
+ BiVariable v = getVariable(name);
+ Object oldValue = null;
+ if (v != null) {
+ oldValue = v.getJavaObject();
+ v.setJavaObject(runtime, value);
+ } else {
+ v = interceptor.getVariableInstance(runtime, name, value);
+ if (v != null) {
+ varNames.add(name);
+ variables.add(v);
+ }
+ }
+ return (V)oldValue;
+ }
+
+ /**
+ * Returns Ruby's local variable names this map has. The returned array
is mainly
+ * used to inject local variables to Ruby scripts while parseing.
+ *
+ * @return String array of Ruby's local variable names
+ */
+ public String[] getLocalVarNames() {
+ List<String> localVarNames = new ArrayList<String>();
+ for (BiVariable v : variables) {
+ if (v.getType() == BiVariable.Type.LocalVariable) {
+ localVarNames.add(v.getName());
+ }
+ }
+ if (localVarNames.size() > 0) {
+ return localVarNames.toArray(new String[localVarNames.size()]);
+ }
+ return null;
+ }
+
+ /**
+ * Returns Ruby's local variable values this map has. The returned array
is
+ * mainly used to inject local variables to Ruby scripts while
evaluating.
+ *
+ * @return IRubyObject array of Ruby's local variable names.
+ */
+ public IRubyObject[] getLocalVarValues() {
+ List<IRubyObject> localVarValues = new ArrayList<IRubyObject>();
+ for (BiVariable v : variables) {
+ if (v.getType() == BiVariable.Type.LocalVariable) {
+ localVarValues.add(v.getRubyObject());
+ }
+ }
+ if (localVarValues.size() > 0) {
+ return localVarValues.toArray(new
IRubyObject[localVarValues.size()]);
+ }
+ return null;
+ }
+
+ void inject(ManyVarsDynamicScope scope, int depth, IRubyObject receiver)
{
+ interceptor.inject(this, runtime, scope, depth, receiver);
+ }
+
+ void retrieve(IRubyObject receiver) {
+ interceptor.retrieve(this, runtime, receiver);
+ }
+
+ void terminate() {
+ interceptor.terminateGlobalVariables(variables, runtime);
+ interceptor.terminateLocalVariables(varNames, variables);
+ }
+
+ /**
+ * Removes the mapping for a key from this map if it is present.
+ *
+ * <p>Returns the value to which this map previously associated the key,
+ * or <tt>null</tt> if the map contained no mapping for the key.
+
+ * @param key the key whose mapping is to be removed from the map
+ * @return the previous value associated with <tt>key</tt>, or
+ * <tt>null</tt> if there was no mapping for <tt>key</tt>.
+ */
+ public V remove(Object key) {
+ if (containsKey(key)) {
+ int index = varNames.indexOf(key);
+ varNames.remove(index);
+ BiVariable v = variables.remove(index);
+ v.remove(runtime);
+ return (V)v.getJavaObject();
+ }
+ return null;
+ }
+
+ /**
+ * Copies all of the mappings from the specified map to this map.
+ *
+ * @param t mappings to be stored in this map
+ */
+ public void putAll(Map<? extends K, ? extends V> t) {
+ if (t == null) {
+ throw new NullPointerException("map is null");
+ }
+ if (t.isEmpty()) {
+ throw new IllegalArgumentException("map is empty");
+ }
+ Set set = t.entrySet();
+ Iterator itr = set.iterator();
+ while (itr.hasNext()) {
+ Map.Entry entry = (Map.Entry)itr.next();
+ if (entry.getKey() instanceof String) {
+ K key = (K)entry.getKey();
+ V value = (V)entry.getValue();
+ put(key, value);
+ } else {
+ throw new ClassCastException("key is NOT String");
+ }
+ }
+ }
+
+ /**
+ * Removes all of the mappings from this map.
+ * The map will be empty after this call returns. Ruby variables are also
+ * remove from Ruby instance. However, Ruby instance keep having global
variable
+ * names with null value.
+ */
+ public void clear() {
+ varNames.clear();
+ for (BiVariable v : variables) {
+ if (v != null) {
+ v.remove(runtime);
+ }
+ }
+ variables.clear();
+ }
+
+ /**
+ * Returns a {@link Set} view of the keys contained in this map.
+ * The set is backed by the map, so changes to the map should be
+ * reflected in the set, and vice-versa. However, the implementation
+ * does not reflect changes currently.
+ *
+ * @return a set view of the keys contained in this map
+ */
+ public Set keySet() {
+ if (varNames.isEmpty()) {
+ return null;
+ }
+ Set s = new HashSet();
+ for (String name : varNames) {
+ s.add(name);
+ }
+ return s;
+ }
+
+ /**
+ * Returns a {@link Collection} view of the values contained in this map.
+ * The collection is backed by the map, so changes to the map should be
+ * reflected in the collection, and vice-versa. However, the
implementation
+ * does not reflect changes currently.
+ *
+ * @return a collection view of the values contained in this map
+ */
+ public Collection values() {
+ // should be vice-versa, but currently NOT
+ if (varNames.isEmpty()) {
+ return null;
+ }
+ List l = new ArrayList();
+ for (BiVariable v : variables) {
+ l.add(v.getJavaObject());
+ }
+ return l;
+ }
+
+ /**
+ * Returns a {@link Set} view of the mappings contained in this map.
+ * The set is backed by the map, so changes to the map should be
+ * reflected in the set, and vice-versa. However, the implementation
+ * does not reflect changes currently.
+ *
+ * @return an entry set of a map
+ */
+ public Set entrySet() {
+ if (varNames.isEmpty()) {
+ return null;
+ }
+ return getMap().entrySet();
+ }
+
+ /**
+ * Adds a key-value pair of Ruby local variable to double array.
+ *
+ * @param name is a Ruby's local variable name
+ * @param value is BiVariable type object corresponding to the name
+ */
+ public void update(String name, BiVariable value) {
+ this.varNames.add(name);
+ this.variables.add(value);
+ }
+}
diff --git a/src/org/jruby/embed/EmbedRubyObjectAdapter.java
b/src/org/jruby/embed/EmbedRubyObjectAdapter.java
new file mode 100644
index 0000000..bde6111
--- /dev/null
+++ b/src/org/jruby/embed/EmbedRubyObjectAdapter.java
@@ -0,0 +1,152 @@
+/**
+ * **** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2009 Yoko Harada <yokolet@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the
"LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ * **** END LICENSE BLOCK *****
+ */
+package org.jruby.embed;
+
+import org.jruby.RubyObjectAdapter;
+import org.jruby.javasupport.JavaEmbedUtils.EvalUnit;
+import org.jruby.runtime.Block;
+
+/**
+ * Wrapper interface of RubyObjectAdapter for embedding. Methods' arguments
can have
+ * simple Java objects for easiness. Each methods converts returned object
+ * to a Java type specifed in the argumnet.
+ *
+ * @author Yoko Harada <yokolet@gmail.com>
+ */
+public interface EmbedRubyObjectAdapter extends RubyObjectAdapter {
+ /**
+ * Executes a method defined in Ruby script. This method is used when a
Ruby
+ * method does not have any argument.
+ *
+ * @param receiver is an instance that will receive this method call
+ * @param methodName is a method name to be called
+ * @param returnType is the type we want it to convert to
+ * @return an instance of requested Java type
+ */
+ <T> T callMethod(Object receiver, String methodName, Class<T>
returnType);
+
+ /**
+ * Executes a method defined in Ruby script. This method is used when a
Ruby
+ * method have only one argument.
+ *
+ * @param receiver is an instance that will receive this method call
+ * @param methodName is a method name to be called
+ * @param singleArg is an method argument
+ * @param returnType returnType is the type we want it to convert to
+ * @return an instance of requested Java type
+ */
+ <T> T callMethod(Object receiver, String methodName, Object singleArg,
Class<T> returnType);
+
+ /**
+ * Executes a method defined in Ruby script. This method is used when a
Ruby
+ * method have multiple arguments.
+ *
+ * @param receiver is an instance that will receive this method call
+ * @param methodName is a method name to be called
+ * @param args is an array of method arguments
+ * @param returnType is the type we want it to convert to
+ * @return an instance of requested Java type
+ */
+ <T> T callMethod(Object receiver, String methodName, Object[] args,
Class<T> returnType);
+
+ /**
+ * Executes a method defined in Ruby script. This method is used when a
Ruby
+ * method have multiple arguments, one of which is a block.
+ *
+ * @param receiver is an instance that will receive this method call
+ * @param methodName is a method name to be called
+ * @param args is an array of method arguments except a block
+ * @param block is a block to be executed in this method
+ * @param returnType is the type we want it to convert to
+ * @return an instance of requested Java type
+ */
+ <T> T callMethod(Object receiver, String methodName, Object[] args,
Block block, Class<T> returnType);
+
+ /**
+ * Executes a method defined in Ruby script. This method is used when a
Ruby
+ * method does not have any argument, and users want to inject Ruby's
local
+ * variables' values from Java.
+ *
+ * @param receiver is an instance that will receive this method call
+ * @param methodName is a method name to be called
+ * @param returnType is the type we want it to convert to
+ * @param unit is parsed unit
+ * @return an instance of requested Java type
+ */
+ <T> T callMethod(Object receiver, String methodName, Class<T>
returnType, EvalUnit unit);
+
+ /**
+ * Executes a method defined in Ruby script. This method is used when a
Ruby
+ * method have multiple arguments, and users want to inject Ruby's local
+ * variables' values from Java.
+ *
+ * @param receiver is an instance that will receive this method call
+ * @param methodName is a method name to be calleid
+ * @param args is an array of method arguments
+ * @param returnType is the type we want it to convert to
+ * @param unit is parsed unit
+ * @return an instance of requested Java type
+ */
+ <T> T callMethod(Object receiver, String methodName, Object[] args,
Class<T> returnType, EvalUnit unit);
+
+ /**
+ * Executes a method defined in Ruby script. This method is used when a
Ruby
+ * method have multiple arguments, one of which is a block, and users
want to
+ * inject Ruby's local variables' values from Java.
+ *
+ * @param receiver is an instance that will receive this method call
+ * @param methodName is a method name to be calleid
+ * @param args is an array of method arguments except a block
+ * @param block is a block to be executed in this method
+ * @param returnType is the type we want it to convert to
+ * @param unit is parsed unit
+ * @return is the type we want it to convert to
+ */
+ <T> T callMethod(Object receiver, String methodName, Object[] args,
Block block, Class<T> returnType, EvalUnit unit);
+
+ /**
+ *
+ * @param receiver is an instance that will receive this method call
+ * @param args is an array of method arguments
+ * @param returnType is the type we want it to convert to
+ * @return is the type we want it to convert to
+ */
+ <T> T callSuper(Object receiver, Object[] args, Class<T> returnType);
+
+ /**
+ *
+ * @param receiver is an instance that will receive this method call
+ * @param args is an array of method arguments except a block
+ * @param block is a block to be executed in this method
+ * @param returnType is the type we want it to convert to
+ * @return is the type we want it to convert to
+ */
+ <T> T callSuper(Object receiver, Object[] args, Block block, Class<T>
returnType);
+}
diff --git a/src/org/jruby/embed/EmbedRubyObjectAdapterImpl.java
b/src/org/jruby/embed/EmbedRubyObjectAdapterImpl.java
new file mode 100644
index 0000000..cc0e9f7
--- /dev/null
+++ b/src/org/jruby/embed/EmbedRubyObjectAdapterImpl.java
@@ -0,0 +1,371 @@
+/**
+ * **** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2009 Yoko Harada <yokolet@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the
"LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ * **** END LICENSE BLOCK *****
+ */
+package org.jruby.embed;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.Method;
+import org.jruby.Ruby;
+import org.jruby.RubyException;
+import org.jruby.RubyInteger;
+import org.jruby.RubyModule;
+import org.jruby.RubyObjectAdapter;
+import org.jruby.RubyString;
+import org.jruby.embed.internal.CallMethodType;
+import org.jruby.embed.variable.InstanceVariable;
+import org.jruby.exceptions.RaiseException;
+import org.jruby.javasupport.Java;
+import org.jruby.javasupport.JavaEmbedUtils;
+import org.jruby.javasupport.JavaEmbedUtils.EvalUnit;
+import org.jruby.javasupport.JavaObject;
+import org.jruby.javasupport.JavaUtil;
+import org.jruby.javasupport.util.RuntimeHelpers;
+import org.jruby.runtime.Block;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.scope.ManyVarsDynamicScope;
+
+/**
+ * Implementation of {@link EmbedRubyObjectAdapter}. Users get an instance
of this
+ * class by newObjectAdapter() method of {@link ScriptingContainer}.
+ *
+ * @author Yoko Harada <yokolet@gmail.com>
+ */
+class EmbedRubyObjectAdapterImpl implements EmbedRubyObjectAdapter {
+ private RubyObjectAdapter adapter = JavaEmbedUtils.newObjectAdapter();
+ private ScriptingContainer container;
+
+ EmbedRubyObjectAdapterImpl(ScriptingContainer container) {
+ this.container = container;
+ }
+
+ public boolean isKindOf(IRubyObject value, RubyModule rubyModule) {
+ return adapter.isKindOf(value, rubyModule);
+ }
+
+ public IRubyObject[] convertToJavaArray(IRubyObject array) {
+ return adapter.convertToJavaArray(array);
+ }
+
+ public RubyInteger convertToRubyInteger(IRubyObject obj) {
+ return adapter.convertToRubyInteger(obj);
+ }
+
+ public RubyString convertToRubyString(IRubyObject obj) {
+ return adapter.convertToRubyString(obj);
+ }
+
+ public synchronized IRubyObject setInstanceVariable(IRubyObject obj,
String variableName, IRubyObject value) {
+ BiVariableMap map = container.getVarMap();
+ Ruby runtime = container.getRuntime();
+ if (map.containsKey(variableName)) {
+ BiVariable bv = map.getVariable(variableName);
+ bv.setRubyObject(obj);
+ } else {
+ InstanceVariable iv = new InstanceVariable(variableName, value);
+ map.update(variableName, iv);
+ }
+ return obj.getInstanceVariables().setInstanceVariable(variableName,
value);
+ }
+
+ public IRubyObject getInstanceVariable(IRubyObject obj, String
variableName) {
+ BiVariableMap map = container.getVarMap();
+ if (map.containsKey(variableName)) {
+ BiVariable bv = map.getVariable(variableName);
+ return bv.getRubyObject();
+ }
+ return null;
+ }
+
+ public IRubyObject callMethod(IRubyObject receiver, String methodName) {
+ return adapter.callMethod(receiver, methodName);
+ }
+
+ public IRubyObject callMethod(IRubyObject receiver, String methodName,
IRubyObject singleArg) {
+ return adapter.callMethod(receiver, methodName, singleArg);
+ }
+
+ public IRubyObject callMethod(IRubyObject receiver, String methodName,
IRubyObject[] args) {
+ return adapter.callMethod(receiver, methodName, args);
+ }
+
+ public IRubyObject callMethod(IRubyObject receiver, String methodName,
IRubyObject[] args, Block block) {
+ return adapter.callMethod(receiver, methodName, args, block);
+ }
+
+ public IRubyObject callSuper(IRubyObject receiver, IRubyObject[] args) {
+ return adapter.callSuper(receiver, args);
+ }
+
+ public IRubyObject callSuper(IRubyObject receiver, IRubyObject[] args,
Block block) {
+ return adapter.callSuper(receiver, args, block);
+ }
+
+ @CallMethodType(methodType=0)
+ public <T> T callMethod(Object receiver, String methodName, Class<T>
returnType) {
+ Class[] params = {Object.class, String.class, Class.class};
+ Method method;
+ try {
+ method = getClass().getMethod("callMethod", params);
+ return call(returnType, method, receiver, methodName, null,
null, new Object[]{});
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ @CallMethodType(methodType=1)
+ public <T> T callMethod(Object receiver, String methodName, Object
singleArg, Class<T> returnType) {
+ Class[] params = {Object.class, String.class, Object.class,
Class.class};
+ Method method;
+ try {
+ method = getClass().getMethod("callMethod", params);
+ return call(returnType, method, receiver, methodName, null,
null, singleArg);
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ @CallMethodType(methodType=2)
+ public <T> T callMethod(Object receiver, String methodName, Object[]
args, Class<T> returnType) {
+ Class[] params = {Object.class, String.class, Object[].class,
Class.class};
+ Method method;
+ try {
+ method = getClass().getMethod("callMethod", params);
+ return call(returnType, method, receiver, methodName, null,
null, args);
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ @CallMethodType(methodType=3)
+ public <T> T callMethod(Object receiver, String methodName, Object[]
args, Block block, Class<T> returnType) {
+ Class[] params = {Object.class, String.class,Object[].class,
Block.class, Class.class};
+ Method method;
+ try {
+ method = getClass().getMethod("callMethod", params);
+ return call(returnType, method, receiver, methodName, block,
null, args);
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ @CallMethodType(methodType=4)
+ public <T> T callMethod(Object receiver, String methodName, Class<T>
returnType, EvalUnit unit) {
+ Class[] params = {Object.class, String.class, Class.class,
EvalUnit.class};
+ Method method;
+ try {
+ method = getClass().getMethod("callMethod", params);
+ return call(returnType, method, receiver, methodName, null,
unit, new Object[]{});
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ @CallMethodType(methodType=5)
+ public <T> T callMethod(Object receiver, String methodName, Object[]
args, Class<T> returnType, EvalUnit unit) {
+ Class[] params = {Object.class, String.class,Object[].class,
Class.class, EvalUnit.class};
+ Method method;
+ try {
+ method = getClass().getMethod("callMethod", params);
+ return call(returnType, method, receiver, methodName, null,
unit, args);
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ @CallMethodType(methodType=6)
+ public <T> T callMethod(Object receiver, String methodName, Object[]
args, Block block, Class<T> returnType, EvalUnit unit) {
+ Class[] params = {Object.class, String.class,Object[].class,
Block.class, Class.class, EvalUnit.class};
+ Method method;
+ try {
+ method = getClass().getMethod("callMethod", params);
+ return call(returnType, method, receiver, methodName, block,
unit, args);
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ @CallMethodType(methodType=7)
+ public <T> T callSuper(Object receiver, Object[] args, Class<T>
returnType) {
+ Class[] params = {Object.class, Object[].class, Class.class};
+ Method method;
+ try {
+ method = getClass().getMethod("callSuper", params);
+ return call(returnType, method, receiver, null, null, null,
args);
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ @CallMethodType(methodType=8)
+ public <T> T callSuper(Object receiver, Object[] args, Block block,
Class<T> returnType) {
+ Class[] params = {Object.class, Object[].class, Block.class,
Class.class};
+ Method method;
+ try {
+ method = getClass().getMethod("callSuper", params);
+ return call(returnType, method, receiver, null, block, null,
args);
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ private <T> T call(Class<T> returnType, Method method, Object receiver,
String methodName, Block block, EvalUnit unit, Object... args) {
+ if (methodName == null || methodName.length()==0) {
+ return null;
+ }
+ Ruby runtime = container.getRuntime();
+ IRubyObject rubyReceiver = receiver != null ?
JavaUtil.convertJavaToRuby(runtime, receiver) : runtime.getTopSelf();
+ try {
+ ManyVarsDynamicScope scope = unit != null ? unit.getScope() :
null;
+ container.getVarMap().inject(scope, 0, rubyReceiver);
+ runtime.getCurrentContext().pushScope(scope);
+ IRubyObject result = callEachType(method, rubyReceiver,
methodName, block, args);
+ Object ret = JavaEmbedUtils.rubyToJava(runtime, result,
returnType);
+ container.getVarMap().retrieve(rubyReceiver);
+ return ret != null ? returnType.cast(ret) : null;
+ } catch (RaiseException e) {
+ RubyException re = e.getException();
+ runtime.printError(re);
+ throw new RuntimeException(e);
+ } catch (Exception e) {
+ try {
+ PrintWriter w = (PrintWriter)container.getErrorWriter();
+ e.printStackTrace(w);
+ container.getErrorWriter().write(e.getMessage());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ } finally {
+ runtime.getCurrentContext().popScope();
+ JavaEmbedUtils.terminate(runtime);
+ }
+ }
+
+ private IRubyObject callEachType(Method method, IRubyObject
rubyReceiver, String methodName, Block block, Object... args) {
+ Ruby runtime = rubyReceiver.getRuntime();
+ IRubyObject[] rubyArgs = null;
+ if (args != null && args.length > 0) {
+ rubyArgs = JavaUtil.convertJavaArrayToRuby(runtime, args);
+ for (int i = 0; i < rubyArgs.length; i++) {
+ IRubyObject obj = rubyArgs[i];
+ if (obj instanceof JavaObject) {
+ rubyArgs[i] = Java.wrap(runtime, obj);
+ }
+ }
+ }
+ ThreadContext context = runtime.getCurrentContext();
+ CallMethodType type = method.getAnnotation(CallMethodType.class);
+ if (type != null) {
+ switch (type.methodType()) {
+ case 0:
+ case 4:
+ return RuntimeHelpers.invoke(context, rubyReceiver,
methodName);
+ case 1:
+ case 2:
+ case 5:
+ return RuntimeHelpers.invoke(context, rubyReceiver,
methodName, rubyArgs);
+ case 3:
+ case 6:
+ return RuntimeHelpers.invoke(context, rubyReceiver,
methodName, rubyArgs, block);
+ case 7:
+ return RuntimeHelpers.invokeSuper(context, rubyReceiver,
rubyArgs, Block.NULL_BLOCK);
+ case 9:
+ return RuntimeHelpers.invokeSuper(context, rubyReceiver,
rubyArgs, block);
+ default:
+ break;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/org/jruby/embed/EvalUnitWrapper.java
b/src/org/jruby/embed/EvalUnitWrapper.java
new file mode 100644
index 0000000..c2fa891
--- /dev/null
+++ b/src/org/jruby/embed/EvalUnitWrapper.java
@@ -0,0 +1,142 @@
+/**
+ * **** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2009 Yoko Harada <yokolet@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the
"LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ * **** END LICENSE BLOCK *****
+ */
+package org.jruby.embed;
+
+import java.io.PrintWriter;
+import org.jruby.Ruby;
+import org.jruby.RubyException;
+import org.jruby.RubyInstanceConfig.CompileMode;
+import org.jruby.ast.Node;
+import org.jruby.ast.executable.Script;
+import org.jruby.exceptions.RaiseException;
+import org.jruby.javasupport.JavaEmbedUtils;
+import org.jruby.javasupport.JavaEmbedUtils.EvalUnit;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.scope.ManyVarsDynamicScope;
+
+/**
+ * Implementation of org.jruby.javasupport.JavaEmbedUtils.EvalUnit for
Embeddiing.
+ * This class is created when a Ruby script has been parsed. Once parsed,
the script
+ * is ready to run many times without parsing.
+ *
+ * <p>Users do not instantiate explicitly. Instead, they can get the
instance by parsing
+ * Ruby script by parse method of {@link ScriptingContainer}.
+ *
+ * @author Yoko Harada <yokolet@gmail.com>
+ */
+public class EvalUnitWrapper implements EvalUnit {
+ private EvalUnit unit;
+ private Script script;
+ private ScriptingContainer container;
+
+ EvalUnitWrapper(ScriptingContainer container, EvalUnit unit) {
+ this(container, unit, null);
+ }
+
+ EvalUnitWrapper(ScriptingContainer container, EvalUnit unit, Script
script) {
+ this.container = container;
+ this.unit = unit;
+ this.script = script;
+ }
+
+ /**
+ * Returns environment used to parse a Ruby script
+ *
+ * @return Ruby instance, which was used to parse Ruby script
+ */
+ public Ruby getRuntime() {
+ return unit.getRuntime();
+ }
+
+ /**
+ * Returns a root node of parsed Ruby script.
+ *
+ * @return a root node of parsed Ruby script
+ */
+ public Node getNode() {
+ return unit.getNode();
+ }
+
+ /**
+ * Returns a ManyVarsDynamicScope used to parse a script. A returned
value
+ * is used to inject Ruby's local variable when script is evaluated.
+ *
+ * @return a scope to refer local variables
+ */
+ public ManyVarsDynamicScope getScope() {
+ return unit.getScope();
+ }
+
+ /**
+ * Evaluates a Ruby script, which has been parsed before.
+ *
+ * @return results of executing this evaluation unit
+ */
+ public IRubyObject run() {
+ if (unit.getNode() == null && script == null) {
+ return null;
+ }
+ BiVariableMap vars = container.getVarMap();
+ ManyVarsDynamicScope scope = unit.getScope();
+ try {
+ vars.inject(scope, 0, null);
+
container.getRuntime().getCurrentContext().pushScope(unit.getScope());
+ IRubyObject ret;
+ CompileMode mode =
container.getRuntime().getInstanceConfig().getCompileMode();
+ if (mode == Compi
[truncated due to length]
|
[redbridge~redbridge:d031959c] integrating three projects, embed API, jsr223, and bsf |
yokolet | 09/12/2009 |





