diff options
Diffstat (limited to 'libjava/gnu/gcj/util/path')
-rw-r--r-- | libjava/gnu/gcj/util/path/CacheEntry.java | 65 | ||||
-rw-r--r-- | libjava/gnu/gcj/util/path/DirectoryPathEntry.java | 136 | ||||
-rw-r--r-- | libjava/gnu/gcj/util/path/PathEntry.java | 55 | ||||
-rw-r--r-- | libjava/gnu/gcj/util/path/SearchPath.java | 205 | ||||
-rw-r--r-- | libjava/gnu/gcj/util/path/URLPathEntry.java | 67 | ||||
-rw-r--r-- | libjava/gnu/gcj/util/path/ZipPathEntry.java | 86 |
6 files changed, 614 insertions, 0 deletions
diff --git a/libjava/gnu/gcj/util/path/CacheEntry.java b/libjava/gnu/gcj/util/path/CacheEntry.java new file mode 100644 index 00000000000..949200b7a29 --- /dev/null +++ b/libjava/gnu/gcj/util/path/CacheEntry.java @@ -0,0 +1,65 @@ +// CacheEntry.java -- directory cache + +/* Copyright (C) 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +/* Author: Kresten Krab Thorup <krab@gnu.org> */ + +package gnu.gcj.util.path; + +import java.util.*; +import java.util.zip.*; +import java.io.*; +import java.net.*; + + +final class CacheEntry { + String dir; + String[] files; + long time; + + CacheEntry (String d) + { + dir = d; + files = new File(dir).list(); + time = System.currentTimeMillis (); + } + + void touch () + { + time = System.currentTimeMillis (); + } + + final long EXPIRATION_TIME_MS = 1000; + + boolean is_old () { + return (System.currentTimeMillis () - time) > EXPIRATION_TIME_MS; + } + + public int hashCode () { return dir.hashCode(); } + boolean contains (String file) { + if (files == null) + return false; + + int index = file.lastIndexOf(SearchPath.file_seperator_char); + String f; + + if (index == -1) + f = file; + else + f = file.substring (index+1); + + for (int i = 0; i < files.length; i++) + { + if (f.equals (files[i])) return true; + } + + return false; + } +} + diff --git a/libjava/gnu/gcj/util/path/DirectoryPathEntry.java b/libjava/gnu/gcj/util/path/DirectoryPathEntry.java new file mode 100644 index 00000000000..a9ca602341b --- /dev/null +++ b/libjava/gnu/gcj/util/path/DirectoryPathEntry.java @@ -0,0 +1,136 @@ +// DirectoryPathEntry.java -- search path element for directories + +/* Copyright (C) 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +/* Author: Kresten Krab Thorup <krab@gnu.org> */ + +package gnu.gcj.util.path; + +import java.util.*; +import java.util.zip.*; +import java.io.*; +import java.net.*; + +final class DirectoryPathEntry extends PathEntry +{ + final File dir; + final String base_canon; + + public String toString () { return base_canon; } + + DirectoryPathEntry (File f) + throws java.io.IOException + { + if (!f.isAbsolute ()) + throw new IllegalArgumentException (); + + dir = f; + base_canon = dir.getCanonicalPath (); + } + + /* + * We maintain a cache of files, so that we + * can avoid many calls to stat(), which are + * very expensive. + * + * seen_cache contains (as keys) the directories + * which we have visited so far. The values are + * instances of CacheEntry, containing a time stamp, + * and a list of files in that directory. + * + */ + + private Hashtable seen_cache = new Hashtable (); + + private boolean in_cache (File f) + { + String rel_dir = f.getParent (); + CacheEntry ent; + + if (rel_dir == null) + throw new IllegalArgumentException (); + + ent = (CacheEntry) seen_cache.get (rel_dir); + if (ent == null) + { + ent = new CacheEntry (rel_dir); + seen_cache.put (rel_dir, ent); + } + + if (ent.contains (f.getPath ())) + { + return true; + } + + if ( ent.is_old () ) + { + if (f.exists ()) + { + seen_cache.remove (rel_dir); + return true; + } + else + { + ent.touch (); + } + } + + return false; + } + + URL getURL (String file) { + try { + File f = new File((new File (dir, file).getCanonicalPath ())); + + if (! f.getCanonicalPath ().startsWith (base_canon)) + throw new IllegalArgumentException (file); + + + if (in_cache (f)) + return new URL ("file", "", f.getPath ()); + else + return null; + + } catch (IOException x) { + return null; + } + } + + InputStream getStream (String file) { + try { + File f = new File((new File (dir, file)).getCanonicalPath ()); + + if (! f.getCanonicalPath ().startsWith (base_canon)) + throw new IllegalArgumentException (file); + + if (in_cache (f)) + return new FileInputStream (f); + else + return null; + } catch (IOException x) { + return null; + } + } + + byte[] getBytes (String file) { + File f = new File (dir, file); + + try { + if (in_cache (f)) + return readbytes (new FileInputStream (f), + (int) f.length ()); + else + return null; + } catch (IOException x) { + return null; + } + } + +} + diff --git a/libjava/gnu/gcj/util/path/PathEntry.java b/libjava/gnu/gcj/util/path/PathEntry.java new file mode 100644 index 00000000000..f83fc170170 --- /dev/null +++ b/libjava/gnu/gcj/util/path/PathEntry.java @@ -0,0 +1,55 @@ +// PathEntry.java -- abstract element of search paths + +/* Copyright (C) 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +/* Author: Kresten Krab Thorup <krab@gnu.org> */ + +package gnu.gcj.util.path; + +import java.util.*; +import java.util.zip.*; +import java.io.*; +import java.net.*; + +abstract class PathEntry { + abstract URL getURL (String file); + abstract InputStream getStream (String file); + abstract byte[] getBytes (String file); + + /** + * Utility routine like InputStream.read(byte[], 0, len), but will + * read fully, even if all the data is not available at once. + */ + protected static byte[] readbytes (InputStream is, int length) + { + try { + + byte[] data = new byte[length]; + int read; + int off = 0; + + while (off != length) + { + read = is.read (data, off, (int) (length-off)); + + if (read == -1) + return null; + + off += read; + } + + return data; + } catch (IOException x) { + return null; + } + } + +} + + diff --git a/libjava/gnu/gcj/util/path/SearchPath.java b/libjava/gnu/gcj/util/path/SearchPath.java new file mode 100644 index 00000000000..ffc2ca8d178 --- /dev/null +++ b/libjava/gnu/gcj/util/path/SearchPath.java @@ -0,0 +1,205 @@ +// SearchPath.java -- generic search path utility + +/* Copyright (C) 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +/* Author: Kresten Krab Thorup <krab@gnu.org> */ + + +package gnu.gcj.util.path; + +import java.util.*; +import java.util.zip.*; +import java.io.*; +import java.net.*; + +final public class SearchPath { + + final static String path_seperator + = System.getProperty ("path.separator"); + final static char path_seperator_char + = path_seperator.charAt (0); + final static String file_seperator + = System.getProperty ("file.separator"); + final static char file_seperator_char + = file_seperator.charAt (0); + + private Vector path; + + /** + * Constructs a SearchPath object, given a system path. + * The system path is expected to be seperated by the string + * defined by the <code>path.seperator</code> property. + * (<code>":"</code> on unix, <code>;</code> on Windows, etc.). + * The path may contain names of directories, or names of + * .zip or .jar files. Elements that are neither of these + * are ignored. + * @param sys_path the search path + */ + + SearchPath (String sys_path) + { + StringTokenizer st = new StringTokenizer (sys_path, path_seperator); + init (st); + } + + /** + * Constructs a SearchPath object, given a Vector of + * <code>String</code>, <code>File</code> or <code>URL</code> + * objects. + * The path may contain names of directories, or names of + * .zip or .jar files. Elements that are neither of these + * are ignored. + * @param p the vector of search path elements + */ + + SearchPath (Vector p) + { + init (p.elements ()); + } + + public URL getURL (String element) + { + URL result; + + Enumeration e = path.elements (); + while (e.hasMoreElements ()) + { + PathEntry ent = (PathEntry) e.nextElement (); + + result = ent.getURL (element); + + if (result != null) + { + return result; + } + } + + return null; + } + + + public InputStream getStream (String element) + { + InputStream result; + + Enumeration e = path.elements (); + while (e.hasMoreElements ()) + { + PathEntry ent = (PathEntry) e.nextElement (); + + result = ent.getStream (element); + + if (result != null) + { + return result; + } + } + + return null; + } + + + public byte[] getBytes (String element) + { + byte[] result; + + Enumeration e = path.elements (); + while (e.hasMoreElements ()) + { + PathEntry ent = (PathEntry) e.nextElement (); + result = ent.getBytes (element); + if (result != null) + { + System.out.println ("loading " + ent + + "(" + element + ")"); + return result; + } + } + + return null; + } + + + + private void init (Enumeration st) + { + path = new Vector (); + while (st.hasMoreElements ()) + { + Object e = st.nextElement (); + + String elem; + File efile; + + if (e instanceof URL) + { + path.addElement (new URLPathEntry ((URL) e)); + continue; + } + + if (e instanceof File) + { + efile = (File) e; + elem = efile.getPath (); + } + + else if (e instanceof String) + { + elem = (String) e; + efile = new File (elem); + } + + else + throw new IllegalArgumentException (); + + // make sure it is absolute, so we won't get + // trouble if the cwd is changed... + if (! efile.isAbsolute ()) + efile = new File (efile.getAbsolutePath ()); + + if (efile.isDirectory ()) + { + try { + path.addElement(new DirectoryPathEntry (efile)); + } catch (IOException x) { + /* ignore for now */ + } + } + + else if (efile.isFile ()) + { + int ext = elem.lastIndexOf ('.'); + if (ext == -1) + continue; + + if (!elem.substring(ext+1).equalsIgnoreCase("zip")) + continue; + + ZipPathEntry zpe = null; + try { + zpe = new ZipPathEntry (efile); + } catch (ZipException zx) { + System.err.println ("SearchPath::ZipException"); + zpe = null; + } catch (MalformedURLException mx) { + System.err.println ("SearchPath::URLException"); + zpe = null; + } catch (IOException iox) { + System.err.println ("SearchPath::IOException"); + zpe = null; + } + if (zpe != null) path.addElement (zpe); + } + } + + } + + +} + diff --git a/libjava/gnu/gcj/util/path/URLPathEntry.java b/libjava/gnu/gcj/util/path/URLPathEntry.java new file mode 100644 index 00000000000..68f9200b555 --- /dev/null +++ b/libjava/gnu/gcj/util/path/URLPathEntry.java @@ -0,0 +1,67 @@ +// URLPathEntry.java -- search path element for URL's + +/* Copyright (C) 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +/* Author: Kresten Krab Thorup <krab@gnu.org> */ + +package gnu.gcj.util.path; + +import java.util.*; +import java.util.zip.*; +import java.io.*; +import java.net.*; + +final class URLPathEntry extends PathEntry { + final URL base; + + URLPathEntry (URL f) { + base = f; + } + + public String toString () { return base.toString (); } + + URL getURL (String file) { + + try { + URL res = new URL (base, file); + InputStream is = res.openStream (); // exc if not found + is.close (); + return res; + } catch (java.io.IOException x) { + return null; + } + } + + InputStream getStream (String file) { + + try { + URL res = new URL (base, file); + return res.openStream (); + } catch (java.io.IOException x) { + return null; + } + + } + + byte[] getBytes (String file) { + + try { + URL res = new URL (base, file); + URLConnection conn = res.openConnection (); + int len = conn.getContentLength (); + if (len == -1) return null; + return readbytes (conn.getInputStream (), len); + } catch (java.io.IOException x) { + return null; + } + + } + +} + diff --git a/libjava/gnu/gcj/util/path/ZipPathEntry.java b/libjava/gnu/gcj/util/path/ZipPathEntry.java new file mode 100644 index 00000000000..ac0226290a5 --- /dev/null +++ b/libjava/gnu/gcj/util/path/ZipPathEntry.java @@ -0,0 +1,86 @@ +// ZipPathEntry.java -- search path element for directories + +/* Copyright (C) 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +/* Author: Kresten Krab Thorup <krab@gnu.org> */ + +package gnu.gcj.util.path; + +import java.util.*; +import java.util.zip.*; +import java.io.*; +import java.net.*; + + +final class ZipPathEntry extends PathEntry { + final ZipFile zip; + final URL file; + + public String toString () { return zip.getName (); } + + ZipPathEntry (File f) + throws MalformedURLException, ZipException, IOException + { + file = new URL ("file", "", f.getPath ()); + zip = new ZipFile (f); + zip.readDirectory (); + } + + /* + The url for a zip-file resource is, + + <code>file:///path/file.zip#name</code> + + Then, it is URLConnection's problem to handle that. + */ + + URL getURL (String f) { + + ZipEntry ent = zip.getEntry (f); + + try { + if (ent != null) + return new URL (file, "#"+f); + else + return null; + } catch (IOException x) { + return null; + } + } + + InputStream getStream (String f) { + + ZipEntry ent = zip.getEntry (f); + + try { + if (ent != null) + return zip.getInputStream (ent); + else + return null; + } catch (IOException x) { + return null; + } + } + + byte[] getBytes (String f) { + ZipEntry ent = zip.getEntry (f); + + try { + if (ent != null) + return readbytes (zip.getInputStream (ent), + (int) ent.getSize ()); + else + return null; + } catch (IOException x) { + return null; + } + + } +} + |