KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > loader > ModuleFinder


1 /*
2  * Copyright (c) 2001, 2002 The XDoclet team
3  * All rights reserved.
4  */

5 package xdoclet.loader;
6
7 import java.io.File JavaDoc;
8 import java.io.FileFilter JavaDoc;
9 import java.io.FileInputStream JavaDoc;
10 import java.io.IOException JavaDoc;
11 import java.io.InputStream JavaDoc;
12
13 import java.net.URL JavaDoc;
14 import java.util.*;
15 import java.util.jar.JarEntry JavaDoc;
16 import java.util.jar.JarFile JavaDoc;
17 import java.util.zip.ZipException JavaDoc;
18
19 import org.apache.commons.logging.Log;
20
21 import org.apache.tools.ant.AntClassLoader;
22 import org.xml.sax.InputSource JavaDoc;
23
24 import xdoclet.util.LogUtil;
25 import xdoclet.util.Translator;
26
27 /**
28  * Finds xdoclet modules.
29  *
30  * @author <a HREF="mailto:aslak.nospam@users.sf.net">Aslak Hellesøy</a>
31  * @created 7. april 2002
32  * @todo Use reflection to call AntClassLoader.getClasspath to remove dependency to Ant. This package should be Ant
33  * independent
34  * @version $Revision: 1.15 $
35  */

36 public class ModuleFinder
37 {
38     private final static FileFilter JavaDoc jarFilter =
39         new FileFilter JavaDoc()
40         {
41             public boolean accept(File JavaDoc file)
42             {
43                 return file.getName().endsWith(".jar");
44             }
45         };
46     private static String JavaDoc classpath;
47     private static List modules = null;
48
49     public static String JavaDoc getClasspath()
50     {
51         return classpath;
52     }
53
54     /**
55      * Get the newest Jar file on the classpath. This method is used to see if a generation is needed because one of the
56      * xdoclet jars might have changed since the last generation.
57      *
58      * @return The timestamp of the newest jar file on the classpath
59      */

60     public static File JavaDoc getNewestFileOnClassPath()
61     {
62         List moduleFiles = findModuleFiles();
63         long newest = Long.MIN_VALUE;
64         File JavaDoc newestFile = null;
65
66         Iterator i = moduleFiles.iterator();
67
68         while (i.hasNext()) {
69             File JavaDoc moduleFile = (File JavaDoc) i.next();
70
71             if (moduleFile.lastModified() >= newest) {
72                 newestFile = moduleFile;
73                 newest = moduleFile.lastModified();
74             }
75         }
76         return newestFile;
77     }
78
79     public static void setClasspath(String JavaDoc classpath)
80     {
81         ModuleFinder.classpath = classpath;
82     }
83
84     /**
85      * Initialises the classpath. If a system property named <code>xdoclet.class.path</code>, then that value will be
86      * used. If not, we'll try to cast the clazz' class loader to an AntClassLoader and get classpath from there. If
87      * that fails (happens if the clazz was loaded by the system class loader), we'll use java.class.path.
88      *
89      * @param clazz the class used to find classpath.
90      */

91     public static void initClasspath(Class JavaDoc clazz)
92     {
93         if (System.getProperty("xdoclet.class.path") == null) {
94             try {
95                 classpath = ((AntClassLoader) clazz.getClassLoader()).getClasspath();
96             }
97             catch (ClassCastException JavaDoc e) {
98                 classpath = System.getProperty("java.class.path");
99             }
100         }
101         else {
102             classpath = System.getProperty("xdoclet.class.path");
103         }
104     }
105
106     /**
107      * Returns a List of XDocletModule objects
108      *
109      * @return
110      */

111     public static List findModules()
112     {
113         if (modules == null) {
114             modules = new ArrayList();
115
116             Log log = LogUtil.getLog(ModuleFinder.class, "findModules");
117
118             log.debug(Translator.getString(LoaderMessages.class, LoaderMessages.REGISTERING_MODULES));
119
120             XDocletXmlParser parser = new XDocletXmlParser();
121
122             List moduleFiles = findModuleFiles();
123             Iterator moduleFileIterator = moduleFiles.iterator();
124
125             while (moduleFileIterator.hasNext()) {
126                 File JavaDoc file = (File JavaDoc) moduleFileIterator.next();
127
128                 if (file.exists()) {
129                     try {
130                         InputStream JavaDoc xdocletXmlIs = null;
131                         URL JavaDoc xtagsURL = null;
132
133                         if (file.isDirectory()) {
134                             xdocletXmlIs = new FileInputStream JavaDoc(new File JavaDoc(file, "META-INF" + File.separator + "xdoclet.xml"));
135                             xtagsURL = (new File JavaDoc(file, "META-INF" + File.separator + "xtags.xml")).toURL();
136                         }
137                         else {
138                             JarFile JavaDoc jar = new JarFile JavaDoc(file);
139                             JarEntry JavaDoc xdocletXml = jar.getJarEntry("META-INF/xdoclet.xml");
140
141                             xtagsURL = new URL JavaDoc(new URL JavaDoc("jar:" + file.toURL() + "!/"), "META-INF/xtags.xml");
142
143                             if (xdocletXml != null) {
144                                 log.debug(Translator.getString(LoaderMessages.class, LoaderMessages.PARSING_XDOCLET_XML, new String JavaDoc[]{file.getAbsolutePath()}));
145
146                                 xdocletXmlIs = jar.getInputStream(xdocletXml);
147                             }
148                             else {
149                                 log.debug(Translator.getString(LoaderMessages.class, LoaderMessages.SKIP_NO_XDOCLET_XML, new String JavaDoc[]{file.getAbsolutePath()}));
150                             }
151                         }
152
153                         if (xdocletXmlIs != null) {
154                             InputSource JavaDoc in = new InputSource JavaDoc(xdocletXmlIs);
155
156                             in.setSystemId(xtagsURL.toString());
157
158                             XDocletModule module = parser.parse(in);
159
160                             if (module != null) {
161                                 module.setXTagsDefinitionURL(xtagsURL);
162                                 modules.add(module);
163                             }
164                             else {
165                                 log.warn(Translator.getString(LoaderMessages.class, LoaderMessages.BAD_XDOCLET_XML, new String JavaDoc[]{file.getAbsolutePath()}));
166                             }
167                         }
168                     }
169                     catch (ZipException JavaDoc ze) {
170                         // Zip Exceptions gets only a warning, so invalid zip files
171
// are just skipped by the module finder.
172
log.warn(Translator.getString(LoaderMessages.class, LoaderMessages.INVALID_ZIP_FILE, new String JavaDoc[]{file.getName()}));
173                     }
174                     catch (IOException JavaDoc e) {
175                         throw new IllegalStateException JavaDoc(Translator.getString(LoaderMessages.class, LoaderMessages.LOAD_MODULE_ERROR, new String JavaDoc[]{e.getMessage()}));
176                     }
177                 }
178                 else {
179                     log.warn(Translator.getString(LoaderMessages.class, LoaderMessages.NONEXISTANT_CLASSPATH_ENTRY, new String JavaDoc[]{file.getAbsolutePath()}));
180                 }
181             }
182
183             log.debug(Translator.getString(LoaderMessages.class, LoaderMessages.DONE_REGISTERING_MODULES, new String JavaDoc[]{String.valueOf(modules.size())}));
184         }
185         return modules;
186     }
187
188     public static void resetFoundModules()
189     {
190         modules = null;
191     }
192
193     private static List findModuleFiles()
194     {
195         if (classpath == null) {
196             throw new IllegalStateException JavaDoc(Translator.getString(LoaderMessages.class, LoaderMessages.INIT_CLASSPATH_NOT_CALLED));
197         }
198
199         ArrayList result = new ArrayList();
200
201         StringTokenizer pathTokenizer = new StringTokenizer(classpath, System.getProperty("path.separator"));
202
203         while (pathTokenizer.hasMoreTokens()) {
204             File JavaDoc file = new File JavaDoc(pathTokenizer.nextToken());
205
206             if (file.isDirectory()) {
207                 // a module doesn't have to be a jar. can be a straight directory too.
208
// required in order to solve the chicken and egg for xdoclet itself (externalizer)
209
if (new File JavaDoc(file, "META-INF" + File.separator + "xdoclet.xml").exists()) {
210                     result.add(file);
211                 }
212             }
213             else if (jarFilter.accept(file)) {
214                 result.add(file);
215             }
216         }
217         return result;
218     }
219 }
220
Popular Tags