001: // Segment.java
002: // $Id: Segment.java,v 1.21 2004/03/25 10:49:24 ylafon Exp $
003: // (c) COPYRIGHT MIT, ERCIM and Keio, 2004.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigsaw.ssi;
007:
008: import java.util.Dictionary;
009: import java.util.NoSuchElementException;
010: import java.util.StringTokenizer;
011:
012: import java.io.DataInputStream;
013: import java.io.DataOutputStream;
014: import java.io.IOException;
015:
016: import org.w3c.util.ArrayDictionary;
017:
018: import org.w3c.tools.resources.FileResource;
019:
020: import org.w3c.jigsaw.http.Reply;
021: import org.w3c.jigsaw.http.Request;
022:
023: import org.w3c.jigsaw.ssi.commands.Command;
024: import org.w3c.jigsaw.ssi.commands.CommandRegistry;
025: import org.w3c.jigsaw.ssi.commands.ControlCommand;
026: import org.w3c.jigsaw.ssi.commands.ControlCommandException;
027:
028: /**
029: * Represents a segment within the parsed content
030: * @author Antonio Ramirez <anto@mit.edu>
031: * @author Benoit Mahe <bmahe@sophia.inria.fr>
032: * @author Yves Lafon <ylafon@w3.org>
033: */
034:
035: // FIXME: it's getting complex enough to need encapsulation.
036: public class Segment {
037: // Unpickling/pickling constants
038: protected static final int UNPARSED = 0;
039: protected static final int COMMAND = 1;
040:
041: protected static final String SEPARATOR = "|";
042:
043: protected boolean control = false;
044:
045: protected SSIFrame ssiframe = null;
046:
047: protected Request request = null;
048:
049: public boolean isControl() {
050: return control;
051: }
052:
053: /**
054: * Where this segment starts in the input file (inclusive)
055: */
056: int start = 0;
057:
058: /**
059: * Where it ends (exclusive)
060: */
061: int end = 0;
062:
063: /** The name of the command that this segment runs, if any */
064: String commandName = null;
065:
066: /** The command that it's linked to, if any. */
067: private Command command = null;
068:
069: /** The last registry that this command was executed from, if any */
070: private CommandRegistry registry = null;
071:
072: /** Its list of parameters */
073: ArrayDictionary parameters = null;
074:
075: public Segment(int start, int end) {
076: this .start = start;
077: this .end = end;
078: }
079:
080: public Segment(SSIFrame ssiframe, String commandName,
081: ArrayDictionary parameters, int start, int end) {
082: this .ssiframe = ssiframe;
083: this .commandName = commandName;
084: this .parameters = parameters;
085: this .start = start;
086: this .end = end;
087:
088: }
089:
090: protected Segment() {
091: start = end = -1;
092: }
093:
094: public String pickle() {
095: StringBuffer buffer = new StringBuffer(128);
096: if (commandName != null) {
097: buffer.append(COMMAND);
098: buffer.append(SEPARATOR);
099: buffer.append(start);
100: buffer.append(SEPARATOR);
101: buffer.append(end);
102: buffer.append(SEPARATOR);
103: buffer.append(parameters.size());
104: for (int i = 0; i < parameters.capacity()
105: && parameters.keyAt(i) != null; i++) {
106: buffer.append(SEPARATOR);
107: buffer.append((String) parameters.keyAt(i));
108: buffer.append(SEPARATOR);
109: buffer.append((String) parameters.elementAt(i));
110: }
111: } else {
112: buffer.append(UNPARSED);
113: buffer.append(SEPARATOR);
114: buffer.append(start);
115: buffer.append(SEPARATOR);
116: buffer.append(end);
117: }
118: return buffer.toString();
119: }
120:
121: public static Segment unpickle(String value) {
122: Segment seg = new Segment();
123: StringTokenizer st = new StringTokenizer(value, SEPARATOR);
124: try {
125: int type = Integer.parseInt(st.nextToken());
126: seg.start = Integer.parseInt(st.nextToken());
127: seg.end = Integer.parseInt(st.nextToken());
128: if (type == COMMAND) {
129: int n = Integer.parseInt(st.nextToken());
130: String parNames[] = new String[n];
131: String parValues[] = new String[n];
132: for (int i = 0; i < n; i++) {
133: parNames[i] = st.nextToken();
134: parValues[i] = st.nextToken();
135: }
136: seg.parameters = new ArrayDictionary(parNames,
137: parValues);
138: } else {
139: seg.commandName = null;
140: seg.parameters = null;
141: }
142: } catch (NoSuchElementException ex) {
143: ex.printStackTrace();
144: }
145: return seg;
146: }
147:
148: public void pickle(DataOutputStream out) throws IOException {
149: if (commandName != null) {
150: out.writeInt(COMMAND);
151: out.writeInt(start);
152: out.writeInt(end);
153: out.writeUTF(commandName);
154: out.writeInt(parameters.size());
155: for (int i = 0; i < parameters.capacity()
156: && parameters.keyAt(i) != null; i++) {
157: out.writeUTF((String) parameters.keyAt(i));
158: out.writeUTF((String) parameters.elementAt(i));
159: }
160: } else {
161: out.writeInt(UNPARSED);
162: out.writeInt(start);
163: out.writeInt(end);
164: }
165: }
166:
167: public static Segment unpickle(DataInputStream in)
168: throws IOException {
169: Segment seg = new Segment();
170:
171: int type = in.readInt();
172: seg.start = in.readInt();
173: seg.end = in.readInt();
174: if (type == COMMAND) {
175: seg.commandName = in.readUTF();
176: int n = in.readInt();
177: String parNames[] = new String[n];
178: String parValues[] = new String[n];
179: for (int i = 0; i < n; i++) {
180: parNames[i] = in.readUTF();
181: parValues[i] = in.readUTF();
182: }
183: seg.parameters = new ArrayDictionary(parNames, parValues);
184: } else {
185: seg.commandName = null;
186: seg.parameters = null;
187: }
188: return seg;
189: }
190:
191: public final boolean isUnparsed() {
192: return commandName == null;
193: }
194:
195: public final String toString() {
196: return commandName != null ? "<" + start + ',' + end + ": "
197: + commandName + " " + parameters + '>' : "<" + start
198: + ',' + end + '>';
199: }
200:
201: public int jumpTo() throws ControlCommandException {
202: if ((!control) || (command == null))
203: throw new ControlCommandException("SEGMENT",
204: "Internal Error");
205: ControlCommand cc = (ControlCommand) command;
206: int jump = 0;
207: jump = cc.jumpTo(ssiframe, request, registry, parameters,
208: ssiframe.vars);
209:
210: return jump;
211: }
212:
213: public final Reply get() {
214: if (command == null)
215: return null;
216: return command.execute(ssiframe, request, parameters,
217: ssiframe.vars);
218: }
219:
220: public boolean needsRevalidate() {
221: if (command == null)
222: return false;
223: else
224: return (!command.acceptCaching());
225: }
226:
227: public final Reply init(SSIFrame ssiframe, Request request,
228: Dictionary variables, CommandRegistry registry, int position) {
229: // If we're an unparsed segment, return null;
230: if (commandName == null)
231: return null;
232:
233: this .ssiframe = ssiframe;
234: this .request = request;
235:
236: // Cache the command for efficiency
237: // (Cache the registry just in case the SSIFrame registry
238: // changes without reparsing, even though maybe it shouldn't happen)
239: if (command == null || registry != this .registry) {
240: this .registry = registry;
241: this .command = registry.lookupCommand(commandName);
242: this .control = (command instanceof ControlCommand);
243: }
244: if (control) {
245: ControlCommand cc = (ControlCommand) command;
246: cc.setPosition(ssiframe, request, registry, parameters,
247: variables, position);
248: ssiframe.doNotCacheReply();
249: return null;
250: }
251: if ((ssiframe.cacheReplies()) && command.acceptCaching())
252: return get();
253: else
254: return null;
255: }
256: }
|