--- /dev/null
+// HeaderFilter.java\r
+// $Id: HeaderFilter.java,v 1.2 2010/06/15 17:52:54 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.filters;\r
+\r
+import org.w3c.tools.resources.Attribute;\r
+import org.w3c.tools.resources.AttributeHolder;\r
+import org.w3c.tools.resources.AttributeRegistry;\r
+import org.w3c.tools.resources.BooleanAttribute;\r
+import org.w3c.tools.resources.FilterInterface;\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.ReplyInterface;\r
+import org.w3c.tools.resources.RequestInterface;\r
+import org.w3c.tools.resources.ResourceFilter;\r
+import org.w3c.tools.resources.StringAttribute;\r
+\r
+import org.w3c.tools.resources.ProtocolException;\r
+\r
+import org.w3c.www.http.HttpMessage;\r
+\r
+import org.w3c.jigsaw.http.Reply;\r
+\r
+/**\r
+ * Enforces a specific header value on all replies.\r
+ * Usefull for testing.\r
+ */\r
+\r
+public class HeaderFilter extends ResourceFilter {\r
+ /**\r
+ * Attribute index - The header name to add to replies.\r
+ */\r
+ protected static int ATTR_HEADER_NAME = -1;\r
+ /**\r
+ * Attribute index - The header value.\r
+ */\r
+ protected static int ATTR_HEADER_VALUE = -1;\r
+ /**\r
+ * Attribute index - SHould we use no-cache on that header.\r
+ */\r
+ protected static int ATTR_NOCACHE = -1;\r
+ /**\r
+ * Attribute index - Should we use connection on that header.\r
+ */\r
+ protected static int ATTR_CONNECTION = -1;\r
+\r
+ static {\r
+ Class c = null;\r
+ Attribute a = null;\r
+ try {\r
+ c = Class.forName("org.w3c.jigsaw.filters.HeaderFilter");\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ System.exit(1);\r
+ }\r
+ // Register the header name attribute:\r
+ a = new StringAttribute("header-name"\r
+ , null\r
+ , Attribute.EDITABLE);\r
+ ATTR_HEADER_NAME = AttributeRegistry.registerAttribute(c, a);\r
+ // Register the header value attribute.\r
+ a = new StringAttribute("header-value"\r
+ , null\r
+ , Attribute.EDITABLE);\r
+ ATTR_HEADER_VALUE = AttributeRegistry.registerAttribute(c, a);\r
+ // Register the nocache attribute.\r
+ a = new BooleanAttribute("no-cache"\r
+ , Boolean.FALSE\r
+ , Attribute.EDITABLE);\r
+ ATTR_NOCACHE = AttributeRegistry.registerAttribute(c, a);\r
+ // Register the connection attribute.\r
+ a = new BooleanAttribute("connection"\r
+ , Boolean.FALSE\r
+ , Attribute.EDITABLE);\r
+ ATTR_CONNECTION = AttributeRegistry.registerAttribute(c, a);\r
+ }\r
+\r
+ \r
+ /**\r
+ * Get the header to set, if any.\r
+ * @return A String encoded header name, or <strong>null</strong>.\r
+ */\r
+\r
+ public String getHeaderName() {\r
+ String value = getString(ATTR_HEADER_NAME, null);\r
+ return value;\r
+ }\r
+\r
+ /**\r
+ * Get the header value to set, if any.\r
+ * @return A String encoded value for the header to set, or <strong>\r
+ * null</strong>.\r
+ */\r
+\r
+ public String getHeaderValue() {\r
+ return getString(ATTR_HEADER_VALUE, null);\r
+ }\r
+\r
+ /**\r
+ * Should we add this header's name to the <code>no-cache</code> \r
+ * directive.\r
+ * @return A boolean.\r
+ */\r
+\r
+ public boolean checkNoCache() {\r
+ return getBoolean(ATTR_NOCACHE, false);\r
+ }\r
+\r
+ /**\r
+ * Should we add this header to the connection header.\r
+ * @return A boolean.\r
+ */\r
+\r
+ public boolean checkConnection() {\r
+ return getBoolean(ATTR_CONNECTION, false);\r
+ }\r
+\r
+ private ReplyInterface modifyHeaders(ReplyInterface rep) {\r
+ Reply reply = (Reply) rep;\r
+ String hname = getHeaderName();\r
+ if ( hname != null ) {\r
+ String hvalue = getHeaderValue();\r
+ if ( hvalue == null ) {\r
+ reply.removeHeader(hname);\r
+ } else {\r
+ reply.setValue(hname, hvalue);\r
+ }\r
+ if ( checkNoCache() )\r
+ reply.addNoCache(hname);\r
+ if ( checkConnection() )\r
+ reply.addConnection(hname);\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * @return A Reply instance, if the filter did know how to answer\r
+ * the request without further processing, <strong>null</strong> \r
+ * otherwise. \r
+ * @exception ProtocolException If processing should be interrupted,\r
+ * because an abnormal situation occured. \r
+ */ \r
+ public ReplyInterface ingoingFilter(RequestInterface request) \r
+ throws ProtocolException\r
+ {\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * The outgoing filter decorates the reply appropriately.\r
+ * @param request The original request.\r
+ * @param reply The originial reply.\r
+ * @return Always <strong>null</strong>.\r
+ * @exception ProtocolException If processing should be interrupted,\r
+ * because an abnormal situation occured. \r
+ */\r
+\r
+ public ReplyInterface outgoingFilter(RequestInterface req,\r
+ ReplyInterface rep) \r
+ throws ProtocolException\r
+ {\r
+ return modifyHeaders(rep);\r
+ }\r
+\r
+ public ReplyInterface exceptionFilter(RequestInterface request,\r
+ ProtocolException ex,\r
+ FilterInterface filters[],\r
+ int i) {\r
+ Reply rep = (Reply) ex.getReply();\r
+ if (rep != null) {\r
+ return modifyHeaders(rep);\r
+ }\r
+ return null;\r
+ }\r
+}\r