From 67749a7953fb2e0a65ef9fc8fa0ce54e11755b7d Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Wed, 3 Sep 2003 10:42:36 +0000 Subject: [PATCH] Work for http://bugzilla.mozilla.org/show_bug.cgi?id=213279 : Code for NativeJavaPackage.TopLevelPackage is moved to a separated file NativeJavaTopPackage.java --- .../src/org/mozilla/javascript/Context.java | 6 +- .../mozilla/javascript/NativeJavaPackage.java | 213 ++++-------------- .../javascript/NativeJavaTopPackage.java | 175 ++++++++++++++ 3 files changed, 216 insertions(+), 178 deletions(-) create mode 100644 js/rhino/src/org/mozilla/javascript/NativeJavaTopPackage.java diff --git a/js/rhino/src/org/mozilla/javascript/Context.java b/js/rhino/src/org/mozilla/javascript/Context.java index 032f917369a..0ae490e397e 100644 --- a/js/rhino/src/org/mozilla/javascript/Context.java +++ b/js/rhino/src/org/mozilla/javascript/Context.java @@ -722,15 +722,15 @@ public class Context { // This creates the Packages and java package roots. new LazilyLoadedCtor(scope, "Packages", - "org.mozilla.javascript.NativeJavaPackage", + "org.mozilla.javascript.NativeJavaTopPackage", sealed); new LazilyLoadedCtor(scope, "java", - "org.mozilla.javascript.NativeJavaPackage", + "org.mozilla.javascript.NativeJavaTopPackage", sealed); new LazilyLoadedCtor(scope, "getClass", - "org.mozilla.javascript.NativeJavaPackage", + "org.mozilla.javascript.NativeJavaTopPackage", sealed); // Define the JavaAdapter class, allowing it to be overridden. diff --git a/js/rhino/src/org/mozilla/javascript/NativeJavaPackage.java b/js/rhino/src/org/mozilla/javascript/NativeJavaPackage.java index 8937091abb5..ebfd3de704c 100644 --- a/js/rhino/src/org/mozilla/javascript/NativeJavaPackage.java +++ b/js/rhino/src/org/mozilla/javascript/NativeJavaPackage.java @@ -54,132 +54,6 @@ import java.lang.reflect.*; public class NativeJavaPackage extends ScriptableObject { - // we know these are packages so we can skip the class check - // note that this is ok even if the package isn't present. - private static final String commonPackages = "" - +"java.lang;" - +"java.lang.reflect" - +"java.io;" - +"java.math;" - +"java.net;" - +"java.util;" - +"java.util.zip;" - +"java.text;" - +"java.text.resources;" - +"java.applet;" - +"javax.swing;" - ; - - public static class TopLevelPackage extends NativeJavaPackage - implements Function - { - public TopLevelPackage() { - super(""); - } - - public Object call(Context cx, Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - return construct(cx, scope, args); - } - - public Scriptable construct(Context cx, Scriptable scope, Object[] args) - throws JavaScriptException - { - ClassLoader loader = getClassLoaderFromArgs(args); - if (loader == null) { - Context.reportRuntimeError0("msg.not.classloader"); - return null; - } - return new NativeJavaPackage("", loader); - } - - private ClassLoader getClassLoaderFromArgs(Object[] args) { - if (args.length < 1) { - return null; - } - Object arg = args[0]; - if (arg instanceof Wrapper) { - arg = ((Wrapper)arg).unwrap(); - } - if (!(arg instanceof ClassLoader)) { - return null; - } - return (ClassLoader) arg; - } - - } - public static Scriptable init(Scriptable scope) - throws PropertyException - { - final NativeJavaPackage packages = new TopLevelPackage(); - packages.setPrototype(getObjectPrototype(scope)); - packages.setParentScope(scope); - - // We want to get a real alias, and not a distinct JavaPackage - // with the same packageName, so that we share classes and packages - // that are underneath. - NativeJavaPackage javaAlias = (NativeJavaPackage)packages.get("java", - packages); - - for (int nameStart = 0; ;) { - int nameEnd = commonPackages.indexOf(';', nameStart); - if (nameEnd < 0) { break; } - String packageName = commonPackages.substring(nameStart, nameEnd); - packages.forcePackage(packageName); - nameStart = nameEnd + 1; - } - - JIFunction getClass = new JIFunction("getClass", 1) { - public Object call(Context fcx, Scriptable fscope, - Scriptable thisObj, Object[] args) - { - return js_getClass(fcx, fscope, packages, args); - } - }; - - // It's safe to downcast here since initStandardObjects takes - // a ScriptableObject. - ScriptableObject global = (ScriptableObject) scope; - - getClass.defineAsProperty(global, ScriptableObject.DONTENUM); - global.defineProperty("Packages", packages, ScriptableObject.DONTENUM); - global.defineProperty("java", javaAlias, ScriptableObject.DONTENUM); - - // I think I'm supposed to return the prototype, but I don't have one. - return packages; - } - - // set up a name which is known to be a package so we don't - // need to look for a class by that name - void forcePackage(String name) { - NativeJavaPackage pkg; - int end = name.indexOf('.'); - if (end == -1) - end = name.length(); - - String id = name.substring(0, end); - Object cached = super.get(id, this); - if (cached != null && cached instanceof NativeJavaPackage) { - pkg = (NativeJavaPackage) cached; - } else { - String newPackage = packageName.length() == 0 - ? id - : packageName + "." + id; - pkg = new NativeJavaPackage(newPackage, classLoader); - pkg.setParentScope(this); - pkg.setPrototype(this.prototype); - super.put(id, this, pkg); - } - if (end < name.length()) - pkg.forcePackage(name.substring(end+1)); - } - - public NativeJavaPackage(String packageName) { - this(packageName, null); - } - public NativeJavaPackage(String packageName, ClassLoader classLoader) { this.packageName = packageName; this.classLoader = classLoader; @@ -213,6 +87,34 @@ public class NativeJavaPackage extends ScriptableObject { return NOT_FOUND; } + // set up a name which is known to be a package so we don't + // need to look for a class by that name + void forcePackage(String name) + { + NativeJavaPackage pkg; + int end = name.indexOf('.'); + if (end == -1) { + end = name.length(); + } + + String id = name.substring(0, end); + Object cached = super.get(id, this); + if (cached != null && cached instanceof NativeJavaPackage) { + pkg = (NativeJavaPackage) cached; + } else { + String newPackage = packageName.length() == 0 + ? id + : packageName + "." + id; + pkg = new NativeJavaPackage(newPackage, classLoader); + pkg.setParentScope(this); + pkg.setPrototype(this.prototype); + super.put(id, this, pkg); + } + if (end < name.length()) { + pkg.forcePackage(name.substring(end+1)); + } + } + synchronized Object getPkgProperty(String name, Scriptable start, boolean createPkg) { @@ -220,14 +122,18 @@ public class NativeJavaPackage extends ScriptableObject { if (cached != NOT_FOUND) return cached; - String newPackage = packageName.length() == 0 - ? name - : packageName + '.' + name; + String className = (packageName.length() == 0) + ? name : packageName + '.' + name; Context cx = Context.getContext(); ClassShutter shutter = cx.getClassShutter(); Scriptable newValue = null; - if (shutter == null || shutter.visibleToScripts(newPackage)) { - Class cl = findClass(cx, newPackage); + if (shutter == null || shutter.visibleToScripts(className)) { + Class cl = null; + if (classLoader != null) { + cl = ScriptRuntime.classOrNull(classLoader, className); + } else { + cl = ScriptRuntime.classOrNull(className); + } if (cl != null) { newValue = new NativeJavaClass(getTopLevelScope(this), cl); newValue.setParentScope(this); @@ -235,7 +141,7 @@ public class NativeJavaPackage extends ScriptableObject { } } if (newValue == null && createPkg) { - NativeJavaPackage pkg = new NativeJavaPackage(newPackage, + NativeJavaPackage pkg = new NativeJavaPackage(className, classLoader); pkg.setParentScope(this); pkg.setPrototype(this.prototype); @@ -257,49 +163,6 @@ public class NativeJavaPackage extends ScriptableObject { return "[JavaPackage " + packageName + "]"; } - static final Scriptable js_getClass(Context cx, Scriptable scope, - NativeJavaPackage top, Object[] args) - { - if (args.length > 0 && args[0] instanceof Wrapper) { - Scriptable result = top; - Class cl = ((Wrapper) args[0]).unwrap().getClass(); - // Evaluate the class name by getting successive properties of - // the string to find the appropriate NativeJavaClass object - String name = cl.getName(); - int offset = 0; - for (;;) { - int index = name.indexOf('.', offset); - String propName = index == -1 - ? name.substring(offset) - : name.substring(offset, index); - Object prop = result.get(propName, result); - if (!(prop instanceof Scriptable)) - break; // fall through to error - result = (Scriptable) prop; - if (index == -1) - return result; - offset = index+1; - } - } - throw Context.reportRuntimeError( - Context.getMessage0("msg.not.java.obj")); - } - - private Class findClass(Context cx, String className) - { - Class cl = null; - ClassLoader loader = classLoader; - if (loader == null) { - loader = cx.getApplicationClassLoader(); - } - if (loader != null) { - cl = ScriptRuntime.classOrNull(loader, className); - } else { - cl = ScriptRuntime.classOrNull(className); - } - return cl; - } - private String packageName; private ClassLoader classLoader; } diff --git a/js/rhino/src/org/mozilla/javascript/NativeJavaTopPackage.java b/js/rhino/src/org/mozilla/javascript/NativeJavaTopPackage.java new file mode 100644 index 00000000000..1821ca480f4 --- /dev/null +++ b/js/rhino/src/org/mozilla/javascript/NativeJavaTopPackage.java @@ -0,0 +1,175 @@ +/* -*- 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-1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Norris Boyd + * Frank Mitchell + * Mike Shaver + * + * 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.lang.reflect.*; + +/** + * This class reflects Java packages into the JavaScript environment. We + * lazily reflect classes and subpackages, and use a caching/sharing + * system to ensure that members reflected into one JavaPackage appear + * in all other references to the same package (as with Packages.java.lang + * and java.lang). + * + * @author Mike Shaver + * @see NativeJavaArray + * @see NativeJavaObject + * @see NativeJavaClass + */ + +public class NativeJavaTopPackage + extends NativeJavaPackage implements Function +{ + + // we know these are packages so we can skip the class check + // note that this is ok even if the package isn't present. + private static final String commonPackages = "" + +"java.lang;" + +"java.lang.reflect" + +"java.io;" + +"java.math;" + +"java.net;" + +"java.util;" + +"java.util.zip;" + +"java.text;" + +"java.text.resources;" + +"java.applet;" + +"javax.swing;" + ; + + public NativeJavaTopPackage(ClassLoader loader) + { + super("", loader); + } + + public Object call(Context cx, Scriptable scope, Scriptable thisObj, + Object[] args) + throws JavaScriptException + { + return construct(cx, scope, args); + } + + public Scriptable construct(Context cx, Scriptable scope, Object[] args) + throws JavaScriptException + { + ClassLoader loader = null; + if (args.length != 0) { + Object arg = args[0]; + if (arg instanceof Wrapper) { + arg = ((Wrapper)arg).unwrap(); + } + if (arg instanceof ClassLoader) { + loader = (ClassLoader)arg; + } + } + if (loader == null) { + Context.reportRuntimeError0("msg.not.classloader"); + return null; + } + return new NativeJavaPackage("", loader); + } + + public static void init(Context cx, Scriptable scope, boolean sealed) + throws PropertyException + { + ClassLoader loader = cx.getApplicationClassLoader(); + final NativeJavaTopPackage top = new NativeJavaTopPackage(loader); + top.setPrototype(getObjectPrototype(scope)); + top.setParentScope(scope); + + for (int nameStart = 0; ;) { + int nameEnd = commonPackages.indexOf(';', nameStart); + if (nameEnd < 0) { break; } + String packageName = commonPackages.substring(nameStart, nameEnd); + top.forcePackage(packageName); + nameStart = nameEnd + 1; + } + + // getClass implementation + JIFunction getClass = new JIFunction("getClass", 1) { + public Object call(Context fcx, Scriptable fscope, + Scriptable thisObj, Object[] args) + { + return top.js_getClass(fcx, fscope, args); + } + }; + + // We want to get a real alias, and not a distinct JavaPackage + // with the same packageName, so that we share classes and top + // that are underneath. + NativeJavaPackage javaAlias = (NativeJavaPackage)top.get("java", + top); + + // It's safe to downcast here since initStandardObjects takes + // a ScriptableObject. + ScriptableObject global = (ScriptableObject) scope; + + getClass.defineAsProperty(global, ScriptableObject.DONTENUM); + global.defineProperty("Packages", top, ScriptableObject.DONTENUM); + global.defineProperty("java", javaAlias, ScriptableObject.DONTENUM); + } + + final Scriptable js_getClass(Context cx, Scriptable scope, Object[] args) + { + if (args.length > 0 && args[0] instanceof Wrapper) { + Scriptable result = this; + Class cl = ((Wrapper) args[0]).unwrap().getClass(); + // Evaluate the class name by getting successive properties of + // the string to find the appropriate NativeJavaClass object + String name = cl.getName(); + int offset = 0; + for (;;) { + int index = name.indexOf('.', offset); + String propName = index == -1 + ? name.substring(offset) + : name.substring(offset, index); + Object prop = result.get(propName, result); + if (!(prop instanceof Scriptable)) + break; // fall through to error + result = (Scriptable) prop; + if (index == -1) + return result; + offset = index+1; + } + } + throw Context.reportRuntimeError( + Context.getMessage0("msg.not.java.obj")); + } + +} +