001: // HTTPExtFrame.java
002: // $Id: HTTPExtFrame.java,v 1.8 2000/08/16 21:37:38 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1998.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005: package org.w3c.jigsaw.frames;
006:
007: import java.util.Hashtable;
008: import java.util.Vector;
009:
010: import org.w3c.jigsaw.html.HtmlGenerator;
011: import org.w3c.jigsaw.http.Reply;
012: import org.w3c.jigsaw.http.Request;
013: import org.w3c.jigsaw.http.HTTPException;
014: import org.w3c.tools.resources.ProtocolException;
015: import org.w3c.tools.resources.ResourceException;
016: import org.w3c.www.http.HTTP;
017: import org.w3c.www.http.HttpExtList;
018: import org.w3c.www.http.HttpExt;
019:
020: /**
021: * @version $Revision: 1.8 $
022: * @author Benoît Mahé (bmahe@w3.org)
023: */
024: public class HTTPExtFrame extends HTTPFrame {
025:
026: /**
027: * Supported extensions
028: */
029: protected static Hashtable extensions = null;
030:
031: /**
032: * Register a protocol extension name.
033: * @param name the extension name (absoluteURI or field-name);
034: * @param methods the allowed methods (an array of String)
035: * @param classname the associated frame classname.
036: */
037: protected final static void registerExtension(String name,
038: String methods[], String classname) {
039: for (int i = 0; i < methods.length; i++) {
040: registerExtension(name, methods[i], classname);
041: }
042: }
043:
044: /**
045: * Register a protocol extension name.
046: * @param name the extension name (absoluteURI or field-name);
047: * @param method the allowed method
048: * @param classname the associated frame classname.
049: */
050: protected final static void registerExtension(String name,
051: String method, String classname) {
052: if (extensions == null)
053: extensions = new Hashtable(2);
054:
055: String idx = classname + "." + method;
056: Hashtable methods = (Hashtable) extensions.get(idx);
057:
058: if (methods == null) {
059: methods = new Hashtable(2);
060: extensions.put(idx, methods);
061: }
062: methods.put(name, Boolean.TRUE);
063: }
064:
065: /**
066: * Check if an extension is known.
067: * @param name the extension name
068: * @return a boolean
069: */
070: protected final static boolean supportedExtension(String name,
071: String method, Object obj) {
072: if (extensions != null) {
073: String idx = obj.getClass().getName() + "." + method;
074: Hashtable methods = (Hashtable) extensions.get(idx);
075: if (methods != null)
076: return (methods.get(name) != null);
077: }
078: return false;
079: }
080:
081: /**
082: * The handler for unknown method replies with a not implemented.
083: * @param request The request to handle.
084: * @exception ProtocolException If processsing the request failed.
085: * @exception ResourceException If the resource got a fatal error.
086: */
087: public Reply extended(Request request) throws ProtocolException,
088: ResourceException {
089: String method = request.getMethod();
090: Reply reply = null;
091:
092: if ((method != null) && method.equals("BROWSE")
093: && getBrowsableFlag())
094: return browse(request);
095:
096: if ((method != null) && (method.startsWith("M-"))) {
097: //HTTP Extension Framework
098: if (method.equals("M-GET")) {
099: checkMandatoryExtension(request, method);
100: reply = get(request);
101: } else if (method.equals("M-HEAD")) {
102: checkMandatoryExtension(request, method);
103: reply = head(request);
104: } else if (method.equals("M-POST")) {
105: checkMandatoryExtension(request, method);
106: reply = post(request);
107: } else if (method.equals("M-PUT")) {
108: checkMandatoryExtension(request, method);
109: reply = put(request);
110: } else if (method.equals("M-OPTIONS")) {
111: checkMandatoryExtension(request, method);
112: reply = options(request);
113: } else if (method.equals("M-DELETE")) {
114: checkMandatoryExtension(request, method);
115: reply = delete(request);
116: } else if (method.equals("M-LINK")) {
117: checkMandatoryExtension(request, method);
118: reply = link(request);
119: } else if (method.equals("M-UNLINK")) {
120: checkMandatoryExtension(request, method);
121: reply = unlink(request);
122: } else if (method.equals("M-TRACE")) {
123: checkMandatoryExtension(request, method);
124: reply = trace(request);
125: } else {
126: reply = mextended(request);
127: }
128: return acknowledgeExtension(request, reply);
129: }
130:
131: Reply error = request.makeReply(HTTP.NOT_IMPLEMENTED);
132: error.setContent("Method " + method + " not implemented.");
133: throw new HTTPException(error);
134: }
135:
136: /**
137: * Set the Ext and/or C-Ext Header if necessary.
138: * @param request the incomming request.
139: * @param reply the reply
140: * @return the acknowledged reply instance
141: */
142: protected Reply acknowledgeExtension(Request request, Reply reply) {
143: return reply;
144: }
145:
146: public Reply mextended(Request request) throws ProtocolException,
147: ResourceException {
148: String method = request.getMethod();
149: Reply error = request.makeReply(HTTP.NOT_IMPLEMENTED);
150: error.setContent("Method " + method + " not implemented.");
151: throw new HTTPException(error);
152: }
153:
154: /**
155: * Check if the mandatory extensions are supported.
156: * @param request The request to handle.
157: * @exception ProtocolException thrown when there is one (or more)
158: * unsupported extensions or if there is no extension in the M-XXX
159: * method.
160: */
161: public void checkMandatoryExtension(Request request, String mmethod)
162: throws ProtocolException {
163: HttpExtList extl = request.getHttpManExtDecl();
164: HttpExtList cextl = request.getHttpCManExtDecl();
165: HttpExt exts[] = null;
166: HttpExt cexts[] = null;
167: Vector notsupported = new Vector(2);
168: //remove the M-
169: String method = mmethod.substring(2);
170:
171: if ((extl == null) && (cextl == null)) {
172: Reply error = request.makeReply(HTTP.NOT_EXTENDED);
173: error.setContent("Mandatory extension expected.");
174: throw new HTTPException(error);
175: }
176:
177: int nb_extensions = 0;
178:
179: if (extl != null) {
180: exts = extl.getHttpExts();
181: int len = exts.length;
182: nb_extensions += len;
183: for (int i = 0; i < len; i++) {
184: if (!supportedExtension(exts[i].getName(), method, this ))
185: notsupported.addElement(exts[i].getName());
186: }
187: }
188:
189: if (cextl != null) {
190: cexts = cextl.getHttpExts();
191: int len = cexts.length;
192: nb_extensions += len;
193: for (int i = 0; i < cexts.length; i++) {
194: if (!supportedExtension(cexts[i].getName(), method,
195: this ))
196: notsupported.addElement(cexts[i].getName());
197: }
198: }
199:
200: if (nb_extensions == 0) {
201: Reply error = request.makeReply(HTTP.NOT_EXTENDED);
202: error.setContent("Mandatory extension expected.");
203: throw new HTTPException(error);
204: }
205:
206: int len = -1;
207: if ((len = notsupported.size()) > 0) {
208: Reply error = request.makeReply(HTTP.NOT_EXTENDED);
209: HtmlGenerator content = new HtmlGenerator("Error");
210: content.append("<h1>Mandatory extension(s) not supported:",
211: "</h1><p>\n");
212: content.append("<ul>\n");
213: for (int i = 0; i < len; i++)
214: content.append("<li> "
215: + (String) notsupported.elementAt(i) + "\n");
216: content.append("</ul>\n");
217: error.setStream(content);
218: throw new HTTPException(error);
219: }
220: }
221:
222: }
|