/* * ZipInputStreamTree.java * * Created on March 15, 2001, 4:33 PM */ package org.freehep.demo.iconbrowser; import javax.swing.tree.*; import javax.swing.Icon; import javax.swing.ImageIcon; import java.util.*; import java.util.zip.*; import java.io.IOException; import java.io.InputStream; import java.io.File; import org.freehep.util.images.ImageHandler; /** * Build an IconArchive by reading a ZipFile * @author Tony Johnson (tonyj@slac.stanford.edu) * @version $Id: ZipInputStreamTree.java 10506 2007-01-30 22:48:57Z duns $ */ class ZipInputStreamTree extends DefaultMutableTreeNode { private Hashtable hash = new Hashtable(); private String name; ZipInputStreamTree(String name, ZipInputStream zip) throws IOException { super(new ZipArchive(name)); this.name = name; for (;;) { ZipEntry entry = zip.getNextEntry(); if (entry == null) break; String fullName = entry.getName(); DefaultMutableTreeNode parent = findParentNode(fullName); if (entry.isDirectory()) { DefaultMutableTreeNode node = new DefaultMutableTreeNode(new ZipDirectory(fullName)); hash.put(fullName,node); parent.add(node); } else { if (fullName.endsWith(".gif") || fullName.endsWith(".png") || fullName.endsWith(".jpg")) { Object dir = parent.getUserObject(); if (dir instanceof ZipDirectory) ((ZipDirectory) dir).addEntry(entry,zip); } } } // Trim empty nodes boolean changesWereMade = true; while (changesWereMade) { changesWereMade = false; for (DefaultMutableTreeNode node = getFirstLeaf(); node != null; ) { DefaultMutableTreeNode next = node.getNextLeaf(); if (node != this) { ZipDirectory dir = (ZipDirectory) node.getUserObject(); if (dir.getNEntries() == 0) { node.removeFromParent(); changesWereMade = true; } } node = next; } } hash = null; // not needed anymore } private DefaultMutableTreeNode findParentNode(String fullName) { String dirName = IconBrowser.dirName(fullName); if (dirName == null) return this; DefaultMutableTreeNode parent = (DefaultMutableTreeNode) hash.get(dirName); if (parent == null) { DefaultMutableTreeNode pp = findParentNode(dirName); parent = new DefaultMutableTreeNode(new ZipDirectory(dirName)); hash.put(dirName,parent); pp.add(parent); } return parent; } public String toString() { return IconBrowser.fileName(name,File.separator); } private static class ZipArchive extends ZipDirectory implements IconArchive { ZipArchive(String name) { super(name); } public void close() { } } private static class ZipDirectory implements IconDirectory { ZipDirectory(String name) { this.name = name; } public String getName() { return name; } void addEntry(ZipEntry entry, InputStream in) { entries.add(createIconFromZipEntry(entry,in)); } public String toString() { StringBuffer b = new StringBuffer(IconBrowser.fileName(name)); if (!entries.isEmpty()) { int n = entries.size(); b.append(" ("); b.append(n); if (n == 1) b.append(" entry)"); else b.append(" entries)"); } return b.toString(); } public int getNEntries() { return entries.size(); } public String getEntryName(int index) { ImageIcon e = (ImageIcon) entries.get(index); return e.getDescription(); } public Icon getEntryIcon(int index) { return (Icon) entries.get(index); } private Icon createIconFromZipEntry(ZipEntry entry, InputStream in) { try { int len = (int) entry.getSize(); if (len <= 0) len = 1000; byte[] data = new byte[len]; for (int off = 0;; ) { int l = in.read(data,off,len-off); if (l<0) break; if (l>0) off += l; else { len += 1000; byte[] newData = new byte[len]; System.arraycopy(data,0,newData,0,off); data = newData; } } return new ImageIcon(data,entry.getName()); } catch (IOException x) { return ImageHandler.brokenIcon; } } private String name; private java.util.List entries = new ArrayList(); } }