--- /dev/null
+// ZipFrame.java\r
+// $Id: ZipFrame.java,v 1.2 2010/06/15 17:53:04 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.jigsaw.zip;\r
+\r
+import java.util.Vector;\r
+import java.util.Enumeration;\r
+import java.io.InputStream;\r
+import java.io.File;\r
+import java.net.URLEncoder;\r
+import org.w3c.tools.sorter.Sorter;\r
+import org.w3c.tools.resources.FramedResource;\r
+import org.w3c.tools.resources.FileResource;\r
+import org.w3c.tools.resources.ContainerInterface;\r
+import org.w3c.tools.resources.ContainerResource;\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.ResourceException;\r
+import org.w3c.jigsaw.frames.HTTPFrame;\r
+import org.w3c.jigsaw.http.HTTPException;\r
+import org.w3c.jigsaw.http.Reply;\r
+import org.w3c.jigsaw.http.Request;\r
+import org.w3c.www.http.HTTP;\r
+import org.w3c.jigsaw.html.HtmlGenerator;\r
+import org.w3c.tools.resources.ResourceReference;\r
+import org.w3c.tools.resources.InvalidResourceException;\r
+import org.w3c.tools.resources.MultipleLockException;\r
+\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.ResourceException;\r
+\r
+/**\r
+ * @version $Revision: 1.2 $\r
+ * @author Benoît Mahé (bmahe@w3.org)\r
+ */\r
+public class ZipFrame extends HTTPFrame {\r
+\r
+ protected ZipFileResource zipfresource = null;\r
+\r
+ public void registerResource(FramedResource resource) {\r
+ super.registerResource(resource);\r
+ if (resource instanceof ZipFileResource)\r
+ zipfresource = (ZipFileResource) resource;\r
+ }\r
+\r
+ /**\r
+ * Create the reply relative to the given file.\r
+ * @param request the incomming request.\r
+ * @return A Reply instance\r
+ * @exception org.w3c.tools.resources.ProtocolException if processing \r
+ * the request failed.\r
+ * @exception org.w3c.tools.resources.ResourceException if the resource\r
+ * got a fatal error.\r
+ */\r
+ protected Reply createFileReply(Request request) \r
+ throws ProtocolException, ResourceException\r
+ {\r
+ Reply reply = null;\r
+ if (zipfresource == null) {\r
+ throw new ResourceException("this frame is not attached to a "+\r
+ "ZipFileResource. ("+\r
+ resource.getIdentifier()+")");\r
+ }\r
+ // Default to full reply:\r
+ reply = createDefaultReply(request, HTTP.OK) ;\r
+ InputStream in = zipfresource.getInputStream();\r
+ if (in != null)\r
+ reply.setStream(in);\r
+ return reply ;\r
+ }\r
+\r
+ /**\r
+ * Get for FileResource\r
+ * @param request the incomming request.\r
+ * @return A Reply instance\r
+ * @exception ProtocolException If processsing the request failed.\r
+ * @exception ResourceException If the resource got a fatal error.\r
+ */\r
+ protected Reply getFileResource(Request request) \r
+ throws ProtocolException, ResourceException\r
+ {\r
+ if (fresource == null) \r
+ throw new ResourceException("this frame is not attached to a "+\r
+ "FileResource. ("+\r
+ resource.getIdentifier()+")");\r
+ Reply reply = null;\r
+ File file = fresource.getFile() ;\r
+ fresource.checkContent();\r
+ updateCachedHeaders();\r
+ // Check validators:\r
+ int cim = checkIfMatch(request);\r
+ if ((cim == COND_FAILED) || (cim == COND_WEAK)) {\r
+ reply = request.makeReply(HTTP.PRECONDITION_FAILED);\r
+ reply.setContent("Pre-conditions failed.");\r
+ reply.setContentMD5(null);\r
+ return reply;\r
+ }\r
+ if ( checkIfUnmodifiedSince(request) == COND_FAILED ) {\r
+ reply = request.makeReply(HTTP.PRECONDITION_FAILED);\r
+ reply.setContent("Pre-conditions failed.");\r
+ reply.setContentMD5(null);\r
+ return reply;\r
+ }\r
+ if ( checkValidators(request) == COND_FAILED) {\r
+ return createDefaultReply(request, HTTP.NOT_MODIFIED);\r
+ } \r
+ // Does this file really exists, if so send it back\r
+ if ( zipfresource.hasEntry()) {\r
+ reply = createFileReply(request);\r
+ if (request.hasState(STATE_CONTENT_LOCATION))\r
+ reply.setContentLocation(getURL(request).toExternalForm());\r
+ return reply;\r
+ } else {\r
+ return deleteMe(request);\r
+ }\r
+ }\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ /**\r
+ * Get ContainerResource listing\r
+ * @param refresh should we refresh the listing?\r
+ * @return a boolean (true if refreshed)\r
+ */ \r
+ public synchronized boolean computeContainerListing(boolean refresh) {\r
+ ContainerResource cresource = (ContainerResource)resource;\r
+ if ((refresh) ||\r
+ (listing == null) || \r
+ (cresource.getLastModified() > listing_stamp) || \r
+ (getLastModified() > listing_stamp)) {\r
+ \r
+ Class http_class = null;\r
+ try {\r
+ http_class = Class.forName("org.w3c.jigsaw.frames.HTTPFrame");\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ } catch (ClassNotFoundException ex) {\r
+ http_class = null;\r
+ }\r
+\r
+ Enumeration e = cresource.enumerateResourceIdentifiers();\r
+ Vector resources = Sorter.sortStringEnumeration(e) ;\r
+ HtmlGenerator g = \r
+ new HtmlGenerator("Index of "+cresource.getIdentifier());\r
+ // Add style link\r
+ addStyleSheet(g);\r
+ g.append("<h1>"+cresource.getIdentifier()+"</h1>");\r
+ // Link to the parent, when possible:\r
+ if ( cresource.getParent() != null ) {\r
+ g.append("<p><a href=\"..\">Parent</a><br>");\r
+ }\r
+ // List the children:\r
+ for (int i = 0 ; i < resources.size() ; i++) {\r
+ String name = (String) resources.elementAt(i);\r
+ ResourceReference rr = null;\r
+ long size = -1;\r
+ rr = cresource.lookup(name);\r
+ FramedResource resource = null;\r
+ if (rr != null) {\r
+ try {\r
+ resource = (FramedResource) rr.lock();\r
+ // remove manually deleted FileResources\r
+ if( resource instanceof ZipFileResource ) {\r
+ ZipFileResource zfr = (ZipFileResource)resource;\r
+ if( ! zfr.hasEntry() ) {\r
+ try {\r
+ zfr.delete();\r
+ } catch (MultipleLockException ex) {};\r
+ continue;\r
+ } else {\r
+ size = zfr.getEntrySize();\r
+ }\r
+ }\r
+ // remove manually deleted DirectoryResources\r
+ if( resource instanceof ZipDirectoryResource ) {\r
+ ZipDirectoryResource zdr = (ZipDirectoryResource)resource;\r
+ if( ! zdr.hasEntry() ) {\r
+ try {\r
+ zdr.delete();\r
+ } catch (MultipleLockException ex) {};\r
+ continue;\r
+ }\r
+ }\r
+ HTTPFrame itsframe = null;\r
+ if (http_class != null) {\r
+ itsframe = \r
+ (HTTPFrame) resource.getFrame(http_class); \r
+ }\r
+ if (itsframe != null) {\r
+ // Icon first, if available\r
+ String icon = itsframe.getIcon() ;\r
+ if ( icon != null ) \r
+ g.append("<img src=\""+\r
+ getIconDirectory() +"/" + icon+\r
+ "\" alt=\"" + icon + "\">");\r
+ // Resource's name with link:\r
+ if (resource instanceof ContainerInterface)\r
+ g.append("<a href=\"" \r
+ , URLEncoder.encode(name)\r
+ , "/\">"+name+"</a>");\r
+ else\r
+ g.append("<a href=\"" \r
+ , URLEncoder.encode(name)\r
+ , "\">"+name+"</a>");\r
+ // resource's title, if any:\r
+ String title = itsframe.getTitle();\r
+ if ( title != null )\r
+ g.append(" "+title);\r
+ //size (if any)\r
+ if (size != -1) {\r
+ String s = null;\r
+ if (size > 1023) {\r
+ s = " ["+(size/1024)+" Kb]";\r
+ } else {\r
+ s = " ["+size+" bytes]";\r
+ }\r
+ g.append(s);\r
+ }\r
+ g.append("<br>\n");\r
+ } else {\r
+ // Resource's name with link:\r
+ g.append(name+" (<i>Not available via HTTP.</i>)");\r
+ g.append("<br>\n");\r
+ }\r
+ } catch (InvalidResourceException ex) {\r
+ g.append(name+\r
+ " cannot be loaded (server misconfigured)");\r
+ g.append("<br>\n");\r
+ continue;\r
+ } finally { \r
+ rr.unlock();\r
+ }\r
+ }\r
+ }\r
+ g.close() ;\r
+ listing_stamp = getLastModified() ;\r
+ listing = g ;\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+\r
+ \r
+\r
+ /**\r
+ * The default PUT method replies with a not implemented.\r
+ * @param request The request to handle.\r
+ * @exception ProtocolException Always thrown, to return a NOT_IMPLEMENTED\r
+ * error.\r
+ * @exception ResourceException If the resource got a fatal error.\r
+ */\r
+\r
+ public Reply put(Request request)\r
+ throws ProtocolException, ResourceException\r
+ {\r
+ Reply error = request.makeReply(HTTP.NOT_IMPLEMENTED) ;\r
+ error.setContent("Method PUT not implemented for zipped document") ;\r
+ throw new HTTPException (error) ;\r
+ }\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ \r
+}\r