--- /dev/null
+// PutFilter.java\r
+// $Id: PutFilter.java,v 1.2 2010/06/15 17:53:04 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.jigedit.filters;\r
+\r
+import java.io.IOException;\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.FramedResource;\r
+import org.w3c.tools.resources.InvalidResourceException;\r
+import org.w3c.tools.resources.LookupResult;\r
+import org.w3c.tools.resources.LookupState;\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
+import org.w3c.tools.resources.ResourceFrame;\r
+import org.w3c.tools.resources.ResourceReference;\r
+import org.w3c.tools.resources.StringAttribute;\r
+\r
+import org.w3c.www.http.HTTP;\r
+import org.w3c.www.http.HttpReplyMessage;\r
+import org.w3c.www.http.HttpRequestMessage;\r
+\r
+import org.w3c.jigsaw.http.Client;\r
+import org.w3c.jigsaw.http.Reply;\r
+import org.w3c.jigsaw.http.Request;\r
+import org.w3c.jigsaw.http.httpd;\r
+\r
+import org.w3c.jigsaw.html.HtmlGenerator;\r
+\r
+public class PutFilter extends ResourceFilter {\r
+ /**\r
+ * Attribute index - The companion PutList resource's URL.\r
+ */\r
+ protected static int ATTR_PUTLIST = -1;\r
+\r
+ static {\r
+ Class c = null;\r
+ Attribute a = null;\r
+\r
+ try {\r
+ c = Class.forName("org.w3c.jigedit.filters.PutFilter");\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ System.exit(1);\r
+ }\r
+ // Register the PutList URL attribute:\r
+ a = new StringAttribute("put-list"\r
+ , null\r
+ , Attribute.EDITABLE|Attribute.MANDATORY);\r
+ ATTR_PUTLIST = AttributeRegistry.registerAttribute(c, a);\r
+ }\r
+\r
+ /**\r
+ * Resolve the companion PutList URL attribute into a resource:\r
+ */\r
+\r
+ private ResourceReference list = null;\r
+ protected synchronized ResourceReference resolvePutListResource() {\r
+ // Prepare for lookup:\r
+ ResourceReference rr_root = null;\r
+ rr_root = ((httpd) getServer()).getRootReference();\r
+ FramedResource root = null;\r
+ root = ((httpd) getServer()).getRoot();\r
+ String u = getPutListURL();\r
+ if ( u == null )\r
+ return null;\r
+ // Do the lookup:\r
+ ResourceReference r_target = null;\r
+ try {\r
+ LookupState ls = new LookupState(u);\r
+ LookupResult lr = new LookupResult(rr_root);\r
+ root.lookup(ls, lr);\r
+ r_target = lr.getTarget();\r
+ } catch (Exception ex) {\r
+ r_target = null;\r
+ }\r
+ if (r_target != null) {\r
+ try {\r
+ Resource target = r_target.lock();\r
+ if (! (target instanceof PutListResource) )\r
+ r_target = null;\r
+ else\r
+ list = r_target;\r
+ } catch (InvalidResourceException ex) {\r
+ // continue\r
+ } finally {\r
+ r_target.unlock();\r
+ }\r
+ }\r
+ return r_target;\r
+ }\r
+\r
+ /**\r
+ * Get our companion PutListResource's URL.\r
+ * @return The URL encoded as a String, or <strong>null</strong> if\r
+ * undefined.\r
+ */\r
+\r
+ public String getPutListURL() {\r
+ return getString(ATTR_PUTLIST, null);\r
+ }\r
+\r
+ /**\r
+ * Catch PUTLIST assignments.\r
+ * @param idx The attribute being updated.\r
+ * @param value It's new value.\r
+ */\r
+\r
+ public void setValue(int idx, Object value) {\r
+ super.setValue(idx, value);\r
+ if ( idx == ATTR_PUTLIST ) {\r
+ synchronized(this) {\r
+ list = null;\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Nothing done in the ingoingFilter.\r
+ * We wait until the outgoigFilter.\r
+ * @param request The request that is about to be processsed.\r
+ */\r
+\r
+ public ReplyInterface ingoingFilter(RequestInterface req) {\r
+ Request request = (Request) req;\r
+ String expect = request.getExpect();\r
+ if (expect != null) {\r
+ if (expect.startsWith("100")) { // expect 100?\r
+ Client client = request.getClient();\r
+ if (client != null) {\r
+ try {\r
+ client.sendContinue();\r
+ } catch (java.io.IOException ex) {\r
+ }\r
+ }\r
+ }\r
+ }\r
+ //register request, but this must be confirmed.\r
+ if ( request.getMethod().equals("DELETE") &&\r
+ (request.getTargetResource() != null) ) {\r
+ boolean done = false;\r
+ synchronized (this) {\r
+ ResourceReference rr = resolvePutListResource();\r
+ PutListResource l = null;\r
+ if (rr != null) {\r
+ try {\r
+ l = (PutListResource) rr.lock();\r
+ if ( l != null ) {\r
+ l.registerDeleteRequest(request);\r
+ done = true;\r
+ }\r
+ } catch (InvalidResourceException ex) {\r
+ done = false;\r
+ } finally {\r
+ rr.unlock();\r
+ }\r
+ }\r
+ }\r
+ if (! done) {\r
+ httpd s = (httpd) getServer();\r
+ s.errlog(getClass().getName()+\r
+ ": unable to resolve companion PutListResource at "+\r
+ getPutListURL());\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ protected HtmlGenerator getHtmlGenerator(String title) {\r
+ HtmlGenerator g = new HtmlGenerator(title);\r
+ g.addStyle("BODY {color: black; background: white; "+\r
+ "font-family: serif; margin-top: 35px }\n");\r
+ return g;\r
+ }\r
+\r
+ /**\r
+ * Catch successfull PUTs, and keep track of them.\r
+ * @param request The original request.\r
+ * @param reply The original reply.\r
+ * @return Always <strong>null</strong>.\r
+ */\r
+\r
+ public ReplyInterface outgoingFilter(RequestInterface req, \r
+ ReplyInterface rep) \r
+ {\r
+ Request request = (Request) req;\r
+ Reply reply = (Reply) rep;\r
+ int status = PutListResource.FILE_UC;\r
+ boolean put = false;\r
+ // Is this a successfull PUT request ?\r
+ if (((put = request.getMethod().equals("PUT")) ||\r
+ request.getMethod().equals("DELETE"))\r
+ && ((reply.getStatus()/100) == 2)) {\r
+ // Cool, keep track of the modified file:\r
+ ResourceReference rr = null;\r
+ PutListResource l = null;\r
+ boolean done = false;\r
+ synchronized (this) {\r
+ rr = resolvePutListResource();\r
+ if (rr != null) {\r
+ try {\r
+ l = (PutListResource) rr.lock();\r
+ if ( l != null ) {\r
+ if (put)\r
+ status = l.registerRequest(request);\r
+ else\r
+ status = l.confirmDelete(request);\r
+ done = true;\r
+ }\r
+ } catch (InvalidResourceException ex) {\r
+ done = false;\r
+ } finally {\r
+ rr.unlock();\r
+ }\r
+ }\r
+ }\r
+ // Make sure we did something:\r
+ if ( !done ) {\r
+ httpd s = (httpd) getServer();\r
+ s.errlog(getClass().getName()+\r
+ ": unable to resolve companion PutListResource at "+\r
+ getPutListURL());\r
+ } \r
+ \r
+ switch (status) {\r
+ case PutListResource.FILE_UC:\r
+ case PutListResource.FILE_PB:\r
+ case PutListResource.FILE_DEL:\r
+ return null;\r
+ case PutListResource.FILE_MG:\r
+ Reply msg = request.makeReply(HTTP.CONFLICT);\r
+ HtmlGenerator g = getHtmlGenerator("Warning");\r
+ g.append ("<H1>Warning</H1> The file on publish space has "+\r
+ "been modified directly but attempting to merge "+\r
+ "has succeed.<p>"+\r
+ "You should update the file before editing "+\r
+ "it again.");\r
+ msg.setStream(g);\r
+ return msg;\r
+ case PutListResource.FILE_CF:\r
+ Reply error = request.makeReply(HTTP.CONFLICT);\r
+ HtmlGenerator gerr = getHtmlGenerator("Warning");\r
+ gerr.append ("<H1>Warning</H1> The file on publish space has "+\r
+ "been modified directly and attempting to merge"+\r
+ " has failed.<p>"+\r
+ "Ask your system administrator.");\r
+ error.setStream(gerr);\r
+ return error;\r
+ default:\r
+ return null;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public void initialize(Object values[]) {\r
+ super.initialize(values);\r
+ }\r
+\r
+}\r