Code for NativeJavaPackage.TopLevelPackage is moved to a separated file NativeJavaTopPackage.java
This commit is contained in:
igor%mir2.org 2003-09-03 10:42:36 +00:00
Родитель 31972bf975
Коммит 67749a7953
3 изменённых файлов: 216 добавлений и 178 удалений

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

@ -722,15 +722,15 @@ public class Context {
// This creates the Packages and java package roots. // This creates the Packages and java package roots.
new LazilyLoadedCtor(scope, new LazilyLoadedCtor(scope,
"Packages", "Packages",
"org.mozilla.javascript.NativeJavaPackage", "org.mozilla.javascript.NativeJavaTopPackage",
sealed); sealed);
new LazilyLoadedCtor(scope, new LazilyLoadedCtor(scope,
"java", "java",
"org.mozilla.javascript.NativeJavaPackage", "org.mozilla.javascript.NativeJavaTopPackage",
sealed); sealed);
new LazilyLoadedCtor(scope, new LazilyLoadedCtor(scope,
"getClass", "getClass",
"org.mozilla.javascript.NativeJavaPackage", "org.mozilla.javascript.NativeJavaTopPackage",
sealed); sealed);
// Define the JavaAdapter class, allowing it to be overridden. // Define the JavaAdapter class, allowing it to be overridden.

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

@ -54,132 +54,6 @@ import java.lang.reflect.*;
public class NativeJavaPackage extends ScriptableObject { 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) { public NativeJavaPackage(String packageName, ClassLoader classLoader) {
this.packageName = packageName; this.packageName = packageName;
this.classLoader = classLoader; this.classLoader = classLoader;
@ -213,6 +87,34 @@ public class NativeJavaPackage extends ScriptableObject {
return NOT_FOUND; 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, synchronized Object getPkgProperty(String name, Scriptable start,
boolean createPkg) boolean createPkg)
{ {
@ -220,14 +122,18 @@ public class NativeJavaPackage extends ScriptableObject {
if (cached != NOT_FOUND) if (cached != NOT_FOUND)
return cached; return cached;
String newPackage = packageName.length() == 0 String className = (packageName.length() == 0)
? name ? name : packageName + '.' + name;
: packageName + '.' + name;
Context cx = Context.getContext(); Context cx = Context.getContext();
ClassShutter shutter = cx.getClassShutter(); ClassShutter shutter = cx.getClassShutter();
Scriptable newValue = null; Scriptable newValue = null;
if (shutter == null || shutter.visibleToScripts(newPackage)) { if (shutter == null || shutter.visibleToScripts(className)) {
Class cl = findClass(cx, newPackage); Class cl = null;
if (classLoader != null) {
cl = ScriptRuntime.classOrNull(classLoader, className);
} else {
cl = ScriptRuntime.classOrNull(className);
}
if (cl != null) { if (cl != null) {
newValue = new NativeJavaClass(getTopLevelScope(this), cl); newValue = new NativeJavaClass(getTopLevelScope(this), cl);
newValue.setParentScope(this); newValue.setParentScope(this);
@ -235,7 +141,7 @@ public class NativeJavaPackage extends ScriptableObject {
} }
} }
if (newValue == null && createPkg) { if (newValue == null && createPkg) {
NativeJavaPackage pkg = new NativeJavaPackage(newPackage, NativeJavaPackage pkg = new NativeJavaPackage(className,
classLoader); classLoader);
pkg.setParentScope(this); pkg.setParentScope(this);
pkg.setPrototype(this.prototype); pkg.setPrototype(this.prototype);
@ -257,49 +163,6 @@ public class NativeJavaPackage extends ScriptableObject {
return "[JavaPackage " + packageName + "]"; 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 String packageName;
private ClassLoader classLoader; private ClassLoader classLoader;
} }

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

@ -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"));
}
}