]> granicus.if.org Git - php/commitdiff
Improved handing of instances of private classes. Added servlet examples.
authorSam Ruby <rubys@php.net>
Mon, 28 Feb 2000 17:02:28 +0000 (17:02 +0000)
committerSam Ruby <rubys@php.net>
Mon, 28 Feb 2000 17:02:28 +0000 (17:02 +0000)
13 files changed:
ext/java/jver.php
ext/java/reflect.java
ext/rpc/java/jver.php
ext/rpc/java/reflect.java
sapi/servlet/README
sapi/servlet/cookies.php [new file with mode: 0644]
sapi/servlet/date.php [new file with mode: 0644]
sapi/servlet/jinfo.php [new file with mode: 0644]
sapi/servlet/jver.php [new file with mode: 0644]
sapi/servlet/reqheaders.php [new file with mode: 0644]
sapi/servlet/reqinfo.php [new file with mode: 0644]
sapi/servlet/reqparams.php [new file with mode: 0644]
sapi/servlet/sessions.php [new file with mode: 0644]

index 7df8c07ac40ca4b8cb8d75c55ea35b45f6d794f7..7015944101e78d02f829d0326fd291a92a03024e 100644 (file)
@@ -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>
index 3dafcf719a70d8a2be31c1d4dfa69d63068d972f..b7693e907cc79405cc8f5e1adc6adfecb2694954 100644 (file)
@@ -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++) {
index 7df8c07ac40ca4b8cb8d75c55ea35b45f6d794f7..7015944101e78d02f829d0326fd291a92a03024e 100644 (file)
@@ -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>
index 3dafcf719a70d8a2be31c1d4dfa69d63068d972f..b7693e907cc79405cc8f5e1adc6adfecb2694954 100644 (file)
@@ -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++) {
index ac93e633db68a6f23f01ce6a3bb64b9846bf64d4..be0ea3cb1f0c562f67c51d87a9e70e10f69c76bc 100644 (file)
@@ -12,17 +12,7 @@ What is PHP4 sapi/servlet?
         reports, success stories and/or patches required to get this code
         to run on other engines would be appreciated.
 
-     2) This code clean compiles on Win32 and Linux, and is able to process
-        phpinfo() commands.  Most of the code is in place, but very little
-        testing has been done on even such basic things as cookies and
-        sessions.  Treat this code as early alpha at this point.
-
-     3) Until overload resolution is addressed in php/java, much of the
-        javax.servlet interfaces can not be directly called.  For example,
-        don't try to get the output stream from $response, and expect to
-        be able to use println.  For now, use PHP's "echo" instead.
-
-     4) PHP has a habit of changing the working directory.  Sapi/servlet will
+     2) PHP has a habit of changing the working directory.  Sapi/servlet will
         eventually change it back, but while PHP is running the servlet engine
         may not be able to load any classes from the CLASSPATH which are
         specified using a relative directory syntax, or find the work directory
diff --git a/sapi/servlet/cookies.php b/sapi/servlet/cookies.php
new file mode 100644 (file)
index 0000000..5ce605b
--- /dev/null
@@ -0,0 +1,47 @@
+<html>
+<body bgcolor="white">
+<head>
+<title>Cookies Example</title>
+</head>
+<body>
+<a href="/examples/servlets/cookies.html">
+<img src="/examples/images/code.gif" height=24 width=24 align=right border=0 alt="view code"></a>
+<a href="/examples/servlets/index.html">
+<img src="/examples/images/return.gif" height=24 width=24 align=right border=0 alt="return"></a>
+<h3>Cookies Example</h3>
+
+<?
+  $cookies = $request->cookies;
+  // print out cookies
+
+  if (!current($cookies)) {
+    echo "Your browser isn't sending any cookies\n";
+  } else {
+    echo "Your browser is sending the following cookies:<br>\n";
+
+    for ($cookie=current($cookies); $cookie; $cookie=next($cookies)) {
+      echo "Cookie Name: $cookie->name<br>Cookie value: $cookie->value<br>\n";
+    }
+  }
+
+  // set a cookie
+
+  $name = $request->getParameter("cookieName");
+  if ($name) {
+    $value = $request->getParameter("cookieValue");
+    $response->addCookie(new Java("javax.servlet.http.Cookie", $name, $value));
+    echo "<p>You just sent the following cookie to your browser:<br>\n";
+    echo "Name: $name<br>Value: $value<P>\n";
+  }
+
+?>
+<P>
+Create a cookie to send to your browser<br>
+<form action="<?PHP echo $PHP_SELF ?>" method=POST>
+Name:  <input type=text length=20 name=cookieName><br>
+Value:  <input type=text length=20 name=cookieValue><br>
+<input type=submit></form>
+</body>
+</html>
+
diff --git a/sapi/servlet/date.php b/sapi/servlet/date.php
new file mode 100644 (file)
index 0000000..1146d31
--- /dev/null
@@ -0,0 +1,28 @@
+<html>
+<!--
+  Copyright (c) 1999 The Apache Software Foundation.  All rights 
+  reserved.
+-->
+
+<body bgcolor="white">
+<?php $clock=new Java("dates.JspCalendar"); ?>
+
+<font size=4>
+<ul>
+<li>   Day of month: is  <?php echo $clock->dayOfMonth ?>
+<li>   Year: is  <?php echo $clock->year ?>
+<li>   Month: is  <?php echo $clock->month ?>
+<li>   Time: is  <?php echo $clock->time ?>
+<li>   Date: is  <?php echo $clock->date ?>
+<li>   Day: is  <?php echo $clock->day ?>
+<li>   Day Of Year: is  <?php echo $clock->dayOfYear ?>
+<li>   Week Of Year: is  <?php echo $clock->weekOfYear ?>
+<li>   era: is  <?php echo $clock->era ?>
+<li>   DST Offset: is  <?php echo $clock->dSTOffset ?>
+<li>   Zone Offset: is  <?php echo $clock->zoneOffset ?>
+</ul>
+</font>
+
+</body>
+</html>
+
diff --git a/sapi/servlet/jinfo.php b/sapi/servlet/jinfo.php
new file mode 100644 (file)
index 0000000..f20bbfb
--- /dev/null
@@ -0,0 +1,5 @@
+<?
+
+  phpinfo();
+
+?>
diff --git a/sapi/servlet/jver.php b/sapi/servlet/jver.php
new file mode 100644 (file)
index 0000000..e5e029c
--- /dev/null
@@ -0,0 +1,17 @@
+<html>
+<?
+
+  $system = new Java("java.lang.System");
+  print "Java version=".$system->getProperty("java.version")." <br>\n";
+  print "Java vendor=".$system->getProperty("java.vendor")." <p>\n\n";
+  print "OS=".$system->getProperty("os.name")." ".
+             $system->getProperty("os.version")." on ".
+             $system->getProperty("os.arch")." <br>\n";
+
+  $formatter = new Java("java.text.SimpleDateFormat",
+                       "EEEE, MMMM dd, yyyy 'at' h:mm:ss a zzzz");
+
+  print $formatter->format(new Java("java.util.Date"))."\n";
+
+?>
+</html>
diff --git a/sapi/servlet/reqheaders.php b/sapi/servlet/reqheaders.php
new file mode 100644 (file)
index 0000000..97011a2
--- /dev/null
@@ -0,0 +1,28 @@
+<html>
+<body bgcolor="white">
+<head>
+<title>Request Header Example</title>
+</head>
+<body>
+<a href="/examples/servlets/reqheaders.html">
+<img src="/examples/images/code.gif" height=24 width=24 align=right border=0 alt="view code"></a>
+<a href="/examples/servlets/index.html">
+<img src="/examples/images/return.gif" height=24 width=24 align=right border=0 alt="return"></a>
+<h3>Request Header Example</h3>
+<table border=0>
+
+<?php
+
+   $e = $request->headerNames;
+   while ($e->hasMoreElements()) {
+     $name = $e->nextElement();
+     $value = $request->getHeader($name);
+     print "<tr><td bgcolor=\"#CCCCCC\">$name\n";
+     print "</td><td>$value</td></tr>\n";
+    }
+
+?>
+
+</table>
+</body>
+</html>
diff --git a/sapi/servlet/reqinfo.php b/sapi/servlet/reqinfo.php
new file mode 100644 (file)
index 0000000..2b96ae6
--- /dev/null
@@ -0,0 +1,33 @@
+<html>
+<body>
+<head>
+<title>Request Information Example</title>
+</head>
+<body bgcolor="white">
+<a href="/examples/servlets/reqinfo.html">
+<img src="/examples/images/code.gif" height=24 width=24 align=right border=0 alt="view code"></a>
+<a href="/examples/servlets/index.html">
+<img src="/examples/images/return.gif" height=24 width=24 align=right border=0 alt="return"></a>
+<h3>Request Information Example</h3>
+<table border=0><tr><td>
+Method:
+</td><td>
+<?php print $request->method ?>
+</td></tr><tr><td>
+Request URI:
+</td><td>
+<?php print $request->requestURI ?>
+</td></tr><tr><td>
+Protocol:
+</td><td>
+<?php print $request->protocol ?>
+</td></tr><tr><td>
+Path Info:
+</td><td>
+<?php print $request->pathInfo ?>
+</td></tr><tr><td>
+Remote Address:
+</td><td>
+<?php print $request->remoteAddr ?>
+</table>
+
diff --git a/sapi/servlet/reqparams.php b/sapi/servlet/reqparams.php
new file mode 100644 (file)
index 0000000..d2fcf78
--- /dev/null
@@ -0,0 +1,39 @@
+<html>
+<body>
+<head>
+<title>Request Parameters Example</title>
+</head>
+<body bgcolor="white">
+<a href="/examples/servlets/reqparams.html">
+<img src="/examples/images/code.gif" height=24 width=24 align=right border=0 alt="view code"></a>
+<a href="/examples/servlets/index.html">
+<img src="/examples/images/return.gif" height=24 width=24 align=right border=0 alt="return"></a>
+<h3>Request Parameters Example</h3>
+Parameters in this request:<br>
+<?php
+  $e = $request->parameterNames;
+
+  if (!$e->hasMoreElements()) {
+    echo "No Parameters, Please enter some"; 
+  }
+
+  while ($e->hasMoreElements()) {
+    $name = $e->nextElement();
+    $value = $request->getParameter($name);
+    echo "$name = $value<br>\n";
+  }
+
+?>
+<P>
+<form action="<?php echo $PHP_SELF ?>" method=POST>
+First Name:
+<input type=text size=20 name=firstname>
+<br>
+Last Name:
+<input type=text size=20 name=lastname>
+<br>
+<input type=submit>
+</form>
+</body>
+</html>
+
diff --git a/sapi/servlet/sessions.php b/sapi/servlet/sessions.php
new file mode 100644 (file)
index 0000000..81f4604
--- /dev/null
@@ -0,0 +1,58 @@
+<html>
+<body bgcolor="white">
+<head>
+<title>Sessions Example</title>
+</head>
+<body>
+<a href="/examples/servlets/sessions.html">
+<img src="/examples/images/code.gif" height=24 width=24 align=right border=0 alt="view code"></a>
+<a href="/examples/servlets/index.html">
+<img src="/examples/images/return.gif" height=24 width=24 align=right border=0 alt="return"></a>
+<h3>Sessions Example</h3>
+<?php
+
+  // print session info 
+
+  $session  = $request->session;
+  $created  = new Java("java.util.Date", $session->creationTime);
+  $accessed = new Java("java.util.Date", $session->lastAccessedTime);
+
+  print "Session ID: $session->id<br>\n";
+  print "Created: " . $created->toString() . "<br>\n";
+  print "Last Accessed: " . $accessed->toString() . "<br>\n";
+
+  // set session info if needed
+
+  $dataName = $request->getParameter("dataName");
+  if ($dataName) {
+    $dataValue = $request->getParameter("dataValue");
+    $dataValue = $request->getParameter("dataValue");
+    $session->setAttribute($dataName, $dataValue);
+  }
+
+  // print session contents
+
+  print "<P>\n";
+  print "The following data is in your session:<br>\n";
+  $e = $session->attributeNames;
+  while ($e->hasMoreElements()) {
+    $name = $e->nextElement();
+    $value = $session->getAttribute($name);
+    print "$name = $value<br>\n";
+  }
+
+?>
+<P>
+<form action="<?php echo $PHP_SELF ?>" method=POST>
+Name of Session Attribute:
+<input type=text size=20 name=dataName>
+<br>
+Value of Session Attribute:
+<input type=text size=20 name=dataValue>
+<br>
+<input type=submit>
+</form>
+</body>
+</html>
+</body>
+</html>