Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / www / protocol / http / FilterEngine.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/www/protocol/http/FilterEngine.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/www/protocol/http/FilterEngine.java
new file mode 100644 (file)
index 0000000..0995060
--- /dev/null
@@ -0,0 +1,278 @@
+// FilterEngine.java\r
+// $Id: FilterEngine.java,v 1.1 2010/06/15 12:25:12 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.www.protocol.http;\r
+\r
+import java.util.StringTokenizer;\r
+import java.util.Vector;\r
+\r
+import java.net.URL;\r
+\r
+class ScopeNode {\r
+    private static final int FILTER_INIT_SIZE = 2;\r
+    private static final int CHILD_INIT_SIZE  = 4;\r
+\r
+    String        key       = null;\r
+    RequestFilter filters[] = null;\r
+    boolean       inex[]    = null;\r
+    ScopeNode     child[]   = null;\r
+\r
+    /**\r
+     * Trigger the sync method of filters set on this node, and recurse.\r
+     */\r
+\r
+    synchronized void sync() {\r
+       // Sync our own filters\r
+       if ( filters != null ) {\r
+           for (int i = 0 ; i < filters.length ; i++) {\r
+               RequestFilter f = filters[i];\r
+               if ( f == null )\r
+                   continue;\r
+               f.sync();\r
+           }\r
+       }\r
+       // Sync all our children filters:\r
+       if ( child != null ) {\r
+           for (int i = 0 ; i < child.length ; i++) {\r
+               ScopeNode c = child[i];\r
+               if ( c == null )\r
+                   continue;\r
+               c.sync();\r
+           }\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Resolve this scope node into the provided vector.\r
+     * @param into The vector containing the list of filter settings.\r
+     */\r
+\r
+    synchronized void resolve(Vector into) {\r
+       // Anything to be done here ?\r
+       if ( filters == null )\r
+           return;\r
+       // Apply the filters:\r
+       for (int i = 0 ; i < filters.length ; i++) {\r
+           if ( filters[i] == null ) \r
+               continue;\r
+           boolean is = into.contains(filters[i]); \r
+           if ((! inex[i]) && ( is )) {\r
+               // The filter is to be excluded, but is actually present:\r
+               into.removeElement(filters[i]);\r
+           } else if (inex[i] && ( !is)) {\r
+               // The filter is to be included, but is not present:\r
+               into.addElement(filters[i]);\r
+           }\r
+       }\r
+    }\r
+\r
+    synchronized void setFilter(boolean ie, RequestFilter filter) {\r
+       int slot = -1;\r
+       // Find a slot:\r
+       if ( filters == null ) {\r
+           // Initialize the filters list:\r
+           filters = new RequestFilter[FILTER_INIT_SIZE];\r
+           inex    = new boolean[FILTER_INIT_SIZE];\r
+           slot    = 0;\r
+       } else {\r
+           // Look for a free slot:\r
+           for (int i = 0 ; i < filters.length ; i++) {\r
+               if ( filters[i] == null ) {\r
+                   slot = i;\r
+                   break;\r
+               }\r
+           }\r
+           // Do we need to resize the filters arrays:\r
+           if ( slot == -1 ) {\r
+               slot = filters.length;\r
+               RequestFilter nf[] = new RequestFilter[slot<<1];\r
+               boolean       ni[] = new boolean[slot<<1];\r
+               System.arraycopy(filters, 0, nf, 0, slot);\r
+               System.arraycopy(inex, 0, ni, 0, slot);\r
+               filters = nf;\r
+               inex    = ni;\r
+           }\r
+       }\r
+       // Updae the appropriate slot:\r
+       filters[slot] = filter;\r
+       inex[slot]    = ie;\r
+    }\r
+\r
+    synchronized ScopeNode lookup(String key) {\r
+       // No children ?\r
+       if ( child == null )\r
+           return null;\r
+       // Lookup children, may be made more efficient if prooves usefull:\r
+       for (int i = 0 ; i < child.length ; i++) {\r
+           if ( child[i] == null )\r
+               continue;\r
+           if ( key.equals(child[i].key) )\r
+               return child[i];\r
+       }\r
+       return null;\r
+    }\r
+\r
+    synchronized ScopeNode create(String key) {\r
+       int slot = -1;\r
+       // Get a slot:\r
+       if ( child == null ) {\r
+           child = new ScopeNode[CHILD_INIT_SIZE];\r
+           slot  = 0;\r
+       } else {\r
+           // Look for a free slot:\r
+           for (int i = 0 ; i < child.length ; i++) {\r
+               if ( child[i] == null ) {\r
+                   slot = i;\r
+                   break;\r
+               }\r
+           }\r
+           // Do we need to resize ?\r
+           if ( slot == -1 ) {\r
+               slot = child.length;\r
+               ScopeNode nc[] = new ScopeNode[slot << 1];\r
+               System.arraycopy(child, 0, nc, 0, slot);\r
+               child = nc;\r
+           }\r
+       }\r
+       // Update the slot:\r
+       return child[slot] = new ScopeNode(key);\r
+    }\r
+\r
+    ScopeNode(String key) {\r
+       this.key = key;\r
+    }\r
+\r
+    ScopeNode() {\r
+       // Valid only for the root node\r
+    }\r
+\r
+}\r
+\r
+class FilterEngine {\r
+    ScopeNode root = null;\r
+\r
+    /**\r
+     * Split an URL into its various parts.\r
+     * @return An array of Strings containing the URL parts.\r
+     */\r
+\r
+    private String[] urlParts(URL url) {\r
+       Vector parts = new Vector(8);\r
+       // The protocol is always the first part:\r
+       parts.addElement(url.getProtocol());\r
+       // Then comes the host:port identifier (we deal *only* with http):\r
+       if ((url.getPort() == -1) || (url.getPort() == 80)) {\r
+           parts.addElement(url.getHost());\r
+       } else {\r
+           parts.addElement(url.getHost()+":"+url.getPort());\r
+       }\r
+       // get the "file" part of URI with a fix for jdk1.4\r
+       String sUrl = url.getFile();\r
+       if (sUrl.length() == 0) {\r
+           sUrl = "/";\r
+       }\r
+       // And last but not least, the parsed path (really not efficient !)\r
+       StringTokenizer st = new StringTokenizer(sUrl, "/");\r
+       while ( st.hasMoreTokens() )\r
+           parts.addElement(st.nextElement());\r
+       // Build the vector into an array:\r
+       String p[] = new String[parts.size()];\r
+       parts.copyInto(p);\r
+       return p;\r
+    }\r
+\r
+    /**\r
+     * Register this given filter in the given scope.\r
+     * @param scope The URL prefix defining the scope of the filter.\r
+     * @param inex Is the scope an include or an exclude scope.\r
+     * @param filter The filter to register in the given scope.\r
+     */\r
+\r
+    synchronized void setFilter(URL scope, boolean ie, RequestFilter filter) {\r
+       String parts[] = urlParts(scope);\r
+       ScopeNode node = root;\r
+       // Find or create the appropriate scope node for the filter:\r
+       for (int i = 0 ; i < parts.length ; i++) {\r
+           ScopeNode child = node.lookup(parts[i]);\r
+           if ( child == null ) \r
+               child = node.create(parts[i]);\r
+           node = child;\r
+       }\r
+       // Setup the filter in the scope node:\r
+       node.setFilter(ie, filter);\r
+    }\r
+\r
+    synchronized void setFilter(RequestFilter filter) {\r
+       root.setFilter(true, filter);\r
+    }\r
+\r
+    /**\r
+     * Get a global filter of the given class.\r
+     * @return A RequestFilter instance, or <strong>null</strong> if none\r
+     * was found.\r
+     */\r
+\r
+    synchronized RequestFilter getGlobalFilter(Class cls) {\r
+       RequestFilter filters[] = root.filters;\r
+       for (int i = 0 ; i < filters.length ; i++) {\r
+           if ( filters[i] == null )\r
+               continue;\r
+           Class fc = filters[i].getClass();\r
+           while (fc != null) {\r
+               if ( fc == cls )\r
+                   return filters[i];\r
+               fc = fc.getSuperclass();\r
+           }\r
+       }\r
+       return null;\r
+    }\r
+\r
+    /**\r
+     * Trigger the sync method of all installed filters.\r
+     * This method walk through the entire filter tree, and sync all filters\r
+     * found on the way.\r
+     */\r
+\r
+    synchronized void sync() {\r
+       root.sync();\r
+    }\r
+\r
+    /**\r
+     * Compute the set of filters that apply to this request.\r
+     * This method examine the current scopes of all filters, and determine\r
+     * the list of filters to run for the given request.\r
+     * @return An array of filters to run for the given request, or\r
+     * <strong>null</strong> if no filters apply.\r
+     */\r
+\r
+    RequestFilter[] run(Request request) {\r
+       String    parts[] = urlParts(request.getURL());\r
+       int       ipart   = 0;\r
+       ScopeNode node    = root;\r
+       // Compute the filters apply list:\r
+       Vector    applies = new Vector();\r
+       while (node != null) {\r
+           node.resolve(applies);\r
+            if ( ipart < parts.length )\r
+               node = node.lookup(parts[ipart++]);\r
+           else\r
+               break;\r
+       }\r
+       // Optional (not done for now) order the filters:\r
+\r
+       // Now run them, and keep the state in the request:\r
+       if ( applies.size() == 0 )\r
+           return null;\r
+       RequestFilter f[] = new RequestFilter[applies.size()];\r
+       applies.copyInto(f);\r
+       return f;\r
+    }\r
+\r
+    FilterEngine() {\r
+       this.root = new ScopeNode("_root_");\r
+    }\r
+\r
+   \r
+}\r