View Javadoc

1   /*
2    * Created on May 19, 2005
3    *
4    * The default implementation of TargetFinder
5    */
6   package net.sf.tlc.core.impl;
7   
8   import java.io.File;
9   import java.io.FileInputStream;
10  import java.io.IOException;
11  import java.util.ArrayList;
12  import java.util.Arrays;
13  import java.util.logging.Level;
14  import java.util.logging.Logger;
15  
16  import net.sf.tlc.core.PropertyManager;
17  import net.sf.tlc.core.TargetFinder;
18  import net.sf.tlc.model.Target;
19  import net.sf.tlc.util.ClassPathUtils;
20  
21  /***
22   * The default implementation of TargetFinder
23   * 
24   * @author aisrael
25   */
26  public class DefaultFinder implements TargetFinder {
27      
28      private static final Logger logger = Logger.getLogger(DefaultFinder.class.getName());
29  
30      private static final String DEFAULT_TARGET_DIR = "targets";
31  
32      private static final String TLC_TARGET_DIR_KEY = "tlc.target.dir";
33  
34      private final File targetPath;
35  
36      private final ClassLoader cl;
37  
38      /***
39       * @param cl
40       *            ClassLoader
41       * @param pm
42       *            PropertyManager
43       */
44      public DefaultFinder(final ClassLoader cl, final PropertyManager pm) {
45          this.cl = cl;
46          this.targetPath = new File(pm.getProperty(TLC_TARGET_DIR_KEY, DEFAULT_TARGET_DIR));
47      }
48  
49      /***
50       * (non-Javadoc)
51       * 
52       * @see net.sf.tlc.core.TargetFinder#listTargets()
53       */
54      public final Target[] listTargets() {
55          final ArrayList results = new ArrayList();
56          if (targetPath.isDirectory() && targetPath.exists() && targetPath.canRead()) {
57              final File[] files = targetPath.listFiles();
58              for (int i = 0; i < files.length; ++i) {
59                  final File file = files[i];
60                  if (file.isFile() && file.canRead()) {
61                      final String fileName = file.getAbsolutePath();
62  
63                      if (fileName.endsWith(".jar")) {
64                          results.addAll(Arrays.asList(inspectJar(file)));
65                      } else if (fileName.endsWith(".class")) {
66                          final Target target = checkIfTargetClass(file);
67                          if (null != target) {
68                              results.add(target);
69                          }
70                      }
71                  }
72              }
73          }
74          return (Target[]) results.toArray(new Target[0]);
75      }
76  
77      /***
78       * @param file File
79       * @return Target[]
80       */
81      private Target[] inspectJar(final File file) {
82          final ArrayList targets = new ArrayList();
83          try {
84              final Target[] jarTargets = JarInspector.listTargets(file);
85              for (int i = 0; i < jarTargets.length; ++i) {
86                  try {
87                      final Class c = cl.loadClass(jarTargets[i].getName());
88                      if (FinderHelper.isTargetClass(c)) {
89                          targets.add(jarTargets[i]);
90                      }
91                  } catch (ClassNotFoundException e) {
92                      logger.log(Level.WARNING, "ClassNotFoundException on " + jarTargets[i].getName(), e);
93                  }
94              }
95          } catch (IOException e) {
96              logger.log(Level.SEVERE, "IOException on \"" + file.getAbsolutePath() + "\"", e);
97          }
98          return (Target[]) targets.toArray(new Target[0]);
99      }
100 
101     /***
102      * @param classFile
103      *            File
104      * @return a Target object if the (.class) file is a target class, null
105      *         otherwise
106      */
107     private Target checkIfTargetClass(final File classFile) {
108         Target result = null;
109         FileInputStream is = null;
110         try {
111             is = new FileInputStream(classFile);
112             final String classFilename = classFile.getName();
113             System.out.println("attempting to load \"" + classFilename + "\"");
114             final String className = ClassPathUtils.toClassName(targetPath.getAbsolutePath(), classFile
115                     .getAbsolutePath());
116             final Class loadedClass = cl.loadClass(className);
117     
118             if (FinderHelper.isTargetClass(loadedClass)) {
119                 result = new Target(Target.TARGET_IS_CLASS, targetPath.getAbsolutePath(), className);
120             }
121         } catch (NoClassDefFoundError e) {
122             logger.log(Level.WARNING, "NoClassDefFoundError inspecting " + classFile.getAbsolutePath(), e);
123         } catch (ClassNotFoundException e) {
124             logger.log(Level.WARNING, "ClassNotFoundException inspecting " + classFile.getAbsolutePath(), e);
125         } catch (IOException e) {
126             logger.log(Level.WARNING, "IOException inspecting " + classFile.getAbsolutePath(), e);
127         } finally {
128             if (null != is) {
129                 try {
130                     is.close();
131                 } catch (IOException e) {
132                     logger.log(Level.SEVERE, "IOException closing InputStream", e);
133                 }
134             }
135         }
136         return result;
137     }
138 
139 }