Add new Context method "toType" to convert to a specified Java type

This commit is contained in:
nboyd%atg.com 2002-02-12 14:30:27 +00:00
Родитель 797571ad23
Коммит 9cdc547eaa
7 изменённых файлов: 84 добавлений и 46 удалений

Просмотреть файл

@ -175,7 +175,7 @@ public class Context {
Thread old = cx.currentThread;
if (old != null && old != t) {
throw new RuntimeException
("Can not enter on Context active on another thread");
("Cannot enter Context active on another thread");
}
if (Context.check && old == t && cx != current)
Context.codeBug();
@ -1227,6 +1227,23 @@ public class Context {
return ScriptRuntime.toObject(scope, value, staticType);
}
/**
* Convert a JavaScript value into the desired type.
* Uses the semantics defined with LiveConnect3 and throws an
* Illegal argument exception if the conversion cannot be performed.
* @param value the JavaScript value to convert
* @param desired type the Java type to convert to. Primitive Java
* types are represented using the TYPE fields in the corresponding
* wrapper class in java.lang.
* @return the converted value
* @throws IllegalArgumentException if the conversion cannot be performed
*/
public static Object toType(Object value, Class desiredType)
throws IllegalArgumentException
{
return NativeJavaObject.coerceType(desiredType, value, false);
}
/**
* Tell whether debug information is being generated.
* @since 1.3

Просмотреть файл

@ -66,7 +66,7 @@ public class JavaAdapter extends ScriptableObject {
// Avoid an error for an undefined value; return null instead.
return null;
}
return NativeJavaObject.coerceType(c, result);
return NativeJavaObject.coerceType(c, result, true);
}
public static Scriptable setAdapterProto(Scriptable obj, Object adapter) {

Просмотреть файл

@ -215,8 +215,9 @@ class JavaMembers {
if (method == null)
throw reportMemberNotFound(name);
Class[] types = method.getParameterTypes();
Object[] params = { NativeJavaObject.coerceType(types[0], value) };
method.invoke(javaObject, params);
Object[] args = { NativeJavaObject.coerceType(types[0], value,
true) };
method.invoke(javaObject, args);
} catch (IllegalAccessException accessEx) {
throw new RuntimeException("unexpected IllegalAccessException " +
"accessing Java field");
@ -234,7 +235,8 @@ class JavaMembers {
"msg.java.internal.private", name);
}
field.set(javaObject,
NativeJavaObject.coerceType(field.getType(), value));
NativeJavaObject.coerceType(field.getType(), value,
true));
} catch (ClassCastException e) {
throw Context.reportRuntimeError1(
"msg.java.method.assign", name);

Просмотреть файл

@ -110,7 +110,8 @@ public class NativeJavaArray extends NativeJavaObject {
public void put(int index, Scriptable start, Object value) {
if (0 <= index && index < length) {
Array.set(array, index, NativeJavaObject.coerceType(cls, value));
Array.set(array, index, NativeJavaObject.coerceType(cls, value,
true));
return;
}
super.put(index, start, value);

Просмотреть файл

@ -218,7 +218,7 @@ public class NativeJavaClass extends NativeJavaObject implements Function {
Class[] paramTypes = ctor.getParameterTypes();
for (int i = 0; i < args.length; i++) {
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i]);
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i], true);
}
try {
// we need to force this to be wrapped, because construct _has_

Просмотреть файл

@ -204,7 +204,7 @@ public class NativeJavaMethod extends NativeFunction implements Function {
// First, we marshall the args.
for (int i = 0; i < args.length; i++) {
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i]);
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i], true);
}
Object javaObject;
if (Modifier.isStatic(meth.getModifiers())) {

Просмотреть файл

@ -506,7 +506,9 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
* Type-munging for field setting and method invocation.
* Conforms to LC3 specification
*/
public static Object coerceType(Class type, Object value) {
public static Object coerceType(Class type, Object value,
boolean useErrorHandler)
{
if (value != null && value.getClass() == type) {
return value;
}
@ -516,7 +518,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
case JSTYPE_NULL:
// raise error if type.isPrimitive()
if (type.isPrimitive()) {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
return null;
@ -526,7 +528,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return "undefined";
}
else {
reportConversionError("undefined", type);
reportConversionError("undefined", type, !useErrorHandler);
}
break;
@ -541,7 +543,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return value.toString();
}
else {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
break;
@ -550,14 +552,14 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return ScriptRuntime.toString(value);
}
else if (type == ScriptRuntime.ObjectClass) {
return coerceToNumber(Double.TYPE, value);
return coerceToNumber(Double.TYPE, value, useErrorHandler);
}
else if ((type.isPrimitive() && type != Boolean.TYPE) ||
ScriptRuntime.NumberClass.isAssignableFrom(type)) {
return coerceToNumber(type, value);
return coerceToNumber(type, value, useErrorHandler);
}
else {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
break;
@ -576,15 +578,15 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return new Character(((String)value).charAt(0));
}
else {
return coerceToNumber(type, value);
return coerceToNumber(type, value, useErrorHandler);
}
}
else if ((type.isPrimitive() && type != Boolean.TYPE) ||
ScriptRuntime.NumberClass.isAssignableFrom(type)) {
return coerceToNumber(type, value);
return coerceToNumber(type, value, useErrorHandler);
}
else {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
break;
@ -607,7 +609,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return value.toString();
}
else {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
}
break;
@ -616,9 +618,9 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
case JSTYPE_JAVA_ARRAY:
if (type.isPrimitive()) {
if (type == Boolean.TYPE) {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
return coerceToNumber(type, value);
return coerceToNumber(type, value, useErrorHandler);
}
else {
if (value instanceof Wrapper) {
@ -632,7 +634,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return value;
}
else {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
}
}
@ -649,9 +651,9 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
}
else if (type.isPrimitive()) {
if (type == Boolean.TYPE) {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
return coerceToNumber(type, value);
return coerceToNumber(type, value, useErrorHandler);
}
else if (type.isInstance(value)) {
return value;
@ -666,10 +668,11 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
for (int i = 0 ; i < length ; ++i) {
try {
Array.set(Result, i, coerceType(arrayType,
array.get(i, array)));
array.get(i, array),
useErrorHandler));
}
catch (EvaluatorException ee) {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
}
@ -679,10 +682,10 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
value = ((Wrapper)value).unwrap();
if (type.isInstance(value))
return value;
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
else {
reportConversionError(value, type);
reportConversionError(value, type, !useErrorHandler);
}
break;
}
@ -712,7 +715,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
}
}
static Object coerceToNumber(Class type, Object value) {
static Object coerceToNumber(Class type, Object value, boolean useErrorHandler) {
Class valueClass = value.getClass();
// Character
@ -723,7 +726,8 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return new Character((char)toInteger(value,
ScriptRuntime.CharacterClass,
(double)Character.MIN_VALUE,
(double)Character.MAX_VALUE));
(double)Character.MAX_VALUE,
useErrorHandler));
}
// Double, Float
@ -731,7 +735,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
type == ScriptRuntime.DoubleClass || type == Double.TYPE) {
return valueClass == ScriptRuntime.DoubleClass
? value
: new Double(toDouble(value));
: new Double(toDouble(value, useErrorHandler));
}
if (type == ScriptRuntime.FloatClass || type == Float.TYPE) {
@ -739,7 +743,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return value;
}
else {
double number = toDouble(value);
double number = toDouble(value, useErrorHandler);
if (Double.isInfinite(number) || Double.isNaN(number)
|| number == 0.0) {
return new Float((float)number);
@ -770,7 +774,8 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return new Integer((int)toInteger(value,
ScriptRuntime.IntegerClass,
(double)Integer.MIN_VALUE,
(double)Integer.MAX_VALUE));
(double)Integer.MAX_VALUE,
useErrorHandler));
}
}
@ -791,7 +796,8 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return new Long(toInteger(value,
ScriptRuntime.LongClass,
min,
max));
max,
useErrorHandler));
}
}
@ -803,7 +809,8 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return new Short((short)toInteger(value,
ScriptRuntime.ShortClass,
(double)Short.MIN_VALUE,
(double)Short.MAX_VALUE));
(double)Short.MAX_VALUE,
useErrorHandler));
}
}
@ -815,15 +822,16 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
return new Byte((byte)toInteger(value,
ScriptRuntime.ByteClass,
(double)Byte.MIN_VALUE,
(double)Byte.MAX_VALUE));
(double)Byte.MAX_VALUE,
useErrorHandler));
}
}
return new Double(toDouble(value));
return new Double(toDouble(value, useErrorHandler));
}
static double toDouble(Object value) {
static double toDouble(Object value, boolean useErrorHandler) {
if (value instanceof Number) {
return ((Number)value).doubleValue();
}
@ -833,7 +841,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
else if (value instanceof Scriptable) {
if (value instanceof Wrapper) {
// XXX: optimize tail-recursion?
return toDouble(((Wrapper)value).unwrap());
return toDouble(((Wrapper)value).unwrap(), useErrorHandler);
}
else {
return ScriptRuntime.toNumber(value);
@ -856,23 +864,26 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
}
catch (IllegalAccessException e) {
// XXX: ignore, or error message?
reportConversionError(value, Double.TYPE);
reportConversionError(value, Double.TYPE, !useErrorHandler);
}
catch (InvocationTargetException e) {
// XXX: ignore, or error message?
reportConversionError(value, Double.TYPE);
reportConversionError(value, Double.TYPE, !useErrorHandler);
}
}
return ScriptRuntime.toNumber(value.toString());
}
}
static long toInteger(Object value, Class type, double min, double max) {
double d = toDouble(value);
static long toInteger(Object value, Class type, double min, double max,
boolean useErrorHandler)
{
double d = toDouble(value, useErrorHandler);
if (Double.isInfinite(d) || Double.isNaN(d)) {
// Convert to string first, for more readable message
reportConversionError(ScriptRuntime.toString(value), type);
reportConversionError(ScriptRuntime.toString(value), type,
!useErrorHandler);
}
if (d > 0.0) {
@ -884,12 +895,19 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
if (d < min || d > max) {
// Convert to string first, for more readable message
reportConversionError(ScriptRuntime.toString(value), type);
reportConversionError(ScriptRuntime.toString(value), type,
!useErrorHandler);
}
return (long)d;
}
static void reportConversionError(Object value, Class type) {
static void reportConversionError(Object value, Class type,
boolean throwIllegalArg)
{
if (throwIllegalArg) {
throw new IllegalArgumentException("Cannot convert " + value +
" to type " + type);
}
throw Context.reportRuntimeError2
("msg.conversion.not.allowed",
value.toString(), NativeJavaMethod.javaSignature(type));