summaryrefslogtreecommitdiff
path: root/ext/java
diff options
context:
space:
mode:
authorSam Ruby <rubys@php.net>2000-02-28 17:02:28 +0000
committerSam Ruby <rubys@php.net>2000-02-28 17:02:28 +0000
commit6189e219ff6f04f9f00b674b4d90b4c51b14bc78 (patch)
tree2f51bc0ace04e488ae81876552764af6cadac786 /ext/java
parentbafbbea0516641ac5df5e8d285ff79133f55b685 (diff)
downloadphp-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.php2
-rw-r--r--ext/java/reflect.java66
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++) {