--- /dev/null
+// ZipDirectoryResource.java\r
+// $Id: ZipDirectoryResource.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.zip.ZipEntry;\r
+import java.util.zip.ZipFile;\r
+\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+\r
+import org.w3c.util.EmptyEnumeration;\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.ContainerResource;\r
+import org.w3c.tools.resources.DirectoryResource;\r
+import org.w3c.tools.resources.FileAttribute;\r
+import org.w3c.tools.resources.FramedResource;\r
+import org.w3c.tools.resources.InvalidResourceException;\r
+import org.w3c.tools.resources.RequestInterface;\r
+import org.w3c.tools.resources.Resource;\r
+import org.w3c.tools.resources.ResourceContext;\r
+import org.w3c.tools.resources.ResourceReference;\r
+import org.w3c.tools.resources.ResourceSpace;\r
+import org.w3c.tools.resources.StringAttribute;\r
+\r
+import org.w3c.tools.resources.indexer.ResourceIndexer;\r
+\r
+/**\r
+ * @version $Revision: 1.2 $\r
+ * @author Benoît Mahé (bmahe@w3.org)\r
+ */\r
+public class ZipDirectoryResource extends DirectoryResource {\r
+\r
+ /**\r
+ * Attributes index - The filename attribute.\r
+ */\r
+ protected static int ATTR_ZIPFILE = -1 ;\r
+ /**\r
+ * Attribute index - The index for our entry path.\r
+ */\r
+ protected static int ATTR_ENTRYPATH = -1 ;\r
+\r
+ static {\r
+ Attribute a = null ;\r
+ Class cls = null ;\r
+ // Get a pointer to our class.\r
+ try {\r
+ cls = Class.forName("org.w3c.jigsaw.zip.ZipDirectoryResource") ;\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace() ;\r
+ System.exit(1) ;\r
+ }\r
+ // The zip file attribute.\r
+ a = new FileAttribute("zipfile"\r
+ , null\r
+ , Attribute.COMPUTED) ;\r
+ ATTR_ZIPFILE = AttributeRegistry.registerAttribute(cls, a) ;\r
+ // the entry path attribute\r
+ a = new StringAttribute("entrypath"\r
+ , null\r
+ , Attribute.COMPUTED) ;\r
+ ATTR_ENTRYPATH = AttributeRegistry.registerAttribute(cls, a) ;\r
+ }\r
+\r
+ protected Hashtable directories = new Hashtable(3);\r
+\r
+ /**\r
+ * Get this zip file.\r
+ */\r
+ public synchronized File getZipFile() {\r
+ return (File) getValue(ATTR_ZIPFILE, getDirectory());\r
+ }\r
+\r
+\r
+ public String getEntryPath() {\r
+ return getString(ATTR_ENTRYPATH, null);\r
+ }\r
+\r
+ /**\r
+ * Enumerate all available children resource identifiers. \r
+ * This method <em>requires</em> that we create all our pending resources.\r
+ * @return An enumeration of all our resources.\r
+ */\r
+ protected synchronized Enumeration enumerateAllResourceIdentifiers() {\r
+ return enumerateResourceIdentifiers(true);\r
+ }\r
+\r
+ /**\r
+ * Reindex recursivly all the resources from this DirectoryResource.\r
+ */\r
+ public synchronized void reindex() {\r
+ //no reindex here\r
+ }\r
+\r
+ /**\r
+ * Initialize and register a new resource into this directory.\r
+ * @param resource The uninitialized resource to be added.\r
+ */\r
+ protected ResourceContext updateDefaultChildAttributes(Hashtable attrs) {\r
+ //fixme\r
+ attrs.put("zipfile", getZipFile());\r
+ String entrypath = null;\r
+ if (getEntryPath() != null) {\r
+ entrypath = getEntryPath()+"/"+((String) attrs.get(id));\r
+ } else {\r
+ entrypath = (String) attrs.get(id);\r
+ }\r
+ attrs.put("entrypath", entrypath);\r
+ return super.updateDefaultChildAttributes(attrs);\r
+ }\r
+\r
+ /**\r
+ * Enumerate all available children resource identifiers. \r
+ * This method <em>requires</em> that we create all our pending resources\r
+ * if we are in the extensible mode...too bad !\r
+ * @return An enumeration of all our resources.\r
+ */\r
+ public synchronized Enumeration enumerateResourceIdentifiers(boolean all) {\r
+ File zipfile = getZipFile();\r
+ ZipFile zip = null;\r
+ Hashtable lookuped = new Hashtable(20);\r
+ try {\r
+ zip = new ZipFile(zipfile);\r
+ } catch (Exception ex) {\r
+ return new EmptyEnumeration();\r
+ }\r
+ Enumeration entries = zip.entries();\r
+ ZipEntry entry = null;\r
+ String entry_name = null;\r
+ int idx = -1;\r
+ String entry_path = getEntryPath();\r
+ if (entry_path == null) {\r
+ while (entries.hasMoreElements()) {\r
+ entry = (ZipEntry) entries.nextElement();\r
+ entry_name = entry.getName();\r
+ idx = entry_name.indexOf('/');\r
+ if (idx != -1) {\r
+ entry_name = entry_name.substring(0,idx);\r
+ directories.put(entry_name, Boolean.TRUE);\r
+ }\r
+ if (lookuped.get(entry_name) != null)\r
+ continue;\r
+ lookuped.put(entry_name, Boolean.TRUE);\r
+ if (lookup(entry_name) == null) {\r
+ createDefaultResource(entry_name);\r
+ }\r
+ }\r
+ } else {\r
+ int startidx = entry_path.length();\r
+ while (entries.hasMoreElements()) {\r
+ entry = (ZipEntry) entries.nextElement();\r
+ entry_name = entry.getName();\r
+ if (! entry_name.startsWith(entry_path))\r
+ continue;\r
+ // +1 remove "/"\r
+ if (entry_name.length() > startidx+1)\r
+ entry_name = entry_name.substring(startidx+1);\r
+ else continue;\r
+ idx = entry_name.indexOf('/');\r
+ if (idx != -1) {\r
+ entry_name = entry_name.substring(0,idx);\r
+ if (entry_name.length() == 0)\r
+ continue;\r
+ directories.put(entry_name, Boolean.TRUE);\r
+ } \r
+ if (lookuped.get(entry_name) != null)\r
+ continue;\r
+ lookuped.put(entry_name, Boolean.TRUE);\r
+ if (lookup(entry_name) == null) {\r
+ createDefaultResource(entry_name);\r
+ }\r
+ }\r
+ }\r
+ try { zip.close(); } catch (Exception ex) {}\r
+ ResourceSpace space = getSpace();\r
+ acquireChildren();\r
+ return space.enumerateResourceIdentifiers( getChildrenSpaceEntry() );\r
+ }\r
+\r
+ protected boolean entryExists(String name) {\r
+ File zipfile = getZipFile();\r
+ ZipFile zip = null;\r
+ try {\r
+ zip = new ZipFile(zipfile);\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ return false;\r
+ }\r
+ String entry_path = getEntryPath();\r
+ String full_path = null;\r
+ if (entry_path != null) {\r
+ if (entry_path.endsWith("/"))\r
+ full_path = entry_path + name;\r
+ else\r
+ full_path = entry_path + "/" + name;\r
+ } else {\r
+ full_path = name;\r
+ }\r
+\r
+ try {\r
+ return ((zip.getEntry(full_path) != null) ||\r
+ (zip.getEntry(full_path+"/") != null));\r
+ } finally {\r
+ try { zip.close(); } catch (Exception ex) {}\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Index a Resource. Call the indexer.\r
+ * @param name The name of the resource to index.\r
+ * @param defs The defaults attributes.\r
+ * @param req The protocol request.\r
+ * @return A resource instance.\r
+ * @see org.w3c.tools.resources.indexer.SampleResourceIndexer\r
+ */\r
+ protected Resource index(String name, \r
+ Hashtable defs, \r
+ RequestInterface req) \r
+ {\r
+ if (! entryExists(name))\r
+ return null;\r
+ // Prepare a set of default parameters for the resource:\r
+ defs.put(id, name);\r
+ updateDefaultChildAttributes(defs);\r
+ ResourceContext context = getContext();\r
+ // Try to get the indexer to create the resource:\r
+ Resource resource = null;\r
+ ResourceReference rr_indexer = null;\r
+ ResourceReference rr_lastidx = null;\r
+ while ( context != null ) {\r
+ // Lookup for next indexer in hierarchy:\r
+ do {\r
+ rr_indexer = getIndexer(context);\r
+ context = context.getParent();\r
+ } while ((rr_indexer == rr_lastidx) && (context != null));\r
+ // Is this a usefull indexer ?\r
+ if ((rr_lastidx = rr_indexer) != null ) {\r
+ try {\r
+ ResourceIndexer indexer = \r
+ (ResourceIndexer)rr_indexer.lock();\r
+ if (! (indexer instanceof ZipIndexer))\r
+ return null;\r
+ ZipIndexer zindexer = (ZipIndexer) indexer;\r
+ if (directories.get(name) != null) {\r
+ resource = \r
+ zindexer.createDirectoryResource(getDirectory(),\r
+ name,\r
+ defs);\r
+ } else {\r
+ resource = zindexer.createFileResource(getDirectory(),\r
+ name,\r
+ defs);\r
+ }\r
+ if ( resource != null ) \r
+ break;\r
+ } catch (InvalidResourceException ex) {\r
+ resource = null;\r
+ } finally {\r
+ rr_indexer.unlock();\r
+ }\r
+ }\r
+ }\r
+ return resource;\r
+ }\r
+\r
+ /**\r
+ * Create a Resource and the physical file too.\r
+ * @param name the name of the resource.\r
+ * @return A ResourceReference instance.\r
+ */\r
+ public ResourceReference createResource(String name) {\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Create a DirectoryResource and the physical directory too.\r
+ * @param name the name of the resource.\r
+ * @return A ResourceReference instance.\r
+ */\r
+ public ResourceReference createDirectoryResource(String name) {\r
+ return null;\r
+ }\r
+\r
+ public void initialize(Object values[]) {\r
+ super.initialize(values);\r
+ disableEvent();\r
+ if (getZipFile() != null)\r
+ setValue(ATTR_DIRECTORY, getZipFile()) ;\r
+ enableEvent();\r
+ }\r
+\r
+\r
+\r
+public synchronized boolean hasEntry() {\r
+ ZipFile z = null;\r
+ try {\r
+ z = new ZipFile(getZipFile());\r
+ return (z.getEntry(getEntryPath()) != null);\r
+ } catch (IOException ex) {\r
+ return false;\r
+ } finally {\r
+ try { z.close(); } catch (Exception ex) {}\r
+ }\r
+ }\r
+\r
+\r
+}\r