001: /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
002: *
003: * ***** BEGIN LICENSE BLOCK *****
004: * Version: MPL 1.1/GPL 2.0
005: *
006: * The contents of this file are subject to the Mozilla Public License Version
007: * 1.1 (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: * http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the
014: * License.
015: *
016: * The Original Code is Rhino code, released
017: * May 6, 1999.
018: *
019: * The Initial Developer of the Original Code is
020: * Netscape Communications Corporation.
021: * Portions created by the Initial Developer are Copyright (C) 1997-1999
022: * the Initial Developer. All Rights Reserved.
023: *
024: * Contributor(s):
025: * Norris Boyd
026: * Igor Bukanov
027: * Frank Mitchell
028: * Mike Shaver
029: * Kemal Bayram
030: *
031: * Alternatively, the contents of this file may be used under the terms of
032: * the GNU General Public License Version 2 or later (the "GPL"), in which
033: * case the provisions of the GPL are applicable instead of those above. If
034: * you wish to allow use of your version of this file only under the terms of
035: * the GPL and not to allow others to use your version of this file under the
036: * MPL, indicate your decision by deleting the provisions above and replacing
037: * them with the notice and other provisions required by the GPL. If you do
038: * not delete the provisions above, a recipient may use your version of this
039: * file under either the MPL or the GPL.
040: *
041: * ***** END LICENSE BLOCK ***** */
042:
043: package org.mozilla.javascript;
044:
045: import java.lang.reflect.Array;
046:
047: /**
048: * This class reflects Java arrays into the JavaScript environment.
049: *
050: * @author Mike Shaver
051: * @see NativeJavaClass
052: * @see NativeJavaObject
053: * @see NativeJavaPackage
054: */
055:
056: public class NativeJavaArray extends NativeJavaObject {
057: static final long serialVersionUID = -924022554283675333L;
058:
059: public String getClassName() {
060: return "JavaArray";
061: }
062:
063: public static NativeJavaArray wrap(Scriptable scope, Object array) {
064: return new NativeJavaArray(scope, array);
065: }
066:
067: public Object unwrap() {
068: return array;
069: }
070:
071: public NativeJavaArray(Scriptable scope, Object array) {
072: super (scope, null, ScriptRuntime.ObjectClass);
073: Class cl = array.getClass();
074: if (!cl.isArray()) {
075: throw new RuntimeException("Array expected");
076: }
077: this .array = array;
078: this .length = Array.getLength(array);
079: this .cls = cl.getComponentType();
080: }
081:
082: public boolean has(String id, Scriptable start) {
083: return id.equals("length") || super .has(id, start);
084: }
085:
086: public boolean has(int index, Scriptable start) {
087: return 0 <= index && index < length;
088: }
089:
090: public Object get(String id, Scriptable start) {
091: if (id.equals("length"))
092: return new Integer(length);
093: Object result = super .get(id, start);
094: if (result == NOT_FOUND
095: && !ScriptableObject.hasProperty(getPrototype(), id)) {
096: throw Context.reportRuntimeError2(
097: "msg.java.member.not.found", array.getClass()
098: .getName(), id);
099: }
100: return result;
101: }
102:
103: public Object get(int index, Scriptable start) {
104: if (0 <= index && index < length) {
105: Context cx = Context.getContext();
106: Object obj = Array.get(array, index);
107: return cx.getWrapFactory().wrap(cx, this , obj, cls);
108: }
109: return Undefined.instance;
110: }
111:
112: public void put(String id, Scriptable start, Object value) {
113: // Ignore assignments to "length"--it's readonly.
114: if (!id.equals("length"))
115: throw Context.reportRuntimeError1(
116: "msg.java.array.member.not.found", id);
117: }
118:
119: public void put(int index, Scriptable start, Object value) {
120: if (0 <= index && index < length) {
121: Array.set(array, index, Context.jsToJava(value, cls));
122: } else {
123: throw Context
124: .reportRuntimeError2(
125: "msg.java.array.index.out.of.bounds",
126: String.valueOf(index), String
127: .valueOf(length - 1));
128: }
129: }
130:
131: public Object getDefaultValue(Class hint) {
132: if (hint == null || hint == ScriptRuntime.StringClass)
133: return array.toString();
134: if (hint == ScriptRuntime.BooleanClass)
135: return Boolean.TRUE;
136: if (hint == ScriptRuntime.NumberClass)
137: return ScriptRuntime.NaNobj;
138: return this ;
139: }
140:
141: public Object[] getIds() {
142: Object[] result = new Object[length];
143: int i = length;
144: while (--i >= 0)
145: result[i] = new Integer(i);
146: return result;
147: }
148:
149: public boolean hasInstance(Scriptable value) {
150: if (!(value instanceof Wrapper))
151: return false;
152: Object instance = ((Wrapper) value).unwrap();
153: return cls.isInstance(instance);
154: }
155:
156: public Scriptable getPrototype() {
157: if (prototype == null) {
158: prototype = ScriptableObject.getClassPrototype(this
159: .getParentScope(), "Array");
160: }
161: return prototype;
162: }
163:
164: Object array;
165: int length;
166: Class cls;
167: }
|