Example #1
0
  protected Set<Class> processFileUrl(URL url, String basepath, Class clazz) throws IOException {
    Set<Class> set = new HashSet<Class>();
    String urlBase = url.getFile();
    // We can't URLDecoder.decode(path) since some encoded chars are allowed on file uris
    urlBase = urlBase.replaceAll("%20", " ");
    File dir = new File(urlBase);
    if (!dir.isDirectory()) {
      logger.warn("Cannot process File URL: " + url + ". Path is not a directory");
      return set;
    }

    Collection<File> files = FileUtils.listFiles(new File(urlBase), new String[] {"class"}, true);
    for (File file : files) {
      try {
        InputStream classStream = new FileInputStream(file);
        ClassReader reader = new ClosableClassReader(classStream);

        ClassScanner visitor = getScanner(clazz);
        reader.accept(visitor, 0);
        if (visitor.isMatch()) {
          Class c = loadClass(visitor.getClassName());
          if (c != null) {
            set.add(c);
          }
        }
      } catch (IOException e) {
        if (logger.isDebugEnabled()) {
          Throwable t = ExceptionHelper.getRootException(e);
          logger.debug(String.format("%s: caused by: %s", e.toString(), t.toString()));
        }
      }
    }
    return set;
  }
Example #2
0
  protected Set<Class> processFileUrl(URL url, String basepath, Class clazz) throws IOException {
    Set<Class> set = new HashSet<Class>();
    String urlBase = url.getFile();
    urlBase = URLDecoder.decode(urlBase);

    Collection<File> files = FileUtils.listFiles(new File(urlBase), new String[] {"class"}, true);
    for (File file : files) {
      try {
        ClassReader reader = new ClassReader(new FileInputStream(file));
        ClassScanner visitor = getScanner(clazz);
        reader.accept(visitor, 0);
        if (visitor.isMatch()) {
          Class c = loadClass(visitor.getClassName());
          if (c != null) {
            set.add(c);
          }
        }
      } catch (IOException e) {
        if (logger.isDebugEnabled()) {
          Throwable t = ExceptionHelper.getRootException(e);
          logger.debug(String.format("%s: caused by: %s", e.toString(), t.toString()));
        }
      }
    }
    return set;
  }
Example #3
0
  protected Set<Class> processJarUrl(URL url, String basepath, Class clazz) throws IOException {
    Set<Class> set = new HashSet<Class>();
    String path = url.getFile().substring(5, url.getFile().indexOf("!"));
    JarFile jar = new JarFile(path);

    for (Enumeration entries = jar.entries(); entries.hasMoreElements(); ) {
      JarEntry entry = (JarEntry) entries.nextElement();
      if (entry.getName().startsWith(basepath) && entry.getName().endsWith(".class")) {
        try {
          String name = entry.getName();
          // Ignore anonymous
          // TODO RM what about the other anonymous classes like $2, $3 ?
          if (name.contains("$1")) {
            continue;
          }
          URL classURL = classLoader.getResource(name);
          ClassReader reader = new ClassReader(classURL.openStream());
          ClassScanner visitor = getScanner(clazz);
          reader.accept(visitor, 0);
          if (visitor.isMatch()) {
            Class c = loadClass(visitor.getClassName());
            if (c != null) {
              set.add(c);
            }
          }
        } catch (Exception e) {
          if (logger.isDebugEnabled()) {
            Throwable t = ExceptionHelper.getRootException(e);
            logger.debug(String.format("%s: caused by: %s", e.toString(), t.toString()));
          }
        }
      }
    }
    return set;
  }
  private void generateMetadata(Archiver archiver)
      throws ArchiverException, MojoExecutionException {

    Log log = getLog();
    File tmpServicesDir = new File(new File(tmpDirectory, "META-INF"), "services");
    File buildServicesDir = new File(new File(buildOutputDirectory, "META-INF"), "services");
    if (!tmpServicesDir.mkdirs()) {
      throw new MojoExecutionException(
          "Error while creating the directory: " + tmpServicesDir.getPath());
    }

    log.debug("Initializing class scanner ...");
    ClassScanner scanner = new ClassScanner(buildOutputDirectory);
    for (Artifact artifact :
        filterArtifacts(
            (Set<Artifact>) project.getArtifacts(),
            new ScopeArtifactFilter(Artifact.SCOPE_COMPILE))) {
      scanner.addToClasspath(artifact.getFile());
    }
    List<ServiceLocator> serviceLocators = new ArrayList<ServiceLocator>(serviceClassNames.length);
    for (String serviceClassName : serviceClassNames) {
      // If the user provided its own service file, skip generation
      File file = new File(buildServicesDir, serviceClassName);
      if (file.exists()) {
        log.debug(file + " exists; don't scan for " + serviceClassName + " implementation");
      } else {
        ServiceLocator sl = new ServiceLocator(serviceClassName);
        serviceLocators.add(sl);
        scanner.addVisitor(sl);
      }
    }
    try {
      scanner.scan();
    } catch (ClassScannerException e) {
      throw new MojoExecutionException("Failed to scan classes for services", e);
    }
    for (ServiceLocator sl : serviceLocators) {
      File file = new File(tmpServicesDir, sl.getServiceClassName());
      if (!sl.getImplementations().isEmpty()) {
        String destFileName = "META-INF/services/" + sl.getServiceClassName();
        log.info("Generating " + destFileName);
        try {
          Writer out = new OutputStreamWriter(new FileOutputStream(file));
          try {
            for (String impl : sl.getImplementations()) {
              log.debug("  " + impl);
              out.write(impl);
              out.write("\n");
            }
          } finally {
            out.close();
          }
        } catch (IOException e) {
          throw new MojoExecutionException("Unable to create temporary file " + file, e);
        }
        archiver.addFile(file, destFileName);
      }
    }
  }
Example #5
0
 /**
  * Requests the {@link #classScanner} to add a class or all classes from a package. A {@code null}
  * argument indicates the unnamed package.
  */
 public Builder classesOrPackages(String... classesOrPackages) throws IOException {
   if (classesOrPackages == null) {
     classScanner.addPackage(null, true);
   } else
     for (String s : classesOrPackages) {
       classScanner.addClassOrPackage(s);
     }
   return this;
 }
Example #6
0
 @Test
 @SuppressWarnings({"rawtypes", "unchecked"})
 public void testGetActionsByClassIfHasValidSize() {
   Class clazz = UserController.class;
   List<ControllerMapping> mappings = classScanner.getActionsByClass(clazz, "user");
   assertEquals(7, mappings.size());
 }
Example #7
0
 @Test
 @SuppressWarnings({"rawtypes", "unchecked"})
 public void testGetActionsByClassIfIsNotNull() {
   Class clazz = UserController.class;
   List<ControllerMapping> mappings = classScanner.getActionsByClass(clazz, "user");
   assertNotNull(mappings);
 }
Example #8
0
 @Test
 @SuppressWarnings({"rawtypes", "unchecked"})
 public void testObtainControllerAnnotationByClassWithoutValidClass() {
   Class clazz = User.class;
   Controller controller = classScanner.obtainControllerAnnotationByClass(clazz);
   assertNull(controller);
 }
Example #9
0
 @Test
 @SuppressWarnings({"rawtypes", "unchecked"})
 public void testIsControllerWithoutValidClass() {
   Class clazz = User.class;
   boolean annotated = classScanner.isAnnotatedWithController(clazz);
   assertFalse(annotated);
 }
Example #10
0
 @Test
 @SuppressWarnings({"rawtypes", "unchecked"})
 public void testObtainControllerAnnotationByClassWithValidClass() {
   Class clazz = UserController.class;
   Controller controller = classScanner.obtainControllerAnnotationByClass(clazz);
   assertNotNull(controller);
   assertEquals("user", controller.mappedBy());
 }
Example #11
0
 @Test
 @SuppressWarnings({"rawtypes", "unchecked"})
 public void testGetActionsByClassIfHasValidMethodForRunBeforeAllActions() {
   Class clazz = UserController.class;
   List<ControllerMapping> mappings = classScanner.getActionsByClass(clazz, "user");
   for (ControllerMapping mapping : mappings) {
     assertNotNull(mapping.getRunBeforeActions());
   }
 }
Example #12
0
  protected Set<Class> processJarUrl(URL url, String basepath, Class clazz) throws IOException {
    Set<Class> set = new HashSet<Class>();
    String path = url.getFile().substring(5, url.getFile().indexOf("!"));
    // We can't URLDecoder.decode(path) since some encoded chars are allowed on file uris
    path = path.replaceAll("%20", " ");
    JarFile jar = new JarFile(path);

    for (Enumeration entries = jar.entries(); entries.hasMoreElements(); ) {
      JarEntry entry = (JarEntry) entries.nextElement();
      if (entry.getName().startsWith(basepath) && entry.getName().endsWith(".class")) {
        try {
          String name = entry.getName();
          // Ignore anonymous
          if (name.matches("\\$[1-9]")) {
            continue;
          }

          URL classURL = classLoader.getResource(name);
          InputStream classStream = classURL.openStream();
          ClassReader reader = new ClosableClassReader(classStream);

          ClassScanner visitor = getScanner(clazz);
          reader.accept(visitor, 0);
          if (visitor.isMatch()) {
            Class c = loadClass(visitor.getClassName());
            if (c != null) {
              set.add(c);
            }
          }
        } catch (Exception e) {
          if (logger.isDebugEnabled()) {
            Throwable t = ExceptionHelper.getRootException(e);
            logger.debug(String.format("%s: caused by: %s", e.toString(), t.toString()));
          }
        }
      }
    }
    jar.close();

    return set;
  }
Example #13
0
 @Test
 @SuppressWarnings({"rawtypes", "unchecked"})
 public void testGetActionsByClassIfHasValidMethodForRunBeforeSomeActions() {
   Class clazz = PersonController.class;
   List<ControllerMapping> mappings = classScanner.getActionsByClass(clazz, "user");
   for (ControllerMapping mapping : mappings) {
     String action = mapping.getActionName();
     if ("save".equals(action) || "update".equals(action) || "delete".equals(action)) {
       assertNotNull(mapping.getRunBeforeActions());
     } else {
       assertNull(mapping.getRunBeforeActions());
     }
   }
 }
Example #14
0
 @Test
 public void testCreateInstanceWithDefaultDirectoryClasses() {
   ClassScanner instance = ClassScanner.createInstance().withDefaultDirectoryClasses();
   assertNotNull(instance);
 }
Example #15
0
  /**
   * Starts the build process and returns an array of {@link File} produced.
   *
   * @return the array of File produced
   * @throws IOException
   * @throws InterruptedException
   * @throws ParserException
   */
  public File[] build() throws IOException, InterruptedException, ParserException {
    if (classScanner.getClasses().isEmpty()) {
      return null;
    }

    List<File> outputFiles = new ArrayList<File>();
    Map<String, List<Class>> map = new LinkedHashMap<String, List<Class>>();
    for (Class c : classScanner.getClasses()) {
      if (Loader.getEnclosingClass(c) != c) {
        continue;
      }
      ClassProperties p = Loader.loadProperties(c, properties, false);
      String target = p.getProperty("target");
      if (target != null && !c.getName().equals(target)) {
        File f = parse(classScanner.getClassLoader().getPaths(), c);
        if (f != null) {
          outputFiles.add(f);
        }
        continue;
      }
      String libraryName = outputName != null ? outputName : p.getProperty("platform.library", "");
      if (libraryName.length() == 0) {
        continue;
      }
      List<Class> classList = map.get(libraryName);
      if (classList == null) {
        map.put(libraryName, classList = new ArrayList<Class>());
      }
      classList.addAll(p.getEffectiveClasses());
    }
    for (String libraryName : map.keySet()) {
      List<Class> classList = map.get(libraryName);
      Class[] classArray = classList.toArray(new Class[classList.size()]);
      File f = generateAndCompile(classArray, libraryName);
      if (f != null) {
        outputFiles.add(f);
        if (copyLibs) {
          // Do not copy library files from inherit properties ...
          ClassProperties p = Loader.loadProperties(classArray, properties, false);
          List<String> preloads = new ArrayList<String>();
          preloads.addAll(p.get("platform.preload"));
          preloads.addAll(p.get("platform.link"));
          // ... but we should use all the inherited paths!
          p = Loader.loadProperties(classArray, properties, true);

          File directory = f.getParentFile();
          for (String s : preloads) {
            URL[] urls = Loader.findLibrary(null, p, s);
            File fi;
            try {
              fi = new File(urls[0].toURI());
            } catch (Exception e) {
              continue;
            }
            File fo = new File(directory, fi.getName());
            if (fi.exists() && !outputFiles.contains(fo)) {
              logger.info("Copying " + fi);
              FileInputStream fis = new FileInputStream(fi);
              FileOutputStream fos = new FileOutputStream(fo);
              byte[] buffer = new byte[1024];
              int length;
              while ((length = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, length);
              }
              fos.close();
              fis.close();
              outputFiles.add(fo);
            }
          }
        }
      }
    }

    File[] files = outputFiles.toArray(new File[outputFiles.size()]);
    if (jarPrefix != null && files.length > 0) {
      File jarFile = new File(jarPrefix + "-" + properties.get("platform") + ".jar");
      File d = jarFile.getParentFile();
      if (d != null && !d.exists()) {
        d.mkdir();
      }
      createJar(
          jarFile,
          outputDirectory == null ? classScanner.getClassLoader().getPaths() : null,
          files);
    }
    return files;
  }
  public static void main(String[] args) throws ParseException, IOException {
    Options options = createOptions();
    CommandLineParser parser = new GnuParser();
    CommandLine cmd = parser.parse(options, args);
    if (cmd.hasOption("?")) {
      new HelpFormatter().printHelp("java " + ShowMoves.class.getName(), options);
      System.exit(1);
    }
    File rootFile = new File(cmd.getOptionValue("root"));
    File movesFile = new File(cmd.getOptionValue("moves"));
    Predicate<ClassName> packageFilter = new PackagePredicate(cmd.getOptionValue("package", ""));
    String groupPrefix = cmd.getOptionValue("group", "");
    File refsFile = cmd.hasOption("refs") ? new File(cmd.getOptionValue("refs")) : null;

    // scan all the pom.xml files
    Modules modules = new Modules();
    modules.scan(rootFile, groupPrefix);

    // load the moves and refs files
    ClassLocations moves = ClassLocations.parseFile(movesFile, groupPrefix);
    ClassLocations refs =
        (refsFile != null) ? ClassLocations.parseFile(refsFile, groupPrefix) : null;

    // scan the compiled classes of all the maven targets
    ClassScanner classScanner = new ClassScanner(packageFilter);
    classScanner.scan(modules.getAllModules());
    ClassLocations locations = classScanner.getLocations();
    ClassDependencies dependencies = classScanner.getDependencies();

    // apply the moves file
    locations.moveAll(moves);

    // apply the refs file, if one was specified
    if (refs != null) {
      for (ModuleName moduleName : refs.getAllModules()) {
        ClassName refsName = new ClassName(moduleName + ":" + refsFile);
        locations.add(refsName, moduleName);
        dependencies.add(refsName, refs.getClasses(moduleName));
      }
    }

    // find modules that reference classes they don't have access to
    Map<ModuleName, ListMultimap<ClassName, ClassName>> brokenMap = Maps.newHashMap();
    for (Map.Entry<ClassName, ModuleName> entry : locations.getLocations()) {
      ClassName className = entry.getKey();
      ModuleName moduleName = entry.getValue();
      Set<ClassName> referencedClasses = dependencies.getReferencedClasses(className);

      ListMultimap<ClassName, ClassName> moduleBrokenMap = null;
      for (ClassName referencedClass : referencedClasses) {
        ModuleName referencedModule = locations.getModule(referencedClass);
        if (referencedModule != null && !modules.isDependentOf(moduleName, referencedModule)) {
          if (moduleBrokenMap == null) {
            moduleBrokenMap = brokenMap.get(moduleName);
            if (moduleBrokenMap == null) {
              brokenMap.put(moduleName, moduleBrokenMap = ArrayListMultimap.create());
            }
          }
          moduleBrokenMap.put(className, referencedClass);
        }
      }
    }

    // report broken dependencies
    System.out.println();
    for (ModuleName moduleName : Utils.sorted(brokenMap.keySet())) {
      ListMultimap<ClassName, ClassName> missingMap = brokenMap.get(moduleName);

      System.out.println();
      System.out.println(moduleName.toString(groupPrefix));

      for (ClassName className : Utils.sorted(missingMap.keySet())) {
        System.out.println("  " + className);
        for (ClassName referencedClass : Utils.sorted(missingMap.get(className))) {
          ModuleName referencedModule = locations.getModule(referencedClass);
          System.out.println(
              "    " + referencedClass + " (" + referencedModule.toString(groupPrefix) + ")");
        }
      }
    }
  }
Example #17
0
 @Test
 public void testGetDirectoryClassesByDefault() {
   String directory = classScanner.getDirectoryClasses();
   String defaultDirectory = Constants.DEFAULT_DIRECTORY_CLASSES;
   assertEquals(defaultDirectory, directory);
 }
Example #18
0
 /** Appends argument to the paths of the {@link #classScanner}. */
 public Builder classPaths(String... classPaths) {
   classScanner.getClassLoader().addPaths(classPaths);
   return this;
 }
Example #19
0
public class ClassScannerTest {

  private ClassScanner classScanner = ClassScanner.createInstance().withDefaultDirectoryClasses();

  @Test
  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testIsControllerWithValidClass() {
    Class clazz = UserController.class;
    boolean annotated = classScanner.isAnnotatedWithController(clazz);
    assertTrue(annotated);
  }

  @Test
  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testIsControllerWithoutValidClass() {
    Class clazz = User.class;
    boolean annotated = classScanner.isAnnotatedWithController(clazz);
    assertFalse(annotated);
  }

  @Test
  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testObtainControllerAnnotationByClassWithValidClass() {
    Class clazz = UserController.class;
    Controller controller = classScanner.obtainControllerAnnotationByClass(clazz);
    assertNotNull(controller);
    assertEquals("user", controller.mappedBy());
  }

  @Test
  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testObtainControllerAnnotationByClassWithoutValidClass() {
    Class clazz = User.class;
    Controller controller = classScanner.obtainControllerAnnotationByClass(clazz);
    assertNull(controller);
  }

  @Test
  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testGetActionsByClassIfIsNotNull() {
    Class clazz = UserController.class;
    List<ControllerMapping> mappings = classScanner.getActionsByClass(clazz, "user");
    assertNotNull(mappings);
  }

  @Test
  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testGetActionsByClassIfHasValidSize() {
    Class clazz = UserController.class;
    List<ControllerMapping> mappings = classScanner.getActionsByClass(clazz, "user");
    assertEquals(7, mappings.size());
  }

  @Test
  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testGetActionsByClassIfHasValidMethodForRunBeforeAllActions() {
    Class clazz = UserController.class;
    List<ControllerMapping> mappings = classScanner.getActionsByClass(clazz, "user");
    for (ControllerMapping mapping : mappings) {
      assertNotNull(mapping.getRunBeforeActions());
    }
  }

  @Test
  @SuppressWarnings({"rawtypes", "unchecked"})
  public void testGetActionsByClassIfHasValidMethodForRunBeforeSomeActions() {
    Class clazz = PersonController.class;
    List<ControllerMapping> mappings = classScanner.getActionsByClass(clazz, "user");
    for (ControllerMapping mapping : mappings) {
      String action = mapping.getActionName();
      if ("save".equals(action) || "update".equals(action) || "delete".equals(action)) {
        assertNotNull(mapping.getRunBeforeActions());
      } else {
        assertNull(mapping.getRunBeforeActions());
      }
    }
  }

  @Test
  public void testCreateInstance() {
    Builder builder = ClassScanner.createInstance();
    assertNotNull(builder);
  }

  @Test
  public void testCreateInstanceWithDefaultDirectoryClasses() {
    ClassScanner instance = ClassScanner.createInstance().withDefaultDirectoryClasses();
    assertNotNull(instance);
  }

  @Test
  public void testCreateInstanceWithCustomDirectoryClasses() {
    ClassScanner instance = ClassScanner.createInstance().withCustomDirectoryClasses("xpto");
    assertNotNull(instance);
  }

  @Test
  public void testGetDirectoryClassesByDefault() {
    String directory = classScanner.getDirectoryClasses();
    String defaultDirectory = Constants.DEFAULT_DIRECTORY_CLASSES;
    assertEquals(defaultDirectory, directory);
  }
}
Example #20
0
 @Test
 public void testCreateInstanceWithCustomDirectoryClasses() {
   ClassScanner instance = ClassScanner.createInstance().withCustomDirectoryClasses("xpto");
   assertNotNull(instance);
 }
Example #21
0
 @Test
 public void testCreateInstance() {
   Builder builder = ClassScanner.createInstance();
   assertNotNull(builder);
 }