From 79f04e59b0a9997c56f0bc3859be30f6fd262717 Mon Sep 17 00:00:00 2001 From: crawshaw Date: Sun, 28 Nov 2004 14:33:43 +0000 Subject: [PATCH] give xt.shell its own package darcs-hash:20041128143343-2eb37-d075ecaec3930c2f9fe9a39fcc136e1cb676b56f.gz --- src/java/org/ibex/xt/Shell.java | 360 -------------------- src/java/org/ibex/xt/shell/Command.java | 160 +++++++++ src/java/org/ibex/xt/shell/Env.java | 35 ++ src/java/org/ibex/xt/shell/Request.java | 99 ++++++ .../xt/{ShellServlet.java => shell/Servlet.java} | 14 +- src/java/org/ibex/xt/shell/Shell.java | 110 ++++++ 6 files changed, 411 insertions(+), 367 deletions(-) delete mode 100644 src/java/org/ibex/xt/Shell.java create mode 100644 src/java/org/ibex/xt/shell/Command.java create mode 100644 src/java/org/ibex/xt/shell/Env.java create mode 100644 src/java/org/ibex/xt/shell/Request.java rename src/java/org/ibex/xt/{ShellServlet.java => shell/Servlet.java} (85%) create mode 100644 src/java/org/ibex/xt/shell/Shell.java diff --git a/src/java/org/ibex/xt/Shell.java b/src/java/org/ibex/xt/Shell.java deleted file mode 100644 index 4696869..0000000 --- a/src/java/org/ibex/xt/Shell.java +++ /dev/null @@ -1,360 +0,0 @@ -package org.ibex.xt; - -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.regex.*; - -import org.ibex.util.*; -import org.ibex.util.Collections; -import org.ibex.js.*; - -public class Shell { - - public static void main(String[] args) throws Exception { - if (args.length == 0 || args.length > 2|| !args[0].startsWith("http://")) { - printUsage(); return; - } - Shell shell = new Shell(new URL(args[0])); - - if (args.length == 2) { - // FIXME - } else { - shell.listen(new InputStreamReader(System.in), new OutputStreamWriter(System.out)); - } - } - - private static void printUsage() { - System.out.println("Usage: xish url [command]"); - } - - protected Command[] commands = new Command[] { - new LsCommand(), - new PwdCommand(), - new CdCommand(), - new RmCommand(), - new HelpCommand() - }; - - /** URL of server. */ - protected URL server; - - /** Current JS path using '.' as a seperator. */ - protected String pwd = "."; - - /** Create a new Shell using the given url for the server. */ - public Shell(URL url) { server = url; } - - public void listen(Reader r, Writer w) throws IOException { - LineNumberReader in = new LineNumberReader(r); - PrintWriter out = new PrintWriter(w); - - out.println("ibex xt shell: type help or exit"); - out.print("xt: "); - out.flush(); - - String line; - String buffer = ""; - while ((line = in.readLine()) != null) { - if (line.length() > 0) { - if (line.startsWith("exit")) return; - if (line.charAt(line.length() - 1) == '\\') { - buffer += line.substring(0, line.length() - 1); - out.print('>'); - out.flush(); continue; - } - - buffer += line; - } - - if (buffer.length() > 0) { - String[] c = buffer.split(" "); - int i=0; while (i < commands.length) { - if (commands[i].name().equals(c[0])) { - commands[i].execute(out, c); break; - } - i++; - } - if (i == commands.length) { - out.write(c[0]); - w.write(": command not found\n"); - } - buffer = ""; - } - out.print("xt: "); - out.flush(); - } - } - - /** Returns a path, based on console input. */ - private String path(String c) { - if (c.equals("") || c.equals(".") || c.equals("/")) { - c = "."; - } else if (c.equals("..")) { - c = c.substring(0, c.lastIndexOf('.')); - if (c.equals("")) c = "."; - } else { - if (c.charAt(0) != '/') c = pwd + c; - c = c.replaceAll("/+", "."); - if (c.length() > 1 && c.charAt(c.length() - 1) == '.') - c = c.substring(0, c.length() - 1); - } - - return c; - } - - private String cookie = null; - public Object send(Request request) throws IOException { - URLConnection c = server.openConnection(); - ((HttpURLConnection)c).setRequestMethod("POST"); - c.setDoOutput(true); - if (cookie != null) c.setRequestProperty("Cookie", cookie); - - c.connect(); - - ObjectOutputStream out = new ObjectOutputStream(c.getOutputStream()); - out.writeObject(request); - out.close(); - - String cook = c.getHeaderField("Set-Cookie"); - if (cook != null && !cook.equals("")) cookie = cook.substring(0, cook.indexOf(';')); - - try { - return new ObjectInputStream(c.getInputStream()).readObject(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - throw new IOException("unexpected ClassNotFoundException"); - } - } - - public abstract class Command { - /** Returns the command name. */ - public abstract String name(); - - /** Returns single-line of usage information, eg. pattern] */ - public abstract String usage(); - - /** Returns single-line description of command. */ - public abstract String summary(); - - /** Returns multi-line description. */ - public abstract String help(); - - /** Writes result of execution, even if result is an error. */ - public abstract void execute(Writer w, String[] args) throws IOException; - } - - /** Returns the command matching the given name. */ - protected Command command(String name) { - for (int i=0; i < commands.length; i++) - if (commands[i].name().equals(name)) return commands[i]; - return null; - } - - public class HelpCommand extends Command { - public String name() { return "help"; } - public String usage() { return "[command name]"; } - public String summary() { return "Lists available commands."; } - public String help() { return ""; } - - public void execute(Writer w, String[] c) throws IOException { - if (c.length > 1) { - Command cmd = command(c[1]); - if (c == null) { - w.write("help: "); - w.write(c[1]); - w.write(": command not found\n"); - } else { - w.write("usage: "); - w.write(cmd.name()); - w.write(" "); - w.write(cmd.usage()); - w.write("\n\n"); - w.write(cmd.help()); - w.write("\n"); - } - } else { - int len = 3; - for (int i=0; i < commands.length; i++) - len = Math.max(commands[i].name().length(), len); - - w.write("Available commands:\n"); - for (int i=0; i < commands.length; i++) { - Command cmd = commands[i]; - w.write(" "); - w.write(cmd.name()); - for (int j=len - cmd.name().length(); j >= 0; j--) w.write(" "); - w.write(" - "); - w.write(cmd.summary()); - w.write("\n"); - } - w.write("\nFor usage details, type help [command name].\n"); - } - } - } - - public class LsCommand extends Command { - public String name() { return "ls"; } - public String usage() { return "[path]"; } - public String summary() { return "List object entries."; } - public String help() { return - "Lists the keys in an object. Modelled after the UNIX ls command."; - } - - public void execute(Writer w, String[] c) throws IOException { - if (c.length > 2) { w.write(usage()); return; } - - Object ret = send(new KeyRequest(path(c[1]))); - if (ret == null) { - w.write("error: (unexpected) returned object is null\n"); - } else if (ret instanceof JSExn) { - String e = ((JSExn)ret).getMessage(); - // FIXME: messy way to get info from server - if (e.endsWith("does not exist")) { - w.write("ls "); - w.write(c[1]); - w.write(": no such path\n"); - } else { - w.write("error: "); - w.write(e); - w.write("\n"); - } - } else if (ret instanceof List) { - List l = (List)ret; Collections.sort(l); - Iterator i = l.iterator(); while (i.hasNext()) { - w.write(i.next().toString()); - w.write("\n"); - } - } else { - w.write("error: (unexpected) returned object is of unknown type: "); - w.write(ret.getClass().getName()); - w.write("\n"); - } - } - } - - public class PwdCommand extends Command { - public String name() { return "pwd"; } - public String usage() { return ""; } - public String summary() { return "Path to current object."; } - public String help() { return "Print the path to the current object."; } - public void execute(Writer w, String[] c) throws IOException { - w.write(c.length == 1 ? pwd.replace('.', '/') : usage()); - w.write("\n"); - } - } - - public class CdCommand extends Command { - public String name() { return "cd"; } - public String usage() { return "[path]"; } - public String summary() { return "Change current object."; } - public String help() { return - "Chnages the current object that all other commands use "+ - "as the base for running.\n Pass either a relative path "+ - "(e.g. in /prevalent, type cd myob, now in /prevalent/myob) "+ - "or an absolute path (e.g. cd /prevalent/myob).\n\n" + - "To go up one level, cd .. can be used."; - } - public void execute(Writer w, String[] c) throws IOException { - if (c.length > 2) w.write(usage()); - else if (c.length == 1 || c[1].equals("") || c[1].equals("/")) pwd = "."; - else if (c[1].equals("..")) { - String n = pwd.substring(0, pwd.lastIndexOf('.')); - pwd = n.equals("") ? "." : n; - } else { - String n = path(c[1]); - Object ret = send(new KeyRequest(n)); - - if (ret == null) { - w.write("error: (unexpected) server returned null\n"); - } else if (ret instanceof List && ((List)ret).size() == 1) { - pwd = n; - } else if (ret instanceof JSExn || - (ret instanceof List && ((List)ret).size() == 0)) { - w.write("cd "); - w.write(c[1]); - w.write(": no such path\n"); - } else { - w.write("error: (unexpected) server returned "); - w.write(ret.toString()); - w.write("\n"); - } - } - } - } - - public class RmCommand extends Command { - public String name() { return "rm"; } - public String usage() { return "[options] [path]"; } - public String summary() { return "Removes objects."; } - public String help() { return "Removes objects."; } // FIXME - public void execute(Writer w, String[] c) throws IOException { - if (c.length == 1) { w.write(usage()); } - - String[] r = new String[c.length - 1]; - for (int i=0; i < r.length; i++) r[i] = path(c[i + 1]); - // Object ret = send(new KeyRequest( FIXME: CompositeRequest - } - } - - public static abstract class Request implements Serializable { - public abstract Object process(JSScope root) throws JSExn; - } - - public static class KeyRequest extends Request { - private String path, matcher; - public KeyRequest() {} - public KeyRequest(String c) { - int pos = c.lastIndexOf('.'); - path = c.substring(0, pos); - matcher = c.substring(pos + 1).replaceAll("\\*+", ".*"); - } - public KeyRequest(String path, String matcher) { - this.path = path; this.matcher = matcher; - } - - /** Returns a List. */ - public Object process(JSScope root) throws JSExn { - String p = path == null ? "" : path.replaceAll("\\.+", "\\."); - if (p.length() > 0 && p.charAt(0) == '.') p = p.substring(1); - if (p.length() > 0 && p.charAt(p.length() - 1) == '.') p = p.substring(0, p.length() - 1); - System.out.println("searching path '"+p+"' for pattern '"+matcher+"'"); - - Object o = p.equals("") ? root : root.get(p); - if (o == null || o instanceof JSDate || - o instanceof JSArray || - !(o instanceof JS)) { - System.out.println("hit bad object: "+o+", class="+ - (o == null ? null : o.getClass().getName())); - throw new JSExn("path /" + p + " does not exist"); - } else { - Pattern pat = Pattern.compile(matcher); - List keys = new ArrayList(); - - Iterator i = ((JS)o).keys().iterator(); while(i.hasNext()) { - String k = i.next().toString(); - if (pat.matcher(k).matches()) keys.add(k); - } - - return keys; - } - } - } - - public static class ExecRequest extends Request { - private JS exec; - public ExecRequest() {} - public ExecRequest(JS exec) { this.exec = exec; } - public ExecRequest(String source) throws IOException, JSExn { - this(new StringReader(source)); - } - public ExecRequest(Reader source) throws IOException, JSExn { - exec = JS.fromReader("xsh", 0, source); - } - - /** Returns the result of JS.eval(). */ - public Object process(JSScope root) throws JSExn { - return JS.eval(JS.cloneWithNewParentScope(exec, root)); - } - } -} diff --git a/src/java/org/ibex/xt/shell/Command.java b/src/java/org/ibex/xt/shell/Command.java new file mode 100644 index 0000000..0ff2952 --- /dev/null +++ b/src/java/org/ibex/xt/shell/Command.java @@ -0,0 +1,160 @@ +package org.ibex.xt.shell; + +import java.util.*; + +import java.io.Writer; +import java.io.IOException; + +public abstract class Command { + /** Returns the command name. */ + public abstract String name(); + + /** Returns single-line of usage information, eg. pattern] */ + public abstract String usage(); + + /** Returns single-line description of command. */ + public abstract String summary(); + + /** Returns multi-line description. */ + public abstract String help(); + + /** Writes result of execution, even if result is an error. */ + public abstract void execute(Writer w, String[] args, Env env) throws IOException; + + public static class Help extends Command { + public String name() { return "help"; } + public String usage() { return "[command name]"; } + public String summary() { return "Lists available commands."; } + public String help() { return ""; } + + public void execute(Writer w, String[] c, Env env) throws IOException { + if (c.length > 1) { + Command cmd = env.command(c[1]); + if (c == null) { + w.write("help: "); + w.write(c[1]); + w.write(": command not found\n"); + } else { + w.write("usage: "); + w.write(cmd.name()); + w.write(" "); + w.write(cmd.usage()); + w.write("\n\n"); + w.write(cmd.help()); + w.write("\n"); + } + } else { + int len = 3; + for (int i=0; i < env.commands.length; i++) + len = Math.max(env.commands[i].name().length(), len); + + w.write("Available commands:\n"); + for (int i=0; i < env.commands.length; i++) { + Command cmd = env.commands[i]; + w.write(" "); + w.write(cmd.name()); + for (int j=len - cmd.name().length(); j >= 0; j--) w.write(" "); + w.write(" - "); + w.write(cmd.summary()); + w.write("\n"); + } + w.write("\nFor usage details, type help [command name].\n"); + } + } + } + + public static class Ls extends Command { + public String name() { return "ls"; } + public String usage() { return "[path]"; } + public String summary() { return "List object entries."; } + public String help() { return + "Lists the keys in an object. Modelled after the UNIX ls command."; + } + + public void execute(Writer w, String[] c, Env env) throws IOException { + if (c.length > 2) { w.write(usage()); return; } + String p = env.path(c.length == 1 ? "*" : c[1]); + + Request.Response ret = env.send(new Request.Key(p)); + if (!(ret instanceof Request.Key.Res)) { + w.write("error: "); + w.write(ret.error().getMessage()); + w.write("\n"); + } else { + List l = ((Request.Key.Res)ret).keys(); + Iterator i = l.iterator(); while (i.hasNext()) { + w.write(i.next().toString()); + w.write("\n"); + } + } + } + } + + public static class Pwd extends Command { + public String name() { return "pwd"; } + public String usage() { return ""; } + public String summary() { return "Path to current object."; } + public String help() { return "Print the path to the current object."; } + public void execute(Writer w, String[] c, Env env) throws IOException { + if (c.length != 1) { w.write(usage()); return; } + w.write(env.path.equals("") ? "/" : env.path.replace('.', '/')); + w.write("\n"); + } + } + + public static class Cd extends Command { + public String name() { return "cd"; } + public String usage() { return "[path]"; } + public String summary() { return "Change current object."; } + public String help() { return + "Chnages the current object that all other commands use "+ + "as the base for running.\n Pass either a relative path "+ + "(e.g. in /prevalent, type cd myob, now in /prevalent/myob) "+ + "or an absolute path (e.g. cd /prevalent/myob).\n\n" + + "To go up one level, cd .. can be used."; + } + public void execute(Writer w, String[] c, Env env) throws IOException { + if (c.length > 2) w.write(usage()); + else if (c.length == 1 || c[1].equals("") || c[1].equals("/")) env.path = ""; + else if (c[1].equals("..")) { + String n = env.path; + n = n.substring(0, n.lastIndexOf('.')); + env.path = n; + } else { + String n = env.path(c[1]); + + Request.Response ret = env.send(new Request.Key(n)); + if (!(ret instanceof Request.Key.Res)) { + w.write("error: "); + w.write(ret.error().getMessage()); + w.write("\n"); + } else { + List l = ((Request.Key.Res)ret).keys(); + if (l.size() == 0) { + w.write("cd "); + w.write(c[1]); + w.write(": no such path\n"); + } else { + env.path = n; + } + } + } + } + } + + public static class Rm extends Command { + public String name() { return "rm"; } + public String usage() { return "[options] [path]"; } + public String summary() { return "Removes objects."; } + public String help() { return "Removes objects."; } // FIXME + public void execute(Writer w, String[] c, Env env) throws IOException { + if (c.length == 1) { w.write(usage()); } + + String[] r = new String[c.length - 1]; + for (int i=0; i < r.length; i++) r[i] = env.path(c[i + 1]); + // Object ret = send(new KeyRequest( FIXME: CompositeRequest + } + } + + +} diff --git a/src/java/org/ibex/xt/shell/Env.java b/src/java/org/ibex/xt/shell/Env.java new file mode 100644 index 0000000..6f37146 --- /dev/null +++ b/src/java/org/ibex/xt/shell/Env.java @@ -0,0 +1,35 @@ +package org.ibex.xt.shell; + +import java.io.IOException; + +public abstract class Env { + /** Current JS path using '.' as a seperator. */ + public String path = ""; + + public Command[] commands = new Command[0]; + + /** Returns the command matching the given name. */ + public Command command(String name) { + for (int i=0; i < commands.length; i++) + if (commands[i].name().equals(name)) return commands[i]; + return null; + } + + /** Returns a path, based on console-style representation. */ + public String path(String c) { + if (c.equals("") || c.equals(".") || c.equals("/")) { + c = "."; + } else if (c.equals("..")) { + c = c.substring(0, c.lastIndexOf('.')); + if (c.equals("")) c = "."; + } else { + if (c.charAt(0) != '/') c = path + "." + c; + c = c.replaceAll("/+", "."); + if (c.length() > 1 && c.charAt(c.length() - 1) == '.') + c = c.substring(0, c.length() - 1); + } + return c; + } + + public abstract Request.Response send(Request request) throws IOException; +} diff --git a/src/java/org/ibex/xt/shell/Request.java b/src/java/org/ibex/xt/shell/Request.java new file mode 100644 index 0000000..eec18b7 --- /dev/null +++ b/src/java/org/ibex/xt/shell/Request.java @@ -0,0 +1,99 @@ +package org.ibex.xt.shell; + +import java.io.*; +import java.util.*; +import java.util.regex.*; + +import org.ibex.js.*; + +public abstract class Request implements Serializable { + + public abstract Response process(JSScope root) throws JSExn; + + public static class Response implements Serializable { + protected Exception ex; + public Response() { ex = null; } + public Response(Exception e) { ex = e; } + public Exception error() { return ex; } + } + + public static class Key extends Request { + private String path, matcher; + public Key() {} + public Key(String c) { + int pos = c.lastIndexOf('.'); + path = c.substring(0, pos); + matcher = c.substring(pos + 1).replaceAll("\\*+", ".*"); + } + public Key(String path, String matcher) { + this.path = path; this.matcher = matcher; + } + + public Response process(JSScope root) throws JSExn { + String p = path == null ? "" : path.replaceAll("\\.+", "\\."); + if (p.length() > 0 && p.charAt(0) == '.') + p = p.substring(1); + if (p.length() > 0 && p.charAt(p.length() - 1) == '.') + p = p.substring(0, p.length() - 1); + + System.out.println("searching path '"+p+"' for pattern '"+matcher+"'"); + + Object o = p.equals("") ? root : root.get(p); + if (o == null || o instanceof JSDate || + o instanceof JSArray || + !(o instanceof JS)) { + System.out.println("hit bad object: "+o+", class="+ + (o == null ? null : o.getClass().getName())); + return new Key.Res(); + } else { + Pattern pat = Pattern.compile(matcher); + List keys = new ArrayList(); + + Iterator i = ((JS)o).keys().iterator(); while(i.hasNext()) { + String k = i.next().toString(); + if (pat.matcher(k).matches()) keys.add(k); + } + + return new Res(keys); + } + } + + public static class Res extends Response { + private List keys; + public Res() { keys = null; } + public Res(List l) { keys = l; } + public List keys() { return keys; } + public boolean isPath() { return keys != null; } + } + } + + public static class Composite extends Request { + private Request[] requests; + public Composite() {} + public Composite(Request[] r) { requests = r; } + public Composite(List r) { + Request[] req = new Request[r.size()]; + r.toArray(req); + requests = req; + } + + public Response process(JSScope root) { + Response[] res = new Response[requests.length]; + + for (int i=0; i < requests.length; i++) { + try { res[i] = requests[i].process(root); } + catch (JSExn e) { res[i] = new Response(e); } + } + + return new Res(res); + } + + public static class Res extends Response { + private Response[] responses; + public Res() {} + public Res(Response[] r) { responses = r; } + public Response get(int i) { return responses[i]; } + public int size() { return responses.length; } + } + } +} diff --git a/src/java/org/ibex/xt/ShellServlet.java b/src/java/org/ibex/xt/shell/Servlet.java similarity index 85% rename from src/java/org/ibex/xt/ShellServlet.java rename to src/java/org/ibex/xt/shell/Servlet.java index e9fc0a8..44cc346 100644 --- a/src/java/org/ibex/xt/ShellServlet.java +++ b/src/java/org/ibex/xt/shell/Servlet.java @@ -1,15 +1,15 @@ -package org.ibex.xt; +package org.ibex.xt.shell; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; +import org.ibex.xt.Prevalence; import org.ibex.js.*; import org.prevayler.*; - -public class ShellServlet extends HttpServlet { +public class Servlet extends HttpServlet { private ServletContext cx = null; private Prevayler prevayler; private JS prevalent; @@ -22,8 +22,8 @@ public class ShellServlet extends HttpServlet { } public void doPost(HttpServletRequest rq, HttpServletResponse rs) throws IOException { - Shell.Request r; - try { r = (Shell.Request)new ObjectInputStream(rq.getInputStream()).readObject(); } + Request r; + try { r = (Request)new ObjectInputStream(rq.getInputStream()).readObject(); } catch (ClassNotFoundException e) { e.printStackTrace(); throw new IOException("exception receiving request, class not found"); @@ -47,8 +47,8 @@ public class ShellServlet extends HttpServlet { } rq.getSession().setAttribute("scope", scope); } - Object ret; - try { ret = r.process(scope); } catch (JSExn e) { ret = e; } + Request.Response ret; + try { ret = r.process(scope); } catch (JSExn e) { ret = new Request.Response(e); } new ObjectOutputStream(rs.getOutputStream()).writeObject(ret); } } diff --git a/src/java/org/ibex/xt/shell/Shell.java b/src/java/org/ibex/xt/shell/Shell.java new file mode 100644 index 0000000..746479e --- /dev/null +++ b/src/java/org/ibex/xt/shell/Shell.java @@ -0,0 +1,110 @@ +package org.ibex.xt.shell; + +import java.io.*; +import java.net.*; + +public class Shell extends Env { + + public static void main(String[] args) throws Exception { + if (args.length == 0 || args.length > 2|| !args[0].startsWith("http://")) { + printUsage(); return; + } + Shell shell = new Shell(new URL(args[0])); + + if (args.length == 2) { + // FIXME + } else { + shell.listen(new InputStreamReader(System.in), new OutputStreamWriter(System.out)); + } + } + + private static void printUsage() { + System.out.println("Usage: xish url [command]"); + } + + /** URL of server. */ + protected URL server; + + /** Server cookie. Reduces server load. */ + private String cookie = null; + + /** Create a new Shell using the given url for the server. */ + public Shell(URL url) { + server = url; + commands = new Command[] { + new Command.Ls(), + new Command.Pwd(), + new Command.Cd(), + new Command.Rm(), + new Command.Help() + }; + } + + public void listen(Reader r, Writer w) throws IOException { + LineNumberReader in = new LineNumberReader(r); + PrintWriter out = new PrintWriter(w); + + out.println("ibex xt shell: type help or exit"); + out.print("xt: "); + out.flush(); + + String line; + String buffer = ""; + while ((line = in.readLine()) != null) { + if (line.length() > 0) { + if (line.startsWith("exit")) return; + if (line.charAt(line.length() - 1) == '\\') { + buffer += line.substring(0, line.length() - 1); + out.print('>'); + out.flush(); continue; + } + + buffer += line; + } + + if (buffer.length() > 0) { + String[] c = buffer.split(" "); + Command cmd = command(c[0]); + + if (cmd == null) { + out.write(c[0]); + w.write(": command not found\n"); + } else cmd.execute(out, c, this); + + buffer = ""; + } + out.print("xt: "); + out.flush(); + } + } + + public Request.Response send(Request request) throws IOException { + URLConnection c = server.openConnection(); + ((HttpURLConnection)c).setRequestMethod("POST"); + c.setDoOutput(true); + if (cookie != null) c.setRequestProperty("Cookie", cookie); + + c.connect(); + + ObjectOutputStream out = new ObjectOutputStream(c.getOutputStream()); + out.writeObject(request); + out.close(); + + String cook = c.getHeaderField("Set-Cookie"); + if (cook != null && !cook.equals("")) cookie = cook.substring(0, cook.indexOf(';')); + + try { + Object o = new ObjectInputStream(c.getInputStream()).readObject(); + if (o == null) { + throw new IOException("unexpected null object returned"); + } else if (!(o instanceof Request.Response)) { + throw new IOException("unexpected object returned: "+o.getClass().getName()); + } else { + return (Request.Response)o; + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new IOException("unexpected ClassNotFoundException"); + } + } +} -- 1.7.10.4