Récupérer la liste des classes d'un package
Est il possible de récupérer le liste des classes d'un package de façon dynamique ?
Plus précisemment :
je récupère le nom d'un package sous forme de String et j'aimerais pouvoir récupérer la liste des classes de ce package se trouvant dans le classloader.
Si c'est possible, pouvez vous m'indiquer comment ?
Merci par avance,
Arnaud
Une solution... plus complète
Bon à force de chercher, j'ai finis par bidouiller un bout de code qui fonctionne. Il pallie les manques du code fournis plus haut en recherchant aussi les classes d'un package à l'intérieur d'un jar. Bon je met le code, je pense avoir assez bien commenté.
J'espère avoir été utile pour mon premier post sur ce forum...
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
/**
* Cette méthode permet de lister toutes les classes d'un package donné
*
* @param pckgname Le nom du package à lister
* @return La liste des classes
*/
public List<Class> getClasses(String pckgname) throws ClassNotFoundException, IOException {
// Création de la liste qui sera retournée
ArrayList<Class> classes = new ArrayList<Class>();
// On récupère toutes les entrées du CLASSPATH
String [] entries = System.getProperty("java.class.path")
.split(System.getProperty("path.separator"));
// Pour toutes ces entrées, on verifie si elles contiennent
// un répertoire ou un jar
for (int i = 0; i < entries.length; i++) {
if(entries[i].endsWith(".jar")){
classes.addAll(traitementJar(entries[i], pckgname));
}else{
classes.addAll(traitementRepertoire(entries[i], pckgname));
}
}
return classes;
}
/**
* Cette méthode retourne la liste des classes présentes
* dans un répertoire du classpath et dans un package donné
*
* @param repertoire Le répertoire où chercher les classes
* @param pckgname Le nom du package
* @return La liste des classes
*/
private Collection<Class> traitementRepertoire(String repertoire, String pckgname) throws ClassNotFoundException {
ArrayList<Class> classes = new ArrayList<Class>();
// On génère le chemin absolu du package
StringBuffer sb = new StringBuffer(repertoire);
String[] repsPkg = pckgname.split("\\.");
for (int i = 0; i < repsPkg.length; i++) {
sb.append(System.getProperty("file.separator") + repsPkg[i]);
}
File rep = new File(sb.toString());
// Si le chemin existe, et que c'est un dossier, alors, on le liste
if(rep.exists() && rep.isDirectory()){
// On filtre les entrées du répertoire
FilenameFilter filter = new DotClassFilter();
File[] liste = rep.listFiles(filter );
// Pour chaque classe présente dans le package, on l'ajoute à la liste
for (int i = 0; i < liste.length; i++) {
classes.add(Class.forName(pckgname + "." + liste[i].getName().split("\\.")[0]));
}
}
return classes;
}
/**
* Cette méthode retourne la liste des classes présentes dans un jar du classpath et dans un package donné
*
* @param repertoire Le jar où chercher les classes
* @param pckgname Le nom du package
* @return La liste des classes
* @throws IOException
* @throws ClassNotFoundException
*/
private Collection<Class> traitementJar(String jar, String pckgname) throws IOException, ClassNotFoundException {
ArrayList<Class> classes = new ArrayList<Class>();
JarFile jfile = new JarFile(jar);
String pkgpath = pckgname.replace(".", "/");
// Pour chaque entrée du Jar
for (Enumeration<JarEntry> entries = jfile.entries(); entries.hasMoreElements();) {
JarEntry element = entries.nextElement();
// Si le nom de l'entrée commence par le chemin du package et finit par .class
if(element.getName().startsWith(pkgpath)
&& element.getName().endsWith(".class")){
String nomFichier = element.getName().substring(pckgname.length() + 1);
classes.add(Class.forName(pckgname + "." + nomFichier.split("\\.")[0]));
}
}
return classes;
}
/**
* Cette classe permet de filtrer les fichiers d'un répertoire. Il n'accepte que les fichiers .class.
*/
private class DotClassFilter implements FilenameFilter{
public boolean accept(File arg0, String arg1) {
return arg1.endsWith(".class");
}
} |