Fix for JRUBY-2882. Handle error messages related to constructors better
[jruby.git] / src / org / jruby / javasupport / JavaArray.java
blob8b36f5d0379c45446c3e7f62bd146e2bdf708f03
1 /***** BEGIN LICENSE BLOCK *****
2 * Version: CPL 1.0/GPL 2.0/LGPL 2.1
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
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.
14 * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
15 * Copyright (C) 2002-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
16 * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
17 * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
19 * Alternatively, the contents of this file may be used under the terms of
20 * either of the GNU General Public License Version 2 or later (the "GPL"),
21 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
22 * in which case the provisions of the GPL or the LGPL are applicable instead
23 * of those above. If you wish to allow use of your version of this file only
24 * under the terms of either the GPL or the LGPL, and not to allow others to
25 * use your version of this file under the terms of the CPL, indicate your
26 * decision by deleting the provisions above and replace them with the notice
27 * and other provisions required by the GPL or the LGPL. If you do not delete
28 * the provisions above, a recipient may use your version of this file under
29 * the terms of any one of the CPL, the GPL or the LGPL.
30 ***** END LICENSE BLOCK *****/
31 package org.jruby.javasupport;
33 import java.lang.reflect.Array;
35 import org.jruby.Ruby;
36 import org.jruby.RubyClass;
37 import org.jruby.RubyFixnum;
38 import org.jruby.RubyInteger;
39 import org.jruby.RubyModule;
40 import org.jruby.anno.JRubyClass;
41 import org.jruby.runtime.ObjectAllocator;
42 import org.jruby.runtime.builtin.IRubyObject;
44 @JRubyClass(name="Java::JavaArray", parent="Java::JavaObject")
45 public class JavaArray extends JavaObject {
46 private JavaUtil.RubyConverter rubyConverter;
48 public JavaArray(Ruby runtime, Object array) {
49 super(runtime, runtime.getJavaSupport().getJavaArrayClass(), array);
50 assert array.getClass().isArray();
51 rubyConverter = JavaUtil.getArrayConverter(array.getClass().getComponentType());
54 public static RubyClass createJavaArrayClass(Ruby runtime, RubyModule javaModule) {
55 // FIXME: NOT_ALLOCATABLE_ALLOCATOR is probably not right here, since we might
56 // eventually want JavaArray to be marshallable. JRUBY-414
57 return javaModule.defineClassUnder("JavaArray", javaModule.fastGetClass("JavaObject"), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
60 public Class getComponentType() {
61 return getValue().getClass().getComponentType();
64 public JavaUtil.RubyConverter getRubyConverter() {
65 return rubyConverter;
68 public RubyFixnum length() {
69 return getRuntime().newFixnum(getLength());
72 private int getLength() {
73 return Array.getLength(getValue());
76 public boolean equals(Object other) {
77 return other instanceof JavaArray &&
78 this.getValue() == ((JavaArray)other).getValue();
81 public IRubyObject aref(IRubyObject index) {
82 if (! (index instanceof RubyInteger)) {
83 throw getRuntime().newTypeError(index, getRuntime().getInteger());
85 int intIndex = (int) ((RubyInteger) index).getLongValue();
86 if (intIndex < 0 || intIndex >= getLength()) {
87 throw getRuntime().newArgumentError(
88 "index out of bounds for java array (" + intIndex +
89 " for length " + getLength() + ")");
91 Object result = Array.get(getValue(), intIndex);
92 if (result == null) {
93 return getRuntime().getNil();
95 return JavaObject.wrap(getRuntime(), result);
98 public IRubyObject at(int index) {
99 Object result = Array.get(getValue(), index);
100 if (result == null) {
101 return getRuntime().getNil();
103 return JavaObject.wrap(getRuntime(), result);
106 public IRubyObject aset(IRubyObject index, IRubyObject value) {
107 if (! (index instanceof RubyInteger)) {
108 throw getRuntime().newTypeError(index, getRuntime().getInteger());
110 int intIndex = (int) ((RubyInteger) index).getLongValue();
111 if (! (value instanceof JavaObject)) {
112 throw getRuntime().newTypeError("not a java object:" + value);
114 Object javaObject = ((JavaObject) value).getValue();
115 setWithExceptionHandling(intIndex, javaObject);
116 return value;
119 public void setWithExceptionHandling(int intIndex, Object javaObject) {
120 try {
121 Array.set(getValue(), intIndex, javaObject);
122 } catch (IndexOutOfBoundsException e) {
123 throw getRuntime().newArgumentError(
124 "index out of bounds for java array (" + intIndex +
125 " for length " + getLength() + ")");
126 } catch (ArrayStoreException e) {
127 throw getRuntime().newArgumentError(
128 "wrong element type " + javaObject.getClass() + "(array is " +
129 getValue().getClass() + ")");
133 public IRubyObject afill(IRubyObject beginIndex, IRubyObject endIndex, IRubyObject value) {
134 if (! (beginIndex instanceof RubyInteger)) {
135 throw getRuntime().newTypeError(beginIndex, getRuntime().getInteger());
137 int intIndex = (int) ((RubyInteger) beginIndex).getLongValue();
138 if (! (endIndex instanceof RubyInteger)) {
139 throw getRuntime().newTypeError(endIndex, getRuntime().getInteger());
141 int intEndIndex = (int) ((RubyInteger) endIndex).getLongValue();
142 if (! (value instanceof JavaObject)) {
143 throw getRuntime().newTypeError("not a java object:" + value);
145 Object javaObject = ((JavaObject) value).getValue();
146 fillWithExceptionHandling(intIndex, intEndIndex, javaObject);
147 return value;
150 public void fillWithExceptionHandling(int intIndex, int intEndIndex, Object javaObject) {
151 try {
152 for ( ; intIndex < intEndIndex; intIndex++) {
153 Array.set(getValue(), intIndex, javaObject);
155 } catch (IndexOutOfBoundsException e) {
156 throw getRuntime().newArgumentError(
157 "index out of bounds for java array (" + intIndex +
158 " for length " + getLength() + ")");
159 } catch (ArrayStoreException e) {
160 throw getRuntime().newArgumentError(
161 "wrong element type " + javaObject.getClass() + "(array is " +
162 getValue().getClass() + ")");