Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / jigsaw / http / socket / SocketClient.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/http/socket/SocketClient.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/http/socket/SocketClient.java
new file mode 100644 (file)
index 0000000..70b7ef0
--- /dev/null
@@ -0,0 +1,314 @@
+// SocketClient.java\r
+// $Id: SocketClient.java,v 1.1 2010/06/15 12:26:10 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1996.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigsaw.http.socket ;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.DataOutputStream;\r
+import java.io.IOException;\r
+import java.io.PrintStream;\r
+\r
+import java.net.InetAddress;\r
+import java.net.Socket;\r
+import java.net.SocketException;\r
+\r
+import org.w3c.jigsaw.http.Client;\r
+import org.w3c.jigsaw.http.ClientException;\r
+import org.w3c.jigsaw.http.httpd;\r
+\r
+import org.w3c.tools.resources.ServerInterface;\r
+\r
+/**\r
+ * This class implements the object that handles client connections. \r
+ * One such object exists per open connections at any given time.\r
+ * <p>The basic architecture is the following: the httpd instance accepts \r
+ * new connections on its port. When such a connection is accepted a Client \r
+ * object is requested to the client pool (which can implement what ever \r
+ * strategy is suitable). Each request is than managed by looking up an\r
+ *  resource and invoking the resource methods corresponding to the request.\r
+ * @see org.w3c.jigsaw.http.httpd\r
+ * @see org.w3c.jigsaw.http.Request\r
+ * @see org.w3c.jigsaw.http.Reply\r
+ */\r
+\r
+public class SocketClient extends Client implements Runnable {\r
+    private static final boolean trace = false;\r
+\r
+    /**\r
+     * The ClientFactory that created this client.\r
+     */\r
+    private SocketClientFactory pool = null ;\r
+    /**\r
+     * The socket currently handled by the client.\r
+     */\r
+    protected Socket socket = null ;\r
+    /**\r
+     * Is this client still alive ?\r
+     */\r
+    protected boolean alive = false;\r
+    /**\r
+     * The client state for this client, has managed by the SocketClientFactory\r
+     * @see SocketClientFactory\r
+     */\r
+    SocketClientState state = null;\r
+    /**\r
+     * Number of times this client was bound to a connection.\r
+     */\r
+    protected int bindcount = 0;\r
+    /**\r
+     * The thread that we have been attached to.\r
+     */\r
+    protected Thread thread = null;\r
+    /**\r
+     * Our reusable output buffer.\r
+     */\r
+    protected SocketOutputBuffer bufout = null;\r
+    /**\r
+     * Our we idle (waiting for next request ?)\r
+     */\r
+    protected boolean idle = false;\r
+\r
+    /**\r
+     * are we done?\r
+     */\r
+    protected boolean done = false;\r
+\r
+    /**\r
+     * Print that client into a String.\r
+     * @return A String instance.\r
+     */\r
+\r
+    public String toString() {\r
+       if ( thread != null )\r
+           return "client-"+state.id+"("+thread.getName()+")";\r
+       else\r
+           return "client-"+state.id;\r
+    }\r
+\r
+    /**\r
+     * If this client is allocated a thread, join it.\r
+     */\r
+\r
+    public void join() {\r
+       if (thread != null) {\r
+           while ( true ) {\r
+               try {\r
+                   thread.join();\r
+               } catch (InterruptedException ex) {\r
+               }\r
+           }\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Run for our newly attached connection.\r
+     * @return A boolean, <strong>true</strong> if the client is to be killed\r
+     * as decided by its SocketClientFactory creator.\r
+     */\r
+\r
+    public void run() {\r
+       thread = Thread.currentThread();\r
+       if ( trace )\r
+           System.out.println(this+": powered by "+thread);\r
+       try {\r
+           if ( bufout == null ) {\r
+               // Make sure that buffer is a little smaller then the client\r
+               // buffer. so writing to it will not copy it\r
+               int bufsize = getServer().getClientBufferSize() - 1;\r
+               bufout = new SocketOutputBuffer(socket.getOutputStream()\r
+                                               , bufsize);\r
+           } else {\r
+               bufout.reuse(socket.getOutputStream());\r
+           }\r
+           startConnection(new BufferedInputStream(socket.getInputStream())\r
+                           , new DataOutputStream(bufout));\r
+       } catch (IOException ex) {\r
+           if ( debug )\r
+               ex.printStackTrace();\r
+       } catch (ClientException ex) {\r
+           if ( debug )\r
+               ex.printStackTrace();\r
+           // Emit some debugging traces:\r
+           if ( debug ) {\r
+               if (ex.ex != null )\r
+                   ex.ex.printStackTrace() ;\r
+               else\r
+                   ex.printStackTrace();\r
+           }\r
+           // If output is null, we have killed the connection...\r
+           if ( alive && ! idle ) {\r
+               error("caught ClientException: [" \r
+                      + ex.getClass().getName()\r
+                     + "] " + ex.getMessage()) ;\r
+           }\r
+       } catch (Exception ex) {\r
+           if (debug) {\r
+               System.out.println("unknown exception caught in client run");\r
+               ex.printStackTrace();\r
+           }\r
+       } finally {\r
+           if ( ! pool.clientConnectionFinished(this) ) {\r
+               pool.clientFinished(this);\r
+           }\r
+           thread = null;\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Client implementation - Get the IP address of this client.\r
+     * @return An InetAddress instance, or <strong>null</strong> if the\r
+     * client is not currently running.\r
+     */\r
+\r
+    public InetAddress getInetAddress () {\r
+       return (socket != null) ? socket.getInetAddress() : null;\r
+    }\r
+\r
+    /**\r
+     * Client implementation - This connection has been stopped.\r
+     * Make sure the whole socket is closed, and be ready to handle \r
+     * next connection.\r
+     */\r
+\r
+    protected void stopConnection() {\r
+       if ( trace )\r
+           System.out.println(this+": stopConnection.");\r
+       if ( socket != null ) {\r
+           try {\r
+               socket.close();\r
+           } catch (Exception ex) {\r
+           }\r
+           socket = null;\r
+//         alive = false;\r
+//         if (!pool.idleClientRemove(this)) {\r
+//             pool.clientFinished(this);\r
+//         }\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Get the thread powering that client.\r
+     * @return A Thread instance, or <strong>null</strong>.\r
+     */\r
+\r
+    protected Thread getThread() {\r
+       return thread;\r
+    }\r
+\r
+    /**\r
+     * Client implementation - The current connection is idle.\r
+     * The client is about to wait for the next request from the net, mark\r
+     * it as idle to make it a candidate for persistent connection closing.\r
+     * @return A boolean, if <strong>true</strong> our client factory wants\r
+     * us to stop right now, in order to handle some other connection.\r
+     */\r
+\r
+    protected boolean idleConnection() {\r
+       synchronized (state) {\r
+           if ( trace )\r
+               System.out.println(this+": idleConnection.");\r
+           idle = true;\r
+           return ! pool.notifyIdle(this);\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Client implementation - The current connection is in use.\r
+     * A request is about to be processed, mark that connection as used, to\r
+     * remove it from the idle state.\r
+     */\r
+\r
+    protected void usedConnection() {\r
+       synchronized (state) {\r
+           if ( trace )\r
+               System.out.println(this+": usedConnection.");\r
+           idle = false;\r
+           pool.notifyUse(this) ;\r
+       }\r
+    }\r
+\r
+    /**\r
+     * SocketClientFactory interface - Bind the socket to this client.\r
+     * Binding a socket to a client triggers the processing of the underlying\r
+     * connection. It is assumed that the client was ready to handle a new \r
+     * connection before this method was called.\r
+     * @param socket The socket this client should now handle.\r
+     */\r
+\r
+    protected synchronized void bind(Socket socket) {\r
+       done = false;\r
+       ServerInterface server = getServer();\r
+       if ( trace )\r
+           System.out.println(this+": bind.");\r
+       this.socket = socket ;\r
+        try {\r
+//            socket.setSoTimeout(server.getRequestTimeOut());\r
+           socket.setSoTimeout(pool.timeout);\r
+        } catch (SocketException ex) { \r
+           if (trace)\r
+               ex.printStackTrace(); \r
+           server.errlog("Unable to set socket timeout!");\r
+        } \r
+       this.idle   = false;\r
+       bindcount++;\r
+       pool.run(this);\r
+    }\r
+\r
+    /**\r
+     * SocketClientFactory interface - Unbind this client.\r
+     * This client is handling an idle connection, unbind it to make\r
+     * it free for handling some other more buzy connection.\r
+     */\r
+\r
+    protected synchronized void unbind() {\r
+       if ( trace )\r
+           System.out.println(this+": unbind.");\r
+       interruptConnection(true);\r
+    }\r
+\r
+    /**\r
+     * SocketClientFactory interface - Kill this client.\r
+     * The clean way for our client factory to shut us down unconditionally.\r
+     * This will free all resources acquired by this client, stop the current\r
+     * connection processing if needed, and terminate the underlying thread.\r
+     */\r
+\r
+    protected synchronized void kill(boolean now) {\r
+       if ( trace )\r
+           System.out.println(this+": kill.");\r
+       alive = false;\r
+       interruptConnection(now);\r
+    }\r
+\r
+    /**\r
+     * Get the total number of times this client was bound to a socket.\r
+     * @return An integer, indicatingthe number of bind calls on this client.\r
+     */\r
+\r
+    public final int getBindCount() {\r
+       return bindcount;\r
+    }\r
+\r
+    /**\r
+     * Create an empty client, that will be ready to work.\r
+     * The created client will run and wait for it to be <code>bind</code>\r
+     * to some socket before proceeding.\r
+     * @param server The server to which this client is attached.\r
+     * @param id The client identifier.\r
+     * @see org.w3c.jigsaw.http.Client\r
+     * @see org.w3c.jigsaw.http.ClientFactory\r
+     */\r
+\r
+    protected SocketClient(httpd server,\r
+                          SocketClientFactory pool,\r
+                          SocketClientState state) {\r
+       initialize(server, state.id);\r
+       this.socket   = null ;\r
+       this.pool     = pool;\r
+       this.state    = state;\r
+       this.alive    = true;\r
+    }\r
+\r
+}\r