diff options
author | Sam Ruby <rubys@php.net> | 2000-02-28 17:02:28 +0000 |
---|---|---|
committer | Sam Ruby <rubys@php.net> | 2000-02-28 17:02:28 +0000 |
commit | 6189e219ff6f04f9f00b674b4d90b4c51b14bc78 (patch) | |
tree | 2f51bc0ace04e488ae81876552764af6cadac786 /ext/java | |
parent | bafbbea0516641ac5df5e8d285ff79133f55b685 (diff) | |
download | php-git-6189e219ff6f04f9f00b674b4d90b4c51b14bc78.tar.gz |
Improved handing of instances of private classes. Added servlet examples.
Diffstat (limited to 'ext/java')
-rw-r--r-- | ext/java/jver.php | 2 | ||||
-rw-r--r-- | ext/java/reflect.java | 66 |
2 files changed, 48 insertions, 20 deletions
diff --git a/ext/java/jver.php b/ext/java/jver.php index 7df8c07ac4..7015944101 100644 --- a/ext/java/jver.php +++ b/ext/java/jver.php @@ -1,3 +1,4 @@ +<html> <? $system = new Java("java.lang.System"); @@ -13,3 +14,4 @@ print $formatter->format(new Java("java.util.Date"))."\n"; ?> +</html> diff --git a/ext/java/reflect.java b/ext/java/reflect.java index 3dafcf719a..b7693e907c 100644 --- a/ext/java/reflect.java +++ b/ext/java/reflect.java @@ -102,22 +102,30 @@ class reflect { // public static void CreateObject(String name, Object args[], long result) { try { + Vector matches = new Vector(); + Constructor cons[] = Class.forName(name).getConstructors(); for (int i=0; i<cons.length; i++) { if (cons[i].getParameterTypes().length == args.length) { - setResult(result, cons[i].newInstance(args)); - return; + matches.addElement(cons[i]); } } - // for classes which have no visible constructor, return the class - // useful for classes like java.lang.System and java.util.Calendar. - if (args.length == 0) { - setResult(result, Class.forName(name)); - return; + Constructor selected = (Constructor)select(matches, args); + + if (selected == null) { + if (args.length > 0) { + throw new InstantiationException("No matching constructor found"); + } else { + // for classes which have no visible constructor, return the class + // useful for classes like java.lang.System and java.util.Calendar. + setResult(result, Class.forName(name)); + return; + } } - throw new InstantiationException("No matching constructor found"); + Object coercedArgs[] = coerce(selected.getParameterTypes(), args); + setResult(result, selected.newInstance(coercedArgs)); } catch (Exception e) { setException(result, e); @@ -127,16 +135,20 @@ class reflect { // // Select the best match from a list of methods // - private static Method select(Vector methods, Object args[]) { - if (methods.size() == 1) return (Method) methods.firstElement(); + private static Object select(Vector methods, Object args[]) { + if (methods.size() == 1) return methods.firstElement(); - Method selected = null; + Object selected = null; int best = Integer.MAX_VALUE; for (Enumeration e = methods.elements(); e.hasMoreElements(); ) { - Method method = (Method)e.nextElement(); + Object element = e.nextElement(); int weight=0; - Class parms[] = method.getParameterTypes(); + + Class parms[] = (element instanceof Method) ? + ((Method)element).getParameterTypes() : + ((Constructor)element).getParameterTypes(); + for (int i=0; i<parms.length; i++) { if (parms[i].isInstance(args[i])) { for (Class c=parms[i]; (c=c.getSuperclass()) != null; ) { @@ -168,9 +180,9 @@ class reflect { } if (weight < best) { - if (weight == 0) return method; + if (weight == 0) return element; best = weight; - selected = method; + selected = element; } } @@ -178,11 +190,13 @@ class reflect { } // - // Select the best match from a list of methods + // Coerce arguments when possible to conform to the argument list. + // Java's reflection will automatically do widening conversions, + // unfortunately PHP only supports wide formats, so to be practical + // some (possibly lossy) conversions are required. // - private static Object[] coerce(Method method, Object args[]) { + private static Object[] coerce(Class parms[], Object args[]) { Object result[] = args; - Class parms[] = method.getParameterTypes(); for (int i=0; i<args.length; i++) { if (parms[i].isInstance(args[i])) continue; if (args[i] instanceof Number && parms[i].isPrimitive()) { @@ -238,10 +252,10 @@ class reflect { if (!(object instanceof Class) || (jclass==object)) break; } - Method selected = select(matches, args); + Method selected = (Method)select(matches, args); if (selected == null) throw new NoSuchMethodException(method); - Object coercedArgs[] = coerce(selected, args); + Object coercedArgs[] = coerce(selected.getParameterTypes(), args); setResult(result, selected.invoke(object, coercedArgs)); } catch (Exception e) { @@ -258,6 +272,18 @@ class reflect { try { for (Class jclass = object.getClass();;jclass=(Class)object) { + while (!Modifier.isPublic(jclass.getModifiers())) { + // OK, some joker gave us an instance of a non-public class + // Substitute the first public interface in its place, + // and barring that, try the superclass + Class interfaces[] = jclass.getInterfaces(); + jclass=jclass.getSuperclass(); + for (int i=interfaces.length; i-->0;) { + if (Modifier.isPublic(interfaces[i].getModifiers())) { + jclass=interfaces[i]; + } + } + } BeanInfo beanInfo = Introspector.getBeanInfo(jclass); PropertyDescriptor props[] = beanInfo.getPropertyDescriptors(); for (int i=0; i<props.length; i++) { |