View Javadoc

    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                  // System.out.println( javaBean.getName() + " isn't a xjavadoc.XTag class. Ignoring" );
    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                      // Ignore. There was no Manifest here.
    81                  }
    82              } else {
    83                  try {
    84                      JarFile jarFile = new JarFile(dirOrJar);
    85
    86                      manifest = jarFile.getManifest();
    87                  } catch (IOException e) {
    88                      // Ignore. Wasn't a jar file.
    89                  }
    90              }
    91
    92              if (manifest != null) {
    93                  // Now loop over all entries in the Manifest.
    94                  for (Iterator entryNames = manifest.getEntries().keySet().iterator(); entryNames.hasNext();) {
    95                      String entryName = (String) entryNames.next();
    96                      // Is it a class?
    97                      if (entryName.endsWith(".class")) {
    98                          Attributes attributes = manifest.getAttributes(entryName);
    99                          // See if it's a java bean.
    100                         String javaBean = attributes.getValue("Java-Bean");
    101
    102                         if ("true".equalsIgnoreCase(javaBean)) {
    103                             // OK. Get the BeanInfo.
    104                             String className = entryName.substring(0, entryName.length() - 6);
    105
    106                             className = className.replace('/', '.');
    107
    108                             // Load the class
    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 }