Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / jigsaw / frames / RelocateFrame.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/frames/RelocateFrame.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/frames/RelocateFrame.java
new file mode 100644 (file)
index 0000000..2c99bdc
--- /dev/null
@@ -0,0 +1,412 @@
+// RelocateFrame.java\r
+// $Id: RelocateFrame.java,v 1.2 2010/06/15 17:52:52 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.frames;\r
+\r
+import java.io.InputStream;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+\r
+import org.w3c.tools.resources.Attribute;\r
+import org.w3c.tools.resources.AttributeHolder;\r
+import org.w3c.tools.resources.AttributeRegistry;\r
+import org.w3c.tools.resources.BooleanAttribute;\r
+import org.w3c.tools.resources.LookupResult;\r
+import org.w3c.tools.resources.LookupState;\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.Resource;\r
+import org.w3c.tools.resources.ResourceException;\r
+import org.w3c.tools.resources.ResourceFrame;\r
+import org.w3c.tools.resources.ServerInterface;\r
+import org.w3c.tools.resources.StringArrayAttribute;\r
+import org.w3c.tools.resources.StringAttribute;\r
+\r
+import org.w3c.jigsaw.http.HTTPException;\r
+import org.w3c.jigsaw.http.Reply;\r
+import org.w3c.jigsaw.http.Request;\r
+import org.w3c.jigsaw.http.httpd;\r
+\r
+import org.w3c.jigsaw.html.HtmlGenerator;\r
+\r
+import org.w3c.www.http.HTTP;\r
+import org.w3c.www.http.HttpMessage;\r
+import org.w3c.www.http.HttpReplyMessage;\r
+import org.w3c.www.http.HttpRequestMessage;\r
+\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.ResourceException;\r
+\r
+/**\r
+ * Emit a HTTP redirect.\r
+ */\r
+public class RelocateFrame extends HTTPFrame {\r
+\r
+    /**\r
+     * Name of the state to hold the PATH_INFO in the request.\r
+     */\r
+    public final static \r
+       String PATH_INFO = \r
+       "org.w3c.jigsaw.resources.RelocateResource.PathInfo";\r
+\r
+    /**\r
+     * Attribute index - The relocation location.\r
+     */\r
+    protected static int ATTR_LOCATION = -1 ;\r
+    /**\r
+     * Attribute index - Should we also handle extra path infos ?\r
+     */\r
+    protected static int ATTR_HANDLE_PATHINFO = -1;\r
+    /**\r
+     * Attribute index - Is the relocation permanent?\r
+     */\r
+    protected static int ATTR_PERMANENT_REDIRECT = -1;\r
+    /**\r
+     * Attribute index - SHould we use the ambiguous 302?\r
+     */\r
+    protected static int ATTR_USE_302 = -1;\r
+    /**\r
+     * Attribute index - The methods affected by this frame\r
+     */\r
+    protected static int ATTR_METHODS = -1 ;\r
+\r
+    static {\r
+       Attribute a = null ;\r
+       Class     c = null ;\r
+\r
+       try {\r
+           c = Class.forName("org.w3c.jigsaw.frames.RelocateFrame");\r
+           //Added by Jeff Huang\r
+           //TODO: FIXIT\r
+       } catch (Exception ex) {\r
+           ex.printStackTrace() ;\r
+           System.exit(1) ;\r
+       }\r
+       // The location attribute\r
+       a = new StringAttribute("location"\r
+                               , null\r
+                               , Attribute.EDITABLE|Attribute.MANDATORY) ;\r
+       ATTR_LOCATION = AttributeRegistry.registerAttribute(c, a) ;\r
+       // The handle path info attribute\r
+       a = new BooleanAttribute("handle-pathinfo"\r
+                                , Boolean.TRUE\r
+                                , Attribute.EDITABLE);\r
+       ATTR_HANDLE_PATHINFO = AttributeRegistry.registerAttribute(c, a);\r
+       // the permanent redirection attribute\r
+       a = new BooleanAttribute("permanent-redirect"\r
+                                , Boolean.FALSE\r
+                                , Attribute.EDITABLE);\r
+       ATTR_PERMANENT_REDIRECT = AttributeRegistry.registerAttribute(c, a);\r
+       // should we use the ambiguous 302 response code?\r
+       a = new BooleanAttribute("use-usual-response"\r
+                                , Boolean.TRUE\r
+                                , Attribute.EDITABLE);\r
+       ATTR_USE_302 = AttributeRegistry.registerAttribute(c, a);\r
+       // The affected methods\r
+       a = new StringArrayAttribute("methods"\r
+                                    , null\r
+                                    , Attribute.EDITABLE) ;\r
+       ATTR_METHODS = AttributeRegistry.registerAttribute(c, a) ;\r
+    }\r
+\r
+    /**\r
+     * Get the location for the relocation\r
+     * @return a string, containing the relative path or absolute\r
+     */\r
+    public String getLocation() {\r
+       return (String) getValue(ATTR_LOCATION, null) ;\r
+    }\r
+\r
+    /**\r
+     * Get the list of methods affected by the redirect\r
+     * @return An array of String giving the name of the redirected methods,\r
+     *    or <strong>null</strong>, in wich case <em>all</em> methods are\r
+     *    to be redirected.\r
+     */\r
+    public String[] getMethods() {\r
+       return (String[]) getValue(ATTR_METHODS, null) ;\r
+    }\r
+\r
+    /**\r
+     * Get the path info value\r
+     * @return a boolean\r
+     */\r
+    public boolean checkHandlePathInfo() {\r
+       return getBoolean(ATTR_HANDLE_PATHINFO, true);\r
+    }\r
+\r
+    /**\r
+     * Get the permanent redirect flag\r
+     * @return a boolean\r
+     */\r
+    public boolean checkPermanentRedirect() {\r
+       return getBoolean(ATTR_PERMANENT_REDIRECT, false);\r
+    }\r
+\r
+     /**\r
+     * Get the "use ambigous 302 response code" flag\r
+     * @return a boolean\r
+     */\r
+    public boolean checkUse302() {\r
+       return getBoolean(ATTR_USE_302, true);\r
+    }   \r
+\r
+     /**\r
+     * Lookup the target resource (dispath to more specific lookup methods).\r
+     * @param ls The current lookup state\r
+     * @param lr The result\r
+     * @return true if lookup is done.\r
+     * @exception ProtocolException If an error relative to the protocol occurs\r
+     * @see #lookupDirectory\r
+     * @see #lookupFile\r
+     * @see #lookupOther\r
+     */\r
+    protected boolean lookupResource(LookupState ls, LookupResult lr) \r
+       throws ProtocolException\r
+    {\r
+       String methods[] = getMethods();\r
+       \r
+       if (ls.hasRequest() && (methods != null)) {\r
+           Request request = (Request) ls.getRequest();\r
+           String reqmeth = request.getMethod();\r
+           boolean affected = false;\r
+           for (int i=0; i< methods.length; i++) {\r
+               if (reqmeth.equals(methods[i])) {\r
+                   affected = true;\r
+                   break;\r
+               }\r
+           }\r
+           if (!affected) {\r
+               return super.lookupResource(ls, lr);\r
+           }\r
+       }\r
+       // Perform our super-class lookup strategy:\r
+       if ( super.lookupOther(ls, lr) ) {\r
+           return true;\r
+        } else if ( ! checkHandlePathInfo() ) {\r
+            return false;\r
+        }\r
+       // Compute PATH INFO, store it as a piece of state in\r
+       // the request:\r
+       StringBuffer pathinfo = new StringBuffer();\r
+       while ( ls.hasMoreComponents() ) {\r
+           pathinfo.append('/');\r
+           pathinfo.append(ls.getNextComponent());\r
+       }\r
+       if (ls.hasRequest() ) {\r
+           Request request = (Request) ls.getRequest();\r
+           String reqfile = request.getURL().getFile();\r
+           if (reqfile.endsWith("/")) {\r
+               pathinfo.append('/');\r
+           }\r
+           request.setState(PATH_INFO, pathinfo.toString());\r
+       }\r
+       lr.setTarget(resource.getResourceReference());\r
+       return true;\r
+    }\r
+\r
+    /**\r
+     * build the redirect reply based on the request and the current\r
+     * configuration\r
+     * @param request The request to handle.\r
+     * @exception ProtocolException If processsing the request failed.\r
+     * @return a Reply\r
+     */\r
+    private Reply getRedirectReply(Request request)\r
+       throws ProtocolException\r
+    {\r
+       String location = getLocation() ;\r
+       if ( location == null ) {\r
+           Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;\r
+           error.setContent("The target RelocateResource doesn't define the"\r
+                            + " relocation location. The server is "\r
+                            + " misconfigured.") ;\r
+           throw new HTTPException(error) ;\r
+       } else {\r
+           Reply  reply = null;\r
+           URL    loc      = null;\r
+           if (checkUse302()) {\r
+               reply = request.makeReply(HTTP.FOUND) ;\r
+           } else {\r
+               if (checkPermanentRedirect()) {\r
+                   reply = request.makeReply(HTTP.MOVED_PERMANENTLY) ;\r
+               } else {\r
+                   reply = request.makeReply(HTTP.TEMPORARY_REDIRECT) ;\r
+               }\r
+           }\r
+           try {\r
+               httpd  server = (httpd) getServer();\r
+               String   host = request.getHost(); \r
+               if (host == null)\r
+                   loc = new URL(server.getURL(), location);\r
+               else {\r
+                   int ic = host.indexOf(':');\r
+                   if (ic < 0 ) {\r
+                       loc = new URL(new URL(server.getURL().getProtocol(),\r
+                                             host,server.getURL().getFile()),\r
+                                     location);\r
+                   } else {\r
+                       loc = new URL(new URL(server.getURL().getProtocol(),\r
+                                             host.substring(0, ic),\r
+                                             Integer.parseInt(\r
+                                                 host.substring(ic+1))\r
+                                             ,server.getURL().getFile()),\r
+                                     location);\r
+                   }\r
+               }\r
+               if (checkHandlePathInfo()) {\r
+                   String pathinfo = (String) request.getState(PATH_INFO);\r
+                   // Given the way pathinfo is computed, it starts with a /\r
+                   try {\r
+                       if (pathinfo != null) {\r
+                           loc = new URL(loc.toExternalForm()+pathinfo);\r
+                       }\r
+                   } catch (MalformedURLException ex) {\r
+                       resource.getServer().errlog(resource, \r
+                                            "This resource handle Pathinfo "+\r
+                                            "but the request has an invalid "+\r
+                                            "PATH_INFO state.");\r
+                   }\r
+                   if (request.hasQueryString()) {\r
+                       try {\r
+                           loc = new URL(loc.toExternalForm() + "?" +\r
+                                         request.getQueryString());\r
+                       } catch (MalformedURLException ex) {\r
+                           resource.getServer().errlog(resource, \r
+                                                       "This resource handle "\r
+                                                       +"Pathinfo but the "\r
+                                                       +"request has an " \r
+                                                       +"invalid "+\r
+                                                       "PATH_INFO state.");\r
+                       }\r
+                   }\r
+               }\r
+           } catch (Exception ex) {\r
+               ex.printStackTrace();\r
+           }\r
+           reply.setLocation(loc);\r
+           HtmlGenerator g = new HtmlGenerator("Moved");\r
+           g.append("<P>This resources has moved, click on the link if your"\r
+                    + " browser doesn't support automatic redirection<BR>"+\r
+                    "<A HREF=\""+loc.toExternalForm()+"\">"+\r
+                    loc.toExternalForm()+"</A>");\r
+           reply.setStream(g);\r
+           return reply ;\r
+       }\r
+    }\r
+\r
+    /**\r
+     * The GET method, may emit a redirect \r
+     * @param request The request to handle.\r
+     * @exception ProtocolException If processsing the request failed.\r
+     * @exception ResourceException If the resource got a fatal error.\r
+     */\r
+    public Reply get(Request request)\r
+       throws ProtocolException, ResourceException\r
+    {\r
+       String methods[] = getMethods();\r
+       \r
+       if (methods != null) {\r
+           String reqmeth = request.getMethod();\r
+           boolean affected = false;\r
+           for (int i=0; i< methods.length; i++) {\r
+               if (reqmeth.equals(methods[i])) {\r
+                   affected = true;\r
+                   break;\r
+               }\r
+           }\r
+           if (!affected) {\r
+               return super.get(request);\r
+           }\r
+       }\r
+       // now we can modify it :)\r
+       return getRedirectReply(request);\r
+    }\r
+\r
+    /**\r
+     * The HEAD method, may emit a redirect \r
+     * @param request The request to handle.\r
+     * @exception ProtocolException If processsing the request failed.\r
+     * @exception ResourceException If the resource got a fatal error.\r
+     */\r
+    public Reply head(Request request)\r
+       throws ProtocolException, ResourceException\r
+    {\r
+       String methods[] = getMethods();\r
+       \r
+       if (methods != null) {\r
+           String reqmeth = request.getMethod();\r
+           boolean affected = false;\r
+           for (int i=0; i< methods.length; i++) {\r
+               if (reqmeth.equals(methods[i])) {\r
+                   affected = true;\r
+                   break;\r
+               }\r
+           }\r
+           if (!affected) {\r
+               return super.head(request);\r
+           }\r
+       }\r
+       // now we can modify it :)\r
+       Reply reply = getRedirectReply(request);\r
+       reply.setStream((InputStream) null);\r
+       return reply ;\r
+    }\r
+\r
+    /**\r
+     * The PUT method, may emit a redirect, otherwise uses its parent put\r
+     * @param request The request to handle.\r
+     * @exception ProtocolException If processsing the request failed.\r
+     * @exception ResourceException If the resource got a fatal error.\r
+     */\r
+    public Reply put(Request request)\r
+       throws ProtocolException, ResourceException\r
+    {\r
+       String methods[] = getMethods();\r
+       \r
+       if (methods != null) {\r
+           String reqmeth = request.getMethod();\r
+           boolean affected = false;\r
+           for (int i=0; i< methods.length; i++) {\r
+               if (reqmeth.equals(methods[i])) {\r
+                   affected = true;\r
+                   break;\r
+               }\r
+           }\r
+           if (!affected) {\r
+               return super.put(request);\r
+           }\r
+       }\r
+       // now we can modify it :)\r
+       return getRedirectReply(request);\r
+    }\r
+    /**\r
+     * The POST method, may emit a redirect, otherwise uses its parent put\r
+     * @param request The request to handle.\r
+     * @exception ProtocolException If processsing the request failed.\r
+     * @exception ResourceException If the resource got a fatal error.\r
+     */\r
+    public Reply post(Request request)\r
+       throws ProtocolException, ResourceException\r
+    {\r
+       String methods[] = getMethods();\r
+       \r
+       if (methods != null) {\r
+           String reqmeth = request.getMethod();\r
+           boolean affected = false;\r
+           for (int i=0; i< methods.length; i++) {\r
+               if (reqmeth.equals(methods[i])) {\r
+                   affected = true;\r
+                   break;\r
+               }\r
+           }\r
+           if (!affected) {\r
+               return super.post(request);\r
+           }\r
+       }\r
+       // now we can modify it :)\r
+       return getRedirectReply(request);\r
+    }\r
+}\r