/* * Copyright 2015 the original author or authors. * @https://github.com/scouter-project/scouter * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package scouter.util.scan; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; import java.util.jar.JarEntry; import java.util.jar.JarFile; import scouter.util.StringUtil; public class Scanner { private String prefix; public Scanner(String prefix) { if (StringUtil.isEmpty(prefix)) this.prefix = null; else this.prefix = prefix.replace('.', '/'); } public Set<String> process() { return process(Thread.currentThread().getContextClassLoader()); } public Set<String> process(ClassLoader loader) { Set<String> mainSet = new TreeSet<String>(); if (this.prefix == null) return mainSet; try { Set<File> files = getRoot(loader); Iterator<File> itr = files.iterator(); while (itr.hasNext()) { Set<String> classes = listUp(itr.next()); mainSet.addAll(classes); } } catch (IOException e) { e.printStackTrace(); } return mainSet; } public Set<File> getRoot() throws IOException { Set<File> files = new HashSet<File>(); if (this.prefix != null) { Enumeration<URL> en = Thread.currentThread().getContextClassLoader().getResources(prefix); while (en.hasMoreElements()) { File file = parse(en.nextElement()); files.add(file); } } return files; } public Set<File> getRoot(ClassLoader loader) throws IOException { Set<File> files = new HashSet<File>(); if (this.prefix != null) { Enumeration<URL> en = loader.getResources(prefix); while (en.hasMoreElements()) { File file = parse(en.nextElement()); files.add(file); } } return files; } private File parse(URL res) { String file = res.getFile(); int x = file.indexOf("!"); if (x > 0) return new File(file.substring(file.indexOf("/"), x)); else return new File(file.substring(file.indexOf("/"), file.length() - prefix.length())); } public Set<String> listUp(File root) { Set<String> classes = new HashSet<String>(); if (this.prefix != null) { if (root.isDirectory()) { listUp(classes, new File(root, prefix), root.getAbsolutePath()); } else { try { listUp(classes, new JarFile(root)); } catch (IOException e) { e.printStackTrace(); } } } return classes; } public static Set<String> getClassesInJar(String jarName) { Set<String> classes = new HashSet<String>(); try { if (jarName == null) return classes; JarFile file = new JarFile(jarName); Enumeration<JarEntry> en = file.entries(); while (en.hasMoreElements()) { JarEntry entry = en.nextElement(); if (entry.getName().toLowerCase().endsWith(".class")) { classes.add(getClassName(entry.getName())); } } } catch (Exception e) { } return classes; } public void listUp(Set<String> classes, JarFile file) { if (this.prefix == null) return; Enumeration<JarEntry> en = file.entries(); while (en.hasMoreElements()) { JarEntry entry = en.nextElement(); if (entry.getName().startsWith(prefix) == false) { continue; } if (entry.getName().toLowerCase().endsWith(".class")) { classes.add(getClassName(entry.getName())); } } } private void listUp(Set<String> classes, File file, String root) { if (file.isDirectory() == false) return; File[] sub = file.listFiles(); for (int i = 0; i < sub.length; i++) { if (sub[i].getName().toLowerCase().endsWith(".class")) { String name = sub[i].getAbsolutePath().substring(root.length()); name = name.replace('\\', '/'); if (name.startsWith("/")) name = name.substring(1); classes.add(getClassName(name)); } if (sub[i].getName().startsWith(".")) continue; if (sub[i].isDirectory()) { listUp(classes, sub[i], root); } } } public static String getClassName(String name) { return name.substring(0, name.length() - 6).replace('/', '.'); } public static String cutOutLast(String name, String seperator) { int x = name.lastIndexOf(seperator); if (x < 0) return name; return name.substring(0, x); } }