KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cobertura > util > FileFinder


1 /*
2  * Cobertura - http://cobertura.sourceforge.net/
3  *
4  * Copyright (C) 2005 Jeremy Thomerson
5  * Copyright (C) 2005 Grzegorz Lukasik
6  *
7  * Cobertura is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published
9  * by the Free Software Foundation; either version 2 of the License,
10  * or (at your option) any later version.
11  *
12  * Cobertura is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Cobertura; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20  * USA
21  */

22 package net.sourceforge.cobertura.util;
23
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Set JavaDoc;
33
34 import org.apache.log4j.Logger;
35
36
37 /**
38  * Maps source file names to existing files. After adding description
39  * of places files can be found in, it can be used to localize
40  * the files.
41  *
42  * <p>
43  * FileFinder supports two types of source files locations:
44  * <ul>
45  * <li>source root directory, defines the directory under
46  * which source files are located,</li>
47  * <li>pair (base directory, file path relative to base directory).</li>
48  * </ul>
49  * The difference between these two is that in case of the first you add all
50  * source files under the specified root directory, and in the second you add
51  * exactly one file. In both cases file to be found has to be located under
52  * subdirectory that maps to package definition provided with the source file name.
53  *
54  * @author Jeremy Thomerson
55  */

56 public class FileFinder {
57
58     private static Logger LOGGER = Logger.getLogger(FileFinder.class);
59     
60     // Contains Strings with directory paths
61
private Set JavaDoc sourceDirectories = new HashSet JavaDoc();
62     
63     // Contains pairs (String directoryRoot, Set fileNamesRelativeToRoot)
64
private Map JavaDoc sourceFilesMap = new HashMap JavaDoc();
65
66     /**
67      * Adds directory that is a root of sources. A source file
68      * that is under this directory will be found if relative
69      * path to the file from root matches package name.
70      * <p>
71      * Example:
72      * <pre>
73      * fileFinder.addSourceDirectory( "C:/MyProject/src/main");
74      * fileFinder.addSourceDirectory( "C:/MyProject/src/test");
75      * </pre>
76      * In path both / and \ can be used.
77      * </p>
78      *
79      * @param directory The root of source files
80      * @throws NullPointerException if <code>directory</code> is <code>null</code>
81      */

82     public void addSourceDirectory( String JavaDoc directory) {
83         if( LOGGER.isDebugEnabled())
84             LOGGER.debug( "Adding sourceDirectory=[" + directory + "]");
85
86         // Change \ to / in case of Windows users
87
directory = getCorrectedPath(directory);
88         sourceDirectories.add(directory);
89     }
90
91     /**
92      * Adds file by specifying root directory and relative path to the
93      * file in it. Adds exactly one file, relative path should match
94      * package that the source file is in, otherwise it will be not
95      * found later.
96      * <p>
97      * Example:
98      * <pre>
99      * fileFinder.addSourceFile( "C:/MyProject/src/main", "com/app/MyClass.java");
100      * fileFinder.addSourceFile( "C:/MyProject/src/test", "com/app/MyClassTest.java");
101      * </pre>
102      * In paths both / and \ can be used.
103      * </p>
104      *
105      * @param baseDir sources root directory
106      * @param file path to source file relative to <code>baseDir</code>
107      * @throws NullPointerException if either <code>baseDir</code> or <code>file</code> is <code>null</code>
108      */

109     public void addSourceFile( String JavaDoc baseDir, String JavaDoc file) {
110         if( LOGGER.isDebugEnabled())
111             LOGGER.debug( "Adding sourceFile baseDir=[" + baseDir + "] file=[" + file + "]");
112
113         if( baseDir==null || file==null)
114             throw new NullPointerException JavaDoc();
115     
116         // Change \ to / in case of Windows users
117
file = getCorrectedPath( file);
118         baseDir = getCorrectedPath( baseDir);
119         
120         // Add file to sourceFilesMap
121
Set JavaDoc container = (Set JavaDoc) sourceFilesMap.get(baseDir);
122         if( container==null) {
123             container = new HashSet JavaDoc();
124             sourceFilesMap.put( baseDir, container);
125         }
126         container.add( file);
127     }
128
129     /**
130      * Maps source file name to existing file.
131      * When mapping file name first values that were added with
132      * {@link #addSourceDirectory} and later added with {@link #addSourceFile} are checked.
133      *
134      * @param fileName source file to be mapped
135      * @return existing file that maps to passed sourceFile
136      * @throws IOException if cannot map source file to existing file
137      * @throws NullPointerException if fileName is null
138      */

139     public File JavaDoc getFileForSource(String JavaDoc fileName) throws IOException JavaDoc {
140         // Correct file name
141
if( LOGGER.isDebugEnabled())
142             LOGGER.debug( "Searching for file, name=[" + fileName + "]");
143         fileName = getCorrectedPath( fileName);
144
145         // Check inside sourceDirectories
146
for( Iterator JavaDoc it=sourceDirectories.iterator(); it.hasNext();) {
147             String JavaDoc directory = (String JavaDoc)it.next();
148             File JavaDoc file = new File JavaDoc( directory, fileName);
149             if( file.isFile()) {
150                 LOGGER.debug( "Found inside sourceDirectories");
151                 return file;
152             }
153         }
154         
155         // Check inside sourceFilesMap
156
for( Iterator JavaDoc it=sourceFilesMap.keySet().iterator(); it.hasNext();) {
157             String JavaDoc directory = (String JavaDoc)it.next();
158             Set JavaDoc container = (Set JavaDoc) sourceFilesMap.get(directory);
159             if( !container.contains( fileName))
160                 continue;
161             File JavaDoc file = new File JavaDoc( directory, fileName);
162             if( file.isFile()) {
163                 LOGGER.debug( "Found inside sourceFilesMap");
164                 return file;
165             }
166         }
167
168         // Have not found? Throw an error.
169
LOGGER.debug( "File not found");
170         throw new IOException JavaDoc( "Cannot find source file, name=["+fileName+"]");
171     }
172
173     /**
174      * Returns a list with string for all source directories.
175      * Example: <code>[C:/MyProject/src/main,C:/MyProject/src/test]</code>
176      *
177      * @return list with Strings for all source roots, or empty list if no source roots were specified
178      */

179     public List JavaDoc getSourceDirectoryList() {
180         // Get names from sourceDirectories
181
List JavaDoc result = new ArrayList JavaDoc();
182         for( Iterator JavaDoc it=sourceDirectories.iterator(); it.hasNext();) {
183             result.add( it.next());
184         }
185         
186         // Get names from sourceFilesMap
187
for( Iterator JavaDoc it=sourceFilesMap.keySet().iterator(); it.hasNext();) {
188             result.add(it.next());
189         }
190         
191         // Return combined names
192
return result;
193     }
194
195     private String JavaDoc getCorrectedPath(String JavaDoc path) {
196         return path.replace('\\', '/');
197     }
198
199     /**
200      * Returns string representation of FileFinder.
201      */

202     public String JavaDoc toString() {
203         return "FileFinder, source directories: " + getSourceDirectoryList().toString();
204     }
205 }
206
Popular Tags