001: // EchoCommand.java
002: // $Id: EchoCommand.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.Date;
009: import java.util.Dictionary;
010:
011: import java.net.URL;
012:
013: import org.w3c.www.http.HTTP;
014: import org.w3c.www.http.HeaderValue;
015: import org.w3c.www.http.HttpEntityMessage;
016: import org.w3c.www.http.HttpMessage;
017: import org.w3c.www.http.HttpReplyMessage;
018: import org.w3c.www.http.HttpRequestMessage;
019:
020: import org.w3c.util.ArrayDictionary;
021: import org.w3c.util.TimeFormatter;
022:
023: import org.w3c.jigsaw.http.Reply;
024: import org.w3c.jigsaw.http.Request;
025:
026: import org.w3c.jigsaw.ssi.SSIFrame;
027:
028: /**
029: * Implementation of the <code>echo</code> SSI command.
030: * As extensions, it has the parameters "reqstate" (for echoing
031: * Jigsaw request states) and "reqheader" (for echoing request
032: * header).
033: * <p>Also, it can take the flag "here", whose presence means that the
034: * variable is to be interpreted at the deepest request level (in the
035: * case of chained internal requests), instead of doing so at the top
036: * (external request) level. It inserts the value of a variable in
037: * the document.
038: * @author Antonio Ramirez <anto@mit.edu>
039: */
040:
041: public class EchoCommand implements Command {
042: private final static String NAME = "echo";
043:
044: private static Dictionary modFlags = null;
045:
046: private static final String[] keys = { "var", "reqstate",
047: "reqheader", "here" };
048:
049: static {
050: String[] names = { "DOCUMENT_NAME", "DOCUMENT_URI",
051: "QUERY_STRING_UNESCAPED", "SERVER_SOFTWARE",
052: "SERVER_NAME", "GATEWAY_INTERFACE", "SERVER_PROTOCOL",
053: "SERVER_PORT", "REQUEST_METHOD", "PATH_INFO",
054: "PATH_TRANSLATED", "SCRIPT_NAME", "QUERY_STRING",
055: "REMOTE_HOST", "REMOTE_ADDR", "REMOTE_USER",
056: "AUTH_TYPE", "REMOTE_IDENT", "CONTENT_TYPE",
057: "CONTENT_LENGTH", "HTTP_ACCEPT", "HTTP_USER_AGENT",
058: "DATE_LOCAL", "DATE_GMT", "LAST_MODIFIED" };
059:
060: Boolean[] values = { Boolean.FALSE, // DOCUMENT_NAME
061: Boolean.FALSE, // DOCUMENT_URI
062: Boolean.TRUE, // QUERY_STRING_UNESCAPED
063: Boolean.FALSE, // SERVER_SOFTWARE
064: Boolean.FALSE, // SERVER_NAME
065: Boolean.FALSE, // GATEWAY_INTERFACE
066: Boolean.FALSE, // SERVER_PROTOCOL
067: Boolean.FALSE, // SERVER_PORT
068: Boolean.FALSE, // REQUEST_METHOD
069: Boolean.FALSE, // PATH_INFO
070: Boolean.FALSE, // PATH_TRANSLATED
071: Boolean.FALSE, // SCRIPT_NAME"
072: Boolean.TRUE, // QUERY_STRING
073: Boolean.FALSE, // REMOTE_HOST
074: Boolean.FALSE, // REMOTE_ADDR
075: Boolean.FALSE, // REMOTE_USER
076: Boolean.FALSE, // AUTH_TYPE
077: Boolean.FALSE, // REMOTE_IDENT
078: Boolean.FALSE, // CONTENT_TYPE
079: Boolean.FALSE, // CONTENT_LENGTH
080: Boolean.FALSE, // HTTP_ACCEPT
081: Boolean.FALSE, // HTTP_USER_AGENT
082: Boolean.TRUE, // DATE_LOCAL
083: Boolean.TRUE, // DATE_GMT
084: Boolean.FALSE // LAST_MODIFIED
085: };
086:
087: modFlags = new ArrayDictionary(names, values);
088: }
089:
090: /**
091: * return true if reply can be cached.
092: * @return a boolean.
093: */
094: public boolean acceptCaching() {
095: return true;
096: }
097:
098: public Reply execute(SSIFrame ssiframe, Request request,
099: ArrayDictionary parameters, Dictionary variables) {
100: // Get the relevant parameters
101: Object[] values = parameters.getMany(keys);
102: String var = (String) values[0];
103: String reqstate = (String) values[1];
104: String reqheader = (String) values[2];
105: boolean here = values[3] != null;
106:
107: boolean notMod = false;
108:
109: Reply reply = ssiframe.createCommandReply(request, HTTP.OK);
110: String content = null;
111:
112: if (var != null) {
113: if (var.equals("DOCUMENT_URI")) {
114: URL theUrl = here ? request.getURL() : request
115: .getOriginal().getURL();
116: if (theUrl != null)
117: content = theUrl.toString();
118: } else {
119: Dictionary ssiVars = (Dictionary) variables
120: .get(here ? "ssiVars" : "topSsiVars");
121:
122: if (ssiVars == null)
123: return null;
124:
125: if (var.equals("DATE_LOCAL")) {
126: content = TimeFormatter.format(new Date(),
127: (String) variables.get("datefmt"));
128: } else if (var.equals("DATE_GMT")) {
129:
130: // FIXME: won't do formatting
131: content = new Date().toGMTString();
132:
133: } else if (var.equals("LAST_MODIFIED")) {
134:
135: content = TimeFormatter.format((Date) ssiVars
136: .get("X_LAST_MODIFIED"), (String) variables
137: .get("datefmt"));
138:
139: } else {
140:
141: content = (String) ssiVars.get(var);
142: if (content == null)
143: content = "";
144: }
145: }
146: long ims = request.getIfModifiedSince();
147: if (ims != -1) {
148: if (var == null)
149: notMod = true;
150: else {
151: Boolean result = (Boolean) modFlags.get(var);
152: notMod = (result == null) ? true : !result
153: .booleanValue();
154: }
155: }
156: } else if (reqstate != null) {
157: Object state = here ? request.getState(reqstate) : request
158: .getOriginal().getState(reqstate);
159:
160: if (state != null)
161: content = state.toString();
162: } else if (reqheader != null) {
163: reqheader = reqheader.toLowerCase();
164: HeaderValue hvalue = here ? request
165: .getHeaderValue(reqheader) : request.getOriginal()
166: .getHeaderValue(reqheader);
167:
168: if (hvalue != null)
169: content = hvalue.toExternalForm();
170: } else
171: return null;
172:
173: if (content != null) {
174: reply.setContent(content);
175: } else
176: return null;
177:
178: if (notMod) {
179: reply.setStatus(HTTP.NOT_MODIFIED);
180: reply.setLastModified(request.getIfModifiedSince());
181: }
182:
183: return reply;
184: }
185:
186: public String getName() {
187: return NAME;
188: }
189:
190: public String getValue(Dictionary variables, String variable,
191: Request request) {
192: return "null";
193: }
194:
195: }
|