--- /dev/null
+// JigsawRequestDispatcher.java\r
+// $Id: JigsawRequestDispatcher.java,v 1.1 2010/06/15 12:24:10 smhuang Exp $\r
+// (c) COPYRIGHT MIT, INRIA and Keio, 1999.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigsaw.servlet;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.Reader;\r
+import java.io.Writer;\r
+import java.io.InputStreamReader;\r
+\r
+import java.net.URL;\r
+import java.net.MalformedURLException;\r
+\r
+import javax.servlet.RequestDispatcher;\r
+import javax.servlet.ServletException;\r
+import javax.servlet.ServletRequest;\r
+import javax.servlet.ServletResponse;\r
+import javax.servlet.ServletOutputStream;\r
+\r
+import org.w3c.jigsaw.http.httpd;\r
+import org.w3c.jigsaw.http.Request;\r
+import org.w3c.jigsaw.http.Reply;\r
+\r
+import org.w3c.tools.resources.InvalidResourceException;\r
+import org.w3c.tools.resources.ResourceReference;\r
+import org.w3c.tools.resources.Resource;\r
+import org.w3c.tools.resources.LookupState;\r
+import org.w3c.tools.resources.LookupResult;\r
+import org.w3c.tools.resources.FramedResource;\r
+import org.w3c.tools.resources.ResourceException;\r
+import org.w3c.tools.resources.ProtocolException;\r
+\r
+import org.w3c.www.http.HTTP;\r
+\r
+/**\r
+ * @version $Revision: 1.1 $\r
+ * @author Benoît Mahé (bmahe@w3.org)\r
+ */\r
+public class JigsawRequestDispatcher implements RequestDispatcher {\r
+\r
+ public static final String REQUEST_URI_P = \r
+ "javax.servlet.include.request_uri";\r
+ public static final String CONTEXT_PATH_P = \r
+ "javax.servlet.include.context_path";\r
+ public static final String SERVLET_PATH_P = \r
+ "javax.servlet.include.servlet_path";\r
+ public static final String PATH_INFO_P = \r
+ "javax.servlet.include.path_info";\r
+ public static final String QUERY_STRING_P = \r
+ "javax.servlet.include.query_string";\r
+\r
+ private httpd server = null;\r
+ private String urlpath = null;\r
+\r
+ public void forward(ServletRequest request, ServletResponse response)\r
+ throws ServletException, IOException\r
+ {\r
+ JigsawHttpServletResponse jres = (JigsawHttpServletResponse) response;\r
+ JigsawHttpServletRequest jreq = (JigsawHttpServletRequest) request;\r
+ if (jres.isStreamObtained())\r
+ throw new IllegalStateException("Can't Forward! OutputStream or "+\r
+ "Writer has allready been obtained.");\r
+ Request req = (Request)jreq.getRequest().getClone();\r
+ String host = req.getHost(); \r
+ try {\r
+ //update URL...\r
+ if (host == null) {\r
+ req.setURL(new URL(server.getURL(), urlpath));\r
+ } else {\r
+ req.setURL(new URL(server.getURL().getProtocol(), host, \r
+ urlpath));\r
+ }\r
+ } catch (MalformedURLException ex) {\r
+ //should not occurs\r
+ }\r
+ \r
+ //do nothing more with this reply\r
+ jres.getReply().setStatus(HTTP.DONE);\r
+\r
+ Reply reply = null;\r
+ try {\r
+ reply = (Reply) server.perform(req);\r
+ } catch (ResourceException ex) {\r
+ reply = req.makeReply(HTTP.INTERNAL_SERVER_ERROR);\r
+ reply.setContent(ex.getMessage());\r
+ } catch (ProtocolException pex) {\r
+ if (pex.hasReply())\r
+ reply = (Reply) pex.getReply();\r
+ else {\r
+ reply = req.makeReply(HTTP.INTERNAL_SERVER_ERROR);\r
+ reply.setContent(pex.getMessage());\r
+ }\r
+ }\r
+ //copy reply into response...\r
+ if (reply.hasStream()) {\r
+ jres.getReply().setStatus(reply.getStatus());\r
+ InputStream is = reply.openStream();\r
+ try {\r
+ ServletOutputStream out = jres.getOutputStream();\r
+ byte buffer[] = new byte[512];\r
+ int len = -1;\r
+ while((len = is.read(buffer, 0, 512)) != -1)\r
+ out.write(buffer, 0, len);\r
+ } catch (IllegalStateException ex) {\r
+ Writer writer = jres.getWriter();\r
+ Reader reader = new InputStreamReader(is);\r
+ char buffer[] = new char[512];\r
+ int len = -1;\r
+ while((len = reader.read(buffer, 0, 512)) != -1)\r
+ writer.write(buffer, 0, len);\r
+ }\r
+ }\r
+ }\r
+\r
+ public void include(ServletRequest request, ServletResponse response)\r
+ throws ServletException, IOException\r
+ {\r
+ JigsawHttpServletResponse jres = (JigsawHttpServletResponse) response;\r
+ JigsawHttpServletRequest jreq = (JigsawHttpServletRequest) request;\r
+\r
+ Request req = (Request)jreq.getRequest().getClone();\r
+ String host = req.getHost(); \r
+\r
+ try {\r
+ //update URL...\r
+ if (host == null)\r
+ req.setURL(new URL(server.getURL(), urlpath));\r
+ else\r
+ req.setURL(new URL(server.getURL().getProtocol(), host, \r
+ urlpath));\r
+ } catch (MalformedURLException ex) {\r
+ //should not occurs\r
+ }\r
+\r
+ jres.flushStream(false);\r
+\r
+ Reply reply = null;\r
+ try {\r
+ //req.setState(CONTEXT_PATH_P, jreq.getContextPath());\r
+ req.setState(REQUEST_URI_P, jreq.getRequestURI());\r
+ req.setState(SERVLET_PATH_P, jreq.getServletPath());\r
+ req.setState(PATH_INFO_P, jreq.getPathInfo());\r
+ req.setState(QUERY_STRING_P, jreq.getQueryString());\r
+ req.setState(JigsawHttpServletResponse.INCLUDED, Boolean.TRUE);\r
+ reply = (Reply) server.perform(req);\r
+ } catch (ResourceException ex) {\r
+ reply = req.makeReply(HTTP.INTERNAL_SERVER_ERROR);\r
+ reply.setContent(ex.getMessage());\r
+ } catch (ProtocolException pex) {\r
+ if (pex.hasReply())\r
+ reply = (Reply) pex.getReply();\r
+ else {\r
+ reply = req.makeReply(HTTP.INTERNAL_SERVER_ERROR);\r
+ reply.setContent(pex.getMessage());\r
+ }\r
+ }\r
+\r
+ if (reply.hasStream()) {\r
+ InputStream is = reply.openStream();\r
+ try {\r
+ ServletOutputStream out = jres.getOutputStream();\r
+ byte buffer[] = new byte[512];\r
+ int len = -1;\r
+ while((len = is.read(buffer, 0, 512)) != -1)\r
+ out.write(buffer, 0, len);\r
+ } catch (IllegalStateException ex) {\r
+ Writer writer = jres.getWriter();\r
+ Reader reader = new InputStreamReader(is);\r
+ char buffer[] = new char[512];\r
+ int len = -1;\r
+ while((len = reader.read(buffer, 0, 512)) != -1)\r
+ writer.write(buffer, 0, len);\r
+ }\r
+ }\r
+ }\r
+\r
+ protected JigsawRequestDispatcher(String urlpath, httpd server) {\r
+ this.server = server;\r
+ this.urlpath = urlpath;\r
+ }\r
+\r
+ /**\r
+ * Get the appropriate dispatcher\r
+ * @param name The servlet name\r
+ * @param rr the ServletContainer (ServletDirectoryFrame) reference\r
+ * @param server the HTTP server\r
+ * @return the RequestDispatcher\r
+ */\r
+ public static RequestDispatcher getRequestDispatcher(String name,\r
+ ResourceReference rr,\r
+ httpd server)\r
+ {\r
+ try {\r
+ Resource res = rr.lock();\r
+ if (! (res instanceof ServletDirectoryFrame)) {\r
+ throw new IllegalArgumentException("Not a servlet container!");\r
+ }\r
+ ServletDirectoryFrame sdf = (ServletDirectoryFrame) res;\r
+ // if (sdf.getServlet(name) != null) {\r
+ if (sdf.isServletLoaded(name)) {\r
+ // servlet exists, so return the dispatcher\r
+ String urlpath = sdf.getResource().getURLPath();\r
+ urlpath = \r
+ urlpath.endsWith("/") ? urlpath+name : urlpath+"/"+name;\r
+ return new JigsawRequestDispatcher(urlpath, server);\r
+ }\r
+ } catch(InvalidResourceException ex) {\r
+ return null;\r
+ } finally {\r
+ rr.unlock();\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Get the appropriate dispatcher\r
+ * @param urlpath the servlet URI\r
+ * @param server the HTTP server\r
+ * @param rr the ServletContainer reference or a servlet reference \r
+ * (Just used for Virtual Host)\r
+ * @return the RequestDispatcher\r
+ */\r
+ public static RequestDispatcher getRequestDispatcher(String urlpath,\r
+ httpd server,\r
+ ResourceReference rr) \r
+ {\r
+ ResourceReference rr_root = null;\r
+ FramedResource root = null;\r
+ rr_root = JigsawServletContext.getLocalRoot(server.getRootReference(),\r
+ rr);\r
+ try {\r
+ root = (FramedResource) rr_root.lock();\r
+ // Do the lookup:\r
+ ResourceReference r_target = null;\r
+ try {\r
+ LookupState ls = new LookupState(urlpath);\r
+ LookupResult lr = new LookupResult(rr_root);\r
+ root.lookup(ls, lr);\r
+ r_target = lr.getTarget();\r
+ } catch (Exception ex) {\r
+ r_target = null;\r
+ }\r
+ if (r_target == null)\r
+ return null;\r
+ //there is a resource, return the dispatcher...\r
+ return new JigsawRequestDispatcher(urlpath, server);\r
+ } catch (InvalidResourceException ex) {\r
+ return null;\r
+ } finally {\r
+ rr_root.unlock(); \r
+ }\r
+ }\r
+\r
+}\r