?? nativejavaobject.java
字號:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape 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/NPL/ * * 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 Netscape are * Copyright (C) 1997-2000 Netscape Communications Corporation. 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 Public License (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 NPL, indicate your decision by * deleting the provisions above and replace 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 NPL or the GPL. */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.parent = scope; this.javaObject = javaObject; this.staticType = staticType; initMembers(); } protected void initMembers() { Class dynamicType; if (javaObject != null) { dynamicType = javaObject.getClass(); } else { dynamicType = staticType; } members = JavaMembers.lookupClass(parent, dynamicType, staticType); 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 {@linkWrapFactory#wrap(Context cx, Scriptable scope, Object obj, 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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -