--- /dev/null
+// ToolsListerFrame.java\r
+// $Id: ToolsListerFrame.java,v 1.2 2010/06/15 17:53:05 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1998.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigedit.tools ;\r
+\r
+import java.io.File;\r
+import java.io.PrintStream;\r
+\r
+import java.text.SimpleDateFormat;\r
+\r
+import java.util.Date;\r
+import java.util.Enumeration;\r
+import java.util.TimeZone;\r
+import java.util.Vector;\r
+\r
+import org.w3c.tools.resources.AbstractContainer;\r
+import org.w3c.tools.resources.DirectoryResource;\r
+import org.w3c.tools.resources.FramedResource;\r
+import org.w3c.tools.resources.InvalidResourceException;\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.Resource;\r
+import org.w3c.tools.resources.ResourceException;\r
+import org.w3c.tools.resources.ResourceFrame;\r
+import org.w3c.tools.resources.ResourceReference;\r
+\r
+import org.w3c.tools.sorter.Sorter;\r
+\r
+import org.w3c.jigsaw.forms.URLDecoder;\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
+import org.w3c.jigsaw.frames.HTTPFrame;\r
+import org.w3c.jigsaw.frames.PostableFrame;\r
+\r
+import org.w3c.jigedit.cvs2.CvsFrame;\r
+\r
+import org.w3c.www.http.HTTP;\r
+import org.w3c.www.http.HttpEntityMessage;\r
+import org.w3c.www.http.HttpRequestMessage;\r
+\r
+import org.w3c.tools.resources.event.StructureChangedEvent;\r
+import org.w3c.tools.resources.event.StructureChangedListener;\r
+\r
+/**\r
+ * Emit the content of its parent directory.\r
+ */\r
+public class ToolsListerFrame extends PostableFrame \r
+ implements StructureChangedListener \r
+{\r
+ private static final boolean debug = true;\r
+\r
+ private boolean invalid = true;\r
+\r
+ private ResourceReference dirResourceRef = null;\r
+\r
+ protected ResourceReference getDirResourceRef() {\r
+ if (invalid || (dirResourceRef == null)) {\r
+ dirResourceRef = getResource().getParent();\r
+ }\r
+ return dirResourceRef;\r
+ }\r
+\r
+ public void registerResource(FramedResource resource) {\r
+ super.registerOtherResource(resource);\r
+ dirResourceRef = resource.getParent();\r
+ try {\r
+ FramedResource fres = (FramedResource)dirResourceRef.lock();\r
+ // register us as a listener \r
+ fres.addStructureChangedListener(this);\r
+ } catch(InvalidResourceException ex) {\r
+ ex.printStackTrace();\r
+ } finally {\r
+ dirResourceRef.unlock();\r
+ }\r
+ invalid = false;\r
+ }\r
+\r
+ /**\r
+ * Unused here.\r
+ */\r
+ public void resourceModified(StructureChangedEvent evt) { }\r
+\r
+ /**\r
+ * Unused here.\r
+ */\r
+ public void resourceCreated(StructureChangedEvent evt) { }\r
+\r
+ public void resourceUnloaded(StructureChangedEvent evt){ }\r
+\r
+ /**\r
+ * A resource is about to be removed\r
+ * This handles the <code>RESOURCE_REMOVED</code> kind of events.\r
+ * @param evt The event describing the change.\r
+ */\r
+\r
+ public void resourceRemoved(StructureChangedEvent evt) {\r
+ invalid = true;\r
+ }\r
+\r
+ protected Class httpClass = null;\r
+\r
+ private String getResourceLine(ResourceReference rr, String name, \r
+ boolean even) {\r
+ if (httpClass == null) {\r
+ try {\r
+ httpClass=Class.forName("org.w3c.jigsaw.frames.HTTPFrame");\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ } catch (ClassNotFoundException ex) {\r
+ httpClass = null;\r
+ }\r
+ }\r
+ // get the right date formatter\r
+ SimpleDateFormat df;\r
+ df = new SimpleDateFormat ("yyyy MMM dd - HH:mm:ss zzz");\r
+ df.setTimeZone(TimeZone.getTimeZone("GMT"));\r
+\r
+ StringBuffer buffer = new StringBuffer(100);\r
+ try {\r
+ FramedResource resource = (FramedResource) rr.lock();\r
+ if (name == null)\r
+ name = resource.getIdentifier();\r
+ if (even) {\r
+ buffer.append("<tr class=\"evenlist\" align=\"left\" "\r
+ + "valign=\"bottom\">");\r
+ } else {\r
+ buffer.append("<tr class=\"oddlist\" align=\"left\" "\r
+ + "valign=\"bottom\">"); \r
+ }\r
+ HTTPFrame itsframe = null;\r
+ if (httpClass != null)\r
+ itsframe = (HTTPFrame)resource.getFrame(httpClass);\r
+ if (itsframe instanceof CvsFrame) {\r
+ buffer.append("<td></td>");\r
+ } else {\r
+ buffer.append("<td>");\r
+ buffer.append("<INPUT TYPE=\"CHECKBOX\" NAME=\"" + name\r
+ + "\"> ");\r
+ buffer.append("</td>");\r
+ }\r
+ buffer.append("<td>");\r
+ if (itsframe != null) {\r
+ String icon = itsframe.getIcon() ;\r
+ if ( icon != null ) \r
+ buffer.append("<IMG SRC=\""+\r
+ getIconDirectory() +"/" + icon+\r
+ "\">");\r
+ // Resource's name with link:\r
+ buffer.append("<A HREF=\""+resource.getURLPath()+\r
+ "\">"+name+"</A>");\r
+ // resource's title, if any:\r
+ String title = itsframe.getTitle();\r
+ if (title != null) {\r
+ buffer.append("</td><td>"+title);\r
+ } else {\r
+ buffer.append("</td><td>");\r
+ }\r
+ int clength = itsframe.getContentLength();\r
+ if (clength != -1) {\r
+ int kcl = clength / 1024;\r
+ buffer.append("</td><td>[ " + kcl + " kB ]");\r
+ } else {\r
+ buffer.append("</td><td>-");\r
+ }\r
+ long clm = itsframe.getLastModified();\r
+ if (clm != -1) {\r
+ buffer.append("</td><td>"+ df.format(new Date(clm)));\r
+ } else {\r
+ buffer.append("</td><td>-");\r
+ }\r
+ } else {\r
+ // Resource's name with link:\r
+ buffer.append("<A HREF=\""+resource.getURLPath()+\r
+ "\">"+name+"</A>"+" Not available via HTTP");\r
+ buffer.append("</td><td></td><td></td><td>\n");\r
+ }\r
+ buffer.append("</td></tr>\n");\r
+ } catch (InvalidResourceException ex) {\r
+ buffer.append("<td> "+name);\r
+ buffer.append("cannot be loaded (server misconfigured)");\r
+ buffer.append("<BR>");\r
+ buffer.append("</td></tr>\n");\r
+ } finally {\r
+ rr.unlock();\r
+ }\r
+ return buffer.toString();\r
+ }\r
+\r
+ /**\r
+ * Get the directory listing.\r
+ * @param request the incomming request.\r
+ * @exception ProtocolException if a protocol error occurs\r
+ * @exception ResourceException if a server error occurs\r
+ */\r
+ public synchronized Reply getDirectoryListing(Request request)\r
+ throws ProtocolException, ResourceException\r
+ {\r
+ DirectoryResource dirResource = null;\r
+ try {\r
+ dirResource = (DirectoryResource) getDirResourceRef().lock();\r
+ if (dirResource == null) \r
+ throw new ResourceException("parent is NOT a "+\r
+ "DirectoryResource. ("+\r
+ resource.getIdentifier()+")");\r
+ if (! dirResource.verify()) {\r
+ // the directory was deleted, but we can't delete it here\r
+ // (Multiple Locks)\r
+ // Emit an error back:\r
+ Reply error = request.makeReply(HTTP.NOT_FOUND) ;\r
+ error.setContent ("<h1>Document not found</h1>"+\r
+ "<p>The document "+\r
+ request.getURL()+\r
+ " is indexed but not available."+\r
+ "<p>The server is misconfigured.") ;\r
+ throw new HTTPException (error) ;\r
+ }\r
+ // Have we already an up-to-date computed a listing ?\r
+ if ((listing == null) \r
+ || (dirResource.getDirectory().lastModified() > listing_stamp)\r
+ || (dirResource.getLastModified() > listing_stamp)\r
+ || (getLastModified() > listing_stamp)) {\r
+ \r
+ Enumeration e = dirResource.enumerateResourceIdentifiers() ;\r
+ Vector resources = Sorter.sortStringEnumeration(e) ;\r
+ HtmlGenerator g = new HtmlGenerator("Directory listing of "+\r
+ dirResource.getIdentifier());\r
+ // Add style link\r
+ addStyleSheet(g);\r
+ g.append("<h1>Directory listing of ",\r
+ dirResource.getIdentifier(),\r
+ "</h1>");\r
+ // Link to the parent, when possible:\r
+ if ( dirResource.getParent() != null )\r
+ g.append("<p><a href=\"..\">Parent</a><br>");\r
+ g.append("\n<form method=\"POST\" action=\""+request.getURL()\r
+ +"\">\n");\r
+ String listername = getResource().getIdentifier();\r
+ // List the children:\r
+ g.append("<table border=\"0\">\n");\r
+\r
+ ResourceReference rr = null;\r
+ FramedResource resource = null;\r
+ String name = null;\r
+ //ugly hack to put CVS link first\r
+ rr = dirResource.lookup("CVS");\r
+ if (rr != null) {\r
+ g.append(getResourceLine(rr, "CVS", false));\r
+ }\r
+ boolean even = true;\r
+ for (int i = 0 ; i < resources.size() ; i++) {\r
+ name = (String) resources.elementAt(i);\r
+ if ( name.equals(listername) || name.equals("CVS"))\r
+ continue;\r
+ rr = dirResource.lookup(name);\r
+ g.append(getResourceLine(rr, name, even));\r
+ even = !even;\r
+ }\r
+ g.append("</table>\n");\r
+ g.append("<P><INPUT TYPE=\"SUBMIT\" NAME=\"SUBMIT\" VALUE=\""+\r
+ "Delete file from publishing space\"></FORM>\n");\r
+ g.close() ;\r
+ listing_stamp = getLastModified() ;\r
+ listing = g ;\r
+ } else if ( checkIfModifiedSince(request) == COND_FAILED ) {\r
+ // Is it an IMS request ?\r
+ return createDefaultReply(request, HTTP.NOT_MODIFIED) ;\r
+ }\r
+ } catch (InvalidResourceException ex) {\r
+ return createDefaultReply(request, HTTP.INTERNAL_SERVER_ERROR);\r
+ } finally {\r
+ getDirResourceRef().unlock();\r
+ }\r
+ // New content or need update:\r
+ Reply reply = createDefaultReply(request, HTTP.OK) ;\r
+ reply.setLastModified(listing_stamp) ;\r
+ reply.setStream(listing) ;\r
+ return reply ;\r
+ }\r
+\r
+ /**\r
+ * @exception org.w3c.tools.resources.ProtocolException \r
+ * if a protocol error occurs\r
+ * @exception org.w3c.tools.resources.ResourceException \r
+ * if a server error occurs\r
+ */\r
+ protected Reply getOtherResource (Request request) \r
+ throws ProtocolException, ResourceException \r
+ {\r
+ return getDirectoryListing(request);\r
+ }\r
+\r
+ /**\r
+ * Handle the form submission, after posted data parsing.\r
+ * <p>This method ought to be abstract, but for reasonable reason, it\r
+ * will just dump (parsed) the form content back to the client, so that it\r
+ * can be used for debugging.\r
+ * @param request The request proper.\r
+ * @param data The parsed data content.\r
+ * @exception ProtocolException If form data processing failed.\r
+ * @see org.w3c.jigsaw.forms.URLDecoder\r
+ */\r
+\r
+ public Reply handle (Request request, URLDecoder data)\r
+ throws ProtocolException\r
+ {\r
+ Reply r;\r
+ Enumeration e = data.keys() ;\r
+ while ( e.hasMoreElements () ) {\r
+ String name = (String) e.nextElement() ;\r
+ if (name.equals("SUBMIT"))\r
+ continue;\r
+ // delete file now... avoit deleting CVS and lister\r
+ // (should be in an attribute)\r
+ synchronized (this) {\r
+ DirectoryResource dr;\r
+ Resource toDeleteRes;\r
+ ResourceReference rr;\r
+ File dir, toDeleteFile;\r
+ try {\r
+ dr = (DirectoryResource) getDirResourceRef().lock();\r
+ dir = dr.getDirectory();\r
+ if (debug)\r
+ System.out.println("Deleting " + name);\r
+ rr = dr.lookup(name);\r
+ if (rr != null) {\r
+ try {\r
+ toDeleteFile = new File(dir, name);\r
+ toDeleteFile.delete();\r
+ } catch (Exception ex) {\r
+ // fancy message. file not present\r
+ // Or security manager forbiding deletion.\r
+ }\r
+ // and now, at least remove the resource\r
+ try {\r
+ toDeleteRes = (Resource) rr.lock();\r
+ toDeleteRes.delete();\r
+ } catch (Exception ex) {\r
+ // some other locks... or pb with the resource\r
+ } finally {\r
+ rr.unlock();\r
+ }\r
+ }\r
+ } catch (Exception ex) {\r
+ // some other locks... abort\r
+ } finally {\r
+ getDirResourceRef().unlock();\r
+ }\r
+ }\r
+ }\r
+ try {\r
+ r = getDirectoryListing(request);\r
+ } catch (ResourceException ex) {\r
+ r = createDefaultReply(request, HTTP.INTERNAL_SERVER_ERROR);\r
+ }\r
+ return r;\r
+ }\r
+}\r