Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: EPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Eclipse 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/epl-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) 2001 Alan Moore <alan_moore@gmx.net> Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de> Copyright (C) 2002 Anders Bengtsson <ndrsbngtssn@yahoo.se> Copyright (C) 2002 Benoit Cerrina <b.cerrina@wanadoo.fr> Copyright (C) 2002 Don Schwartz <schwardo@users.sourceforge.net> Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de> Copyright (C) 2006 Kresten Krab Thorup <krab@gnu.org> 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 EPL, 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 EPL, the GPL or the LGPL. END LICENSE BLOCK ***
  
  package org.jruby.javasupport;
  
  import static java.lang.Character.isLetter;
  import static java.lang.Character.isLowerCase;
  import static java.lang.Character.isUpperCase;
  import static java.lang.Character.isDigit;
  import static java.lang.Character.toLowerCase;
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import java.util.Set;
  import org.jruby.Ruby;
  import org.jruby.RubyNil;
  
  
  public class JavaUtil {
  
      public static final boolean CAN_SET_ACCESSIBLE;
  
      static {
          boolean canSetAccessible = false;
  
          if (.) {
             try {
                 AccessController.checkPermission(new ReflectPermission("suppressAccessChecks"));
                 canSetAccessible = true;
             } catch (Throwable t) {
                 // added this so if things are weird in the future we can debug without
                 // spinning a new binary
                 if (..load()) {
                     t.printStackTrace();
                 }
 
                 // assume any exception means we can't suppress access checks
                 canSetAccessible = false;
             }
         }
 
          = canSetAccessible;
     }
 
     public static IRubyObject[] convertJavaArrayToRuby(final Ruby runtimefinal Object[] objects) {
         if ( objects == null ) return .;
 
         IRubyObject[] rubyObjects = new IRubyObject[objects.length];
         for (int i = 0; i < objects.lengthi++) {
             rubyObjects[i] = convertJavaToUsableRubyObject(runtimeobjects[i]);
         }
         return rubyObjects;
     }
 
     public static RubyArray convertJavaArrayToRubyWithNesting(final ThreadContext contextfinal Object array) {
         final int length = Array.getLength(array);
         final RubyArray outer = context.runtime.newArray(length);
         for ( int i = 0; i < lengthi++ ) {
             final Object element = Array.get(arrayi);
             if ( element instanceof ArrayJavaProxy ) {
                 outer.appendconvertJavaArrayToRubyWithNesting(context, ((ArrayJavaProxyelement).getObject()) );
             }
             else if ( element != null && element.getClass().isArray() ) {
                 outer.appendconvertJavaArrayToRubyWithNesting(contextelement) );
             }
             else {
                 outer.appendconvertJavaToUsableRubyObject(context.runtimeelement) );
             }
         }
         return outer;
     }
 
     public static JavaConverter getJavaConverter(Class clazz) {
         final JavaConverter converter = .get(clazz);
         return converter == null ?  : converter;
     }
 
     public static IRubyObject convertJavaToRuby(Ruby runtimeObject object) {
         return convertJavaToUsableRubyObject(runtimeobject);
     }
 
     public static IRubyObject convertJavaToRuby(Ruby runtimeObject objectClass javaClass) {
         return convertJavaToUsableRubyObjectWithConverter(runtimeobjectgetJavaConverter(javaClass));
     }
 
     public static IRubyObject convertJavaToRuby(Ruby runtimeint i) {
         return runtime.newFixnum(i);
     }
 
     public static IRubyObject convertJavaToRuby(Ruby runtimelong l) {
         return runtime.newFixnum(l);
     }
 
     public static IRubyObject convertJavaToRuby(Ruby runtimefloat f) {
         return runtime.newFloat(f);
     }
 
     public static IRubyObject convertJavaToRuby(Ruby runtimedouble d) {
         return runtime.newFloat(d);
     }
 
     public static IRubyObject convertJavaToRuby(Ruby runtimeboolean b) {
         return runtime.newBoolean(b);
     }

    
Returns a usable RubyObject; for types that are not converted to Ruby native types, a Java proxy will be returned.

Parameters:
runtime
object
Returns:
corresponding Ruby type, or a functional Java proxy
 
     public static IRubyObject convertJavaToUsableRubyObject(Ruby runtimeObject object) {
         IRubyObject result = trySimpleConversions(runtimeobject);
 
         if (result != nullreturn result;
 
         JavaConverter converter = getJavaConverter(object.getClass());
         if (converter == null || converter == ) {
             return Java.getInstance(runtimeobject);
         }
         return converter.convert(runtimeobject);
     }
 
     public static IRubyObject convertJavaToUsableRubyObjectWithConverter(Ruby runtimeObject objectJavaConverter converter) {
         IRubyObject result = trySimpleConversions(runtimeobject);
 
         if (result != nullreturn result;
 
         if (converter == null || converter == ) {
             return Java.getInstance(runtimeobject);
         }
         return converter.convert(runtimeobject);
     }
 
     public static IRubyObject convertJavaArrayElementToRuby(Ruby runtimeJavaConverter converterObject arrayint i) {
         if (converter == null || converter == ) {
             IRubyObject x = convertJavaToUsableRubyObject(runtime, ((Object[])array)[i]);
             return x;
         }
         return converter.get(runtimearrayi);
     }
 
     public static Class<?> primitiveToWrapper(final Class<?> type) {
         if (type.isPrimitive()) {
             return CodegenUtils.getBoxType(type);
         }
         return type;
     }
 
     @SuppressWarnings("unchecked")
     public static boolean isDuckTypeConvertable(Class providedArgumentTypeClass parameterType) {
         return parameterType.isInterface() &&
                 ! parameterType.isAssignableFrom(providedArgumentType) &&
                     RubyObject.class.isAssignableFrom(providedArgumentType);
     }
 
     public static Object convertProcToInterface(ThreadContext contextRubyObject rubyObjectClass target) {
         return convertProcToInterface(context, (RubyBasicObjectrubyObjecttarget);
     }
 
     public static Object convertProcToInterface(ThreadContext contextRubyBasicObject rubyObjectClass target) {
         final Ruby runtime = context.runtime;
 
         final RubyModule ifaceModule = Java.getInterfaceModule(runtime, JavaClass.get(runtimetarget));
         if ( ! ifaceModule.isInstance(rubyObject) ) {
             ifaceModule.callMethod(context"extend_object"rubyObject);
             ifaceModule.callMethod(context"extended"rubyObject);
         }
 
         if ( rubyObject instanceof RubyProc ) {
             // Proc implementing an interface, pull in the catch-all code that lets the proc get invoked
             // no matter what method is called on the interface
             final RubyClass singletonClass = rubyObject.getSingletonClass();
             singletonClass.addMethod("method_missing"new Java.ProcToInterface(singletonClass));
         }
         JavaObject javaObject = (JavaObject) Helpers.invoke(contextrubyObject"__jcreate_meta!");
         return javaObject.getValue();
     }
 
     public static NumericConverter getNumericConverter(Class target) {
         final NumericConverter converter = .get(target);
         return converter == null ?  : converter;
     }

    
Test if a passed instance is a wrapper Java object.

Parameters:
object
Returns:
true if the object is wrapping a Java object
 
     public static boolean isJavaObject(final IRubyObject object) {
         return object instanceof JavaProxy || object.dataGetStruct() instanceof JavaObject;
     }

    
Unwrap a wrapped Java object.

Parameters:
object
Returns:
Java object
See also:
isJavaObject(org.jruby.runtime.builtin.IRubyObject)
 
     public static Object unwrapJavaObject(final IRubyObject object) {
         if ( object instanceof JavaProxy ) {
             return ((JavaProxyobject).getObject();
         }
         return ((JavaObjectobject.dataGetStruct()).getValue();
     }
 
     @Deprecated // no longer used
     public static Object unwrapJavaValue(final Ruby runtimefinal IRubyObject objectfinal String errorMessage) {
         if ( object instanceof JavaProxy ) {
             return ((JavaProxyobject).getObject();
         }
         if ( object instanceof JavaObject ) {
             return ((JavaObjectobject).getValue();
         }
         final Object unwrap = object.dataGetStruct();
         if ( unwrap != null && unwrap instanceof IRubyObject ) {
             return unwrapJavaValue(runtime, (IRubyObjectunwraperrorMessage);
         }
         throw runtime.newTypeError(errorMessage);
     }

    

Parameters:
object
Returns:
unwrapped Java (object's) value
Note:
Returns null if not a wrapped Java value.
 
     public static Object unwrapJavaValue(final IRubyObject object) {
         if ( object instanceof JavaProxy ) {
             return ((JavaProxyobject).getObject();
         }
         if ( object instanceof JavaObject ) {
             return ((JavaObjectobject).getValue();
         }
         final Object unwrap = object.dataGetStruct();
         if ( unwrap != null && unwrap instanceof IRubyObject ) {
             return unwrapJavaValue((IRubyObjectunwrap);
         }
         return null;
     }

    
For methods that match /(get|set|is)([A-Z0-9])(.*)/, return the "name" part of the property with leading lower-case.

Parameters:
beanMethodName the bean method from which to extract a name
Returns:
the bean property name (or null)
Note:
Does not use regular expression for performance reasons.
 
     public static String getJavaPropertyName(final String beanMethodName) {
         final int length = beanMethodName.length(); char ch;
         final boolean maybeGetOrSet = length > 3 && beanMethodName.charAt(2) == 't';
         if ( maybeGetOrSet && ( beanMethodName.startsWith("get") || beanMethodName.startsWith("set") ) ) {
             if (isUpperDigit(ch = beanMethodName.charAt(3))) {
                 if ( length == 4 ) return Character.toString(toLowerCase(ch));
                 return "" + toLowerCase(ch) + beanMethodName.substring(4);
             }
         }
         else if ( beanMethodName.startsWith("is") && length > 2 ) {
             if (isUpperDigit(ch = beanMethodName.charAt(2))) {
                 if ( length == 3 ) return Character.toStringtoLowerCase(ch) );
                 return "" + toLowerCase(ch) + beanMethodName.substring(3);
             }
         }
         return null;
     }

    
Build a Ruby name from a Java name by treating '_' as divider and successive caps as all the same word.

Parameters:
javaCasedName
Returns:
Ruby (under-score) cased named e.g. "get_foo_bar"
 
     public static String getRubyCasedName(final String javaCasedName) {
         final char[] javaName = javaCasedName.toCharArray();
         final int len = javaName.length;
         final StringBuilder rubyName = new StringBuilder(len + 8);
 
         int behind = 0;
         for (int i = 0; i < leni++) {
             if ( behind < 2 ) behind++;
             else behind = consume(rubyNamejavaNamei);
         }
 
         if (behind == 2) {
             final char c1 = javaName[len - 1], c2 = javaName[len - 2];
             rubyName.appendtoLowerCasec2 ) );
             if ( isUpperCasec1 ) && ! isUpperCasec2 ) ) rubyName.append('_');
             rubyName.appendtoLowerCasec1 ) );
         }
         else if (behind > 0) {
             if ( behind > 1 ) {
                 rubyName.appendtoLowerCasejavaName[len - 2] ) );
             }
             rubyName.appendtoLowerCasejavaName[len - 1] ) );
         }
         return rubyName.toString();
     }
 
     private static int consume(final StringBuilder rubyNamefinal char[] javaNameint i) {
         final char prev1 = javaName[i - 1], prev2 = javaName[i - 2];
         if ( isLowerDigitprev2 ) && isUpperCaseprev1 ) ) {
             rubyName.appendprev2 ).append('_').appendtoLowerCase(prev1) );
             return 1;
         }
         char cur;
         if ( isLetterDigitprev2 ) && isUpperCaseprev1 ) && isLowerCasecur = javaName[i] )) {
             rubyName.appendtoLowerCase(prev2) ).append('_').appendtoLowerCase(prev1) ).append(cur);
             return 0;
         }
         rubyName.appendtoLowerCase(prev2) );
         return 2;
     }
 
     private static boolean isUpperDigit(char c) {
         return isUpperCase(c) || isDigit(c);
     }
     private static boolean isLowerDigit(char c) {
         return isLowerCase(c) || isDigit(c);
     }
     private static boolean isLetterDigit(char c) {
         return isLetter(c) || isDigit(c);
     }
 
     private static final Pattern RUBY_CASE_SPLITTER = Pattern.compile("([a-z][0-9]*)_([a-z])");
     public static String getJavaCasedName(String javaCasedName) {
         Matcher m = .matcher(javaCasedName);
         StringBuffer newName = new StringBuffer();
         if (!m.find()) {
             return null;
         }
         m.reset();
 
         while (m.find()) {
             m.appendReplacement(newNamem.group(1) + Character.toUpperCase(m.group(2).charAt(0)));
         }
 
         m.appendTail(newName);
 
         return newName.toString();
     }

    
Given a simple Java method name and the Java Method objects that represent all its overloads, add to the given nameSet all possible Ruby names that would be valid.

Parameters:
javaName
methods
Returns:
method names
 
     public static Set<StringgetRubyNamesForJavaName(final String javaNamefinal List<Methodmethods) {
         final String javaPropertyName = getJavaPropertyName(javaName);
         final String rubyName = getRubyCasedName(javaName);
 
         final int len = methods.size();
 
         final LinkedHashSet<StringnameSet = new LinkedHashSet<String>(6 * len + 2, 1f); // worse-case 6
         nameSet.add(javaName);
         nameSet.add(rubyName);
 
         if ( len == 1 ) { // hot-path - most of the time no-overloads for a given method name
             addRubyNamesForJavaName(javaNamemethods.get(0), javaPropertyNamerubyNamenameSet);
         }
         else {
             for ( int i = 0; i < leni++ ) { // passed list is ArrayList
                 addRubyNamesForJavaName(javaNamemethods.get(i), javaPropertyNamerubyNamenameSet);
             }
         }
         return nameSet;
     }
 
     private static void addRubyNamesForJavaName(final String javaNamefinal Method method,
         final String javaPropertyNamefinal String rubyNamefinal LinkedHashSet<StringnameSet) {
         final Class<?> resultType = method.getReturnType();
 
         // Add property name aliases
         if (javaPropertyName != null) {
             final Class<?>[] argTypes = method.getParameterTypes();
             final int argCount = argTypes.length;
             // string starts-with "get_" or "set_" micro-optimization :
             final boolean maybeGetOrSet_ = rubyName.length() > 3 && rubyName.charAt(3) == '_';
 
             if (maybeGetOrSet_ && rubyName.startsWith("get")) { // rubyName.startsWith("get_")
                 if (argCount == 0 ||                                // getFoo      => foo
                     argCount == 1 && argTypes[0] == int.class) {    // getFoo(int) => foo(int)
                     final String rubyPropertyName = rubyName.substring(4);
                     nameSet.add(javaPropertyName);
                     nameSet.add(rubyPropertyName);
                     if (resultType == boolean.class) {              // getFooBar() => fooBar?, foo_bar?(*)
                         nameSet.add(javaPropertyName + '?');
                         nameSet.add(rubyPropertyName + '?');
                     }
                 }
             }
             else if (maybeGetOrSet_ && rubyName.startsWith("set")) { // rubyName.startsWith("set_")
                 if (argCount == 1 && resultType == void.class) {    // setFoo(Foo) => foo=(Foo)
                     final String rubyPropertyName = rubyName.substring(4);
                     nameSet.add(javaPropertyName + '=');
                     nameSet.add(rubyPropertyName + '=');
                 }
             }
             else if (rubyName.startsWith("is_")) {
                 if (resultType == boolean.class) {                  // isFoo() => foo, isFoo(*) => foo(*)
                     final String rubyPropertyName = rubyName.substring(3);
                     nameSet.add(javaPropertyName);
                     nameSet.add(rubyPropertyName);
                     nameSet.add(javaPropertyName + '?');
                     nameSet.add(rubyPropertyName + '?');
                 }
             }
         } else {
             // If not a property, but is boolean add ?-postfixed aliases.
             if (resultType == boolean.class) {
                 // is_something?, contains_thing?
                     nameSet.add(javaName + '?');
                     nameSet.add(rubyName + '?');
             }
         }
     }
 
     public static abstract class JavaConverter {
         private final Class type;
         public JavaConverter(Class type) {this. = type;}
         public abstract IRubyObject convert(Ruby runtimeObject object);
         public abstract IRubyObject get(Ruby runtimeObject arrayint i);
         public abstract void set(Ruby runtimeObject arrayint iIRubyObject value);
         public String toString() {return .getName() + " converter";}
     }
 
     public interface NumericConverter {
         public Object coerce(RubyNumeric numericClass target);
     }
 
     private static IRubyObject trySimpleConversions(Ruby runtimeObject object) {
         if ( object == null ) return runtime.getNil();
 
         if ( object instanceof IRubyObject ) return (IRubyObjectobject;
 
         if ( object instanceof RubyObjectHolderProxy ) {
             return ((RubyObjectHolderProxyobject).__ruby_object();
         }
 
         if ( object instanceof InternalJavaProxy ) {
             final InternalJavaProxy internalJavaProxy = (InternalJavaProxyobject;
             IRubyObject orig = internalJavaProxy.___getInvocationHandler().getOrig();
             if (orig != nullreturn orig;
         }
 
         return null;
     }
 
     private static final JavaConverter JAVA_DEFAULT_CONVERTER = new JavaConverter(Object.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             IRubyObject result = trySimpleConversions(runtimeobject);
 
             if (result != nullreturn result;
 
             return JavaObject.wrap(runtimeobject);
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((Object[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((Object[])array)[i] = value.toJava(Object.class);
         }
     };
 
     private static final JavaConverter JAVA_BOOLEAN_CONVERTER = new JavaConverter(Boolean.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyBoolean.newBoolean(runtime, ((Boolean)object).booleanValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((Boolean[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((Boolean[])array)[i] = (Boolean)value.toJava(Boolean.class);
         }
     };
 
     private static final JavaConverter JAVA_FLOAT_CONVERTER = new JavaConverter(Float.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFloat.newFloat(runtime, ((Float)object).doubleValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((Float[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((Float[])array)[i] = (Float)value.toJava(Float.class);
         }
     };
 
     private static final JavaConverter JAVA_DOUBLE_CONVERTER = new JavaConverter(Double.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFloat.newFloat(runtime, ((Double)object).doubleValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((Double[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((Double[])array)[i] = (Double)value.toJava(Double.class);
         }
     };
 
     private static final JavaConverter JAVA_CHAR_CONVERTER = new JavaConverter(Character.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Character)object).charValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((Character[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((Character[])array)[i] = (Character)value.toJava(Character.class);
         }
     };
 
     private static final JavaConverter JAVA_BYTE_CONVERTER = new JavaConverter(Byte.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Byte)object).byteValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((Byte[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((Byte[])array)[i] = (Byte)value.toJava(Byte.class);
         }
     };
 
     private static final JavaConverter JAVA_SHORT_CONVERTER = new JavaConverter(Short.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Short)object).shortValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((Short[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((Short[])array)[i] = (Short)value.toJava(Short.class);
         }
     };
 
     private static final JavaConverter JAVA_INT_CONVERTER = new JavaConverter(Integer.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Integer)object).intValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((Integer[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((Integer[])array)[i] = (Integer)value.toJava(Integer.class);
         }
     };
 
     private static final JavaConverter JAVA_LONG_CONVERTER = new JavaConverter(Long.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Long)object).longValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((Long[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((Long[])array)[i] = (Long)value.toJava(Long.class);
         }
     };
 
     private static final JavaConverter JAVA_BOOLEANPRIM_CONVERTER = new JavaConverter(boolean.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyBoolean.newBoolean(runtime, ((Boolean)object).booleanValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return RubyBoolean.newBoolean(runtime, ((boolean[])array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((boolean[])array)[i] = (Boolean)value.toJava(boolean.class);
         }
     };
 
     private static final JavaConverter JAVA_FLOATPRIM_CONVERTER = new JavaConverter(float.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFloat.newFloat(runtime, ((Float)object).doubleValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return RubyFloat.newFloat(runtime, ((float[])array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((float[])array)[i] = (Float)value.toJava(float.class);
         }
     };
 
     private static final JavaConverter JAVA_DOUBLEPRIM_CONVERTER = new JavaConverter(double.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFloat.newFloat(runtime, ((Double)object).doubleValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return RubyFloat.newFloat(runtime, ((double[])array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((double[])array)[i] = (Double)value.toJava(double.class);
         }
     };
 
     private static final JavaConverter JAVA_CHARPRIM_CONVERTER = new JavaConverter(char.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Character)object).charValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return RubyFixnum.newFixnum(runtime, ((char[])array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((char[])array)[i] = (Character)value.toJava(char.class);
         }
     };
 
     private static final JavaConverter JAVA_BYTEPRIM_CONVERTER = new JavaConverter(byte.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Byte)object).byteValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return RubyFixnum.newFixnum(runtime, ((byte[])array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((byte[])array)[i] = (Byte)value.toJava(byte.class);
         }
     };
 
     private static final JavaConverter JAVA_SHORTPRIM_CONVERTER = new JavaConverter(short.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Short)object).shortValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return RubyFixnum.newFixnum(runtime, ((short[])array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((short[])array)[i] = (Short)value.toJava(short.class);
         }
     };
 
     private static final JavaConverter JAVA_INTPRIM_CONVERTER = new JavaConverter(int.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Integer)object).intValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return RubyFixnum.newFixnum(runtime, ((int[])array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((int[])array)[i] = (Integer)value.toJava(int.class);
         }
     };
 
     private static final JavaConverter JAVA_LONGPRIM_CONVERTER = new JavaConverter(long.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyFixnum.newFixnum(runtime, ((Long)object).longValue());
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return RubyFixnum.newFixnum(runtime, ((long[])array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((long[])array)[i] = (Long)value.toJava(long.class);
         }
     };
 
     private static final JavaConverter JAVA_STRING_CONVERTER = new JavaConverter(String.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyString.newUnicodeString(runtime, (String)object);
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((String[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((String[])array)[i] = (String)value.toJava(String.class);
         }
     };
 
     private static final JavaConverter JAVA_CHARSEQUENCE_CONVERTER = new JavaConverter(String.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyString.newUnicodeString(runtime, (CharSequence)object);
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((CharSequence[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((CharSequence[])array)[i] = (CharSequence)value.toJava(CharSequence.class);
         }
     };
 
     private static final JavaConverter BYTELIST_CONVERTER = new JavaConverter(ByteList.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyString.newString(runtime, (ByteList)object);
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((ByteList[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((ByteList[])array)[i] = (ByteList)value.toJava(ByteList.class);
         }
     };
 
     private static final JavaConverter JAVA_BIGINTEGER_CONVERTER = new JavaConverter(BigInteger.class) {
         public IRubyObject convert(Ruby runtimeObject object) {
             if (object == nullreturn runtime.getNil();
             return RubyBignum.newBignum(runtime, (BigInteger)object);
         }
         public IRubyObject get(Ruby runtimeObject arrayint i) {
             return convert(runtime, ((BigInteger[]) array)[i]);
         }
         public void set(Ruby runtimeObject arrayint iIRubyObject value) {
             ((BigInteger[])array)[i] = (BigInteger)value.toJava(BigInteger.class);
         }
     };
 
     private static final Map<Class,JavaConverterJAVA_CONVERTERS =
         new HashMap<Class,JavaConverter>();
 
     static {
         .put(Byte.class);
         .put(Short.class);
         .put(Integer.class);
         .put(Long.class);
         .put(Float.class);
 
 
 
     }
 
     private static final NumericConverter NUMERIC_TO_BYTE = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             final long value = numeric.getLongValue();
             if ( isLongByteable(value) ) return (bytevalue;
             throw numeric.getRuntime().newRangeError("too big for byte: " + numeric);
         }
     };
     private static final NumericConverter NUMERIC_TO_SHORT = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             final long value = numeric.getLongValue();
             if ( isLongShortable(value) ) return (shortvalue;
             throw numeric.getRuntime().newRangeError("too big for short: " + numeric);
         }
     };
     private static final NumericConverter NUMERIC_TO_CHARACTER = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             final long value = numeric.getLongValue();
             if ( isLongCharable(value) ) return (charvalue;
             throw numeric.getRuntime().newRangeError("too big for char: " + numeric);
         }
     };
     private static final NumericConverter NUMERIC_TO_INTEGER = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             final long value = numeric.getLongValue();
             if ( isLongIntable(value) ) return (intvalue;
             throw numeric.getRuntime().newRangeError("too big for int: " + numeric);
         }
     };
     private static final NumericConverter NUMERIC_TO_LONG = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             return numeric.getLongValue();
         }
     };
     private static final NumericConverter NUMERIC_TO_FLOAT = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             final double value = numeric.getDoubleValue();
             // many cases are ok to convert to float; if not one of these, error
             if ( isDoubleFloatable(value) ) return (floatvalue;
             throw numeric.getRuntime().newTypeError("too big for float: " + numeric);
         }
     };
     private static final NumericConverter NUMERIC_TO_DOUBLE = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             return numeric.getDoubleValue();
         }
     };
     private static final NumericConverter NUMERIC_TO_BIGINTEGER = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             return numeric.getBigIntegerValue();
         }
     };
     private static final NumericConverter NUMERIC_TO_OBJECT = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             // for Object, default to natural wrapper type
             if (numeric instanceof RubyFixnum) {
                 long value = numeric.getLongValue();
                 return Long.valueOf(value);
             } else if (numeric instanceof RubyFloat) {
                 double value = numeric.getDoubleValue();
                 return Double.valueOf(value);
             } else if (numeric instanceof RubyBignum) {
                 return ((RubyBignum)numeric).getValue();
             } else if (numeric instanceof RubyBigDecimal) {
                 return ((RubyBigDecimal)numeric).getValue();
             } else {
                 return .coerce(numerictarget);
             }
         }
     };
     private static final NumericConverter NUMERIC_TO_OTHER = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             if (target.isAssignableFrom(numeric.getClass())) {
                 // just return as-is, since we can't do any coercion
                 return numeric;
             }
             // otherwise, error; no conversion available
             throw numeric.getRuntime().newTypeError("could not coerce " + numeric.getMetaClass() + " to " + target);
         }
     };
     private static final NumericConverter NUMERIC_TO_VOID = new NumericConverter() {
         public Object coerce(RubyNumeric numericClass target) {
             return null;
         }
     };
     private static boolean isDoubleFloatable(double value) {
         return true;
     }
     private static boolean isLongByteable(long value) {
         return value >= . && value <= .;
     }
     private static boolean isLongShortable(long value) {
         return value >= . && value <= .;
     }
     private static boolean isLongCharable(long value) {
         return value >= . && value <= .;
     }
     private static boolean isLongIntable(long value) {
         return value >= . && value <= .;
     }
 
     private static final Map<ClassNumericConverterNUMERIC_CONVERTERS = new HashMap<ClassNumericConverter>();
 
     static {
         .put(Byte.class);
         .put(Short.class);
         .put(Long.class);
         .put(Float.class);