зеркало из https://github.com/mozilla/gecko-dev.git
New helper class JIFunction for easy implementation of JS functions in Java without using reflection and its usage in ImporterTopLevel and NativeJavaPackage
This commit is contained in:
Родитель
9831ce8fc4
Коммит
b7d1664a5d
|
@ -85,7 +85,7 @@ public class ImporterTopLevel extends ScriptableObject {
|
|||
}
|
||||
|
||||
private void init() {
|
||||
(new ImporterFunctions(this)).define(this);
|
||||
ImporterFunctions.setup(this);
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
|
@ -177,41 +177,44 @@ public class ImporterTopLevel extends ScriptableObject {
|
|||
private ObjArray importedPackages = new ObjArray();
|
||||
}
|
||||
|
||||
final class ImporterFunctions implements Serializable, IdFunctionMaster
|
||||
final class ImporterFunctions extends JIFunction
|
||||
{
|
||||
ImporterFunctions(ImporterTopLevel importer)
|
||||
private ImporterFunctions(ImporterTopLevel importer, int id)
|
||||
{
|
||||
this.importer = importer;
|
||||
this.id = id;
|
||||
if (id == Id_importClass) {
|
||||
initNameArity("importClass", 1);
|
||||
} else {
|
||||
if (id != Id_importPackage) Context.codeBug();
|
||||
initNameArity("importPackage", 1);
|
||||
}
|
||||
defineAsProperty(importer);
|
||||
}
|
||||
|
||||
void define(Scriptable scope)
|
||||
static void setup(ImporterTopLevel importer)
|
||||
{
|
||||
IdFunction.define(scope, "importClass", this, Id_importClass);
|
||||
IdFunction.define(scope, "importPackage", this, Id_importPackage);
|
||||
new ImporterFunctions(importer, Id_importClass);
|
||||
new ImporterFunctions(importer, Id_importPackage);
|
||||
}
|
||||
|
||||
public Object execMethod(int methodId, IdFunction function, Context cx,
|
||||
Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
throws JavaScriptException
|
||||
{
|
||||
if (methodId == Id_importClass) {
|
||||
if (id == Id_importClass) {
|
||||
importer.importClass(cx, thisObj, args);
|
||||
} else {
|
||||
if (methodId != Id_importPackage) Context.codeBug();
|
||||
if (id != Id_importPackage) Context.codeBug();
|
||||
importer.importPackage(cx, thisObj, args);
|
||||
}
|
||||
return Undefined.instance;
|
||||
}
|
||||
|
||||
public int methodArity(int methodId)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_importClass = 1,
|
||||
Id_importPackage = 2;
|
||||
|
||||
private ImporterTopLevel importer;
|
||||
private int id;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/* -*- 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):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
* JIFunction or Java Implemented unction is a class to simplify implementation
|
||||
* of JS functions in native code.
|
||||
*/
|
||||
|
||||
public abstract class JIFunction extends BaseFunction
|
||||
{
|
||||
public JIFunction() { }
|
||||
|
||||
public JIFunction(String name, int arity)
|
||||
{
|
||||
initNameArity(name, arity);
|
||||
}
|
||||
|
||||
protected final void initNameArity(String name, int arity)
|
||||
{
|
||||
this.functionName = name;
|
||||
this.arity = arity;
|
||||
}
|
||||
|
||||
public final void defineAsProperty(Scriptable scope)
|
||||
{
|
||||
defineAsProperty(scope, ScriptableObject.DONTENUM, false);
|
||||
}
|
||||
|
||||
public final void defineAsProperty(Scriptable scope, int attributes)
|
||||
{
|
||||
defineAsProperty(scope, attributes, false);
|
||||
}
|
||||
|
||||
public final void defineAsProperty(Scriptable scope, int attributes,
|
||||
boolean sealed)
|
||||
{
|
||||
setParentScope(scope);
|
||||
if (sealed) { sealObject(); }
|
||||
ScriptableObject.defineProperty(scope, functionName, this, attributes);
|
||||
}
|
||||
|
||||
public Scriptable getPrototype()
|
||||
{
|
||||
// Lazy initialization of prototype: for native functions this
|
||||
// may not be called at all
|
||||
Scriptable proto = super.getPrototype();
|
||||
if (proto == null) {
|
||||
proto = getFunctionPrototype(getParentScope());
|
||||
setPrototype(proto);
|
||||
}
|
||||
return proto;
|
||||
}
|
||||
|
||||
public abstract Object call(Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
throws JavaScriptException;
|
||||
|
||||
public int getArity()
|
||||
{
|
||||
return arity;
|
||||
}
|
||||
|
||||
public int getLength()
|
||||
{
|
||||
return getArity();
|
||||
}
|
||||
|
||||
private int arity;
|
||||
}
|
|
@ -113,7 +113,7 @@ public class NativeJavaPackage extends ScriptableObject {
|
|||
public static Scriptable init(Scriptable scope)
|
||||
throws PropertyException
|
||||
{
|
||||
NativeJavaPackage packages = new NativeJavaPackage.TopLevelPackage();
|
||||
final NativeJavaPackage packages = new TopLevelPackage();
|
||||
packages.setPrototype(getObjectPrototype(scope));
|
||||
packages.setParentScope(scope);
|
||||
|
||||
|
@ -131,17 +131,19 @@ public class NativeJavaPackage extends ScriptableObject {
|
|||
nameStart = nameEnd + 1;
|
||||
}
|
||||
|
||||
Method[] methods = FunctionObject.getMethodList(
|
||||
NativeJavaPackage.class);
|
||||
Method m = FunctionObject.findSingleMethod(methods,
|
||||
"jsFunction_getClass");
|
||||
FunctionObject f = new FunctionObject("getClass", m, scope);
|
||||
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;
|
||||
|
||||
global.defineProperty("getClass", f, ScriptableObject.DONTENUM);
|
||||
getClass.defineAsProperty(global, ScriptableObject.DONTENUM);
|
||||
global.defineProperty("Packages", packages, ScriptableObject.DONTENUM);
|
||||
global.defineProperty("java", javaAlias, ScriptableObject.DONTENUM);
|
||||
|
||||
|
@ -255,17 +257,15 @@ public class NativeJavaPackage extends ScriptableObject {
|
|||
return "[JavaPackage " + packageName + "]";
|
||||
}
|
||||
|
||||
public static Scriptable jsFunction_getClass(Context cx,
|
||||
Scriptable thisObj,
|
||||
Object[] args,
|
||||
Function funObj)
|
||||
static final Scriptable js_getClass(Context cx, Scriptable scope,
|
||||
NativeJavaPackage top, Object[] args)
|
||||
{
|
||||
if (args.length > 0 && args[0] instanceof Wrapper) {
|
||||
Scriptable result = getTopLevelScope(thisObj);
|
||||
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 = "Packages." + cl.getName();
|
||||
String name = cl.getName();
|
||||
int offset = 0;
|
||||
for (;;) {
|
||||
int index = name.indexOf('.', offset);
|
||||
|
@ -285,7 +285,8 @@ public class NativeJavaPackage extends ScriptableObject {
|
|||
Context.getMessage0("msg.not.java.obj"));
|
||||
}
|
||||
|
||||
private Class findClass(Context cx, String className) {
|
||||
private Class findClass(Context cx, String className)
|
||||
{
|
||||
Class cl = null;
|
||||
ClassLoader loader = classLoader;
|
||||
if (loader == null) {
|
||||
|
@ -302,3 +303,4 @@ public class NativeJavaPackage extends ScriptableObject {
|
|||
private String packageName;
|
||||
private ClassLoader classLoader;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче