/* PHPRPCServer.java
*
* Author: Ma Bingyao <andot@ujn.edu.cn>
* Copyright: CoolCode.CN
* Version: 2.1
* LastModified: 2006-08-05
* This library is free. You can redistribute it and/or modify it.
* http://www.coolcode.cn/?p=204
*/
package PHPRPC;
import java.lang.*;
import java.lang.reflect.*;
import java.io.*;
import java.math.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
class RemoteFunction {
protected String name;
protected Object obj;
protected Class cls;
protected Method[] functions;
protected RemoteFunction(String name, Object obj, Class cls, Method[] functions) {
this.name = name;
this.obj = obj;
this.cls = cls;
this.functions = functions;
}
}
public class PHPRPCServer {
private HttpServletRequest request;
private HttpServletResponse response;
private HttpSession session;
private PrintWriter reswriter;
private ArrayList functions;
private RemoteFunction[] rfs;
private boolean debug;
private String charset;
private boolean encode;
private boolean byref;
private boolean encrypt;
private int encryptmode;
private byte[] key;
private String result;
private String arguments;
private String output;
private String callback;
private Integer errno;
private String errstr;
//private static Regex test = new Regex("[\0-\037\042\047\134]", RegexOptions.Compiled);
public PHPRPCServer(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
this.request = request;
this.response = response;
this.reswriter = response.getWriter();
this.session = session;
this.functions = new ArrayList();
this.encode = true;
this.encrypt = false;
this.encryptmode = 0;
this.errno = 0;
this.errstr = "";
this.output = "";
this.callback = "";
this.byref = true;
this.key = null;
}
public void add(String function, Object obj) {
add(new String[] { function }, obj, obj.getClass());
}
public void add(String[] functions, Object obj) {
add(functions, obj, obj.getClass());
}
public void add(String function, Class cls) {
add(new String[] { function }, null, cls);
}
public void add(String[] functions, Class cls) {
add(functions, null, cls);
}
private void add(String[] functions, Object obj, Class cls) {
Method[] ms = cls.getMethods();
for (int i = 0, n = functions.length; i < n; i++) {
ArrayList fs = new ArrayList();
for (int j = 0, m = ms.length; j < m; j++) {
if (functions[i].toLowerCase() == ms[j].getName().toLowerCase() &&
Modifier.isPublic(ms[j].getModifiers())) {
fs.add(ms[j]);
}
}
this.functions.add(new RemoteFunction(functions[i], obj, cls, (Method[])fs.toArray(new Method[0])));
}
}
private String toHexString(int n) {
return ((n < 16) ? "0" : "") + Integer.toHexString(n);
}
private String addJsSlashes(String str) {
char[] s = str.toCharArray();
StringBuffer sb = new StringBuffer();
for (int i =0, n = s.length; i < n; i++) {
if (s[i] <= 31 || s[i] == 34 || s[i] == 39 || s[i] == 92 || s[i] == 127) {
sb.append("\\x");
sb.append(toHexString((int)s[i] & 0xff));
}
else {
sb.append(s[i]);
}
}
return sb.toString();
}
private String addJsSlashes(byte[] s) {
StringBuffer sb = new StringBuffer();
for (int i = 0, n = s.length; i < n; i++) {
if (s[i] <= 31 || s[i] == 34 || s[i] == 39 || s[i] == 92 || s[i] == 127) {
sb.append("\\x");
sb.append(toHexString((int)s[i] & 0xff));
}
else {
sb.append((char)s[i]);
}
}
return sb.toString();
}
private RemoteFunction[] GetFunction(String function) {
ArrayList rf = new ArrayList();
function = function.toLowerCase();
for (int i = 0, n = this.rfs.length; i < n; i++) {
if (function == this.rfs[i].name.toLowerCase()) {
rf.add(this.rfs[i]);
}
}
return (RemoteFunction[])(rf.toArray(new RemoteFunction[0]));
}
private void appendHeader() {
this.response.setContentType("text/plain; charset=" + this.charset);
this.response.addHeader("X-Powered-By", "PHPRPC Server/2.1");
this.response.setDateHeader("Date", (new Date()).getTime());
this.response.setDateHeader("Last-Modified", (new Date()).getTime());
this.response.addHeader("Cache-Control", "no-store, no-cache, must-revalidate");
this.response.addHeader("Cache-Control", "pre-check=0, post-check=0, max-age=0");
this.response.addHeader("Content-Encoding", "none");
}
private void writeError() throws UnsupportedEncodingException {
reswriter.print("phprpc_errno=\"" + this.errno.toString() + "\";\r\n");
if (this.encode) {
reswriter.print("phprpc_errstr=\"" + Base64.encode(this.errstr.getBytes(this.charset)) + "\";\r\n");
}
else {
reswriter.print("phprpc_errstr=\"" + this.addJsSlashes(this.errstr) + "\";\r\n");
}
reswriter.print("phprpc_output=\"" + this.output + "\";\r\n");
reswriter.print(this.callback);
}
private byte[] Call(Method function, Object obj, byte[] arguments) throws UnSerializeException, UnsupportedEncodingException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Object[] args = (Object[])PHPSerializer.unserialize(arguments, (new Object[0]).getClass(), this.charset);
if (request.getParameter("phprpc_args") != null)
{
Class[] p = function.getParameterTypes();
for (int i = 0, n = Math.min(p.length, args.length); i < n; i++)
{
if (args[i] != null)
{
args[i] = PHPSerializer.cast(args[i], p[i]);
}
}
}
ByteArrayOutputStream bs = new ByteArrayOutputStream();
PrintStream defaultout = System.out;
PrintStream ps = new PrintStream(bs, true, this.charset);
System.setOut(ps);
byte[] result = PHPSerializer.serialize(function.invoke(obj, args), this.charset);
System.setOut(defaultout);
ps.close();
this.output = new String(bs.toByteArray(), this.charset);
return result;
}
}