--- /dev/null
+// PICSFilter.java\r
+// $Id: PICSFilter.java,v 1.2 2010/06/15 17:53:05 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1996.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigsaw.pics ;\r
+\r
+import java.io.File;\r
+\r
+import java.net.URL;\r
+\r
+import java.util.Enumeration;\r
+\r
+import org.w3c.tools.resources.Attribute;\r
+import org.w3c.tools.resources.AttributeRegistry;\r
+import org.w3c.tools.resources.FileAttribute;\r
+import org.w3c.tools.resources.FramedResource;\r
+import org.w3c.tools.resources.ReplyInterface;\r
+import org.w3c.tools.resources.RequestInterface;\r
+import org.w3c.tools.resources.Resource;\r
+import org.w3c.tools.resources.ResourceFilter;\r
+\r
+import org.w3c.www.http.HTTP;\r
+import org.w3c.www.http.HttpBag;\r
+import org.w3c.www.http.HttpMessage;\r
+import org.w3c.www.http.HttpRequestMessage;\r
+\r
+import org.w3c.jigsaw.http.HTTPException;\r
+import org.w3c.jigsaw.http.Reply;\r
+import org.w3c.jigsaw.http.Request;\r
+\r
+import org.w3c.jigsaw.html.HtmlGenerator ;\r
+\r
+/** \r
+ * This package implements a PICS filter. The PICS filters allows server\r
+ * administrator to rate the documents they deliver. The references for this\r
+ * protocol is <a href="http://www.w3.org/hypertext/WWW/PICS/">here</a>.</p>\r
+ * <p>The PICS filter defines the following attributes:</p>\r
+ * <table border>\r
+ * <caption>The list of parameters</caption>\r
+ * <tr> \r
+ * <th align=left>Parameter name</th> \r
+ * <th align=left>Semantics</th>\r
+ * <th align=left>Default value</th> \r
+ * <th align=left>Type</th>\r
+ * </tr>\r
+ * <tr> \r
+ * <th align=left>bureau</th> \r
+ * <th align=left>The label bureau to query for this entity labels.</th>\r
+ * <th align=left><em>none</em></th> \r
+ * <th align=left>java.lang.String</th>\r
+ * </tr>\r
+ * </table>\r
+ */\r
+\r
+public class PICSFilter extends ResourceFilter {\r
+\r
+ /**\r
+ * Attribute index - The identifier of our bureau.\r
+ */\r
+ protected static int ATTR_BUREAU_IDENTIFIER = -1 ;\r
+\r
+ static {\r
+ Attribute a = null ;\r
+ Class cls = null ;\r
+ try {\r
+ cls = Class.forName("org.w3c.jigsaw.pics.PICSFilter");\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace() ;\r
+ System.exit(1) ;\r
+ }\r
+ // The bureau identifier attribute\r
+ a = new FileAttribute("bureau"\r
+ , null\r
+ , Attribute.EDITABLE|Attribute.MANDATORY) ;\r
+ ATTR_BUREAU_IDENTIFIER = AttributeRegistry.registerAttribute(cls, a);\r
+ }\r
+\r
+ /**\r
+ * Our loaded lable bureau.\r
+ */\r
+ protected LabelBureauInterface bureau = null ;\r
+\r
+ /**\r
+ * Get our label bureau identifier.\r
+ */\r
+\r
+ public File getBureauIdentifier() {\r
+ return (File) getValue(ATTR_BUREAU_IDENTIFIER, null) ;\r
+ }\r
+\r
+ /**\r
+ * Make sure our label bureau is loaded.\r
+ */\r
+\r
+ protected final void acquireBureau() {\r
+ if ( bureau != null )\r
+ return ;\r
+ File file = getBureauIdentifier();\r
+ if ( file == null )\r
+ // Not initialize yet:\r
+ return ;\r
+ bureau = LabelBureauFactory.getLabelBureau(file);\r
+ }\r
+\r
+ /**\r
+ * Check the query to examine if it requires some PICS handling. \r
+ * If this is the case, it returns a <em>Bag</em> object\r
+ * corresponding to the part of the <em>Accept-Protocol</em> header that\r
+ * relates with PICS.\r
+ * @param request The request to be checked.\r
+ * @return A Bag object if PICS handling required, <string>null</strong>\r
+ * otherwise.\r
+ * @exception HTTPException if processing the request failed.\r
+ */\r
+\r
+ protected HttpBag isPICSQuery (Request request) \r
+ throws HTTPException\r
+ {\r
+ // If the request doesn't ask for labels, return right now.\r
+ HttpBag requested = request.getProtocolRequest();\r
+ if ( requested == null )\r
+ return null ;\r
+ if ( ! requested.hasBag (PICS.PICS_PROTOCOL_ID) )\r
+ return null ;\r
+ // Now, the request has some PICS stuff in it, let look inside this:\r
+ HttpBag pics = null ;\r
+ try {\r
+ pics = requested.getBag(PICS.PICS_PROTOCOL_ID) ;\r
+ } catch (ClassCastException e) {\r
+ return null ;\r
+ }\r
+ return pics ;\r
+ }\r
+\r
+ /**\r
+ * The outgoingFilter method.\r
+ * This method is the one that gets called by Jigsaw core. By default it\r
+ * will call the simpler <code>outgoingFilter</code> method that takes\r
+ * only the request and the reply as parameters.\r
+ * @param request The request that has been processed.\r
+ * @param reply The original reply as emitted by the resource.\r
+ * @param filters The whole filter that applies to the resource.\r
+ * @param i The current index of filters. The <em>i</em> filter is ourself,\r
+ * filters with lower indexes have already been applied, and filters with\r
+ * greater indexes are still to be applied.\r
+ * @return A Reply instance, if that filter know how to complete the\r
+ * request processing, or <strong>null</strong> if reminaing filters\r
+ * are to be called by Jigsaw engine.\r
+ * @exception HTTPException If processing should be interrupted,\r
+ * because an abnormal situation occured.\r
+ */\r
+\r
+ public ReplyInterface outgoingFilter (RequestInterface req, \r
+ ReplyInterface rep) \r
+ throws HTTPException\r
+ {\r
+ Request request = (Request) req;\r
+ Reply reply = (Reply) rep;\r
+\r
+ HttpBag pics = isPICSQuery (request) ;\r
+ if ( pics == null )\r
+ return reply ;\r
+ // Get the requested services:\r
+ HttpBag params = pics.getBag("params") ;\r
+ HttpBag services = params.getBag("services") ;\r
+ URL url = request.getURL();\r
+ int format = LabelBureauInterface.FMT_MINIMAL ;\r
+ // Get any format parameter:\r
+ if ( params.hasItem ("minimal") ) {\r
+ format = LabelBureauInterface.FMT_MINIMAL ;\r
+ } else if ( params.hasItem ("short") ) {\r
+ format = LabelBureauInterface.FMT_SHORT ;\r
+ } else if ( params.hasItem ("full") ) {\r
+ format = LabelBureauInterface.FMT_FULL ;\r
+ } else if ( params.hasItem ("signed") ) {\r
+ format = LabelBureauInterface.FMT_SIGNED ;\r
+ } else {\r
+ Reply error = request.makeReply(HTTP.BAD_REQUEST) ;\r
+ error.setContent ("Invalid label format: "+format) ;\r
+ throw new HTTPException (error) ;\r
+ }\r
+ // Get labels for each service, building out the ret hashtable\r
+ StringBuffer sb = new StringBuffer(128) ;\r
+ Enumeration e = services.keys() ;\r
+ sb.append ("("+PICS.PICS_PROTOCOL_ID) ;\r
+ sloop:\r
+ while ( e.hasMoreElements() ) {\r
+ String n = (String) e.nextElement() ;\r
+ LabelServiceInterface s = bureau.getLabelService (n) ;\r
+ if ( s == null ) {\r
+ sb.append (" error "\r
+ + "(service-unavailable \"unknown service\")") ;\r
+ continue sloop ;\r
+ } \r
+ s.dump(sb, format) ;\r
+ LabelInterface l = s.getSpecificLabel (url) ;\r
+ if ( (l == null) && ((l = s.getGenericLabel (url)) == null) ) {\r
+ sb.append (" error (not-labeled \"" + url +"\")") ;\r
+ } else {\r
+ sb.append (" labels ") ;\r
+ l.dump (sb, format) ;\r
+ }\r
+ }\r
+ sb.append (")") ;\r
+ // Add additional reply headers:\r
+ reply.setProtocol(PICS.PICS_EXTENSION);\r
+ reply.setValue("PICS-label", sb.toString());\r
+ return reply ;\r
+ }\r
+\r
+ public void initialize (Object values[]) {\r
+ super.initialize(values);\r
+ acquireBureau() ;\r
+ }\r
+}\r