KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > buchuki > ensmer > object > PackagePaths


1 /*
2  * Copyright 2004 Dusty Phillips
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package com.buchuki.ensmer.object;
17
18 import java.io.*;
19 import java.util.*;
20
21 /**
22  * Class to represent an interchangeable list of file paths and
23  * packages/classes. It is used by the Backhoe to determine if a specific
24  * backend exists for a specific frontend, but could theoretically have other
25  * uses as well. This class starts with a base directory and a suffix and then
26  * recursively creates a list of relative pathnames for each file in that
27  * directory or subdirectory with that filename. It then creates a list of
28  * classnames based on those files. It can return the list of paths, the list
29  * of classes, or a list of classes that exist in the classpath.
30  *
31  * @author Dusty Phillips [dusty@buchuki.com]
32  */

33 public class PackagePaths {
34
35     /**
36      * Construct the PackagePaths object with a reference to the file and suffix
37      * it should scan for.
38      *
39      * @param root the root directory that all paths should come from
40      * @param suffix only files containing this suffix will be listed
41      */

42     public PackagePaths(File root, final String JavaDoc suffix) {
43         this.suffix = suffix;
44         this.root = root;
45         acceptor =
46             new FilenameFilter() {
47                 public boolean accept(File dir, String JavaDoc name) {
48                     File testfile = new File(dir, name);
49                     return testfile.isDirectory() || name.endsWith(suffix);
50                 }
51             };
52     }
53
54     /**
55      * Recursively retrieve a list of all files in the root directory that have
56      * the given suffix. The returned list is a list of strings containing
57      * relative paths to all files below the root directory with the given suffix.
58      *
59      * @return list of files in the PackagePath's root that contain the
60      * constructed suffix.
61      */

62     public List<String JavaDoc> getFileList() {
63         //Should probably cache this
64
List<String JavaDoc> retval = new ArrayList<String JavaDoc>();
65         recurseFileList(retval, root);
66         return retval;
67     }
68
69     /**
70      * Get a List of classnames for the files in getFileList. Basically, converts
71      * the paths from x/y/z or x\y\z to x.y.z
72      *
73      * @return list of fully qualified classnames for the Packagepath
74      */

75     public List<String JavaDoc> getClassnameList() {
76         List<String JavaDoc> retval = new ArrayList<String JavaDoc>();
77         List<String JavaDoc> files = getFileList();
78         for (String JavaDoc name : files) {
79             String JavaDoc temp = name.replace(File.separatorChar, '.');
80             retval.add(temp.substring(0, temp.length() - suffix.length()));
81         }
82         return retval;
83     }
84
85     /**
86      * Get a list of classes for the files in getFileList that can actually be
87      * loaded from the ClassPath. Any classes that cannot be loaded are not
88      * loaded.
89      *
90      * @return list of valid classes for the PackagePath
91      */

92     public List<Class JavaDoc<? extends Backend>> getValidClassList() {
93         return getValidClassList(new Object JavaDoc().getClass());
94     }
95
96     /**
97      * Get a list of classes for the files in getFileList that can actually be
98      * loaded from the ClassPath AND is assignable to the given class. This method
99      * can be used to load only classes that are subclasses of the given class or
100      * interface.
101      *
102      * @param parent a class to test for assignability
103      * @return list of valid classes for the PackagePath that are
104      * assignable to the given class
105      */

106     @SuppressWarnings JavaDoc(
107     {"unchecked"})
108     public List<Class JavaDoc<? extends Backend>> getValidClassList(Class JavaDoc<?> parent) {
109         List<Class JavaDoc<? extends Backend>> retval =
110             new ArrayList<Class JavaDoc<? extends Backend>>();
111         List<String JavaDoc> classes = getClassnameList();
112         for (String JavaDoc name : classes) {
113             try {
114                 Class JavaDoc<? extends Backend> clazz =
115                     (Class JavaDoc<? extends Backend>) Class.forName(name);
116                 if (parent.isAssignableFrom(clazz)) {
117                     retval.add(clazz);
118                 }
119             } catch (Exception JavaDoc e) {
120             }
121         }
122         return retval;
123     }
124
125     /**
126      * Get a map of class to file objects. This returns the files in the root that
127      * are associated with the classes returned by getValidClassList(parent)
128      *
129      * @param parent a class to test for assignability
130      * @return a map of Class --> File objects where the key is a class
131      * that is assignable to parent, and the value is a file from the strings
132      * in getFileList() that has the same package structure as the class.
133      */

134     public Map<Class JavaDoc<? extends Backend>, File> getValidClassFileMap(Class JavaDoc parent) {
135         List<Class JavaDoc<? extends Backend>> classes = getValidClassList(parent);
136         List<String JavaDoc> filenames = getFileList();
137         Map<Class JavaDoc<? extends Backend>, File> retval =
138             new HashMap<Class JavaDoc<? extends Backend>, File>();
139         for (Class JavaDoc<? extends Backend> item : classes) {
140             String JavaDoc filename = item.getName().replace(
141                 '.', File.separatorChar) + suffix;
142             if (filenames.contains(filename)) {
143                 File file = new File(root, filename);
144                 if (file.exists()) {
145                     retval.put(item, file);
146                 }
147             }
148         }
149         return retval;
150     }
151
152     /**
153      * Recursively construct a list of files in the given directory that have the
154      * proper suffix.
155      *
156      * @param list the List to add pathnames to
157      * @param directory the directory to search for files
158      */

159     private void recurseFileList(List<String JavaDoc> list, File directory) {
160         File[] dirContents = directory.listFiles(acceptor);
161         for (File file : dirContents) {
162             if (file.isDirectory()) {
163                 recurseFileList(list, file);
164             }
165             else {
166                 list.add(file.getAbsolutePath().substring(root.getAbsolutePath().length() + 1));
167             }
168         }
169     }
170
171     /**
172      * The root directory to start searching from. paths are returned relative to
173      * this root.
174      */

175     private File root;
176
177     /**
178      * A FilenameFilter used to determine if a file should be accepted into the
179      * pathname structure.
180      */

181     private FilenameFilter acceptor;
182
183     /**
184      * The suffix to test for
185      */

186     private String JavaDoc suffix;
187
188 }
189
190
Popular Tags