001: // JigsawRequestDispatcher.java
002: // $Id: JigsawRequestDispatcher.java,v 1.9 2002/07/10 18:52:31 ylafon Exp $
003: // (c) COPYRIGHT MIT, INRIA and Keio, 1999.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigsaw.servlet;
007:
008: import java.io.IOException;
009: import java.io.InputStream;
010: import java.io.Reader;
011: import java.io.Writer;
012: import java.io.InputStreamReader;
013:
014: import java.net.URL;
015: import java.net.MalformedURLException;
016:
017: import javax.servlet.RequestDispatcher;
018: import javax.servlet.ServletException;
019: import javax.servlet.ServletRequest;
020: import javax.servlet.ServletResponse;
021: import javax.servlet.ServletOutputStream;
022:
023: import org.w3c.jigsaw.http.httpd;
024: import org.w3c.jigsaw.http.Request;
025: import org.w3c.jigsaw.http.Reply;
026:
027: import org.w3c.tools.resources.InvalidResourceException;
028: import org.w3c.tools.resources.ResourceReference;
029: import org.w3c.tools.resources.Resource;
030: import org.w3c.tools.resources.LookupState;
031: import org.w3c.tools.resources.LookupResult;
032: import org.w3c.tools.resources.FramedResource;
033: import org.w3c.tools.resources.ResourceException;
034: import org.w3c.tools.resources.ProtocolException;
035:
036: import org.w3c.www.http.HTTP;
037:
038: /**
039: * @version $Revision: 1.9 $
040: * @author Benoît Mahé (bmahe@w3.org)
041: */
042: public class JigsawRequestDispatcher implements RequestDispatcher {
043:
044: public static final String REQUEST_URI_P = "javax.servlet.include.request_uri";
045: public static final String CONTEXT_PATH_P = "javax.servlet.include.context_path";
046: public static final String SERVLET_PATH_P = "javax.servlet.include.servlet_path";
047: public static final String PATH_INFO_P = "javax.servlet.include.path_info";
048: public static final String QUERY_STRING_P = "javax.servlet.include.query_string";
049:
050: private httpd server = null;
051: private String urlpath = null;
052:
053: public void forward(ServletRequest request, ServletResponse response)
054: throws ServletException, IOException {
055: JigsawHttpServletResponse jres = (JigsawHttpServletResponse) response;
056: JigsawHttpServletRequest jreq = (JigsawHttpServletRequest) request;
057: if (jres.isStreamObtained())
058: throw new IllegalStateException(
059: "Can't Forward! OutputStream or "
060: + "Writer has allready been obtained.");
061: Request req = (Request) jreq.getRequest().getClone();
062: String host = req.getHost();
063: try {
064: //update URL...
065: if (host == null) {
066: req.setURL(new URL(server.getURL(), urlpath));
067: } else {
068: req.setURL(new URL(server.getURL().getProtocol(), host,
069: urlpath));
070: }
071: } catch (MalformedURLException ex) {
072: //should not occurs
073: }
074:
075: //do nothing more with this reply
076: jres.getReply().setStatus(HTTP.DONE);
077:
078: Reply reply = null;
079: try {
080: reply = (Reply) server.perform(req);
081: } catch (ResourceException ex) {
082: reply = req.makeReply(HTTP.INTERNAL_SERVER_ERROR);
083: reply.setContent(ex.getMessage());
084: } catch (ProtocolException pex) {
085: if (pex.hasReply())
086: reply = (Reply) pex.getReply();
087: else {
088: reply = req.makeReply(HTTP.INTERNAL_SERVER_ERROR);
089: reply.setContent(pex.getMessage());
090: }
091: }
092: //copy reply into response...
093: if (reply.hasStream()) {
094: jres.getReply().setStatus(reply.getStatus());
095: InputStream is = reply.openStream();
096: try {
097: ServletOutputStream out = jres.getOutputStream();
098: byte buffer[] = new byte[512];
099: int len = -1;
100: while ((len = is.read(buffer, 0, 512)) != -1)
101: out.write(buffer, 0, len);
102: } catch (IllegalStateException ex) {
103: Writer writer = jres.getWriter();
104: Reader reader = new InputStreamReader(is);
105: char buffer[] = new char[512];
106: int len = -1;
107: while ((len = reader.read(buffer, 0, 512)) != -1)
108: writer.write(buffer, 0, len);
109: }
110: }
111: }
112:
113: public void include(ServletRequest request, ServletResponse response)
114: throws ServletException, IOException {
115: JigsawHttpServletResponse jres = (JigsawHttpServletResponse) response;
116: JigsawHttpServletRequest jreq = (JigsawHttpServletRequest) request;
117:
118: Request req = (Request) jreq.getRequest().getClone();
119: String host = req.getHost();
120:
121: try {
122: //update URL...
123: if (host == null)
124: req.setURL(new URL(server.getURL(), urlpath));
125: else
126: req.setURL(new URL(server.getURL().getProtocol(), host,
127: urlpath));
128: } catch (MalformedURLException ex) {
129: //should not occurs
130: }
131:
132: jres.flushStream(false);
133:
134: Reply reply = null;
135: try {
136: //req.setState(CONTEXT_PATH_P, jreq.getContextPath());
137: req.setState(REQUEST_URI_P, jreq.getRequestURI());
138: req.setState(SERVLET_PATH_P, jreq.getServletPath());
139: req.setState(PATH_INFO_P, jreq.getPathInfo());
140: req.setState(QUERY_STRING_P, jreq.getQueryString());
141: req.setState(JigsawHttpServletResponse.INCLUDED,
142: Boolean.TRUE);
143: reply = (Reply) server.perform(req);
144: } catch (ResourceException ex) {
145: reply = req.makeReply(HTTP.INTERNAL_SERVER_ERROR);
146: reply.setContent(ex.getMessage());
147: } catch (ProtocolException pex) {
148: if (pex.hasReply())
149: reply = (Reply) pex.getReply();
150: else {
151: reply = req.makeReply(HTTP.INTERNAL_SERVER_ERROR);
152: reply.setContent(pex.getMessage());
153: }
154: }
155:
156: if (reply.hasStream()) {
157: InputStream is = reply.openStream();
158: try {
159: ServletOutputStream out = jres.getOutputStream();
160: byte buffer[] = new byte[512];
161: int len = -1;
162: while ((len = is.read(buffer, 0, 512)) != -1)
163: out.write(buffer, 0, len);
164: } catch (IllegalStateException ex) {
165: Writer writer = jres.getWriter();
166: Reader reader = new InputStreamReader(is);
167: char buffer[] = new char[512];
168: int len = -1;
169: while ((len = reader.read(buffer, 0, 512)) != -1)
170: writer.write(buffer, 0, len);
171: }
172: }
173: }
174:
175: protected JigsawRequestDispatcher(String urlpath, httpd server) {
176: this .server = server;
177: this .urlpath = urlpath;
178: }
179:
180: /**
181: * Get the appropriate dispatcher
182: * @param name The servlet name
183: * @param rr the ServletContainer (ServletDirectoryFrame) reference
184: * @param server the HTTP server
185: * @return the RequestDispatcher
186: */
187: public static RequestDispatcher getRequestDispatcher(String name,
188: ResourceReference rr, httpd server) {
189: try {
190: Resource res = rr.lock();
191: if (!(res instanceof ServletDirectoryFrame)) {
192: throw new IllegalArgumentException(
193: "Not a servlet container!");
194: }
195: ServletDirectoryFrame sdf = (ServletDirectoryFrame) res;
196: // if (sdf.getServlet(name) != null) {
197: if (sdf.isServletLoaded(name)) {
198: // servlet exists, so return the dispatcher
199: String urlpath = sdf.getResource().getURLPath();
200: urlpath = urlpath.endsWith("/") ? urlpath + name
201: : urlpath + "/" + name;
202: return new JigsawRequestDispatcher(urlpath, server);
203: }
204: } catch (InvalidResourceException ex) {
205: return null;
206: } finally {
207: rr.unlock();
208: }
209: return null;
210: }
211:
212: /**
213: * Get the appropriate dispatcher
214: * @param urlpath the servlet URI
215: * @param server the HTTP server
216: * @param rr the ServletContainer reference or a servlet reference
217: * (Just used for Virtual Host)
218: * @return the RequestDispatcher
219: */
220: public static RequestDispatcher getRequestDispatcher(
221: String urlpath, httpd server, ResourceReference rr) {
222: ResourceReference rr_root = null;
223: FramedResource root = null;
224: rr_root = JigsawServletContext.getLocalRoot(server
225: .getRootReference(), rr);
226: try {
227: root = (FramedResource) rr_root.lock();
228: // Do the lookup:
229: ResourceReference r_target = null;
230: try {
231: LookupState ls = new LookupState(urlpath);
232: LookupResult lr = new LookupResult(rr_root);
233: root.lookup(ls, lr);
234: r_target = lr.getTarget();
235: } catch (Exception ex) {
236: r_target = null;
237: }
238: if (r_target == null)
239: return null;
240: //there is a resource, return the dispatcher...
241: return new JigsawRequestDispatcher(urlpath, server);
242: } catch (InvalidResourceException ex) {
243: return null;
244: } finally {
245: rr_root.unlock();
246: }
247: }
248:
249: }
|