aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java
diff options
context:
space:
mode:
authorElliot Kroo <kroo@appjet.com>2010-03-11 15:21:30 -0800
committerElliot Kroo <kroo@appjet.com>2010-03-11 15:21:30 -0800
commit98e2821b38a775737e42a2479a6bc65107210859 (patch)
tree55939a8ba1dce4f4e48ebb13b658061d62bf1b9a /trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java
parentc1894c8e0a52f4e3d2f89fa92f0066bbf0fcf1b1 (diff)
downloadetherpad-98e2821b38a775737e42a2479a6bc65107210859.tar.gz
etherpad-98e2821b38a775737e42a2479a6bc65107210859.tar.xz
etherpad-98e2821b38a775737e42a2479a6bc65107210859.zip
reorganizing the first level of folders (trunk/branch folders are not the git way :)
Diffstat (limited to 'trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java')
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java1002
1 files changed, 0 insertions, 1002 deletions
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java
deleted file mode 100644
index 3d27852..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java
+++ /dev/null
@@ -1,1002 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Rhino code, released
- * May 6, 1999.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1997-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Igor Bukanov
- * Frank Mitchell
- * Mike Shaver
- * Kemal Bayram
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU General Public License Version 2 or later (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of those above. If
- * you wish to allow use of your version of this file only under the terms of
- * the GPL and not to allow others to use your version of this file under the
- * MPL, indicate your decision by deleting the provisions above and replacing
- * them with the notice and other provisions required by the GPL. If you do
- * not delete the provisions above, a recipient may use your version of this
- * file under either the MPL or the GPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.javascript;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.Hashtable;
-import java.util.Date;
-
-/**
- * This class reflects non-Array Java objects into the JavaScript environment. It
- * reflect fields directly, and uses NativeJavaMethod objects to reflect (possibly
- * overloaded) methods.<p>
- *
- * @author Mike Shaver
- * @see NativeJavaArray
- * @see NativeJavaPackage
- * @see NativeJavaClass
- */
-
-public class NativeJavaObject implements Scriptable, Wrapper, Serializable
-{
- static final long serialVersionUID = -6948590651130498591L;
-
- public NativeJavaObject() { }
-
- public NativeJavaObject(Scriptable scope, Object javaObject,
- Class staticType)
- {
- this(scope, javaObject, staticType, false);
- }
-
- public NativeJavaObject(Scriptable scope, Object javaObject,
- Class staticType, boolean isAdapter)
- {
- this.parent = ScriptableObject.getVeryTopLevelScope(scope); // APPJET
- this.javaObject = javaObject;
- this.staticType = staticType;
- this.isAdapter = isAdapter;
- initMembers();
- }
-
- protected void initMembers() {
- Class dynamicType;
- if (javaObject != null) {
- dynamicType = javaObject.getClass();
- } else {
- dynamicType = staticType;
- }
- members = JavaMembers.lookupClass(parent, dynamicType, staticType,
- isAdapter);
- fieldAndMethods
- = members.getFieldAndMethodsObjects(this, javaObject, false);
- }
-
- public boolean has(String name, Scriptable start) {
- return members.has(name, false);
- }
-
- public boolean has(int index, Scriptable start) {
- return false;
- }
-
- public Object get(String name, Scriptable start) {
- if (fieldAndMethods != null) {
- Object result = fieldAndMethods.get(name);
- if (result != null) {
- return result;
- }
- }
- // TODO: passing 'this' as the scope is bogus since it has
- // no parent scope
- return members.get(this, name, javaObject, false);
- }
-
- public Object get(int index, Scriptable start) {
- throw members.reportMemberNotFound(Integer.toString(index));
- }
-
- public void put(String name, Scriptable start, Object value) {
- // We could be asked to modify the value of a property in the
- // prototype. Since we can't add a property to a Java object,
- // we modify it in the prototype rather than copy it down.
- if (prototype == null || members.has(name, false))
- members.put(this, name, javaObject, value, false);
- else
- prototype.put(name, prototype, value);
- }
-
- public void put(int index, Scriptable start, Object value) {
- throw members.reportMemberNotFound(Integer.toString(index));
- }
-
- public boolean hasInstance(Scriptable value) {
- // This is an instance of a Java class, so always return false
- return false;
- }
-
- public void delete(String name) {
- }
-
- public void delete(int index) {
- }
-
- public Scriptable getPrototype() {
- if (prototype == null && javaObject instanceof String) {
- return ScriptableObject.getClassPrototype(parent, "String");
- }
- return prototype;
- }
-
- /**
- * Sets the prototype of the object.
- */
- public void setPrototype(Scriptable m) {
- prototype = m;
- }
-
- /**
- * Returns the parent (enclosing) scope of the object.
- */
- public Scriptable getParentScope() {
- return parent;
- }
-
- /**
- * Sets the parent (enclosing) scope of the object.
- */
- public void setParentScope(Scriptable m) {
- parent = m;
- }
-
- public Object[] getIds() {
- return members.getIds(false);
- }
-
-/**
-@deprecated Use {@link Context#getWrapFactory()} together with calling {@link
-WrapFactory#wrap(Context, Scriptable, Object, Class)}
-*/
- public static Object wrap(Scriptable scope, Object obj, Class staticType) {
-
- Context cx = Context.getContext();
- return cx.getWrapFactory().wrap(cx, scope, obj, staticType);
- }
-
- public Object unwrap() {
- return javaObject;
- }
-
- public String getClassName() {
- return "JavaObject";
- }
-
- public Object getDefaultValue(Class hint)
- {
- Object value;
- if (hint == null) {
- if (javaObject instanceof Boolean) {
- hint = ScriptRuntime.BooleanClass;
- }
- }
- if (hint == null || hint == ScriptRuntime.StringClass) {
- value = javaObject.toString();
- } else {
- String converterName;
- if (hint == ScriptRuntime.BooleanClass) {
- converterName = "booleanValue";
- } else if (hint == ScriptRuntime.NumberClass) {
- converterName = "doubleValue";
- } else {
- throw Context.reportRuntimeError0("msg.default.value");
- }
- Object converterObject = get(converterName, this);
- if (converterObject instanceof Function) {
- Function f = (Function)converterObject;
- value = f.call(Context.getContext(), f.getParentScope(),
- this, ScriptRuntime.emptyArgs);
- } else {
- if (hint == ScriptRuntime.NumberClass
- && javaObject instanceof Boolean)
- {
- boolean b = ((Boolean)javaObject).booleanValue();
- value = ScriptRuntime.wrapNumber(b ? 1.0 : 0.0);
- } else {
- value = javaObject.toString();
- }
- }
- }
- return value;
- }
-
- /**
- * Determine whether we can/should convert between the given type and the
- * desired one. This should be superceded by a conversion-cost calculation
- * function, but for now I'll hide behind precedent.
- */
- public static boolean canConvert(Object fromObj, Class to) {
- int weight = getConversionWeight(fromObj, to);
-
- return (weight < CONVERSION_NONE);
- }
-
- private static final int JSTYPE_UNDEFINED = 0; // undefined type
- private static final int JSTYPE_NULL = 1; // null
- private static final int JSTYPE_BOOLEAN = 2; // boolean
- private static final int JSTYPE_NUMBER = 3; // number
- private static final int JSTYPE_STRING = 4; // string
- private static final int JSTYPE_JAVA_CLASS = 5; // JavaClass
- private static final int JSTYPE_JAVA_OBJECT = 6; // JavaObject
- private static final int JSTYPE_JAVA_ARRAY = 7; // JavaArray
- private static final int JSTYPE_OBJECT = 8; // Scriptable
-
- static final byte CONVERSION_TRIVIAL = 1;
- static final byte CONVERSION_NONTRIVIAL = 0;
- static final byte CONVERSION_NONE = 99;
-
- /**
- * Derive a ranking based on how "natural" the conversion is.
- * The special value CONVERSION_NONE means no conversion is possible,
- * and CONVERSION_NONTRIVIAL signals that more type conformance testing
- * is required.
- * Based on
- * <a href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">
- * "preferred method conversions" from Live Connect 3</a>
- */
- static int getConversionWeight(Object fromObj, Class to) {
- int fromCode = getJSTypeCode(fromObj);
-
- switch (fromCode) {
-
- case JSTYPE_UNDEFINED:
- if (to == ScriptRuntime.StringClass ||
- to == ScriptRuntime.ObjectClass) {
- return 1;
- }
- break;
-
- case JSTYPE_NULL:
- if (!to.isPrimitive()) {
- return 1;
- }
- break;
-
- case JSTYPE_BOOLEAN:
- // "boolean" is #1
- if (to == Boolean.TYPE) {
- return 1;
- }
- else if (to == ScriptRuntime.BooleanClass) {
- return 2;
- }
- else if (to == ScriptRuntime.ObjectClass) {
- return 3;
- }
- else if (to == ScriptRuntime.StringClass) {
- return 4;
- }
- break;
-
- case JSTYPE_NUMBER:
- if (to.isPrimitive()) {
- if (to == Double.TYPE) {
- return 1;
- }
- else if (to != Boolean.TYPE) {
- return 1 + getSizeRank(to);
- }
- }
- else {
- if (to == ScriptRuntime.StringClass) {
- // native numbers are #1-8
- return 9;
- }
- else if (to == ScriptRuntime.ObjectClass) {
- return 10;
- }
- else if (ScriptRuntime.NumberClass.isAssignableFrom(to)) {
- // "double" is #1
- return 2;
- }
- }
- break;
-
- case JSTYPE_STRING:
- if (to == ScriptRuntime.StringClass) {
- return 1;
- }
- else if (to.isInstance(fromObj)) {
- return 2;
- }
- else if (to.isPrimitive()) {
- if (to == Character.TYPE) {
- return 3;
- } else if (to != Boolean.TYPE) {
- return 4;
- }
- }
- break;
-
- case JSTYPE_JAVA_CLASS:
- if (to == ScriptRuntime.ClassClass) {
- return 1;
- }
- else if (to == ScriptRuntime.ObjectClass) {
- return 3;
- }
- else if (to == ScriptRuntime.StringClass) {
- return 4;
- }
- break;
-
- case JSTYPE_JAVA_OBJECT:
- case JSTYPE_JAVA_ARRAY:
- Object javaObj = fromObj;
- if (javaObj instanceof Wrapper) {
- javaObj = ((Wrapper)javaObj).unwrap();
- }
- if (to.isInstance(javaObj)) {
- return CONVERSION_NONTRIVIAL;
- }
- if (to == ScriptRuntime.StringClass) {
- return 2;
- }
- else if (to.isPrimitive() && to != Boolean.TYPE) {
- return (fromCode == JSTYPE_JAVA_ARRAY)
- ? CONVERSION_NONE : 2 + getSizeRank(to);
- }
- break;
-
- case JSTYPE_OBJECT:
- // Other objects takes #1-#3 spots
- if (to == fromObj.getClass()) {
- // No conversion required
- return 1;
- }
- if (to.isArray()) {
- if (fromObj instanceof NativeArray) {
- // This is a native array conversion to a java array
- // Array conversions are all equal, and preferable to object
- // and string conversion, per LC3.
- return 1;
- }
- }
- else if (to == ScriptRuntime.ObjectClass) {
- return 2;
- }
- else if (to == ScriptRuntime.StringClass) {
- return 3;
- }
- else if (to == ScriptRuntime.DateClass) {
- if (fromObj instanceof NativeDate) {
- // This is a native date to java date conversion
- return 1;
- }
- }
- else if (to.isInterface()) {
- if (fromObj instanceof Function) {
- // See comments in coerceType
- if (to.getMethods().length == 1) {
- return 1;
- }
- }
- return 11;
- }
- else if (to.isPrimitive() && to != Boolean.TYPE) {
- return 3 + getSizeRank(to);
- }
- break;
- }
-
- return CONVERSION_NONE;
- }
-
- static int getSizeRank(Class aType) {
- if (aType == Double.TYPE) {
- return 1;
- }
- else if (aType == Float.TYPE) {
- return 2;
- }
- else if (aType == Long.TYPE) {
- return 3;
- }
- else if (aType == Integer.TYPE) {
- return 4;
- }
- else if (aType == Short.TYPE) {
- return 5;
- }
- else if (aType == Character.TYPE) {
- return 6;
- }
- else if (aType == Byte.TYPE) {
- return 7;
- }
- else if (aType == Boolean.TYPE) {
- return CONVERSION_NONE;
- }
- else {
- return 8;
- }
- }
-
- private static int getJSTypeCode(Object value) {
- if (value == null) {
- return JSTYPE_NULL;
- }
- else if (value == Undefined.instance) {
- return JSTYPE_UNDEFINED;
- }
- else if (value instanceof String) {
- return JSTYPE_STRING;
- }
- else if (value instanceof Number) {
- return JSTYPE_NUMBER;
- }
- else if (value instanceof Boolean) {
- return JSTYPE_BOOLEAN;
- }
- else if (value instanceof Scriptable) {
- if (value instanceof NativeJavaClass) {
- return JSTYPE_JAVA_CLASS;
- }
- else if (value instanceof NativeJavaArray) {
- return JSTYPE_JAVA_ARRAY;
- }
- else if (value instanceof Wrapper) {
- return JSTYPE_JAVA_OBJECT;
- }
- else {
- return JSTYPE_OBJECT;
- }
- }
- else if (value instanceof Class) {
- return JSTYPE_JAVA_CLASS;
- }
- else {
- Class valueClass = value.getClass();
- if (valueClass.isArray()) {
- return JSTYPE_JAVA_ARRAY;
- }
- else {
- return JSTYPE_JAVA_OBJECT;
- }
- }
- }
-
- /**
- * Not intended for public use. Callers should use the
- * public API Context.toType.
- * @deprecated as of 1.5 Release 4
- * @see org.mozilla.javascript.Context#jsToJava(Object, Class)
- */
- public static Object coerceType(Class type, Object value)
- {
- return coerceTypeImpl(type, value);
- }
-
- /**
- * Type-munging for field setting and method invocation.
- * Conforms to LC3 specification
- */
- static Object coerceTypeImpl(Class type, Object value)
- {
- if (value != null && value.getClass() == type) {
- return value;
- }
-
- switch (getJSTypeCode(value)) {
-
- case JSTYPE_NULL:
- // raise error if type.isPrimitive()
- if (type.isPrimitive()) {
- reportConversionError(value, type);
- }
- return null;
-
- case JSTYPE_UNDEFINED:
- if (type == ScriptRuntime.StringClass ||
- type == ScriptRuntime.ObjectClass) {
- return "undefined";
- }
- else {
- reportConversionError("undefined", type);
- }
- break;
-
- case JSTYPE_BOOLEAN:
- // Under LC3, only JS Booleans can be coerced into a Boolean value
- if (type == Boolean.TYPE ||
- type == ScriptRuntime.BooleanClass ||
- type == ScriptRuntime.ObjectClass) {
- return value;
- }
- else if (type == ScriptRuntime.StringClass) {
- return value.toString();
- }
- else {
- reportConversionError(value, type);
- }
- break;
-
- case JSTYPE_NUMBER:
- if (type == ScriptRuntime.StringClass) {
- return ScriptRuntime.toString(value);
- }
- else if (type == ScriptRuntime.ObjectClass) {
- return coerceToNumber(Double.TYPE, value);
- }
- else if ((type.isPrimitive() && type != Boolean.TYPE) ||
- ScriptRuntime.NumberClass.isAssignableFrom(type)) {
- return coerceToNumber(type, value);
- }
- else {
- reportConversionError(value, type);
- }
- break;
-
- case JSTYPE_STRING:
- if (type == ScriptRuntime.StringClass || type.isInstance(value)) {
- return value;
- }
- else if (type == Character.TYPE
- || type == ScriptRuntime.CharacterClass)
- {
- // Special case for converting a single char string to a
- // character
- // Placed here because it applies *only* to JS strings,
- // not other JS objects converted to strings
- if (((String)value).length() == 1) {
- return new Character(((String)value).charAt(0));
- }
- else {
- return coerceToNumber(type, value);
- }
- }
- else if ((type.isPrimitive() && type != Boolean.TYPE)
- || ScriptRuntime.NumberClass.isAssignableFrom(type))
- {
- return coerceToNumber(type, value);
- }
- else {
- reportConversionError(value, type);
- }
- break;
-
- case JSTYPE_JAVA_CLASS:
- if (value instanceof Wrapper) {
- value = ((Wrapper)value).unwrap();
- }
-
- if (type == ScriptRuntime.ClassClass ||
- type == ScriptRuntime.ObjectClass) {
- return value;
- }
- else if (type == ScriptRuntime.StringClass) {
- return value.toString();
- }
- else {
- reportConversionError(value, type);
- }
- break;
-
- case JSTYPE_JAVA_OBJECT:
- case JSTYPE_JAVA_ARRAY:
- if (value instanceof Wrapper) {
- value = ((Wrapper)value).unwrap();
- }
- if (type.isPrimitive()) {
- if (type == Boolean.TYPE) {
- reportConversionError(value, type);
- }
- return coerceToNumber(type, value);
- }
- else {
- if (type == ScriptRuntime.StringClass) {
- return value.toString();
- }
- else {
- if (type.isInstance(value)) {
- return value;
- }
- else {
- reportConversionError(value, type);
- }
- }
- }
- break;
-
- case JSTYPE_OBJECT:
- if (type == ScriptRuntime.StringClass) {
- return ScriptRuntime.toString(value);
- }
- else if (type.isPrimitive()) {
- if (type == Boolean.TYPE) {
- reportConversionError(value, type);
- }
- return coerceToNumber(type, value);
- }
- else if (type.isInstance(value)) {
- return value;
- }
- else if (type == ScriptRuntime.DateClass
- && value instanceof NativeDate)
- {
- double time = ((NativeDate)value).getJSTimeValue();
- // XXX: This will replace NaN by 0
- return new Date((long)time);
- }
- else if (type.isArray() && value instanceof NativeArray) {
- // Make a new java array, and coerce the JS array components
- // to the target (component) type.
- NativeArray array = (NativeArray) value;
- long length = array.getLength();
- Class arrayType = type.getComponentType();
- Object Result = Array.newInstance(arrayType, (int)length);
- for (int i = 0 ; i < length ; ++i) {
- try {
- Array.set(Result, i, coerceType(arrayType,
- array.get(i, array)));
- }
- catch (EvaluatorException ee) {
- reportConversionError(value, type);
- }
- }
-
- return Result;
- }
- else if (value instanceof Wrapper) {
- value = ((Wrapper)value).unwrap();
- if (type.isInstance(value))
- return value;
- reportConversionError(value, type);
- }
- else if (type.isInterface() && value instanceof Callable) {
- // Try to use function as implementation of Java interface.
- //
- // XXX: Curently only instances of ScriptableObject are
- // supported since the resulting interface proxies should
- // be reused next time conversion is made and generic
- // Callable has no storage for it. Weak references can
- // address it but for now use this restriction.
- if (value instanceof ScriptableObject) {
- ScriptableObject so = (ScriptableObject)value;
- Object key = Kit.makeHashKeyFromPair(
- COERCED_INTERFACE_KEY, type);
- Object old = so.getAssociatedValue(key);
- if (old != null) {
- // Function was already wrapped
- return old;
- }
- Context cx = Context.getContext();
- Object glue
- = InterfaceAdapter.create(cx, type, (Callable)value);
- // Store for later retrival
- glue = so.associateValue(key, glue);
- return glue;
- }
- reportConversionError(value, type);
- } else {
- reportConversionError(value, type);
- }
- break;
- }
-
- return value;
- }
-
- private static Object coerceToNumber(Class type, Object value)
- {
- Class valueClass = value.getClass();
-
- // Character
- if (type == Character.TYPE || type == ScriptRuntime.CharacterClass) {
- if (valueClass == ScriptRuntime.CharacterClass) {
- return value;
- }
- return new Character((char)toInteger(value,
- ScriptRuntime.CharacterClass,
- Character.MIN_VALUE,
- Character.MAX_VALUE));
- }
-
- // Double, Float
- if (type == ScriptRuntime.ObjectClass ||
- type == ScriptRuntime.DoubleClass || type == Double.TYPE) {
- return valueClass == ScriptRuntime.DoubleClass
- ? value
- : new Double(toDouble(value));
- }
-
- if (type == ScriptRuntime.FloatClass || type == Float.TYPE) {
- if (valueClass == ScriptRuntime.FloatClass) {
- return value;
- }
- else {
- double number = toDouble(value);
- if (Double.isInfinite(number) || Double.isNaN(number)
- || number == 0.0) {
- return new Float((float)number);
- }
- else {
- double absNumber = Math.abs(number);
- if (absNumber < Float.MIN_VALUE) {
- return new Float((number > 0.0) ? +0.0 : -0.0);
- }
- else if (absNumber > Float.MAX_VALUE) {
- return new Float((number > 0.0) ?
- Float.POSITIVE_INFINITY :
- Float.NEGATIVE_INFINITY);
- }
- else {
- return new Float((float)number);
- }
- }
- }
- }
-
- // Integer, Long, Short, Byte
- if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE) {
- if (valueClass == ScriptRuntime.IntegerClass) {
- return value;
- }
- else {
- return new Integer((int)toInteger(value,
- ScriptRuntime.IntegerClass,
- Integer.MIN_VALUE,
- Integer.MAX_VALUE));
- }
- }
-
- if (type == ScriptRuntime.LongClass || type == Long.TYPE) {
- if (valueClass == ScriptRuntime.LongClass) {
- return value;
- } else {
- /* Long values cannot be expressed exactly in doubles.
- * We thus use the largest and smallest double value that
- * has a value expressible as a long value. We build these
- * numerical values from their hexidecimal representations
- * to avoid any problems caused by attempting to parse a
- * decimal representation.
- */
- final double max = Double.longBitsToDouble(0x43dfffffffffffffL);
- final double min = Double.longBitsToDouble(0xc3e0000000000000L);
- return new Long(toInteger(value,
- ScriptRuntime.LongClass,
- min,
- max));
- }
- }
-
- if (type == ScriptRuntime.ShortClass || type == Short.TYPE) {
- if (valueClass == ScriptRuntime.ShortClass) {
- return value;
- }
- else {
- return new Short((short)toInteger(value,
- ScriptRuntime.ShortClass,
- Short.MIN_VALUE,
- Short.MAX_VALUE));
- }
- }
-
- if (type == ScriptRuntime.ByteClass || type == Byte.TYPE) {
- if (valueClass == ScriptRuntime.ByteClass) {
- return value;
- }
- else {
- return new Byte((byte)toInteger(value,
- ScriptRuntime.ByteClass,
- Byte.MIN_VALUE,
- Byte.MAX_VALUE));
- }
- }
-
- return new Double(toDouble(value));
- }
-
-
- private static double toDouble(Object value)
- {
- if (value instanceof Number) {
- return ((Number)value).doubleValue();
- }
- else if (value instanceof String) {
- return ScriptRuntime.toNumber((String)value);
- }
- else if (value instanceof Scriptable) {
- if (value instanceof Wrapper) {
- // XXX: optimize tail-recursion?
- return toDouble(((Wrapper)value).unwrap());
- }
- else {
- return ScriptRuntime.toNumber(value);
- }
- }
- else {
- Method meth;
- try {
- meth = value.getClass().getMethod("doubleValue",
- (Class [])null);
- }
- catch (NoSuchMethodException e) {
- meth = null;
- }
- catch (SecurityException e) {
- meth = null;
- }
- if (meth != null) {
- try {
- return ((Number)meth.invoke(value,
- (Object [])null)).doubleValue();
- }
- catch (IllegalAccessException e) {
- // XXX: ignore, or error message?
- reportConversionError(value, Double.TYPE);
- }
- catch (InvocationTargetException e) {
- // XXX: ignore, or error message?
- reportConversionError(value, Double.TYPE);
- }
- }
- return ScriptRuntime.toNumber(value.toString());
- }
- }
-
- private static long toInteger(Object value, Class type,
- double min, double max)
- {
- double d = toDouble(value);
-
- if (Double.isInfinite(d) || Double.isNaN(d)) {
- // Convert to string first, for more readable message
- reportConversionError(ScriptRuntime.toString(value), type);
- }
-
- if (d > 0.0) {
- d = Math.floor(d);
- }
- else {
- d = Math.ceil(d);
- }
-
- if (d < min || d > max) {
- // Convert to string first, for more readable message
- reportConversionError(ScriptRuntime.toString(value), type);
- }
- return (long)d;
- }
-
- static void reportConversionError(Object value, Class type)
- {
- // It uses String.valueOf(value), not value.toString() since
- // value can be null, bug 282447.
- throw Context.reportRuntimeError2(
- "msg.conversion.not.allowed",
- String.valueOf(value),
- JavaMembers.javaSignature(type));
- }
-
- private void writeObject(ObjectOutputStream out)
- throws IOException
- {
- out.defaultWriteObject();
-
- out.writeBoolean(isAdapter);
- if (isAdapter) {
- if (adapter_writeAdapterObject == null) {
- throw new IOException();
- }
- Object[] args = { javaObject, out };
- try {
- adapter_writeAdapterObject.invoke(null, args);
- } catch (Exception ex) {
- throw new IOException();
- }
- } else {
- out.writeObject(javaObject);
- }
-
- if (staticType != null) {
- out.writeObject(staticType.getClass().getName());
- } else {
- out.writeObject(null);
- }
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
-
- isAdapter = in.readBoolean();
- if (isAdapter) {
- if (adapter_readAdapterObject == null)
- throw new ClassNotFoundException();
- Object[] args = { this, in };
- try {
- javaObject = adapter_readAdapterObject.invoke(null, args);
- } catch (Exception ex) {
- throw new IOException();
- }
- } else {
- javaObject = in.readObject();
- }
-
- String className = (String)in.readObject();
- if (className != null) {
- staticType = Class.forName(className);
- } else {
- staticType = null;
- }
-
- initMembers();
- }
-
- /**
- * The prototype of this object.
- */
- protected Scriptable prototype;
-
- /**
- * The parent scope of this object.
- */
- protected Scriptable parent;
-
- protected transient Object javaObject;
-
- protected transient Class staticType;
- protected transient JavaMembers members;
- private transient Hashtable fieldAndMethods;
- private transient boolean isAdapter;
-
- private static final Object COERCED_INTERFACE_KEY = new Object();
- private static Method adapter_writeAdapterObject;
- private static Method adapter_readAdapterObject;
-
- static {
- // Reflection in java is verbose
- Class[] sig2 = new Class[2];
- Class cl = Kit.classOrNull("org.mozilla.javascript.JavaAdapter");
- if (cl != null) {
- try {
- sig2[0] = ScriptRuntime.ObjectClass;
- sig2[1] = Kit.classOrNull("java.io.ObjectOutputStream");
- adapter_writeAdapterObject = cl.getMethod("writeAdapterObject",
- sig2);
-
- sig2[0] = ScriptRuntime.ScriptableClass;
- sig2[1] = Kit.classOrNull("java.io.ObjectInputStream");
- adapter_readAdapterObject = cl.getMethod("readAdapterObject",
- sig2);
-
- } catch (Exception ex) {
- adapter_writeAdapterObject = null;
- adapter_readAdapterObject = null;
- }
- }
- }
-
-}