168
|
Chapter 4, File Choosers
#32 Preview ZIP and JAR Files
HACK
Before you read any further, I want to warn you that this is
one of the longest and most complicated hacks in the book. I
don’t want to scare you away, but the code is pretty dense.
Of course, you wouldn’t expect any less from a hacks book,
right? What you will learn from this hack, however, will let
you build custom filesystem views for any type of data-
source, including FTP, WebDAV, or even SQL databases. I
think the complexity is worth it. Plus, you’ll learn more about
how the
File object really works and how to hack it to pieces.
Build File Proxies
The JFileChooser uses a FileSystemView to access the real filesystem. This
view, unfortunately, assumes the existence of actual
java.io.File objects.
There is no way to represent a filesystem without
Files, which wouldn’t be a
problem except that
File is a real class with many methods, not a simple
interface. Fortunately,
File is not declared final. You can override each
method with your own version to redirect the calls to another object, and
that’s exactly how this hack works. By creating proxies around the real ZIP
file objects, you can fool the
FileSystemView into working with items that
aren’t real files.
ZIP files are represented in the
java.util.zip package by a ZipFile object
that contains one
ZipEntry for each compressed file it contains. To show the
compressed files in the chooser, each
ZipEntry is wrapped inside of a
ZipEntryFileProxy, which extends the real File class. It contains a reference
to the
ZipEntry, the enclosing ZipFile, a path string, and the File object of
the actual ZIP file, as shown in Example 4-1.
Example 4-1. A ZIP file proxy
import java.util.zip.*;
public class ZipEntryFileProxy extends File {
ZipFileProxy zip;
ZipFile zipfile;
String name, path;
File parent;
ZipEntry entry;
public ZipEntryFileProxy(ZipFileProxy zip, ZipFile zipfile,
String path, File parent) {
super("");
this.zip = zip;
this.zipfile = zipfile;
this.path = path;
this.parent = parent;
this.entry = zipfile.getEntry(path);
Preview ZIP and JAR Files #32
Chapter 4, File Choosers
|
169
HACK
The constructor is pretty straightforward. It saves references to the passed-in
object and then does some calculations on the path. If the entry is a direc-
tory, then the path will end with a slash. The code chops off this trailing
slash, if present, and then looks for the name of the entry. Files inside of a
ZIP are stored as a list of complete pathnames with slashes, not as a tree of
objects like a real filesystem. Thus, the name of a file—what you would nor-
mally think of as its filename—is actually just the last part of a complete
path, including the parent directories. To parse this and get the real file-
name, the code looks for the last slash in the filename and pulls out the trail-
ing string.
The rest of the
ZipEntryFileProxy class overrides a portion of the standard
File methods. Each call returns a value based on the saved data from the
ZIP file, rather than the actual
File parent class:
public boolean exists( ) { return true; }
public int hashCode( ) {
return name.hashCode( ) ^ 1234321;
}
public String getName( ) { return name; }
public String getPath( ) { return path; }
public boolean isDirectory() { return entry.isDirectory( ); }
public boolean isAbsolute( ) { return true; }
public String getAbsolutePath( ) { return path; }
public File getAbsoluteFile( ) { return this; }
public File getCanonicalFile( ) { return this; }
public File getParentFile( ) { return parent; }
public boolean equals(Object obj) {
if(obj instanceof ZipEntryFileProxy) {
ZipEntryFileProxy zo = (ZipEntryFileProxy)obj;
// determine if the entry is a directory
String tmp = path;
if(entry.isDirectory( )) {
tmp = path.substring(0,path.length( )-1);
}
// then calculate the name
int brk = tmp.lastIndexOf("/");
name = path;
if(brk != -1) {
name = tmp.substring(brk+1);
}
}
Example 4-1. A ZIP file proxy (continued)

Get Swing Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.