Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / www / protocol / http / cache / push / PushCacheProtocol.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/www/protocol/http/cache/push/PushCacheProtocol.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/www/protocol/http/cache/push/PushCacheProtocol.java
new file mode 100644 (file)
index 0000000..856743c
--- /dev/null
@@ -0,0 +1,262 @@
+// PushCacheProtocol.java\r
+// $Id: PushCacheProtocol.java,v 1.1 2010/06/15 12:25:43 smhuang Exp $\r
+// (c) COPYRIGHT MIT, INRIA and Keio, 2001.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.www.protocol.http.cache.push;\r
+\r
+import java.io.DataOutputStream;\r
+import java.io.ByteArrayOutputStream;\r
+\r
+import java.util.TreeMap;\r
+\r
+/**\r
+ * PushCacheProtocol\r
+ * Characteristics of the protocol used to control the push cache, and \r
+ * methods for common operations\r
+ * <p>\r
+ * <b>Protocol Description</b>\r
+ * <p>\r
+ * To request that "/home/abc/page.html" is inserted in cache as \r
+ * "http://www.abc.com/page.html" the client sends a packet with\r
+ * command="ADD", and remain_len set to sizeof(add_packet_t) plus\r
+ * the sum of the lengths of the path and the urls including their\r
+ * null terminators.  The client then sends an add_packet describing\r
+ * the lengths of the two strings followed by the path and then the\r
+ * url.\r
+ * <p>\r
+ * The server replies with either command="OK" and remain_len=0 or\r
+ * command="ERR" and remain_len set the the length of the error\r
+ * string that follows immediately.  In the event of an "ERR" message\r
+ * the connection is closed by the server.\r
+ * <p>\r
+ * To request that the page associated with "http://www.abc.com/page.html"\r
+ * be removed from the cache the client sends a packet with command="DEL",\r
+ * and remain_len set to sizeof(int) plus the length of the url string\r
+ * including the trailing null character.  The server replies as with\r
+ * ADD above.  Attempting to remove a url that is not present in the cache\r
+ * results in an "OK" packet being returned, the cache is unchanged.\r
+ * <p>\r
+ * The client can ask if a url is present in the cache by sending a packet\r
+ * with command="PRS", and url information as with the DEL command.  The\r
+ * server will reply with "OK" if the url is present, "NO" if the url is\r
+ * not present and "ERR" if an error was encountered.\r
+ * <p>\r
+ * The client can request that the cache be emptied of all urls by sending\r
+ * a packet with command="CLN" (clean).  The remain_len field is set to zero.\r
+ * The server will reply with either OK or ERR.\r
+ * \r
+ * <p>\r
+ * The client can terminate the dialogue by sending a command="BYE" \r
+ * packet and then closing the connection.\r
+ * \r
+ * <p>\r
+ * 'C' code describing the packet structures are shown below\r
+ *\r
+ *\r
+ *<pre>\r
+ * typedef struct {\r
+ *                             // Bytes  Notes\r
+ *                             // -----  -----\r
+ *       char  tag[4];         // 0-3    = {'P','C','P','P'}\r
+ *       short major_version;  // 4-5    = 1\r
+ *       short minor_version;  // 6-7    = 1\r
+ *       char  command[4];     // 8-11   Null terminated command string \r
+ *       int   remain_len;     // 12-15  number of remaining bytes to read\r
+ * } packet_t;\r
+ *\r
+ * typedef struct {\r
+ *       int   path_len;       // 4      Length of pathname (including null)\r
+ *       int   url_len;        // 8      Length of URL (including null)\r
+ * } add_packet_t;\r
+ * \r
+ * Note that the command is always 4 characters in length and that the\r
+ * null characters are considered part of the command, so in Java (but\r
+ * not C) we must include the \0 when comparing strings:\r
+ *   "ADD\0", "BYE\0", "OK\0\0", "ERR\0", "CLN\0", "PRS\0", "DEL\0"\r
+ *\r
+ * </pre>\r
+ *\r
+ * @author Paul Henshaw, The Fantastic Corporation, Paul.Henshaw@fantastic.com\r
+ * @version $Revision: 1.1 $\r
+ * $Id: PushCacheProtocol.java,v 1.1 2010/06/15 12:25:43 smhuang Exp $\r
+ */\r
+public class PushCacheProtocol {\r
+    /*\r
+     * Protocol characteristics\r
+     */\r
+\r
+    /**\r
+     * Size of basic packet in bytes\r
+     */\r
+    public final static int   PACKET_LEN=16;\r
+\r
+    /**\r
+     * Size of command string in bytes (including null terminator)\r
+     */\r
+    public final static int   COMMAND_LEN=4;\r
+\r
+    /**\r
+     * Combined size of tag and version information\r
+     */\r
+    public final static int   HEADER_LEN=8;\r
+\r
+    /**\r
+     * Size of packet tag\r
+     */\r
+    public final static int   TAG_LEN=4;\r
+    \r
+    /**\r
+     * Maximum size of strings (urls, paths, error messages)\r
+     */\r
+    public final static int   MAX_STRING_LEN=1024;\r
+\r
+    /**\r
+     * Maximum size of payload (follows basic packet)\r
+     */\r
+    public final static int   MAX_PAYLOAD_LEN=8192;\r
+\r
+    /**\r
+     * Protocol Major version\r
+     */\r
+    public final static short MAJ_PROTO_VERSION=1;\r
+\r
+    /**\r
+     * Protocol minor version\r
+     */\r
+    public final static short MIN_PROTO_VERSION=2;\r
+\r
+    /**\r
+     * Numeric codes for commands, \r
+     */\r
+    public static final int NO_SUCH_COMMAND=-1, \r
+       ERR=0, ADD=1, DEL=2, CLN=3, PRS=4, BYE=5, OK=6, NO=7, NOP=8;\r
+\r
+    private static PushCacheProtocol _instance;\r
+    private TreeMap _map;\r
+    private byte[] _ok_packet_bytes=null;\r
+    private byte[] _no_packet_bytes=null;\r
+    private byte[] _err_packet_bytes=null;\r
+    private byte[] _header=null;\r
+\r
+    /**\r
+     * Access to single instance of this class\r
+     */\r
+    public static PushCacheProtocol instance() {\r
+       if(_instance==null) {\r
+           _instance=new PushCacheProtocol();\r
+       }\r
+       return _instance;\r
+    }\r
+    \r
+    /**\r
+     * Utility function for command string parsing\r
+     */\r
+    public int parseCommand(String command) {\r
+       Integer in=(Integer)_map.get(command);\r
+       if(in==null) {\r
+           return NO_SUCH_COMMAND;\r
+       }\r
+       return(in.intValue());\r
+    }\r
+\r
+    /**\r
+     * Byte array for OK packet\r
+     */\r
+    public byte[] okPacket() {\r
+       return(_ok_packet_bytes);\r
+    }\r
+\r
+    /**\r
+     * Byte array for NO packet\r
+     */\r
+    public byte[] noPacket() {\r
+       return(_no_packet_bytes);\r
+    }\r
+\r
+    public byte[] header() {\r
+       return(_header);\r
+    }\r
+\r
+    /**\r
+     * Create error packet for specified error message\r
+     */\r
+    public byte[] errorPacket(String message) {\r
+       try {\r
+           java.io.ByteArrayOutputStream baos=\r
+               new java.io.ByteArrayOutputStream(16);\r
+           DataOutputStream dos=new \r
+               DataOutputStream(baos);\r
+                   \r
+           dos.write(_header,0,_header.length);\r
+           dos.writeBytes("ERR\0");\r
+           dos.writeInt(message.length());\r
+           dos.writeBytes(message);\r
+           return baos.toByteArray();\r
+       }\r
+       catch(Exception e) {\r
+           e.printStackTrace();\r
+       }\r
+       return(null);\r
+    }\r
+\r
+    /**\r
+     * True iff first four bytes of packet are identical to the protocol tag\r
+     */\r
+    public boolean isValidProtocolTag(byte[] packet) {\r
+       return(packet[0]==(byte)'P' && packet[1]==(byte)'C' || \r
+              packet[2]==(byte)'P' && packet[3]==(byte)'P');\r
+    }\r
+\r
+    /**\r
+     * Singleton, no public constructor, use {@link #instance}\r
+     * @see #instance\r
+     */ \r
+    protected PushCacheProtocol() {\r
+       try {\r
+           _map=new TreeMap();\r
+           _map.put("ERR\0",new Integer(ERR));\r
+           _map.put("ADD\0",new Integer(ADD));\r
+           _map.put("DEL\0",new Integer(DEL));\r
+           _map.put("CLN\0",new Integer(CLN));\r
+           _map.put("PRS\0",new Integer(PRS));\r
+           _map.put("BYE\0",new Integer(BYE));\r
+           _map.put("OK\0\0",new Integer(OK));\r
+           _map.put("NO\0\0",new Integer(NO));\r
+           _map.put("NOP\0",new Integer(NOP));\r
+\r
+           ByteArrayOutputStream baos=new ByteArrayOutputStream(PACKET_LEN);\r
+           DataOutputStream dos=new DataOutputStream(baos);\r
+           dos.writeByte('P');\r
+           dos.writeByte('C');\r
+           dos.writeByte('P');\r
+           dos.writeByte('P');\r
+           dos.writeShort(MAJ_PROTO_VERSION);\r
+           dos.writeShort(MIN_PROTO_VERSION);\r
+           _header=baos.toByteArray();\r
+\r
+           baos=new ByteArrayOutputStream(PACKET_LEN);\r
+           dos=new DataOutputStream(baos);\r
+           \r
+           dos.write(_header,0,_header.length);\r
+           dos.writeBytes("OK\0\0");\r
+           dos.writeInt(0);\r
+\r
+           _ok_packet_bytes=baos.toByteArray();\r
+\r
+           baos=null;\r
+           dos=null;\r
+\r
+           baos=new ByteArrayOutputStream(PACKET_LEN);\r
+           dos=new DataOutputStream(baos);\r
+           dos.write(_header,0,_header.length);\r
+           dos.writeBytes("NO\0\0");\r
+           dos.writeInt(0);\r
+\r
+           _no_packet_bytes=baos.toByteArray();\r
+       }\r
+       catch(Exception e) {\r
+           e.printStackTrace();\r
+       }\r
+    }\r
+}\r