KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jruby > javasupport > JavaUtil


1 /***** BEGIN LICENSE BLOCK *****
2  * Version: CPL 1.0/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Common Public
5  * License Version 1.0 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of
7  * the License at http://www.eclipse.org/legal/cpl-v10.html
8  *
9  * Software distributed under the License is distributed on an "AS
10  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * rights and limitations under the License.
13  *
14  * Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
15  * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
16  * Copyright (C) 2002 Anders Bengtsson <ndrsbngtssn@yahoo.se>
17  * Copyright (C) 2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
18  * Copyright (C) 2002 Don Schwartz <schwardo@users.sourceforge.net>
19  * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
20  * Copyright (C) 2006 Kresten Krab Thorup <krab@gnu.org>
21  *
22  * Alternatively, the contents of this file may be used under the terms of
23  * either of the GNU General Public License Version 2 or later (the "GPL"),
24  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
25  * in which case the provisions of the GPL or the LGPL are applicable instead
26  * of those above. If you wish to allow use of your version of this file only
27  * under the terms of either the GPL or the LGPL, and not to allow others to
28  * use your version of this file under the terms of the CPL, indicate your
29  * decision by deleting the provisions above and replace them with the notice
30  * and other provisions required by the GPL or the LGPL. If you do not delete
31  * the provisions above, a recipient may use your version of this file under
32  * the terms of any one of the CPL, the GPL or the LGPL.
33  ***** END LICENSE BLOCK *****/

34 package org.jruby.javasupport;
35
36 import java.math.BigDecimal JavaDoc;
37 import java.math.BigInteger JavaDoc;
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 /**
51  *
52  * @author Jan Arne Petersen, Alan Moore
53  */

54 public class JavaUtil {
55
56     public static Object JavaDoc convertRubyToJava(IRubyObject rubyObject) {
57         return convertRubyToJava(rubyObject, null);
58     }
59
60     public static Object JavaDoc convertRubyToJava(IRubyObject rubyObject, Class JavaDoc 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 JavaDoc value = ((JavaObject) rubyObject).getValue();
73             
74             return convertArgument(value, javaClass);
75             
76         } else if (javaClass == Object JavaDoc.class || javaClass == null) {
77             /* The Java method doesn't care what class it is, but we need to
78                know what to convert it to, so we use the object's own class.
79                If that doesn't help, we use String to force a call to the
80                object's "to_s" method. */

81             javaClass = rubyObject.getJavaClass();
82             if (javaClass == IRubyObject.class) {
83                 javaClass = String JavaDoc.class;
84             }
85         }
86
87         if (javaClass.isInstance(rubyObject)) {
88             // rubyObject is already of the required jruby class (or subclass)
89
return rubyObject;
90         }
91
92         if (javaClass.isPrimitive()) {
93             String JavaDoc 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 JavaDoc(((RubyNumeric) rubyObject.callMethod(context, "to_f")).getDoubleValue());
99                 }
100                 return new Float JavaDoc(0.0);
101             } else if (cName == "double") {
102                 if (rubyObject.respondsTo("to_f")) {
103                     return new Double JavaDoc(((RubyNumeric) rubyObject.callMethod(context, "to_f")).getDoubleValue());
104                 }
105                 return new Double JavaDoc(0.0);
106             } else if (cName == "long") {
107                 if (rubyObject.respondsTo("to_i")) {
108                     return new Long JavaDoc(((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue());
109                 }
110                 return new Long JavaDoc(0);
111             } else if (cName == "int") {
112                 if (rubyObject.respondsTo("to_i")) {
113                     return new Integer JavaDoc((int) ((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue());
114                 }
115                 return new Integer JavaDoc(0);
116             } else if (cName == "short") {
117                 if (rubyObject.respondsTo("to_i")) {
118                     return new Short JavaDoc((short) ((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue());
119                 }
120                 return new Short JavaDoc((short) 0);
121             } else if (cName == "byte") {
122                 if (rubyObject.respondsTo("to_i")) {
123                     return new Byte JavaDoc((byte) ((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue());
124                 }
125                 return new Byte JavaDoc((byte) 0);
126             }
127
128             // XXX this probably isn't good enough -AM
129
String JavaDoc s = ((RubyString) rubyObject.callMethod(context, "to_s")).toString();
130             if (s.length() > 0) {
131                 return new Character JavaDoc(s.charAt(0));
132             }
133             return new Character JavaDoc('\0');
134         } else if (javaClass == String JavaDoc.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 JavaDoc.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 JavaDoc.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 JavaDoc(double_value);
151             }
152         }
153         try {
154             return ((JavaObject) rubyObject).getValue();
155         } catch (ClassCastException JavaDoc ex) {
156             ex.printStackTrace();
157             return null;
158         }
159     }
160
161     public static IRubyObject[] convertJavaArrayToRuby(Ruby runtime, Object JavaDoc[] 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 JavaDoc 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 JavaDoc object, Class JavaDoc 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 JavaDoc cName = javaClass.getName();
187             if (cName == "boolean") {
188                 return RubyBoolean.newBoolean(runtime, ((Boolean JavaDoc) object).booleanValue());
189             } else if (cName == "float" || cName == "double") {
190                 return RubyFloat.newFloat(runtime, ((Number JavaDoc) object).doubleValue());
191             } else if (cName == "char") {
192                 return runtime.newFixnum(((Character JavaDoc) object).charValue());
193             } else {
194                 // else it's one of the integral types
195
return runtime.newFixnum(((Number JavaDoc) object).longValue());
196             }
197         } else if (javaClass == Boolean JavaDoc.class) {
198             return RubyBoolean.newBoolean(runtime, ((Boolean JavaDoc) object).booleanValue());
199         } else if (javaClass == Float JavaDoc.class || javaClass == Double JavaDoc.class) {
200             return RubyFloat.newFloat(runtime, ((Number JavaDoc) object).doubleValue());
201         } else if (javaClass == Character JavaDoc.class) {
202             return runtime.newFixnum(((Character JavaDoc) object).charValue());
203         } else if (Number JavaDoc.class.isAssignableFrom(javaClass) && javaClass != BigDecimal JavaDoc.class) {
204             return runtime.newFixnum(((Number JavaDoc) object).longValue());
205         } else if (javaClass == String JavaDoc.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 JavaDoc.class) {
212             return RubyBignum.newBignum(runtime, (BigInteger JavaDoc)object);
213         } else if (javaClass == BigDecimal JavaDoc.class) {
214             return JavaObject.wrap(runtime, object);
215         } else {
216             return JavaObject.wrap(runtime, object);
217         }
218     }
219
220     public static Class JavaDoc primitiveToWrapper(Class JavaDoc type) {
221         if (type == Double.TYPE) {
222             return Double JavaDoc.class;
223         } else if (type == Float.TYPE) {
224             return Float JavaDoc.class;
225         } else if (type == Integer.TYPE) {
226             return Integer JavaDoc.class;
227         } else if (type == Long.TYPE) {
228             return Long JavaDoc.class;
229         } else if (type == Short.TYPE) {
230             return Short JavaDoc.class;
231         } else if (type == Byte.TYPE) {
232             return Byte JavaDoc.class;
233         } else if (type == Character.TYPE) {
234             return Character JavaDoc.class;
235         } else if (type == Void.TYPE) {
236             return Void JavaDoc.class;
237         } else if (type == Boolean.TYPE) {
238             return Boolean JavaDoc.class;
239         } else {
240             return type;
241         }
242     }
243
244     public static Object JavaDoc convertArgument(Object JavaDoc argument, Class JavaDoc parameterType) {
245         if (argument instanceof JavaObject) {
246             argument = ((JavaObject) argument).getValue();
247             if (argument == null) {
248                 return null;
249             }
250         }
251         Class JavaDoc type = primitiveToWrapper(parameterType);
252         if (type == Void JavaDoc.class) {
253             return null;
254         }
255         if (argument instanceof Number JavaDoc) {
256             final Number JavaDoc number = (Number JavaDoc) argument;
257             if (type == Long JavaDoc.class) {
258                 return new Long JavaDoc(number.longValue());
259             } else if (type == Integer JavaDoc.class) {
260                 return new Integer JavaDoc(number.intValue());
261             } else if (type == Short JavaDoc.class) {
262                 return new Short JavaDoc(number.shortValue());
263             } else if (type == Byte JavaDoc.class) {
264                 return new Byte JavaDoc(number.byteValue());
265             } else if (type == Character JavaDoc.class) {
266                 return new Character JavaDoc((char) number.intValue());
267             } else if (type == Double JavaDoc.class) {
268                 return new Double JavaDoc(number.doubleValue());
269             } else if (type == Float JavaDoc.class) {
270                 return new Float JavaDoc(number.floatValue());
271             }
272         }
273         return argument;
274     }
275 }
276
Popular Tags