View Javadoc

1   /*
2    * Copyright (c) 2001-2003 The XDoclet team
3    * All rights reserved.
4    */
5   package xjavadoc.filesystem;
6   
7   import java.io.File;
8   import java.io.FileFilter;
9   import java.util.Arrays;
10  import java.util.ArrayList;
11  
12  import xjavadoc.filesystem.AbstractFile;
13  import xjavadoc.filesystem.XJavadocFile;
14  import xjavadoc.SourceSet;
15  import xjavadoc.Util;
16  
17  /***
18   * This class represents a set of Java source files. It designs a directory and
19   * an optional array of files. The size() and getQualifiedName( int ) methods
20   * depend on what files were passed in the constructor. The getSourceFile(
21   * String ) will work regardless of wether the class was instantiated with files
22   * or not (provided the file exists).
23   *
24   * @author    Aslak Hellesøy
25   * @created   14. mars 2002
26   */
27  public final class FileSourceSet implements SourceSet
28  {
29  	/***
30  	 * root directory
31  	 */
32  	private File       _dir;
33  
34  	/***
35  	 * source files
36  	 */
37  	private ArrayList  _files;
38  
39  	/***
40  	 * overridden hash code
41  	 */
42  	private int        hash = Integer.MIN_VALUE;
43  
44  	/***
45  	 * Constructs a new FileSourceSet. If the files parameter is null, the
46  	 * FileSourceSet will report that it does not know about any java source files,
47  	 * even if they exist. See the general class comment.
48  	 *
49  	 * @param dir    The root directory of the java sources
50  	 * @param files  The desired files under the root directory
51  	 */
52  	public FileSourceSet( File dir, String[] files )
53  	{
54  		if( dir == null )
55  		{
56  			throw new IllegalArgumentException( "dir can't be null" );
57  		}
58  		if( !dir.isDirectory() )
59  		{
60  			throw new IllegalArgumentException( dir.getAbsolutePath() + " must be a directory" );
61  		}
62  		_dir = dir;
63  		_files = new ArrayList();
64  		if( files != null )
65  		{
66  			_files.addAll( Arrays.asList( files ) );
67  		}
68  
69  	}
70  
71  	/***
72  	 * Creates a SoureSet from a directory or a file. If fileOrDir is a directory,
73  	 * all java files under that directory (and all subdirectories) will be added
74  	 * to this FileSourceSet.
75  	 *
76  	 * @param fileOrDir
77  	 */
78  	public FileSourceSet( File fileOrDir )
79  	{
80  		if( !fileOrDir.isDirectory() && !fileOrDir.exists() )
81  		{
82  			throw new IllegalArgumentException( fileOrDir.getAbsolutePath() + " must exist" );
83  		}
84  		_files = new ArrayList();
85  		if( fileOrDir.isDirectory() )
86  		{
87  			_dir = fileOrDir;
88  			_files.addAll( Arrays.asList( Util.getJavaFiles( fileOrDir ) ) );
89  
90  		}
91  		else
92  		{
93  			_dir = fileOrDir.getParentFile();
94  			_files.add( fileOrDir.getName() );
95  
96  		}
97  	}
98  
99  	/***
100 	 * Gets the files contained in the source set.
101 	 *
102 	 * @return
103 	 */
104 	public AbstractFile[] getFiles()
105 	{
106 		throw new UnsupportedOperationException( "Not yet implemented." );
107 //		return _files.size() == 0 ? null : ( String[] ) _files.toArray( new String[_files.size()] );
108 	}
109 
110 	/***
111 	 * Gets the File containing the source of the class. <br>
112 	 * <b>IMPORTANT:</b> This method will find a file regardless of whether it was
113 	 * part of the files passed in the constructor.
114 	 *
115 	 * @param qualifiedName  fully qualified class name of the source file to find.
116 	 * @return               the File containing the source of the class
117 	 */
118 	public AbstractFile getSourceFile( String qualifiedName )
119 	{
120 		File sourceFile = new File( _dir, getRelativeFileName( qualifiedName ) );
121 
122 		if( !sourceFile.exists() )
123 		{
124 			return null;
125 		}
126 		return new XJavadocFile( sourceFile );
127 	}
128 
129 	/***
130 	 * Gets the fully qualified class name of the i'th file in the instance.
131 	 *
132 	 * @param i  the index of the class
133 	 * @return   fully qualified class name
134 	 */
135 	public String getQualifiedName( int i )
136 	{
137 		//_log.debug( "returning file: " + _files[i] );
138 		return getQualifiedName( ( String ) _files.get( i ) );
139 	}
140 
141 	/***
142 	 * Returns the number of files in the instance
143 	 *
144 	 * @return   the number of files in the instance
145 	 */
146 	public int getSize()
147 	{
148 		return _files.size();
149 	}
150 
151 	/***
152 	 * whether source set contains given absolute file name
153 	 *
154 	 * @param filename  absolute filename to check
155 	 * @return
156 	 */
157 	public boolean containsAbsolute( String filename )
158 	{
159 		return filename.startsWith( getDir().getPath() ) && _files.contains( filename.substring( getDir().getPath().length() + 1 ) );
160 	}
161 	/***
162 	 * whether source set contains relative file name
163 	 *
164 	 * @param filename  relative filename to check
165 	 * @return
166 	 */
167 	public boolean containsRelative( String filename )
168 	{
169 		return _files.contains( filename );
170 	}
171 
172 	/***
173 	 * Compares with another object. They are equal if o is a FileSourceSet and
174 	 * have the same dir and the same files.
175 	 *
176 	 * @param o  object to compare
177 	 * @return   true if they are equal
178 	 */
179 	public boolean equals( Object o )
180 	{
181 		if( o instanceof FileSourceSet )
182 		{
183 			FileSourceSet other = ( FileSourceSet ) o;
184 
185 			return _dir.equals( other._dir ) && _files.equals( other._files );
186 		}
187 		else
188 		{
189 			return false;
190 		}
191 	}
192 
193 	public int hashCode()
194 	{
195 		if( hash == Integer.MIN_VALUE )
196 		{
197 			hash = _dir.hashCode();
198 			if( _files != null )
199 			{
200 				for( int i = 0; i < _files.size(); i++ )
201 				{
202 					hash += _files.get( i ).hashCode();
203 				}
204 			}
205 		}
206 		return hash;
207 	}
208 
209 	/***
210 	 * Gets the root directory of the source files.
211 	 *
212 	 * @return   the root directory of the source files.
213 	 */
214 	private File getDir()
215 	{
216 		return _dir;
217 	}
218 
219 	/***
220 	 * Gets the fully qualified class name for a relative file
221 	 *
222 	 * @param relativeFileName  filename relative to the dir
223 	 * @return                  fully qualified class name
224 	 */
225 	private String getQualifiedName( String relativeFileName )
226 	{
227 		String result = relativeFileName.replace( '/', '.' ).replace( '//', '.' );
228 
229 		result = result.substring( 0, result.length() - 5 );
230 		return result;
231 	}
232 
233 	/***
234 	 * Gets the relative file name (relative to dir) for a fully qualified class
235 	 * name
236 	 *
237 	 * @param qualifiedName  fully qualified class name
238 	 * @return               the relative file name
239 	 */
240 	private String getRelativeFileName( String qualifiedName )
241 	{
242 		return qualifiedName.replace( '.', File.separatorChar ) + ".java";
243 	}
244 
245 	/***
246 	 * FileFilter that only accepts java sources
247 	 *
248 	 * @created   24. august 2002
249 	 */
250 	class JavaSourceFilter implements FileFilter
251 	{
252 		private final static String suffix = ".java";
253 		public boolean accept( File file )
254 		{
255 			return file.getName().endsWith( suffix );
256 		}
257 	}
258 
259 	/***
260 	 * FileFilter that only accepts directories
261 	 *
262 	 * @created   24. august 2002
263 	 */
264 	class DirectoryFilter implements FileFilter
265 	{
266 		public boolean accept( File file )
267 		{
268 			return file.isDirectory();
269 		}
270 	}
271 
272 }