1 34 package org.jruby.javasupport; 35 36 import java.math.BigDecimal ; 37 import java.math.BigInteger ; 38 39 import org.jruby.Ruby; 40 import org.jruby.RubyBignum; 41 import org.jruby.RubyBoolean; 42 import org.jruby.RubyFloat; 43 import org.jruby.RubyNumeric; 44 import org.jruby.RubyString; 45 import org.jruby.runtime.ThreadContext; 46 import org.jruby.runtime.builtin.IRubyObject; 47 48 import org.jruby.util.ByteList; 49 50 54 public class JavaUtil { 55 56 public static Object convertRubyToJava(IRubyObject rubyObject) { 57 return convertRubyToJava(rubyObject, null); 58 } 59 60 public static Object convertRubyToJava(IRubyObject rubyObject, Class javaClass) { 61 if (rubyObject == null || rubyObject.isNil()) { 62 return null; 63 } 64 65 ThreadContext context = rubyObject.getRuntime().getCurrentContext(); 66 67 if (rubyObject.respondsTo("java_object")) { 68 rubyObject = rubyObject.callMethod(context, "java_object"); 69 } 70 71 if (rubyObject instanceof JavaObject) { 72 Object value = ((JavaObject) rubyObject).getValue(); 73 74 return convertArgument(value, javaClass); 75 76 } else if (javaClass == Object .class || javaClass == null) { 77 81 javaClass = rubyObject.getJavaClass(); 82 if (javaClass == IRubyObject.class) { 83 javaClass = String .class; 84 } 85 } 86 87 if (javaClass.isInstance(rubyObject)) { 88 return rubyObject; 90 } 91 92 if (javaClass.isPrimitive()) { 93 String cName = javaClass.getName(); 94 if (cName == "boolean") { 95 return Boolean.valueOf(rubyObject.isTrue()); 96 } else if (cName == "float") { 97 if (rubyObject.respondsTo("to_f")) { 98 return new Float (((RubyNumeric) rubyObject.callMethod(context, "to_f")).getDoubleValue()); 99 } 100 return new Float (0.0); 101 } else if (cName == "double") { 102 if (rubyObject.respondsTo("to_f")) { 103 return new Double (((RubyNumeric) rubyObject.callMethod(context, "to_f")).getDoubleValue()); 104 } 105 return new Double (0.0); 106 } else if (cName == "long") { 107 if (rubyObject.respondsTo("to_i")) { 108 return new Long (((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue()); 109 } 110 return new Long (0); 111 } else if (cName == "int") { 112 if (rubyObject.respondsTo("to_i")) { 113 return new Integer ((int) ((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue()); 114 } 115 return new Integer (0); 116 } else if (cName == "short") { 117 if (rubyObject.respondsTo("to_i")) { 118 return new Short ((short) ((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue()); 119 } 120 return new Short ((short) 0); 121 } else if (cName == "byte") { 122 if (rubyObject.respondsTo("to_i")) { 123 return new Byte ((byte) ((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue()); 124 } 125 return new Byte ((byte) 0); 126 } 127 128 String s = ((RubyString) rubyObject.callMethod(context, "to_s")).toString(); 130 if (s.length() > 0) { 131 return new Character (s.charAt(0)); 132 } 133 return new Character ('\0'); 134 } else if (javaClass == String .class) { 135 return ((RubyString) rubyObject.callMethod(context, "to_s")).toString(); 136 } else if (javaClass == ByteList.class) { 137 return rubyObject.convertToString().getByteList(); 138 } else if (javaClass == BigInteger .class) { 139 if (rubyObject instanceof RubyBignum) { 140 return ((RubyBignum)rubyObject).getValue(); 141 } else if (rubyObject instanceof RubyNumeric) { 142 return BigInteger.valueOf (((RubyNumeric)rubyObject).getLongValue()); 143 } else if (rubyObject.respondsTo("to_i")) { 144 RubyNumeric rubyNumeric = ((RubyNumeric)rubyObject.callMethod(context,"to_f")); 145 return BigInteger.valueOf (rubyNumeric.getLongValue()); 146 } 147 } else if (javaClass == BigDecimal .class && !(rubyObject instanceof JavaObject)) { 148 if (rubyObject.respondsTo("to_f")) { 149 double double_value = ((RubyNumeric)rubyObject.callMethod(context,"to_f")).getDoubleValue(); 150 return new BigDecimal (double_value); 151 } 152 } 153 try { 154 return ((JavaObject) rubyObject).getValue(); 155 } catch (ClassCastException ex) { 156 ex.printStackTrace(); 157 return null; 158 } 159 } 160 161 public static IRubyObject[] convertJavaArrayToRuby(Ruby runtime, Object [] objects) { 162 IRubyObject[] rubyObjects = new IRubyObject[objects.length]; 163 for (int i = 0; i < objects.length; i++) { 164 rubyObjects[i] = convertJavaToRuby(runtime, objects[i]); 165 } 166 return rubyObjects; 167 } 168 169 public static IRubyObject convertJavaToRuby(Ruby runtime, Object object) { 170 if (object == null) { 171 return runtime.getNil(); 172 } 173 return convertJavaToRuby(runtime, object, object.getClass()); 174 } 175 176 public static IRubyObject convertJavaToRuby(Ruby runtime, Object object, Class javaClass) { 177 if (object == null) { 178 return runtime.getNil(); 179 } 180 181 if (object instanceof IRubyObject) { 182 return (IRubyObject) object; 183 } 184 185 if (javaClass.isPrimitive()) { 186 String cName = javaClass.getName(); 187 if (cName == "boolean") { 188 return RubyBoolean.newBoolean(runtime, ((Boolean ) object).booleanValue()); 189 } else if (cName == "float" || cName == "double") { 190 return RubyFloat.newFloat(runtime, ((Number ) object).doubleValue()); 191 } else if (cName == "char") { 192 return runtime.newFixnum(((Character ) object).charValue()); 193 } else { 194 return runtime.newFixnum(((Number ) object).longValue()); 196 } 197 } else if (javaClass == Boolean .class) { 198 return RubyBoolean.newBoolean(runtime, ((Boolean ) object).booleanValue()); 199 } else if (javaClass == Float .class || javaClass == Double .class) { 200 return RubyFloat.newFloat(runtime, ((Number ) object).doubleValue()); 201 } else if (javaClass == Character .class) { 202 return runtime.newFixnum(((Character ) object).charValue()); 203 } else if (Number .class.isAssignableFrom(javaClass) && javaClass != BigDecimal .class) { 204 return runtime.newFixnum(((Number ) object).longValue()); 205 } else if (javaClass == String .class) { 206 return runtime.newString(object.toString()); 207 } else if (javaClass == ByteList.class) { 208 return RubyString.newString(runtime,((ByteList)object)); 209 } else if (IRubyObject.class.isAssignableFrom(javaClass)) { 210 return (IRubyObject) object; 211 } else if (javaClass == BigInteger .class) { 212 return RubyBignum.newBignum(runtime, (BigInteger )object); 213 } else if (javaClass == BigDecimal .class) { 214 return JavaObject.wrap(runtime, object); 215 } else { 216 return JavaObject.wrap(runtime, object); 217 } 218 } 219 220 public static Class primitiveToWrapper(Class type) { 221 if (type == Double.TYPE) { 222 return Double .class; 223 } else if (type == Float.TYPE) { 224 return Float .class; 225 } else if (type == Integer.TYPE) { 226 return Integer .class; 227 } else if (type == Long.TYPE) { 228 return Long .class; 229 } else if (type == Short.TYPE) { 230 return Short .class; 231 } else if (type == Byte.TYPE) { 232 return Byte .class; 233 } else if (type == Character.TYPE) { 234 return Character .class; 235 } else if (type == Void.TYPE) { 236 return Void .class; 237 } else if (type == Boolean.TYPE) { 238 return Boolean .class; 239 } else { 240 return type; 241 } 242 } 243 244 public static Object convertArgument(Object argument, Class parameterType) { 245 if (argument instanceof JavaObject) { 246 argument = ((JavaObject) argument).getValue(); 247 if (argument == null) { 248 return null; 249 } 250 } 251 Class type = primitiveToWrapper(parameterType); 252 if (type == Void .class) { 253 return null; 254 } 255 if (argument instanceof Number ) { 256 final Number number = (Number ) argument; 257 if (type == Long .class) { 258 return new Long (number.longValue()); 259 } else if (type == Integer .class) { 260 return new Integer (number.intValue()); 261 } else if (type == Short .class) { 262 return new Short (number.shortValue()); 263 } else if (type == Byte .class) { 264 return new Byte (number.byteValue()); 265 } else if (type == Character .class) { 266 return new Character ((char) number.intValue()); 267 } else if (type == Double .class) { 268 return new Double (number.doubleValue()); 269 } else if (type == Float .class) { 270 return new Float (number.floatValue()); 271 } 272 } 273 return argument; 274 } 275 } 276 | Popular Tags |