/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.bindings.util; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.net.URL; /** * @author Greg Hinkle * @author Lukas Krejci */ public class PackageFinder { private List<File> jarLocations; public PackageFinder(List<File> jarLocations) { this.jarLocations = new ArrayList<File>(jarLocations); } public Set<String> findPackages(String packageRoot) throws IOException { HashSet<String> found = new HashSet<String>(); List<File> jars = new ArrayList<File>(); for (File loc : jarLocations) { if (loc.exists()) { jars.addAll(Arrays.asList(loc.listFiles(new FileFilter() { public boolean accept(File pathname) { return pathname.isFile() && pathname.getName().endsWith(".jar"); } }))); } } jars.addAll(loadResourcesFromClassPath(packageRoot, "jar:file:")); for (File jar : jars) { findPackagesInJar(packageRoot, found, jar); } List<File> dirs = loadResourcesFromClassPath(packageRoot, "file:"); for(File d : dirs) { findPackagesInDirectory(packageRoot, found, d); } return found; } private List<File> loadResourcesFromClassPath(String pkgRoot, String prefix) throws IOException { List<File> jarFiles = new ArrayList<File>(); String pkgPath = pkgRoot.replaceAll("\\.", "/"); Enumeration<URL> resources = getClass().getClassLoader().getResources(pkgPath); URL resource = null; while (resources.hasMoreElements()) { resource = resources.nextElement(); if (resource.toString().startsWith(prefix)) { String jarFilePath = getFilePath(resource, prefix); jarFiles.add(new File(jarFilePath)); } } return jarFiles; } private String getFilePath(URL resource, String prefix) { int startIndex = prefix.length(); String string = resource.toString().substring(startIndex); int endIndex = string.indexOf("!"); if (endIndex < 0) { endIndex = string.length(); } return string.substring(0, endIndex); } private void findPackagesInJar(String packageRoot, Set<String> list, File jar) throws IOException { Set<String> paths = new HashSet<String>(); JarFile jf = null; try { jf = new JarFile(jar); String packagePath = packageRoot.replaceAll("\\.", "/"); Enumeration<JarEntry> entries = jf.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); if (entry.getName().startsWith(packagePath)) { String match = entry.getName().substring(0, entry.getName().lastIndexOf("/")); paths.add(match.replaceAll("/", "\\.")); } } list.addAll(paths); } finally { try { if (jf != null) { jf.close(); } } catch (IOException e) { } } } private void findPackagesInDirectory(String packageRoot, Set<String> list, File dir) throws IOException { File[] subDirs = dir.listFiles(); for(File s : subDirs) { if (s.isDirectory()) { String packageName = packageRoot + "." + s.getName(); list.add(packageName); findPackagesInDirectory(packageName, list, s); } } } }