001: // IncludeCommand.java
002: // $Id: IncludeCommand.java,v 1.4 2000/08/16 21:37:47 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigsaw.ssi.commands;
007:
008: import java.util.Dictionary;
009:
010: import java.net.MalformedURLException;
011: import java.net.URL;
012:
013: import org.w3c.www.http.HTTP;
014: import org.w3c.www.http.HttpEntityMessage;
015: import org.w3c.www.http.HttpMessage;
016: import org.w3c.www.http.HttpReplyMessage;
017: import org.w3c.www.http.HttpRequestMessage;
018:
019: import org.w3c.util.ArrayDictionary;
020:
021: import org.w3c.jigsaw.http.Reply;
022: import org.w3c.jigsaw.http.Request;
023:
024: import org.w3c.tools.resources.Resource;
025: import org.w3c.tools.resources.ServerInterface;
026:
027: import org.w3c.jigsaw.ssi.SSIFrame;
028:
029: /**
030: * Implementation of the SSI <code>include</code> command. (CGI
031: * scripts <em>can</em> be included, simply by providing a so-called
032: * virtual path to a CgiResource).
033: * @author Antonio Ramirez <anto@mit.edu>
034: */
035: public class IncludeCommand extends BasicCommand {
036: private final static String NAME = "include";
037:
038: public String getName() {
039: return NAME;
040: }
041:
042: private static final String[] keys = { "virtual", "file",
043: "ifheader", "else" };
044:
045: public Reply execute(SSIFrame ssiframe, Request request,
046: ArrayDictionary parameters, Dictionary variables) {
047: // Get the relevant parameters
048: Object[] values = parameters.getMany(keys);
049: String targetName = (String) values[0];
050: if (targetName == null)
051: targetName = (String) values[1];
052: String ifheader = (String) values[2];
053: String alt = (String) values[3];
054:
055: if (targetName == null)
056: return null; // Nothing to include
057:
058: if (ifheader != null
059: && !request.getOriginal().hasHeader(ifheader)) {
060: if (alt == null)
061: return null;
062: else
063: targetName = alt;
064: }
065:
066: // If we are at an illegal depth, don't include.
067: Integer depth = (Integer) variables.get("depth");
068: int maxDepth = ((Integer) variables.get("maxDepth")).intValue();
069:
070: if (maxDepth != 0 && depth.intValue() > maxDepth) {
071: Reply reply = ssiframe.createCommandReply(request, HTTP.OK);
072: reply.setContent("[recursion depth limit exceeded]");
073:
074: handleSimpleIMS(request, reply);
075: return reply;
076: }
077:
078: Request subReq = null;
079: Reply subRep = null;
080:
081: try {
082: // Prepare an internal request
083: subReq = prepareRequest(request, new URL(ssiframe
084: .getURL(request), targetName).toString(),
085: variables, depth);
086:
087: // Obtain a reply for it
088: subRep = (Reply) ssiframe.getFileResource().getServer()
089: .perform(subReq);
090:
091: // If it has status NOT_MODIFIED, it means the included
092: // ssiframe was also SSI, and we don't calculate anything
093: // here.
094: // Otherwise, see if we can reply NOT_MODIFIED.
095: if (subRep.getStatus() != HTTP.NOT_MODIFIED) {
096: long ims = request.getIfModifiedSince();
097:
098: if (ims == -1) {
099: Long IMS = (Long) request
100: .getState(STATE_IF_MODIFIED_SINCE);
101: if (IMS != null)
102: ims = IMS.longValue();
103: }
104:
105: long lmd = subRep.getLastModified();
106: lmd -= lmd % 1000; // this is annoying
107:
108: if (ims != -1 && lmd != -1 && ims >= lmd) {
109: subRep.setStatus(HTTP.NOT_MODIFIED);
110: //close the stream
111: subRep.openStream().close();
112: }
113: }
114:
115: return subRep;
116:
117: } catch (MalformedURLException ex) {
118: Reply reply = ssiframe.createCommandReply(request, HTTP.OK);
119: reply.setContent("[malformed URL]");
120: handleSimpleIMS(request, reply);
121: return reply;
122: } catch (Exception ex) {
123: Reply reply = ssiframe.createCommandReply(request, HTTP.OK);
124: reply.setContent("[error including: " + targetName + "]");
125: handleSimpleIMS(request, reply);
126: return reply;
127: }
128: }
129:
130: private Request prepareRequest(Request request, String url,
131: Dictionary variables, Integer depth) {
132: Request subReq = (Request) request.getClone();
133:
134: subReq.setURLPath(url);
135: long ims = request.getIfModifiedSince();
136: if (ims != -1) {
137: subReq.setHeaderValue(Request.H_IF_MODIFIED_SINCE, null);
138: subReq.setState(STATE_IF_MODIFIED_SINCE, new Long(ims));
139: }
140:
141: subReq.setState(SSIFrame.STATE_VARIABLES, variables);
142:
143: subReq.setState(SSIFrame.STATE_DEPTH, new Integer(depth
144: .intValue() + 1));
145:
146: return subReq;
147: }
148:
149: public String getValue(Dictionary variables, String variable,
150: Request request) {
151: return "null";
152: }
153:
154: }
|