001: // ZipDirectoryResource.java
002: // $Id: ZipDirectoryResource.java,v 1.7 2002/06/26 17:54:06 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1998.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigsaw.zip;
007:
008: import java.util.zip.ZipEntry;
009: import java.util.zip.ZipFile;
010:
011: import java.util.Enumeration;
012: import java.util.Hashtable;
013:
014: import java.io.File;
015: import java.io.IOException;
016:
017: import org.w3c.util.EmptyEnumeration;
018:
019: import org.w3c.tools.resources.Attribute;
020: import org.w3c.tools.resources.AttributeHolder;
021: import org.w3c.tools.resources.AttributeRegistry;
022: import org.w3c.tools.resources.ContainerResource;
023: import org.w3c.tools.resources.DirectoryResource;
024: import org.w3c.tools.resources.FileAttribute;
025: import org.w3c.tools.resources.FramedResource;
026: import org.w3c.tools.resources.InvalidResourceException;
027: import org.w3c.tools.resources.RequestInterface;
028: import org.w3c.tools.resources.Resource;
029: import org.w3c.tools.resources.ResourceContext;
030: import org.w3c.tools.resources.ResourceReference;
031: import org.w3c.tools.resources.ResourceSpace;
032: import org.w3c.tools.resources.StringAttribute;
033:
034: import org.w3c.tools.resources.indexer.ResourceIndexer;
035:
036: /**
037: * @version $Revision: 1.7 $
038: * @author Benoît Mahé (bmahe@w3.org)
039: */
040: public class ZipDirectoryResource extends DirectoryResource {
041:
042: /**
043: * Attributes index - The filename attribute.
044: */
045: protected static int ATTR_ZIPFILE = -1;
046: /**
047: * Attribute index - The index for our entry path.
048: */
049: protected static int ATTR_ENTRYPATH = -1;
050:
051: static {
052: Attribute a = null;
053: Class cls = null;
054: // Get a pointer to our class.
055: try {
056: cls = Class
057: .forName("org.w3c.jigsaw.zip.ZipDirectoryResource");
058: } catch (Exception ex) {
059: ex.printStackTrace();
060: System.exit(1);
061: }
062: // The zip file attribute.
063: a = new FileAttribute("zipfile", null, Attribute.COMPUTED);
064: ATTR_ZIPFILE = AttributeRegistry.registerAttribute(cls, a);
065: // the entry path attribute
066: a = new StringAttribute("entrypath", null, Attribute.COMPUTED);
067: ATTR_ENTRYPATH = AttributeRegistry.registerAttribute(cls, a);
068: }
069:
070: protected Hashtable directories = new Hashtable(3);
071:
072: /**
073: * Get this zip file.
074: */
075: public synchronized File getZipFile() {
076: return (File) getValue(ATTR_ZIPFILE, getDirectory());
077: }
078:
079: public String getEntryPath() {
080: return getString(ATTR_ENTRYPATH, null);
081: }
082:
083: /**
084: * Enumerate all available children resource identifiers.
085: * This method <em>requires</em> that we create all our pending resources.
086: * @return An enumeration of all our resources.
087: */
088: protected synchronized Enumeration enumerateAllResourceIdentifiers() {
089: return enumerateResourceIdentifiers(true);
090: }
091:
092: /**
093: * Reindex recursivly all the resources from this DirectoryResource.
094: */
095: public synchronized void reindex() {
096: //no reindex here
097: }
098:
099: /**
100: * Initialize and register a new resource into this directory.
101: * @param resource The uninitialized resource to be added.
102: */
103: protected ResourceContext updateDefaultChildAttributes(
104: Hashtable attrs) {
105: //fixme
106: attrs.put("zipfile", getZipFile());
107: String entrypath = null;
108: if (getEntryPath() != null) {
109: entrypath = getEntryPath() + "/" + ((String) attrs.get(id));
110: } else {
111: entrypath = (String) attrs.get(id);
112: }
113: attrs.put("entrypath", entrypath);
114: return super .updateDefaultChildAttributes(attrs);
115: }
116:
117: /**
118: * Enumerate all available children resource identifiers.
119: * This method <em>requires</em> that we create all our pending resources
120: * if we are in the extensible mode...too bad !
121: * @return An enumeration of all our resources.
122: */
123: public synchronized Enumeration enumerateResourceIdentifiers(
124: boolean all) {
125: File zipfile = getZipFile();
126: ZipFile zip = null;
127: Hashtable lookuped = new Hashtable(20);
128: try {
129: zip = new ZipFile(zipfile);
130: } catch (Exception ex) {
131: return new EmptyEnumeration();
132: }
133: Enumeration entries = zip.entries();
134: ZipEntry entry = null;
135: String entry_name = null;
136: int idx = -1;
137: String entry_path = getEntryPath();
138: if (entry_path == null) {
139: while (entries.hasMoreElements()) {
140: entry = (ZipEntry) entries.nextElement();
141: entry_name = entry.getName();
142: idx = entry_name.indexOf('/');
143: if (idx != -1) {
144: entry_name = entry_name.substring(0, idx);
145: directories.put(entry_name, Boolean.TRUE);
146: }
147: if (lookuped.get(entry_name) != null)
148: continue;
149: lookuped.put(entry_name, Boolean.TRUE);
150: if (lookup(entry_name) == null) {
151: createDefaultResource(entry_name);
152: }
153: }
154: } else {
155: int startidx = entry_path.length();
156: while (entries.hasMoreElements()) {
157: entry = (ZipEntry) entries.nextElement();
158: entry_name = entry.getName();
159: if (!entry_name.startsWith(entry_path))
160: continue;
161: // +1 remove "/"
162: if (entry_name.length() > startidx + 1)
163: entry_name = entry_name.substring(startidx + 1);
164: else
165: continue;
166: idx = entry_name.indexOf('/');
167: if (idx != -1) {
168: entry_name = entry_name.substring(0, idx);
169: if (entry_name.length() == 0)
170: continue;
171: directories.put(entry_name, Boolean.TRUE);
172: }
173: if (lookuped.get(entry_name) != null)
174: continue;
175: lookuped.put(entry_name, Boolean.TRUE);
176: if (lookup(entry_name) == null) {
177: createDefaultResource(entry_name);
178: }
179: }
180: }
181: try {
182: zip.close();
183: } catch (Exception ex) {
184: }
185: ResourceSpace space = getSpace();
186: acquireChildren();
187: return space
188: .enumerateResourceIdentifiers(getChildrenSpaceEntry());
189: }
190:
191: protected boolean entryExists(String name) {
192: File zipfile = getZipFile();
193: ZipFile zip = null;
194: try {
195: zip = new ZipFile(zipfile);
196: } catch (Exception ex) {
197: ex.printStackTrace();
198: return false;
199: }
200: String entry_path = getEntryPath();
201: String full_path = null;
202: if (entry_path != null) {
203: if (entry_path.endsWith("/"))
204: full_path = entry_path + name;
205: else
206: full_path = entry_path + "/" + name;
207: } else {
208: full_path = name;
209: }
210:
211: try {
212: return ((zip.getEntry(full_path) != null) || (zip
213: .getEntry(full_path + "/") != null));
214: } finally {
215: try {
216: zip.close();
217: } catch (Exception ex) {
218: }
219: }
220: }
221:
222: /**
223: * Index a Resource. Call the indexer.
224: * @param name The name of the resource to index.
225: * @param defs The defaults attributes.
226: * @param req The protocol request.
227: * @return A resource instance.
228: * @see org.w3c.tools.resources.indexer.SampleResourceIndexer
229: */
230: protected Resource index(String name, Hashtable defs,
231: RequestInterface req) {
232: if (!entryExists(name))
233: return null;
234: // Prepare a set of default parameters for the resource:
235: defs.put(id, name);
236: updateDefaultChildAttributes(defs);
237: ResourceContext context = getContext();
238: // Try to get the indexer to create the resource:
239: Resource resource = null;
240: ResourceReference rr_indexer = null;
241: ResourceReference rr_lastidx = null;
242: while (context != null) {
243: // Lookup for next indexer in hierarchy:
244: do {
245: rr_indexer = getIndexer(context);
246: context = context.getParent();
247: } while ((rr_indexer == rr_lastidx) && (context != null));
248: // Is this a usefull indexer ?
249: if ((rr_lastidx = rr_indexer) != null) {
250: try {
251: ResourceIndexer indexer = (ResourceIndexer) rr_indexer
252: .lock();
253: if (!(indexer instanceof ZipIndexer))
254: return null;
255: ZipIndexer zindexer = (ZipIndexer) indexer;
256: if (directories.get(name) != null) {
257: resource = zindexer.createDirectoryResource(
258: getDirectory(), name, defs);
259: } else {
260: resource = zindexer.createFileResource(
261: getDirectory(), name, defs);
262: }
263: if (resource != null)
264: break;
265: } catch (InvalidResourceException ex) {
266: resource = null;
267: } finally {
268: rr_indexer.unlock();
269: }
270: }
271: }
272: return resource;
273: }
274:
275: /**
276: * Create a Resource and the physical file too.
277: * @param name the name of the resource.
278: * @return A ResourceReference instance.
279: */
280: public ResourceReference createResource(String name) {
281: return null;
282: }
283:
284: /**
285: * Create a DirectoryResource and the physical directory too.
286: * @param name the name of the resource.
287: * @return A ResourceReference instance.
288: */
289: public ResourceReference createDirectoryResource(String name) {
290: return null;
291: }
292:
293: public void initialize(Object values[]) {
294: super .initialize(values);
295: disableEvent();
296: if (getZipFile() != null)
297: setValue(ATTR_DIRECTORY, getZipFile());
298: enableEvent();
299: }
300:
301: public synchronized boolean hasEntry() {
302: ZipFile z = null;
303: try {
304: z = new ZipFile(getZipFile());
305: return (z.getEntry(getEntryPath()) != null);
306: } catch (IOException ex) {
307: return false;
308: } finally {
309: try {
310: z.close();
311: } catch (Exception ex) {
312: }
313: }
314: }
315:
316: }
|