org.mozilla.javascript.NativeJavaTopPackage Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rhino-runtime Show documentation
Show all versions of rhino-runtime Show documentation
Rhino JavaScript runtime jar, excludes tools & JSR-223 Script Engine wrapper.
The newest version!
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.javascript;
/**
* 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, IdFunctionCall {
private static final long serialVersionUID = -1455787259477709999L;
// 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", "reflect"},
{"java", "io"},
{"java", "math"},
{"java", "net"},
{"java", "util", "zip"},
{"java", "text", "resources"},
{"java", "applet"},
{"javax", "swing"}
};
NativeJavaTopPackage(ClassLoader loader) {
super(true, "", loader);
}
@Override
public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
return construct(cx, scope, args);
}
@Override
public Scriptable construct(Context cx, Scriptable scope, Object[] args) {
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.reportRuntimeErrorById("msg.not.classloader");
return null;
}
NativeJavaPackage pkg = new NativeJavaPackage(true, "", loader);
ScriptRuntime.setObjectProtoAndParent(pkg, scope);
return pkg;
}
public static void init(Context cx, Scriptable scope, boolean sealed) {
ClassLoader loader = cx.getApplicationClassLoader();
final NativeJavaTopPackage top = new NativeJavaTopPackage(loader);
top.setPrototype(getObjectPrototype(scope));
top.setParentScope(scope);
for (int i = 0; i != commonPackages.length; i++) {
NativeJavaPackage parent = top;
for (int j = 0; j != commonPackages[i].length; j++) {
parent = parent.forcePackage(commonPackages[i][j], scope);
}
}
// getClass implementation
IdFunctionObject getClass =
new IdFunctionObject(top, FTAG, Id_getClass, "getClass", 1, scope);
// 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.
String[] topNames = ScriptRuntime.getTopPackageNames();
NativeJavaPackage[] topPackages = new NativeJavaPackage[topNames.length];
for (int i = 0; i < topNames.length; i++) {
topPackages[i] = (NativeJavaPackage) top.get(topNames[i], top);
}
// It's safe to downcast here since initStandardObjects takes
// a ScriptableObject.
ScriptableObject global = (ScriptableObject) scope;
if (sealed) {
getClass.sealObject();
}
getClass.exportAsScopeProperty();
global.defineProperty("Packages", top, ScriptableObject.DONTENUM);
for (int i = 0; i < topNames.length; i++) {
global.defineProperty(topNames[i], topPackages[i], ScriptableObject.DONTENUM);
}
}
@Override
public Object execIdCall(
IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
if (f.hasTag(FTAG)) {
if (f.methodId() == Id_getClass) {
return js_getClass(cx, scope, args);
}
}
throw f.unknown();
}
private 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.reportRuntimeErrorById("msg.not.java.obj");
}
private static final Object FTAG = "JavaTopPackage";
private static final int Id_getClass = 1;
}