Improved interface registration mechanism.

Author = sdv@sparc.spb.su
r = idk@eng.sun.com


git-svn-id: svn://10.0.0.236/trunk@79398 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
idk%eng.sun.com
2000-09-17 00:49:42 +00:00
parent 84449c4ab0
commit bd49bfb1fc
10 changed files with 311 additions and 158 deletions

View File

@@ -31,32 +31,35 @@ import java.io.File;
public class ComponentLoader {
// path to jar file. Name of main class sould to be in MANIFEST.
public static Object loadComponent(String location) {
try {
File file = (new File(location)).getCanonicalFile(); //To avoid spelling diffs, e.g c: and C:
location = file.getAbsolutePath();
if (File.separatorChar != '/') {
location = location.replace(File.separatorChar,'/');
}
if (!location.startsWith("/")) {
location = "/" + location;
}
URL url = new URL("file:"+location);
URLClassLoader loader = URLClassLoader.newInstance(new URL[]{url});
URL manifestURL = new URL("jar:file:"+location+"!/META-INF/MANIFEST.MF");
InputStream inputStream = manifestURL.openStream();
Manifest manifest = new Manifest(inputStream);
Attributes attr = manifest.getMainAttributes();
String componentClassName = attr.getValue("Component-Class");
if (componentClassName == null) {
//nb
return null;
}
Object object = loader.loadClass(componentClassName).newInstance();
return object;
} catch (Exception e) {
try {
File file = (new File(location)).getCanonicalFile(); //To avoid spelling diffs, e.g c: and C:
location = file.getAbsolutePath();
if (File.separatorChar != '/') {
location = location.replace(File.separatorChar,'/');
}
if (!location.startsWith("/")) {
location = "/" + location;
}
URL url = new URL("file:"+location);
URLClassLoader loader = URLClassLoader.newInstance(new URL[]{url});
URL manifestURL = new URL("jar:file:"+location+"!/META-INF/MANIFEST.MF");
InputStream inputStream = manifestURL.openStream();
Manifest manifest = new Manifest(inputStream);
Attributes attr = manifest.getMainAttributes();
String componentClassName = attr.getValue("Component-Class");
if (componentClassName == null) {
//nb
return null;
}
Object object = loader.loadClass(componentClassName).newInstance();
if (object instanceof nsISupports) {
InterfaceRegistry.register((nsISupports)object);
}
return object;
} catch (Exception e) {
e.printStackTrace();
return null;
}
return null;
}
}
}

View File

@@ -0,0 +1,186 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Mozilla 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/MPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Sun Microsystems,
* Inc. Portions created by Sun are
* Copyright (C) 1999 Sun Microsystems, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Denis Sharypov <sdv@sparc.spb.su>
*/
package org.mozilla.xpcom;
import java.util.Hashtable;
import java.lang.reflect.*;
class InterfaceRegistry {
private static String IID_STRING = "IID";
private static Hashtable interfaces = null;
private static Hashtable iMethods = null;
private static boolean debug = true;
private InterfaceRegistry() {
}
public static void register(nsISupports obj) {
if (obj == null) {
return;
}
if (interfaces == null) {
interfaces = new Hashtable();
}
if (iMethods == null) {
iMethods = new Hashtable();
}
Class cl = obj.getClass();
if (!cl.isInterface()) {
Class[] ifaces = cl.getInterfaces();
for (int i = 0; i < ifaces.length; i++) {
registerInterfaces(ifaces[i]);
}
} else {
registerInterfaces(cl);
}
}
private static void registerInterfaces(Class cl) {
try {
Object iidStr = cl.getField(IID_STRING).get(cl);
if (iidStr instanceof String) {
IID iid = new IID((String)iidStr);
String[] methodNames = Utilities.getInterfaceMethodNames((String)iidStr);
if (methodNames != null) {
Method[] rmethods = new Method[methodNames.length];
int i = methodNames.length - 1;
Class[] ifaces = new Class[]{cl};
// recursively get all parent interface methods
do {
Method[] methods = ifaces[0].getDeclaredMethods();
int j = methods.length - 1;
while (i >= 0 && j >=0) {
if (methodNames[i].equals(methods[j].getName())) {
rmethods[i--] = methods[j--];
} else {
// put null for notxpcom & noscript methods
rmethods[i--] = null;
}
}
ifaces = ifaces[0].getInterfaces();
// check for single inheritance (xpcom)
} while (ifaces.length == 1);
interfaces.put(iid, cl);
iMethods.put(iid, new MethodArray(rmethods));
debug(cl.getName() + ": " + iid + " ( " + cl + " )");
printMethods(rmethods);
}
}
} catch (NoSuchFieldException e) {
// the interface doesn't define IID field
debug("no such field...");
} catch (IllegalAccessException e1) {
debug("can't access field...");
}
// register interfaces extended by the interface
Class[] ifaces = cl.getInterfaces();
for (int i = 0; i < ifaces.length; i++) {
registerInterfaces(ifaces[i]);
}
}
public static Class getInterface(IID iid) {
Object obj = null;
if (interfaces != null) {
obj = interfaces.get(iid);
}
if (obj == null || !(obj instanceof Class)) {
return null;
}
return (Class)obj;
}
public static Method getMethodByIndex(int index, IID iid) {
Method result = null;
MethodArray m = (MethodArray)iMethods.get(iid);
if (m != null && m.methods !=null) {
try {
result = m.methods[index];
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
public static int getIndexByMethod(Method method, IID iid) {
int result = 0;
MethodArray m = (MethodArray)iMethods.get(iid);
if (m != null && m.methods !=null) {
for (int i = 0; i < m.methods.length; i++) {
if (method.equals(m.methods[i])) {
result = i;
break;
}
}
}
return result;
}
// methods for debugging
private static void printMethods(Method[] methods) {
if (debug) {
for (int i = 0; i < methods.length; i++) {
printMethod(methods[i]);
}
}
}
private static void printMethod(Method m) {
if (m == null) {
System.out.println("<null>");
return;
}
Class retType = m.getReturnType();
Class[] paramTypes = m.getParameterTypes();
String name = m.getName();
System.out.print(Modifier.toString(m.getModifiers()));
System.out.print(" " + retType.getName() + " " + name
+ "(");
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0) System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
private static void debug(String str) {
if (debug) {
System.out.println(str);
}
}
}
class MethodArray {
Method[] methods;
MethodArray(Method[] _methods) {
methods = _methods;
}
}

View File

@@ -1,83 +0,0 @@
/*
* The contents of this file are subject to the Mozilla 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/MPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Sun Microsystems,
* Inc. Portions created by Sun are
* Copyright (C) 1999 Sun Microsystems, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Igor Kushnirskiy <idk@eng.sun.com>
*/
package org.mozilla.xpcom;
import java.lang.reflect.*;
import java.util.*;
public class ProxyClass { //nb it should not be public
public ProxyClass(IID _iid, Method[] _methods) { //nb it should not be public
iid = _iid;
methods = _methods;
if (classes == null) {
classes = new Hashtable();
}
classes.put(iid, this);
}
Method getMethodByIndex(int mid) { //first method has index equal to 'offset'
System.out.println("--[java]ProxyClass.GetMehodByIndex "+mid);
Method result = null;
try {
result = methods[mid-offset];
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
int getIndexByMethod(Method method) {
int result = 0;
if (method == null
||methods == null) {
return result;
}
for (int i = 0; i < methods.length; i++) {
if (method.equals(methods[i])) {
result = i + offset;
break;
}
}
return result;
}
static ProxyClass getProxyClass(IID iid) {
ProxyClass result = null;
Object obj = null;
if (classes != null) {
obj = classes.get(iid);
if (obj != null
&& (obj instanceof ProxyClass)) {
result = (ProxyClass)obj;
}
}
return result;
}
private IID iid;
private Method[] methods;
private final int offset = 0; //from xpcom
static Hashtable classes = null;
}

View File

@@ -30,7 +30,7 @@ public class Utilities {
for (int i = 0; i < args.length; i++) {
System.out.println("--[java]callMethodByIndex args["+i+"] = "+args[i]);
}
Method method = getMethodByIndex(mid,iid);
Method method = InterfaceRegistry.getMethodByIndex(mid,iid);
System.out.println("--[java] org.mozilla.xpcom.Utilities.callMethodByIndex method "+method);
try {
if (method != null) {
@@ -42,9 +42,10 @@ public class Utilities {
System.out.println("--callMethodByIndex method finished"+method);
return null; //nb for testing
}
static Object callMethod(long oid, Method method, IID iid, long orb , Object[] args) {
System.out.println("--[java]Utilities.callMethod "+method);
int mid = getIndexByMethod(method, iid);
int mid = InterfaceRegistry.getIndexByMethod(method, iid);
if (mid <= 0) {
System.out.println("--[java]Utilities.callMethod we do not have implementation for "+method);
return null;
@@ -52,24 +53,9 @@ public class Utilities {
System.out.println("--[java]Utilities.callMethod "+mid);
return callMethodByIndex(oid,mid,iid.getString(), orb, args);
}
private static Method getMethodByIndex(int index, IID iid) {
Method result = null;
ProxyClass proxyClass = ProxyClass.getProxyClass(iid);
if (proxyClass != null) {
result = proxyClass.getMethodByIndex(index);
}
return result;
}
private static int getIndexByMethod(Method method, IID iid) {
int result = 0;
ProxyClass proxyClass = ProxyClass.getProxyClass(iid);
if (proxyClass != null) {
result = proxyClass.getIndexByMethod(method);
}
return result;
}
private static native Object callMethodByIndex(long oid, int index, String iid, long orb, Object[] args);
static native String[] getInterfaceMethodNames(String iid);
static {
System.loadLibrary("bcjavastubs");
}

View File

@@ -0,0 +1,30 @@
/*
* ************* DO NOT EDIT THIS FILE ***********
*
* This file was automatically generated from nsISupports.idl.
*/
package org.mozilla.xpcom;
/**
* Interface nsISupports
*
* IID: 0x00000000-0000-0000-c000-000000000046
*/
public interface nsISupports
{
public static final String IID =
"00000000-0000-0000-c000-000000000046";
/* void QueryInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */
public void queryInterface(IID uuid, Object[] obj);
}
/*
* end
*/