[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
  • Mysql
  • Glassfish
  • Jruby
  • Rails
  • Nblogo
Terms of Use; Privacy Policy;
© 2010, Oracle Corporation and/or its affiliates
(revision 20120518.3c65429)
 
 
Close
loading
Please Confirm
Close