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-2005 Thomas E Enebo <enebo@acm.org>
17 * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
18 * Copyright (C) 2004 David Corbin <dcorbin@users.sourceforge.net>
19 * Copyright (C) 2005 Charles O Nutter <headius@headius.com>
20 * Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
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
;
36 import java
.lang
.reflect
.AccessibleObject
;
37 import java
.lang
.reflect
.Field
;
38 import java
.lang
.reflect
.Modifier
;
40 import org
.jruby
.Ruby
;
41 import org
.jruby
.RubyBoolean
;
42 import org
.jruby
.RubyClass
;
43 import org
.jruby
.RubyModule
;
44 import org
.jruby
.RubyString
;
45 import org
.jruby
.anno
.JRubyClass
;
46 import org
.jruby
.anno
.JRubyMethod
;
47 import org
.jruby
.runtime
.ObjectAllocator
;
48 import org
.jruby
.runtime
.builtin
.IRubyObject
;
50 @JRubyClass(name
="Java::JavaField")
51 public class JavaField
extends JavaAccessibleObject
{
54 public static RubyClass
createJavaFieldClass(Ruby runtime
, RubyModule javaModule
) {
55 // TODO: NOT_ALLOCATABLE_ALLOCATOR is probably ok here, since we don't intend for people to monkey with
56 // this type and it can't be marshalled. Confirm. JRUBY-415
57 RubyClass result
= javaModule
.defineClassUnder("JavaField", runtime
.getObject(), ObjectAllocator
.NOT_ALLOCATABLE_ALLOCATOR
);
59 JavaAccessibleObject
.registerRubyMethods(runtime
, result
);
61 result
.defineAnnotatedMethods(JavaField
.class);
66 public JavaField(Ruby runtime
, Field field
) {
67 super(runtime
, runtime
.getJavaSupport().getJavaFieldClass());
71 public boolean equals(Object other
) {
72 return other
instanceof JavaField
&&
73 this.field
== ((JavaField
)other
).field
;
76 public int hashCode() {
77 return field
.hashCode();
81 public RubyString
value_type() {
82 return getRuntime().newString(field
.getType().getName());
85 @JRubyMethod(name
= {"==", "==="})
86 public IRubyObject
op_equal(IRubyObject other
) {
87 if (!(other
instanceof JavaField
)) {
88 return getRuntime().getFalse();
91 return getRuntime().newBoolean(field
.equals(((JavaField
) other
).field
));
94 @JRubyMethod(name
= "public?")
95 public RubyBoolean
public_p() {
96 return getRuntime().newBoolean(Modifier
.isPublic(field
.getModifiers()));
99 @JRubyMethod(name
= "static?")
100 public RubyBoolean
static_p() {
101 return getRuntime().newBoolean(Modifier
.isStatic(field
.getModifiers()));
104 @JRubyMethod(name
= "enum_constant?")
105 public RubyBoolean
enum_constant_p() {
106 return getRuntime().newBoolean(field
.isEnumConstant());
110 public RubyString
to_generic_string() {
111 return getRuntime().newString(field
.toGenericString());
114 @JRubyMethod(name
= "type")
115 public IRubyObject
field_type() {
116 return JavaClass
.get(getRuntime(), field
.getType());
120 public IRubyObject
value(IRubyObject object
) {
121 JavaObject obj
= JavaUtil
.unwrapJavaObject(getRuntime(), object
, "not a java object");
122 Object javaObject
= obj
.getValue();
124 return JavaUtil
.convertJavaToRuby(getRuntime(), field
.get(javaObject
), field
.getType());
125 } catch (IllegalAccessException iae
) {
126 throw getRuntime().newTypeError("illegal access");
131 public IRubyObject
set_value(IRubyObject object
, IRubyObject value
) {
132 JavaObject obj
= JavaUtil
.unwrapJavaObject(getRuntime(), object
, "not a java object: " + object
);
133 IRubyObject val
= value
;
134 if(val
.dataGetStruct() instanceof JavaObject
) {
135 val
= (IRubyObject
)val
.dataGetStruct();
137 Object javaObject
= obj
.getValue();
139 Object convertedValue
= JavaUtil
.convertArgumentToType(val
.getRuntime().getCurrentContext(), val
, field
.getType());
141 field
.set(javaObject
, convertedValue
);
142 } catch (IllegalAccessException iae
) {
143 throw getRuntime().newTypeError(
144 "illegal access on setting variable: " + iae
.getMessage());
145 } catch (IllegalArgumentException iae
) {
146 throw getRuntime().newTypeError(
147 "wrong type for " + field
.getType().getName() + ": " +
148 val
.getClass().getName());
153 @JRubyMethod(name
= "final?")
154 public RubyBoolean
final_p() {
155 return getRuntime().newBoolean(Modifier
.isFinal(field
.getModifiers()));
159 public JavaObject
static_value() {
161 // TODO: Only setAccessible to account for pattern found by
162 // accessing constants included from a non-public interface.
163 // (aka java.util.zip.ZipConstants being implemented by many
165 if (!Ruby
.isSecurityRestricted()) {
166 field
.setAccessible(true);
168 return JavaObject
.wrap(getRuntime(), field
.get(null));
169 } catch (IllegalAccessException iae
) {
170 throw getRuntime().newTypeError("illegal static value access: " + iae
.getMessage());
175 public JavaObject
set_static_value(IRubyObject value
) {
176 if (! (value
instanceof JavaObject
)) {
177 throw getRuntime().newTypeError("not a java object:" + value
);
180 Object convertedValue
= JavaUtil
.convertArgument(getRuntime(), ((JavaObject
) value
).getValue(),
182 // TODO: Only setAccessible to account for pattern found by
183 // accessing constants included from a non-public interface.
184 // (aka java.util.zip.ZipConstants being implemented by many
186 // TODO: not sure we need this at all, since we only expose
188 //field.setAccessible(true);
189 field
.set(null, convertedValue
);
190 } catch (IllegalAccessException iae
) {
191 throw getRuntime().newTypeError(
192 "illegal access on setting static variable: " + iae
.getMessage());
193 } catch (IllegalArgumentException iae
) {
194 throw getRuntime().newTypeError(
195 "wrong type for " + field
.getType().getName() + ": " +
196 ((JavaObject
) value
).getValue().getClass().getName());
198 return (JavaObject
) value
;
202 public RubyString
name() {
203 return getRuntime().newString(field
.getName());
206 protected AccessibleObject
accessibleObject() {