1 package xjavadoc.tags;
2
3 import java.util.List;
4 import java.util.ArrayList;
5 import java.util.Iterator;
6 import java.util.StringTokenizer;
7 import java.util.jar.Manifest;
8 import java.util.jar.JarFile;
9 import java.util.jar.Attributes;
10 import java.io.File;
11 import java.io.FileInputStream;
12 import java.io.IOException;
13 import java.net.URLClassLoader;
14 import java.net.URL;
15 import java.net.MalformedURLException;
16 import java.beans.BeanInfo;
17 import java.beans.Introspector;
18 import java.beans.IntrospectionException;
19
20 import xjavadoc.XTagFactory;
21 import xjavadoc.XTag;
22
23 /***
24 * This class introspects the classpath and registers tags.
25 *
26 * @author Aslak Hellesøy
27 * @version $Revision: 1.3 $
28 */
29 public final class TagIntrospector {
30
31 public void registerTags(String classpath, XTagFactory tagFactory ) {
32 for( StringTokenizer st = new StringTokenizer(classpath, System.getProperty("path.separator") ); st.hasMoreTokens(); ) {
33 File classpathElement = new File( st.nextToken() );
34 if( classpathElement.exists() ) {
35 List javaBeans = findJavaBeans( classpathElement );
36 registerTags( javaBeans, tagFactory );
37 } else {
38 System.out.println( classpathElement.getAbsolutePath() + " was on classpath, but doesn't exist." );
39 }
40 }
41 }
42
43 private void registerTags(List javaBeans, XTagFactory tagFactory ) {
44 for( Iterator i = javaBeans.iterator(); i.hasNext(); ) {
45 Class javaBean = (Class) i.next();
46 if( XTag.class.isAssignableFrom( javaBean ) ) {
47 try {
48 BeanInfo beanInfo = Introspector.getBeanInfo( javaBean );
49
50 String tagName = beanInfo.getBeanDescriptor().getName();
51 tagFactory.registerTagClass( tagName, javaBean );
52 } catch( IntrospectionException e ) {
53 System.out.println("No BeanInfo for " + javaBean.getName() );
54 }
55 } else {
56
57 }
58 }
59 }
60
61
62 /***
63 * Returns a collection of classes that are Java Beans. The Java Bean
64 * classes are found by looking at the MANIFEST.MF file.
65 *
66 * @param dirOrJar the directory of jar file containing the classes.
67 * @return a Collection of {@link Class}.
68 */
69 private List findJavaBeans( File dirOrJar ) {
70 List result = new ArrayList();
71
72 try {
73 ClassLoader classLoader = new URLClassLoader( new URL[] {dirOrJar.toURL()}, getClass().getClassLoader() );
74
75 Manifest manifest = null;
76 if (dirOrJar.isDirectory()) {
77 try {
78 manifest = new Manifest(new FileInputStream(new File(dirOrJar, "META-INF/MANIFEST.MF")));
79 } catch (IOException e) {
80
81 }
82 } else {
83 try {
84 JarFile jarFile = new JarFile(dirOrJar);
85
86 manifest = jarFile.getManifest();
87 } catch (IOException e) {
88
89 }
90 }
91
92 if (manifest != null) {
93
94 for (Iterator entryNames = manifest.getEntries().keySet().iterator(); entryNames.hasNext();) {
95 String entryName = (String) entryNames.next();
96
97 if (entryName.endsWith(".class")) {
98 Attributes attributes = manifest.getAttributes(entryName);
99
100 String javaBean = attributes.getValue("Java-Bean");
101
102 if ("true".equalsIgnoreCase(javaBean)) {
103
104 String className = entryName.substring(0, entryName.length() - 6);
105
106 className = className.replace('/', '.');
107
108
109 try {
110 Class beanClass = classLoader.loadClass(className);
111 result.add( beanClass );
112 } catch (ClassNotFoundException e) {
113 String errorMessage = className
114 + " was declared as a Java-Bean in the manifest, but the class was not found.";
115
116 e.printStackTrace();
117 throw new IllegalStateException(errorMessage);
118 }
119 }
120 }
121 }
122 }
123 return result;
124 } catch( MalformedURLException e ) {
125 throw new IllegalStateException(e.getMessage());
126 }
127 }
128 }