KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > emma > report > SourcePathCache


1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: SourcePathCache.java,v 1.1.1.1 2004/05/09 16:57:39 vlad_r Exp $
8  */

9 package com.vladium.emma.report;
10
11 import java.io.File JavaDoc;
12 import java.io.FileFilter JavaDoc;
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collections JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Set JavaDoc;
20
21 import com.vladium.util.asserts.$assert;
22
23 // ----------------------------------------------------------------------------
24
/**
25  * @author Vlad Roubtsov, (C) 2003
26  */

27 public
28 final class SourcePathCache
29 {
30     // public: ................................................................
31

32     // TODO: use soft cache for m_packageCache?
33

34     /**
35      * @param sourcepath [can be empty]
36      */

37     public SourcePathCache (final String JavaDoc [] sourcepath, final boolean removeNonExistent)
38     {
39         if (sourcepath == null) throw new IllegalArgumentException JavaDoc ("null input: sourcepath");
40         
41         final List JavaDoc _sourcepath = new ArrayList JavaDoc (sourcepath.length);
42         for (int i = 0; i < sourcepath.length; ++ i)
43         {
44             final File JavaDoc dir = new File JavaDoc (sourcepath [i]);
45             
46             if (! removeNonExistent || (dir.isDirectory () && dir.exists ()))
47                 _sourcepath.add (dir);
48         }
49         
50         m_sourcepath = new File JavaDoc [_sourcepath.size ()];
51         _sourcepath.toArray (m_sourcepath);
52         
53         m_packageCache = new HashMap JavaDoc ();
54     }
55     
56     /**
57      * @param sourcepath [can be empty]
58      */

59     public SourcePathCache (final File JavaDoc [] sourcepath, final boolean removeNonExistent)
60     {
61         if (sourcepath == null) throw new IllegalArgumentException JavaDoc ("null input: sourcepath");
62         
63         final List JavaDoc _sourcepath = new ArrayList JavaDoc (sourcepath.length);
64         for (int i = 0; i < sourcepath.length; ++ i)
65         {
66             final File JavaDoc dir = sourcepath [i];
67             
68             if (! removeNonExistent || (dir.isDirectory () && dir.exists ()))
69                 _sourcepath.add (dir);
70         }
71         
72         m_sourcepath = new File JavaDoc [_sourcepath.size ()];
73         _sourcepath.toArray (m_sourcepath);
74         
75         m_packageCache = new HashMap JavaDoc ();
76     }
77     
78     /**
79      * @return absolute pathname [null if 'name' was not found in cache]
80      */

81     public synchronized File JavaDoc find (final String JavaDoc packageVMName, final String JavaDoc name)
82     {
83         if (packageVMName == null) throw new IllegalArgumentException JavaDoc ("null input: packageVMName");
84         if (name == null) throw new IllegalArgumentException JavaDoc ("null input: name");
85         
86         if (m_sourcepath.length == 0) return null;
87         
88         CacheEntry entry = (CacheEntry) m_packageCache.get (packageVMName);
89         
90         if (entry == null)
91         {
92             entry = new CacheEntry (m_sourcepath.length);
93             m_packageCache.put (packageVMName, entry);
94         }
95         
96         final Set JavaDoc [] listings = entry.m_listings;
97         for (int p = 0; p < listings.length; ++ p)
98         {
99             Set JavaDoc listing = listings [p];
100             if (listing == null)
101             {
102                 listing = faultListing (m_sourcepath [p], packageVMName);
103                 listings [p] = listing;
104             }
105             
106             // TODO: this is case-sensitive at this point
107
if (listing.contains (name))
108             {
109                 final File JavaDoc relativeFile = new File JavaDoc (packageVMName.replace ('/', File.separatorChar), name);
110                 
111                 return new File JavaDoc (m_sourcepath [p], relativeFile.getPath ()).getAbsoluteFile ();
112             }
113         }
114         
115         return null;
116     }
117     
118     // protected: .............................................................
119

120     // package: ...............................................................
121

122     // private: ...............................................................
123

124     
125     private static final class CacheEntry
126     {
127         CacheEntry (final int size)
128         {
129             m_listings = new Set JavaDoc [size];
130         }
131         
132         
133         final Set JavaDoc /* String */ [] m_listings;
134         
135     } // end of nested class
136

137     
138     // NOTE: because java.io.* implements file filtering in bytecode
139
// there is no real perf advantage in using a filter here (I might
140
// as well do list() and filter the result myself
141

142     private static final class FileExtensionFilter implements FileFilter JavaDoc
143     {
144         public boolean accept (final File JavaDoc file)
145         {
146             if ($assert.ENABLED) $assert.ASSERT (file != null, "file = null");
147             
148             if (file.isDirectory ()) return false; // filter out directories
149

150             final String JavaDoc name = file.getName ();
151             final int lastDot = name.lastIndexOf ('.');
152             if (lastDot <= 0) return false;
153             
154             // [assertion: lastDot > 0]
155

156             // note: match is case sensitive
157
return m_extension.equals (name.substring (lastDot));
158         }
159         
160         public String JavaDoc toString ()
161         {
162             return super.toString () + ", extension = [" + m_extension + "]";
163         }
164         
165         FileExtensionFilter (final String JavaDoc extension)
166         {
167             if (extension == null)
168                 throw new IllegalArgumentException JavaDoc ("null input: extension");
169             
170             // ensure starting '.':
171
final String JavaDoc canonical = canonicalizeExtension (extension);
172             
173             if (extension.length () <= 1)
174                 throw new IllegalArgumentException JavaDoc ("empty input: extension");
175             
176             m_extension = canonical;
177         }
178         
179         private static String JavaDoc canonicalizeExtension (final String JavaDoc extension)
180         {
181             if (extension.charAt (0) != '.')
182                 return ".".concat (extension);
183             else
184                 return extension;
185         }
186         
187         
188         private final String JavaDoc m_extension;
189         
190     } // end of nested class
191

192     
193     private Set JavaDoc /* String */ faultListing (final File JavaDoc dir, final String JavaDoc packageVMName)
194     {
195         if ($assert.ENABLED) $assert.ASSERT (dir != null, "dir = null");
196         if ($assert.ENABLED) $assert.ASSERT (packageVMName != null, "packageVMName = null");
197         
198         final File JavaDoc packageFile = new File JavaDoc (dir, packageVMName.replace ('/', File.separatorChar));
199         
200         final File JavaDoc [] listing = packageFile.listFiles (FILE_EXTENSION_FILTER);
201         
202         if ((listing == null) || (listing.length == 0))
203             return Collections.EMPTY_SET;
204         else
205         {
206             final Set JavaDoc result = new HashSet JavaDoc (listing.length);
207             for (int f = 0; f < listing.length; ++ f)
208             {
209                 result.add (listing [f].getName ());
210             }
211             
212             return result;
213         }
214     }
215     
216
217     private final File JavaDoc [] m_sourcepath; // never null
218
private final Map JavaDoc /* packageVMName:String->CacheEntry */ m_packageCache; // never null
219

220     private static final FileExtensionFilter FILE_EXTENSION_FILTER; // set in <clinit>
221

222     static
223     {
224         FILE_EXTENSION_FILTER = new FileExtensionFilter (".java");
225     }
226
227 } // end of class
228
// ----------------------------------------------------------------------------
Popular Tags