summaryrefslogtreecommitdiffstats
path: root/libjava/gnu/gcj/util/path/DirectoryPathEntry.java
blob: a9ca602341be61dc262ed561899985ffac28defe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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;
    }
  }

}

OpenPOWER on IntegriCloud