001: // PICSFilter.java
002: // $Id: PICSFilter.java,v 1.12 2000/08/17 12:54:55 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.pics;
007:
008: import java.io.File;
009:
010: import java.net.URL;
011:
012: import java.util.Enumeration;
013:
014: import org.w3c.tools.resources.Attribute;
015: import org.w3c.tools.resources.AttributeRegistry;
016: import org.w3c.tools.resources.FileAttribute;
017: import org.w3c.tools.resources.FramedResource;
018: import org.w3c.tools.resources.ReplyInterface;
019: import org.w3c.tools.resources.RequestInterface;
020: import org.w3c.tools.resources.Resource;
021: import org.w3c.tools.resources.ResourceFilter;
022:
023: import org.w3c.www.http.HTTP;
024: import org.w3c.www.http.HttpBag;
025: import org.w3c.www.http.HttpMessage;
026: import org.w3c.www.http.HttpRequestMessage;
027:
028: import org.w3c.jigsaw.http.HTTPException;
029: import org.w3c.jigsaw.http.Reply;
030: import org.w3c.jigsaw.http.Request;
031:
032: import org.w3c.jigsaw.html.HtmlGenerator;
033:
034: /**
035: * This package implements a PICS filter. The PICS filters allows server
036: * administrator to rate the documents they deliver. The references for this
037: * protocol is <a href="http://www.w3.org/hypertext/WWW/PICS/">here</a>.</p>
038: * <p>The PICS filter defines the following attributes:</p>
039: * <table border>
040: * <caption>The list of parameters</caption>
041: * <tr>
042: * <th align=left>Parameter name</th>
043: * <th align=left>Semantics</th>
044: * <th align=left>Default value</th>
045: * <th align=left>Type</th>
046: * </tr>
047: * <tr>
048: * <th align=left>bureau</th>
049: * <th align=left>The label bureau to query for this entity labels.</th>
050: * <th align=left><em>none</em></th>
051: * <th align=left>java.lang.String</th>
052: * </tr>
053: * </table>
054: */
055:
056: public class PICSFilter extends ResourceFilter {
057:
058: /**
059: * Attribute index - The identifier of our bureau.
060: */
061: protected static int ATTR_BUREAU_IDENTIFIER = -1;
062:
063: static {
064: Attribute a = null;
065: Class cls = null;
066: try {
067: cls = Class.forName("org.w3c.jigsaw.pics.PICSFilter");
068: } catch (Exception ex) {
069: ex.printStackTrace();
070: System.exit(1);
071: }
072: // The bureau identifier attribute
073: a = new FileAttribute("bureau", null, Attribute.EDITABLE
074: | Attribute.MANDATORY);
075: ATTR_BUREAU_IDENTIFIER = AttributeRegistry.registerAttribute(
076: cls, a);
077: }
078:
079: /**
080: * Our loaded lable bureau.
081: */
082: protected LabelBureauInterface bureau = null;
083:
084: /**
085: * Get our label bureau identifier.
086: */
087:
088: public File getBureauIdentifier() {
089: return (File) getValue(ATTR_BUREAU_IDENTIFIER, null);
090: }
091:
092: /**
093: * Make sure our label bureau is loaded.
094: */
095:
096: protected final void acquireBureau() {
097: if (bureau != null)
098: return;
099: File file = getBureauIdentifier();
100: if (file == null)
101: // Not initialize yet:
102: return;
103: bureau = LabelBureauFactory.getLabelBureau(file);
104: }
105:
106: /**
107: * Check the query to examine if it requires some PICS handling.
108: * If this is the case, it returns a <em>Bag</em> object
109: * corresponding to the part of the <em>Accept-Protocol</em> header that
110: * relates with PICS.
111: * @param request The request to be checked.
112: * @return A Bag object if PICS handling required, <string>null</strong>
113: * otherwise.
114: * @exception HTTPException if processing the request failed.
115: */
116:
117: protected HttpBag isPICSQuery(Request request) throws HTTPException {
118: // If the request doesn't ask for labels, return right now.
119: HttpBag requested = request.getProtocolRequest();
120: if (requested == null)
121: return null;
122: if (!requested.hasBag(PICS.PICS_PROTOCOL_ID))
123: return null;
124: // Now, the request has some PICS stuff in it, let look inside this:
125: HttpBag pics = null;
126: try {
127: pics = requested.getBag(PICS.PICS_PROTOCOL_ID);
128: } catch (ClassCastException e) {
129: return null;
130: }
131: return pics;
132: }
133:
134: /**
135: * The outgoingFilter method.
136: * This method is the one that gets called by Jigsaw core. By default it
137: * will call the simpler <code>outgoingFilter</code> method that takes
138: * only the request and the reply as parameters.
139: * @param request The request that has been processed.
140: * @param reply The original reply as emitted by the resource.
141: * @param filters The whole filter that applies to the resource.
142: * @param i The current index of filters. The <em>i</em> filter is ourself,
143: * filters with lower indexes have already been applied, and filters with
144: * greater indexes are still to be applied.
145: * @return A Reply instance, if that filter know how to complete the
146: * request processing, or <strong>null</strong> if reminaing filters
147: * are to be called by Jigsaw engine.
148: * @exception HTTPException If processing should be interrupted,
149: * because an abnormal situation occured.
150: */
151:
152: public ReplyInterface outgoingFilter(RequestInterface req,
153: ReplyInterface rep) throws HTTPException {
154: Request request = (Request) req;
155: Reply reply = (Reply) rep;
156:
157: HttpBag pics = isPICSQuery(request);
158: if (pics == null)
159: return reply;
160: // Get the requested services:
161: HttpBag params = pics.getBag("params");
162: HttpBag services = params.getBag("services");
163: URL url = request.getURL();
164: int format = LabelBureauInterface.FMT_MINIMAL;
165: // Get any format parameter:
166: if (params.hasItem("minimal")) {
167: format = LabelBureauInterface.FMT_MINIMAL;
168: } else if (params.hasItem("short")) {
169: format = LabelBureauInterface.FMT_SHORT;
170: } else if (params.hasItem("full")) {
171: format = LabelBureauInterface.FMT_FULL;
172: } else if (params.hasItem("signed")) {
173: format = LabelBureauInterface.FMT_SIGNED;
174: } else {
175: Reply error = request.makeReply(HTTP.BAD_REQUEST);
176: error.setContent("Invalid label format: " + format);
177: throw new HTTPException(error);
178: }
179: // Get labels for each service, building out the ret hashtable
180: StringBuffer sb = new StringBuffer(128);
181: Enumeration e = services.keys();
182: sb.append("(" + PICS.PICS_PROTOCOL_ID);
183: sloop: while (e.hasMoreElements()) {
184: String n = (String) e.nextElement();
185: LabelServiceInterface s = bureau.getLabelService(n);
186: if (s == null) {
187: sb.append(" error "
188: + "(service-unavailable \"unknown service\")");
189: continue sloop;
190: }
191: s.dump(sb, format);
192: LabelInterface l = s.getSpecificLabel(url);
193: if ((l == null) && ((l = s.getGenericLabel(url)) == null)) {
194: sb.append(" error (not-labeled \"" + url + "\")");
195: } else {
196: sb.append(" labels ");
197: l.dump(sb, format);
198: }
199: }
200: sb.append(")");
201: // Add additional reply headers:
202: reply.setProtocol(PICS.PICS_EXTENSION);
203: reply.setValue("PICS-label", sb.toString());
204: return reply;
205: }
206:
207: public void initialize(Object values[]) {
208: super.initialize(values);
209: acquireBureau();
210: }
211: }
|