IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)



Auteur : divxdede
Version : 16/09/2004
Comment extraire sous forme de string la position des colonnes d'un JTable
Voici un code permettant d'extraire sous forme de string la position des colonnes d'un JTable. Tres pratique donc pour ensuite sauvegarder cette position dans un .ini via les Properties :

import java.util.*; import javax.swing.*; import javax.swing.table.*; /** * Permet de récuperer/positionner l'ordre des colonnes d'une table * @author divxdede */ public class TableColumnOrderManager { /** Récupere l'ordre des colonnes sous la forme "2,0,1" * Donne l'ordre courant par rapport à l'ordre d'origine de la TableModel * @return Ordre courant des colonnes (ex: "2,0,1") **/ public static String getTableOrder(JTable table) { String Result = ""; int nbrColumns = table.getColumnCount(); for(int i = 0 ; i < nbrColumns ; i++) { int realColumn = table.getColumnModel().getColumn(i).getModelIndex(); Result += realColumn; if(i < nbrColumns - 1) Result +=","; } return Result; } /** Réordonne les colonnes d'une table * IMPORTANT les numero dans "2,0,1" se refere à la position d'origine du TableModel * @param order Ordre souhaité par rapport à l'origine * @param table La JTable à réordonner **/ public static void setTableOrder(String order,JTable table) { ArrayList expected = makeOrderList(order); ArrayList having = makeOrderList( getTableOrder(table) ); for(int i = 0 ; i < table.getColumnCount() ; i++) { Integer valExpected = (Integer)expected.get(i); Integer valHaving = (Integer)having.get(0); if( valExpected.intValue() == valHaving.intValue() ) { having.remove(0); continue; } int posExpectedOnCurrent = having.indexOf(valExpected); System.out.println("Move column " + (posExpectedOnCurrent + i) + " to " + i); having.remove(posExpectedOnCurrent); table.moveColumn( posExpectedOnCurrent + i , i ); } } /** Restaure les colonnes à leur position d'origine * @param table JTable dont ont veux restaurer la position des colonnes **/ public static void restoreTableOrder(JTable table) { String strOrder = ""; for(int i = 0 ; i < table.getColumnCount() ; i++) { strOrder += i; if(i < table.getColumnCount() -1 ) strOrder += ","; } setTableOrder(strOrder,table); } /** Méthode interne pour générer une liste d'ordre **/ private static ArrayList makeOrderList(String strList) { ArrayList result = new ArrayList(); StringTokenizer tokenizer = new StringTokenizer(strList, ","); while(tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); Integer value = new Integer( Integer.parseInt(token) ); result.add(value); } return result; } }
le principe est simple
un exemple

/** Sauve l'ordre actuel des colonnes la table **/ String saveOrder = TableColumnOrderManager.getTableOrder(maTable); /** Modifier l'ordre **/ TableColumnOrderManager.setTableOrder("3,2,1,0",maTable) /** Réinitialiser l'ordre par défaut **/ TableColumnOrderManager.restoreTableOrder(maTable); /** Modifier l'ordre avec celui sauvegardé au début **/ TableColumnOrderManager.setTableOrder(saveOrder,maTable)
on peut meme étendre ce principe sur la taille des colonnes aussi simplement.


Auteur : julien_chable
Version : 14/01/2005
Téléchargez le zip
FullScreen et modification de la résolution de l'écran
Ce code permet de mettre une application en fullscreen et également de changer la résolution de l'écran en choisissant une résolution parmi celles compatibles avec la carte graphique ...


Auteur : julien_chable
Version : 14/01/2005
Téléchargez le zip
ENREGISTRER DES OBJETS EN XML : SÉRIALISATION JAVABEANS
Pour tout ceux qui se demandaient (notamment sur le forum) si on pouvait enregistrer des objets en XML sans passer par le format binaire de sérialisation habituel, voici une petite source qui va vous permettre de le faire ! Attention, la sérialisation XML n'est pas tout à fait l'équivalent de la sérialisation binaire utilisée par beaucoup de mécanismes Java, tout cela est précisé dans les sources. Avec la sérialisation XML (-> JavaBeans) vous ne pouvez pas faire autant qu'avec la sérialisation habituelle, le seul avantage : le fichier de sortie est lisible ... Enjoy it !


Auteur : julien_chable
Version : 14/01/2005
FAIRE CAPTURE ECRAN + REDIMENSIONNEMENT IMAGE
Voici une petite source afin de pallier au nombre de questions relative à l'encodage d'image et autre capture d'écran, ainsi que le redimensionnement d'une image ... code source de moins de 70 lignes et encore avec tous les commentaires et les headers de fichier source ...

public class ScreenShotFactory { public final static String IMAGE_TYPE_JPEG = "jpeg"; public final static String IMAGE_TYPE_GIF = "gif"; public final static String IMAGE_TYPE_PNG = "png"; public static void screenShot(Rectangle screenArea, Dimension screenshotFinalDimension, String pictureName, String compressionType) { BufferedImage buf = null; // Notre capture d'écran originale BufferedImage bufFinal = null; // Notre capture d'écran redimensionnée try { // Création de notre capture d'écran buf = new Robot().createScreenCapture(screenArea); } catch (AWTException e) { e.printStackTrace(); } // Création de la capture finale bufFinal = new BufferedImage(screenshotFinalDimension.width, screenshotFinalDimension.height, BufferedImage.TYPE_INT_RGB); // Redimensionnement de la capture originale Graphics2D g = (Graphics2D) bufFinal.getGraphics(); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.drawImage(buf, 0, 0, screenshotFinalDimension.width, screenshotFinalDimension.height, null); g.dispose(); // Ecriture de notre capture d'écran redimensionnée try { ImageIO.write(bufFinal, compressionType, new File(pictureName)); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { ScreenShotFactory.screenShot(new Rectangle(0, 0, 100, 100), new Dimension(50, 50), "test.png", ScreenShotFactory.IMAGE_TYPE_PNG); } }

Auteur : julien_chable
Version : 14/01/2005
Téléchargez le zip
ORDONNANCEUR : MINI OS
Voici le résultat d'un exercice d'un cours de temps réel : un ordonnanceur non temps réel !!!! Le programme suivant présente la structure d'un mini système d'exploitation (ordonnanceur principalement !), la structure du programme n'est pas celle réellement d'un vrai système d'exploitation notamment à du passage d'objet en paramètres et le manque d'interruptions et de boîtes aux lettres mais au moins cela montre les ordonnanceurs (priorité, aléatoire, réparti)!!! J'y ai joint un petit document (mon compte rendu de TP) afin que vous compreniez ce qu'est un ordonnanceur pour ceux qui ne savent pas ... et c'est à l'intérieur que vous aurez l'ensemble des commandes ainsi que les paramètres !!!! Un petit fichier d'aide vous montre comment procéder !!! LISEZ LE !!!!


Auteur : julien_chable
Version : 14/01/2005
Téléchargez le zip
RMS J2ME: ENREGISTRER DONNEES SUR MOBILE
Voici une petite source pour découvrir ce que son les RecordStore et les Records qui permettent d'enregistrer des données sur n'importe quel téléphone MIDP 1.0 ou MIDP 2.0 ! Le prog ne fait que sauvegarder le nom d'utilisateur et le mot de passe que vous entrez lorsque vous cliquer sur 'Exit' ... Le code est assez simple et je vais le compléter avec des Listener, des recordFilter, ... d'ici très peu de temps !! Je vous ai mis le répertoir entier pour le J2MEWT2.0, vous n'avez qu'à copier le répertoire dans le répertoire 'apps' de votre 'WTK21' ou 'WTK20'. Ensuite ouvrez le KToolBar et faites 'Open project' puis Build et Run ... c'est parti !

Conseil : pour ceux qui ne connaise pas J2ME, télécharger le J2ME Wireless toolkit à l'adresse suivante : http://java.sun.com/products/j2mewtoolkit/download-2_1.html (nécessite un enregistrement sinon télécharger la version 2.0) et pour les tutoriaux qui vous permettrons de bien démarrer : http://developers.sun.com/techtopics/mobility/midp/articles/wtoolkit/


Auteur : julien_chable
Version : 14/01/2005
Téléchargez le zip
SNIFFER JPCAP SIMPLE + MAILBOMBING (ARG ...)
Salut, voici une petite source que j'ai réaliser pour un mémoire technique de BAC+3 et qui utilise la JPCAP pour sniffer le réseau. Le programme est assez simple et pas très puissant mais c'était juste pour mes besoins. Pour le compiler, le ZIP possède des .bat (désolé pour les linuxiens ... qui s'auront tout de même faire la 'conversion' !). Le ZIP contient également toutes les class de la JPCAP pour pouvoir exécuter le programme, en revanche pour pouvoir l'exécuter vous devrez installer WinPCap (un petit tour sur google) qui est l'installetion de la librairie Open Source libpcap pour Windows ... j'espère que tout le monde me suit ! Ensuite un deuxième module permet d'envoyer des mail en masse ... vers un seul utilisateur (je voulais retirer ce module dans mon programme mais n'importe quel débutant est capable de faire pareil donc ...).

Le programme est segmentée en module que l'on appel par le nom du module : ex : sniff // Appel du sniffer smtpflood // Appel du mail bomber Comme vous pourrez le remarquer le code permet de charger des modules de code à l'exécution, rien de trancendant mais c'est plutôt pratique ....


Auteur : julien_chable
Version : 14/01/2005
Téléchargez le zip
FAIRE DE L'ECHO AVEC JAVASOUND
Voici une petite source qui permet de faire faire de l'echo à partir d'un fichier son à notre bon vieux Java ! A partir de ce code vous pouvez réaliser un bon nombre d'effet sur n'importe quel fichier son : metallique, ... à vous de trouver l'effet que vous désirez créer (à condition de trouver l'algo !) La majorité des commentaires sont en anglais (quelques uns ne sont pas finis !). La classe main est la classe AudioFilterEchoTest et vous trouverez 2 paramètres à faire varier selon le volume et le temps de réflexion de l'echo. Un petit bug subsiste dans le son pour certains réglages ('pop' et 'click'), cela est en cour de debugage ...

Pas de capture puisque le tout s'entend !

java AudioFilterEchoTest pour faire foncitonner l'exemple !! Les fans de Wipeout reconnaîtrons l'extrait !


Auteur : julien_chable
Version : 14/01/2005
Téléchargez le zip
CRYPTER VOS CLASSES : CHARGEUR DE CLASSES CRYPTÉES !
Pour ceux qui ne veulent pas que les autres voient leurs sources .... Cette source va vous permettre de crypter vos classes avec les algorithmes que vous désirez (ici celui de César pour simplifier!), puis de les charger dans la JVM. N'oublions pas que javah est un décompilateur et qu'il en existe d'autres, donc pour les projets que vous désirez vendre ...

Le script va vous demander de supprimer un fichier .class, cela dans le but de ne pas charger cette classe mais celle qui est cryptée. Le programme surcharge uniquement la méthode findClass, qui est uniquement appelée si la classe n'a pas déjà été chargée par la JVM, et si la superclasse ClassLoader n'arrive pas à trouver cette classe. Par conséquent, le programme n'empêche pas le chargement de classe non cryptées... Toutes les classes cryptées ont une extension .caesar (César), en attendant une version avec DES...

Un fichier .BAT est inclus mais ne fonctionnera que si vous avez paramétrer les exécutables java et javac dans votre classpath ... pour les adeptes de Linux, je n'ai pas de machine sous mon coude en ce moment, donc j'ai préféré ne pas mettre de script de peur qu'il soit faut !


Auteur : julien_chable
Version : 14/01/2005
Téléchargez le zip
ANALYSER CAPACITÉS D'UNE CLASSE À L'EXÉCUTION (AVEC LA 'REFLECTION')
Ce code vous demande de saisir un nom d'objet et il affiche tous les constructeur, méthodes, champs et parent de cet objet. Vous me direz : quel est l'intérêt ? Je vous répondrais énorme ! Si vous souhaitez créer un programme avec des modules (un peu comme VB pour les composants de la boite à outils), votre code examine chaque module (classe) pendant l'exécution et peut les utiliser ! Le package java.lang.reflect permet de regarder les propriétés (constructeurs, méthodes) de n'importe quelle classe pendant l'exécution. Ainsi vous pouvez ajouter n'importe quelle classe à votre programme à l'exécution sans que cela ne pose problème. Ce code se sert largement des objets Class qui permettent de récupérer le type de n'importe quel objet afin de faire un peu ce que l'on veut et même créer une instance d'un objet en ne connaissant que le nom de sa classe !


Auteur : julien_chable
Version : 14/01/2005
Téléchargez le zip
SERVEUR PROXY HTTP (+ SERVEUR HORAIRE)
Voici un serveur proxy (pour ceux qui ne savent pas ce que c'est : un serveur proxy sert de station de connexion entre un client et un serveur. Les requêtes du client sont redirigées par le proxy au serveur effectif et les réponses de celui-ci transitent également par le proxy avant d'arriver au client) que vous pourrez améliorer afin de contrôler et d'enregistrer les connexions, assister un pare-feu, fournir un accès Internet ou à certains serveurs par mot de passe, effectuer des statistiques, filtrage des adresses pour interdire l'accès à certains sites, ... les idées ne manque pas ! Je vous laisse le soin de configurer votre navigateur HTTP sur le proxy.


Auteur : divxdede
Version : 14/01/2005
Extraire sous forme de string la position des colonnes d'un JTable
Voici un code permettant d'extraire sous forme de string la position des colonnes d'un JTable. Très pratique donc pour ensuite sauvegarder cette position dans un .ini via les Properties :

package xxxx.util.swing; import java.util.*; import javax.swing.*; import javax.swing.table.*; /** * Permet de récuperer/positionner l'ordre des colonnes d'une table * @author divxdede */ public class TableColumnOrderManager { /** Récupere l'ordre des colonnes sous la forme "2,0,1" * Donne l'ordre courant par rapport à l'ordre d'origine de la TableModel * @return Ordre courant des colonnes (ex: "2,0,1") **/ public static String getTableOrder(JTable table) { String Result = ""; int nbrColumns = table.getColumnCount(); for(int i = 0 ; i < nbrColumns ; i++) { int realColumn = table.getColumnModel().getColumn(i).getModelIndex(); Result += realColumn; if(i < nbrColumns - 1) Result +=","; } return Result; } /** Réordonne les colonnes d'une table * IMPORTANT les numero dans "2,0,1" se refere à la position d'origine du TableModel * @param order Ordre souhaité par rapport à l'origine * @param table La JTable à réordonner **/ public static void setTableOrder(String order,JTable table) { ArrayList expected = makeOrderList(order); ArrayList having = makeOrderList( getTableOrder(table) ); for(int i = 0 ; i < table.getColumnCount() ; i++) { Integer valExpected = (Integer)expected.get(i); Integer valHaving = (Integer)having.get(0); if( valExpected.intValue() == valHaving.intValue() ) { having.remove(0); continue; } int posExpectedOnCurrent = having.indexOf(valExpected); System.out.println("Move column " + (posExpectedOnCurrent + i) + " to " + i); having.remove(posExpectedOnCurrent); table.moveColumn( posExpectedOnCurrent + i , i ); } } /** Restaure les colonnes à leur position d'origine * @param table JTable dont ont veux restaurer la position des colonnes **/ public static void restoreTableOrder(JTable table) { String strOrder = ""; for(int i = 0 ; i < table.getColumnCount() ; i++) { strOrder += i; if(i < table.getColumnCount() -1 ) strOrder += ","; } setTableOrder(strOrder,table); } /** Méthode interne pour générer une liste d'ordre **/ private static ArrayList makeOrderList(String strList) { ArrayList result = new ArrayList(); StringTokenizer tokenizer = new StringTokenizer(strList, ","); while(tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); Integer value = new Integer( Integer.parseInt(token) ); result.add(value); } return result; } }
Exemple d'utilisation

/** Sauve l'ordre actuel des colonnes la table **/ String saveOrder = TableColumnOrderManager.getTableOrder(maTable); /** Modifier l'ordre **/ TableColumnOrderManager.setTableOrder("3,2,1,0",maTable) /** Réinitialiser l'ordre par défaut **/ TableColumnOrderManager.restoreTableOrder(maTable); /** Modifier l'ordre avec celui sauvegardé au début **/ TableColumnOrderManager.setTableOrder(saveOrder,maTable)
on peut meme étendre ce principe sur la taille des colonnes aussi simplement.


Auteur : iubito
Version : 14/01/2005
Création et lecture d'un arbre
Résumé de la structure voulue : une structure comme un document XML, avec des noeuds (Node) qui ont des propriétés, qui peuvent avoir des enfants, profondeur et nombre d'enfants illimités.

On utilise org.w3c.dom.*.

Node est une interface.
Element est une autre interface, Node est une superinterface de Element.
Un Element possède des attributs (concrètement : les attributs dans un fichier XML)

Le code pour créer l'arborescence.

import org.w3c.dom.*; //Les 5 import suivants si on veut exporter en XML... import javax.xml.transform.*; import javax.xml.transform.stream.*; import javax.xml.transform.dom.*; import javax.xml.parsers.*; import java.io.*; public class Test { public static void main(String[] args) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.newDocument(); //crée un Node racine Node racine = document.createElement("Racine"); //et l'ajoute au document... document.appendChild(racine); //Maintenant on ajout noeud1 à la racine Node noeud1 = ajoutNoeud(racine,"aaa", "1er noeud"); //et un fils à noeud1 ajoutNoeud(noeud1,"bbb", "Enfant du 1er noeud"); //Un 2e noeud à la racine Node noeud2 = ajoutNoeud(racine,"ccc", "2e noeud"); //Avec 2 fils... ajoutNoeud(noeud2,"ddd", "Ainé du 2e noeud"); ajoutNoeud(noeud2,"eee", "Cadet du 2e noeud"); ajoutNoeud(noeud2,"fff", "Dernier enfant du 2e noeud"); //Pour transformer en XML, ça permet de voir si le document est bien construit TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); t.transform(new DOMSource(document),new StreamResult(new File("toto.xml"))); // //Pour parcourir le document et l'afficher System.out.println(affichage(document.getFirstChild(), 0)); } public static Node ajoutNoeud(Node parent, String valeur1, String valeur2) { Element element = parent.getOwnerDocument().createElement("Noeud"); element.setAttribute("code",valeur1); element.setAttribute("texte",valeur2); parent.appendChild(element); return element; } /** * Parcours par récurrence le noeud N, pour afficher ou faire tout autre * traitement sur l'arborescence * @param Node N le noeud à afficher * @param int profondeur pour connaître la profondeur où on est */ public static String affichage(Node N, int profondeur) { String ret = ""; Node fils; if (N != null) { if (N.hasChildNodes()) { //Premier enfant fils = N.getFirstChild(); while (fils != null) { //ici le traitement spécifique ret += "\n"; for (int i = 0; i <= profondeur; i++) ret += "\t"; //Pour récupérer la valeur d'un attribut : ret += ((Element)fils).getAttribute("code") + " " + ((Element)fils).getAttribute("texte"); //récurrence : affiche les enfants de fils. ret += affichage(fils, profondeur + 1); //Passe au frère suivant fils = fils.getNextSibling(); } } } return ret; } }
Le XML obtenu est :

<?xml version="1.0" encoding="UTF-8"?> <Racine> <Noeud code="aaa" texte="1er noeud"> <Noeud code="bbb" texte="Enfant du 1er noeud"/> </Noeud> <Noeud code="ccc" texte="2e noeud"> <Noeud code="ddd" texte="Ainé du 2e noeud"/> <Noeud code="eee" texte="Cadet du 2e noeud"/> <Noeud code="fff" texte="Dernier enfant du 2e noeud"/> </Noeud> </Racine>
La fonction affichage retourne :

aaa 1er noeud bbb Enfant du 1er noeud ccc 2e noeud ddd Ainé du 2e noeud eee Cadet du 2e noeud fff Dernier enfant du 2e noeud

Auteur : divxdede
Version : 14/01/2005
Supprimer les accents d'une chaine
Avantage :

  • Conserve la casse Majuscule / Minuscule
  • Transforme certains caractères spéciaux tel que ÷ en /
  • Gére le bi-caractères tels que Æ en AE
  • La transformation est efficace en determinant si le caractère est considéré avec accent ou non.

Inconvenients :

  • la taille de la chaine résultat peut ne pas faire la même taille que la source. nottament a cause de Æ et æ
  • Certains caractères spéciaux sont transformé même si ce n'etait pas voulu.

package xxxx; import java.util.*; /** Classe complementaire du J2SDK sur la manipulation de chaines de caractéres * Permet nottament de supprimer les accents d'une chaine de caractères **/ public abstract class StringOperation { /** Index du 1er caractere accentué **/ private static final int MIN = 192; /** Index du dernier caractere accentué **/ private static final int MAX = 255; /** Vecteur de correspondance entre accent / sans accent **/ private static final Vector map = initMap(); /** Initialisation du tableau de correspondance entre les caractéres accentués et leur homologues non accentués **/ private static Vector initMap() { Vector Result = new Vector(); java.lang.String car = null; car = new java.lang.String("A"); Result.add( car ); /* '\u00C0' À alt-0192 */ Result.add( car ); /* '\u00C1' Á alt-0193 */ Result.add( car ); /* '\u00C2' Â alt-0194 */ Result.add( car ); /* '\u00C3' Ã alt-0195 */ Result.add( car ); /* '\u00C4' Ä alt-0196 */ Result.add( car ); /* '\u00C5' Å alt-0197 */ car = new java.lang.String("AE"); Result.add( car ); /* '\u00C6' Æ alt-0198 */ car = new java.lang.String("C"); Result.add( car ); /* '\u00C7' Ç alt-0199 */ car = new java.lang.String("E"); Result.add( car ); /* '\u00C8' È alt-0200 */ Result.add( car ); /* '\u00C9' É alt-0201 */ Result.add( car ); /* '\u00CA' Ê alt-0202 */ Result.add( car ); /* '\u00CB' Ë alt-0203 */ car = new java.lang.String("I"); Result.add( car ); /* '\u00CC' Ì alt-0204 */ Result.add( car ); /* '\u00CD' Í alt-0205 */ Result.add( car ); /* '\u00CE' Î alt-0206 */ Result.add( car ); /* '\u00CF' Ï alt-0207 */ car = new java.lang.String("D"); Result.add( car ); /* '\u00D0' Ð alt-0208 */ car = new java.lang.String("N"); Result.add( car ); /* '\u00D1' Ñ alt-0209 */ car = new java.lang.String("O"); Result.add( car ); /* '\u00D2' Ò alt-0210 */ Result.add( car ); /* '\u00D3' Ó alt-0211 */ Result.add( car ); /* '\u00D4' Ô alt-0212 */ Result.add( car ); /* '\u00D5' Õ alt-0213 */ Result.add( car ); /* '\u00D6' Ö alt-0214 */ car = new java.lang.String("*"); Result.add( car ); /* '\u00D7' × alt-0215 */ car = new java.lang.String("0"); Result.add( car ); /* '\u00D8' Ø alt-0216 */ car = new java.lang.String("U"); Result.add( car ); /* '\u00D9' Ù alt-0217 */ Result.add( car ); /* '\u00DA' Ú alt-0218 */ Result.add( car ); /* '\u00DB' Û alt-0219 */ Result.add( car ); /* '\u00DC' Ü alt-0220 */ car = new java.lang.String("Y"); Result.add( car ); /* '\u00DD' Ý alt-0221 */ car = new java.lang.String("Þ"); Result.add( car ); /* '\u00DE' Þ alt-0222 */ car = new java.lang.String("B"); Result.add( car ); /* '\u00DF' ß alt-0223 */ car = new java.lang.String("a"); Result.add( car ); /* '\u00E0' à alt-0224 */ Result.add( car ); /* '\u00E1' á alt-0225 */ Result.add( car ); /* '\u00E2' â alt-0226 */ Result.add( car ); /* '\u00E3' ã alt-0227 */ Result.add( car ); /* '\u00E4' ä alt-0228 */ Result.add( car ); /* '\u00E5' å alt-0229 */ car = new java.lang.String("ae"); Result.add( car ); /* '\u00E6' æ alt-0230 */ car = new java.lang.String("c"); Result.add( car ); /* '\u00E7' ç alt-0231 */ car = new java.lang.String("e"); Result.add( car ); /* '\u00E8' è alt-0232 */ Result.add( car ); /* '\u00E9' é alt-0233 */ Result.add( car ); /* '\u00EA' ê alt-0234 */ Result.add( car ); /* '\u00EB' ë alt-0235 */ car = new java.lang.String("i"); Result.add( car ); /* '\u00EC' ì alt-0236 */ Result.add( car ); /* '\u00ED' í alt-0237 */ Result.add( car ); /* '\u00EE' î alt-0238 */ Result.add( car ); /* '\u00EF' ï alt-0239 */ car = new java.lang.String("d"); Result.add( car ); /* '\u00F0' ð alt-0240 */ car = new java.lang.String("n"); Result.add( car ); /* '\u00F1' ñ alt-0241 */ car = new java.lang.String("o"); Result.add( car ); /* '\u00F2' ò alt-0242 */ Result.add( car ); /* '\u00F3' ó alt-0243 */ Result.add( car ); /* '\u00F4' ô alt-0244 */ Result.add( car ); /* '\u00F5' õ alt-0245 */ Result.add( car ); /* '\u00F6' ö alt-0246 */ car = new java.lang.String("/"); Result.add( car ); /* '\u00F7' ÷ alt-0247 */ car = new java.lang.String("0"); Result.add( car ); /* '\u00F8' ø alt-0248 */ car = new java.lang.String("u"); Result.add( car ); /* '\u00F9' ù alt-0249 */ Result.add( car ); /* '\u00FA' ú alt-0250 */ Result.add( car ); /* '\u00FB' û alt-0251 */ Result.add( car ); /* '\u00FC' ü alt-0252 */ car = new java.lang.String("y"); Result.add( car ); /* '\u00FD' ý alt-0253 */ car = new java.lang.String("þ"); Result.add( car ); /* '\u00FE' þ alt-0254 */ car = new java.lang.String("y"); Result.add( car ); /* '\u00FF' ÿ alt-0255 */ Result.add( car ); /* '\u00FF' alt-0255 */ return Result; } /** Transforme une chaine pouvant contenir des accents dans une version sans accent * @param chaine Chaine a convertir sans accent * @return Chaine dont les accents ont été supprimé **/ public static java.lang.String sansAccent(java.lang.String chaine) { java.lang.StringBuffer Result = new StringBuffer(chaine); for(int bcl = 0 ; bcl < Result.length() ; bcl++) { int carVal = chaine.charAt(bcl); if( carVal >= MIN && carVal <= MAX ) { // Remplacement java.lang.String newVal = (java.lang.String)map.get( carVal - MIN ); Result.replace(bcl, bcl+1,newVal); } } return Result.toString(); } }
l'utilisation est simple :

String chaine = "Accés à la base"; String chaine2 = StringOperation.sansAccent(chaine); System.out.println("chaine origine : " + chaine ); System.out.println("chaine sans accents : " + chaine2 );

Auteur : Marc A. Mnich
Version : 14/01/2005
Generer des identifiant unique de façon fiable
Avantage:

  • Compatible identifiant SQL

/* * RandomGUID * @version 1.2 01/29/02 * @author Marc A. Mnich * com.brightobject.util.guidgenerator.util; * * From www.JavaExchange.com, Open Software licensing * * 01/29/02 -- Bug fix: Improper seeding of nonsecure Random object * caused duplicate GUIDs to be produced. Random object * is now only created once per JVM. * 01/19/02 -- Modified random seeding and added new constructor * to allow secure random feature. * 01/14/02 -- Added random function seeding with JVM run time * */ import java.net.*; import java.security.*; import java.util.*; /* * In the multitude of java GUID generators, I found none that * guaranteed randomness. GUIDs are guaranteed to be globally unique * by using ethernet MACs, IP addresses, time elements, and sequential * numbers. GUIDs are not expected to be random and most often are * easy/possible to guess given a sample from a given generator. * SQL Server, for example generates GUID that are unique but * sequencial within a given instance. * * GUIDs can be used as security devices to hide things such as * files within a filesystem where listings are unavailable (e.g. files * that are served up from a Web server with indexing turned off). * This may be desireable in cases where standard authentication is not * appropriate. In this scenario, the RandomGUIDs are used as directories. * Another example is the use of GUIDs for primary keys in a database * where you want to ensure that the keys are secret. Random GUIDs can * then be used in a URL to prevent hackers (or users) from accessing * records by guessing or simply by incrementing sequential numbers. * * There are many other possiblities of using GUIDs in the realm of * security and encryption where the element of randomness is important. * This class was written for these purposes but can also be used as a * general purpose GUID generator as well. * * RandomGUID generates truly random GUIDs by using the system's * IP address (name/IP), system time in milliseconds (as an integer), * and a very large random number joined together in a single String * that is passed through an MD5 hash. The IP address and system time * make the MD5 seed globally unique and the random number guarantees * that the generated GUIDs will have no discernable pattern and * cannot be guessed given any number of previously generated GUIDs. * It is generally not possible to access the seed information (IP, time, * random number) from the resulting GUIDs as the MD5 hash algorithm * provides one way encryption. * * ----> Security of RandomGUID: <----- * RandomGUID can be called one of two ways -- with the basic java Random * number generator or a cryptographically strong random generator * (SecureRandom). The choice is offered because the secure random * generator takes about 3.5 times longer to generate its random numbers * and this performance hit may not be worth the added security * especially considering the basic generator is seeded with a * cryptographically strong random seed. * * Seeding the basic generator in this way effectively decouples * the random numbers from the time component making it virtually impossible * to predict the random number component even if one had absolute knowledge * of the System time. Thanks to Ashutosh Narhari for the suggestion * of using the static method to prime the basic random generator. * * Using the secure random option, this class compies with the statistical * random number generator tests specified in FIPS 140-2, Security * Requirements for Cryptographic Modules, secition 4.9.1. * * I converted all the pieces of the seed to a String before handing * it over to the MD5 hash so that you could print it out to make * sure it contains the data you expect to see and to give a nice * warm fuzzy. If you need better performance, you may want to stick * to byte[] arrays. * * I believe that it is important that the algorithm for * generating random GUIDs be open for inspection and modification. * This class is free for all uses. * * * - Marc */ public class RandomGUID extends Object { private static Random myRand; private static SecureRandom mySecureRand; /* * Static block to take care of one time secureRandom seed. * It takes a few seconds to initialize SecureRandom. You might * want to consider removing this static block or replacing * it with a "time since first loaded" seed to reduce this time. * This block will run only once per JVM instance. */ static { mySecureRand = new SecureRandom(); long secureInitializer = mySecureRand.nextLong(); myRand = new Random(secureInitializer); } public String valueBeforeMD5 = ""; public String valueAfterMD5 = ""; /* * Default constructor. With no specification of security option, * this constructor defaults to lower security, high performance. */ public RandomGUID() { getRandomGUID(false); } /* * Constructor with security option. Setting secure true * enables each random number generated to be cryptographically * strong. Secure false defaults to the standard Random function seeded * with a single cryptographically strong random number. */ public RandomGUID(boolean secure) { getRandomGUID(secure); } /* * Method to generate the random GUID */ private void getRandomGUID(boolean secure) { MessageDigest md5 = null; StringBuffer sbValueBeforeMD5 = new StringBuffer(); try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { System.out.println("Error: " + e); } try { InetAddress id = InetAddress.getLocalHost(); long time = System.currentTimeMillis(); long rand = 0; if (secure) { rand = mySecureRand.nextLong(); } else { rand = myRand.nextLong(); } // This StringBuffer can be a long as you need; the MD5 // hash will always return 128 bits. You can change // the seed to include anything you want here. // You could even stream a file through the MD5 making // the odds of guessing it at least as great as that // of guessing the contents of the file! sbValueBeforeMD5.append(id.toString()); sbValueBeforeMD5.append(":"); sbValueBeforeMD5.append(Long.toString(time)); sbValueBeforeMD5.append(":"); sbValueBeforeMD5.append(Long.toString(rand)); valueBeforeMD5 = sbValueBeforeMD5.toString(); md5.update(valueBeforeMD5.getBytes()); byte[] array = md5.digest(); StringBuffer sb = new StringBuffer(); for (int j = 0; j < array.length; ++j) { int b = array[j] & 0xFF; if (b < 0x10) { sb.append('0'); } sb.append(Integer.toHexString(b)); } valueAfterMD5 = sb.toString(); } catch (UnknownHostException e) { System.out.println("Error:" + e); } } /* * Convert to the standard format for GUID * (Useful for SQL Server UniqueIdentifiers, etc.) * Example: C2FEEEAC-CFCD-11D1-8B05-00600806D9B6 */ public String toString() { String raw = valueAfterMD5.toUpperCase(); StringBuffer sb = new StringBuffer(); sb.append(raw.substring(0, 8)); sb.append("-"); sb.append(raw.substring(8, 12)); sb.append("-"); sb.append(raw.substring(12, 16)); sb.append("-"); sb.append(raw.substring(16, 20)); sb.append("-"); sb.append(raw.substring(20)); return sb.toString(); } }

Auteur : ptitom
Version : 14/01/2005
Fonction utilitaire de manipulation de File
/* * FileUtility * @author P. Thomas * ----------------------------------------------------------------------------- Description Les quatres principales methodes de cette classe utilitaire permet : - de calculer un chemin relatif à partir d'un répertoire de référence et du répertoire à relativiser - de supprimer récursivement des répertoires - de copier un fichier - de créer un fichier à un emplacement précis avec un nom défini à l'aide d'un pattern du type "Out-{0,number,#000}.tmp" [Cf. MessageFormat] ----------------------------------------------------------------------------- */ package AltaOcas.Util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import javax.swing.JFileChooser; public class FileUtility { protected static String getPrimaryPath(File ref, File access) { String path = ""; ArrayList refp = new ArrayList(); for (File cur = ref; cur != null; cur = cur.getParentFile()) { String name = cur.getName(); if (name.length() == 0) name = cur.getAbsolutePath(); refp.add(name); //System.out.println("Ref : '" + name + "'"); } ArrayList accp = new ArrayList(); for (File cur = access; cur != null; cur = cur.getParentFile()) { String name = cur.getName(); if (name.length() == 0) name = cur.getAbsolutePath(); accp.add(name); //System.out.println("Acc : '" + name + "'"); } if (refp.size() == 0 || accp.size() == 0) return path; if (refp.get(refp.size()-1).equals(accp.get(accp.size()-1))) { boolean equal = true; while (equal && refp.size() > 1 && accp.size() > 1) { refp.remove(refp.size()-1); accp.remove(accp.size()-1); equal = (refp.get(refp.size()-1).equals(accp.get(accp.size()-1))); } if (refp.size() == 1) { if (!equal) { refp.remove(refp.size()-1); path += ".." ; } else { refp.remove(refp.size()-1); accp.remove(accp.size()-1); path += "."; } } else { if (equal && accp.size() == 1) { refp.remove(refp.size()-1); accp.remove(accp.size()-1); } while (refp.size() > 0) { refp.remove(refp.size()-1); path += ".." ; if (refp.size() > 0) path += File.separator; } } while (accp.size() > 0) { String name = (String)accp.remove(accp.size()-1); path += File.separator; path += name; } } else { try { path = access.getCanonicalPath(); } catch (IOException e) { path = access.getAbsolutePath(); e.printStackTrace(); } } return path; } public static String getDiffPath(File ref, File acc) { try { File cref = ref.getCanonicalFile(); File cacc = acc.getCanonicalFile(); return getPrimaryPath(cref, cacc); } catch (IOException e) { e.printStackTrace(); return getPrimaryPath(ref, acc); } } public static String getDiffPath(String ref, String acc) { File fref = new File(ref); File facc = new File(acc); return getDiffPath(fref, facc); } public static void main(String[] args) { JFileChooser dlg = new JFileChooser(); dlg.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); while (true) { if( dlg.showOpenDialog(null) == JFileChooser.CANCEL_OPTION) return; File first = dlg.getSelectedFile(); if (first == null) return; if( dlg.showOpenDialog(null) == JFileChooser.CANCEL_OPTION) return; File last = dlg.getSelectedFile(); if (last == null) return; System.out.println("First Path : " + first.getPath()); System.out.println("Last Path : " + last.getPath()); System.out.println("First Name : " + first.getName()); System.out.println("Last Name : " + last.getName()); System.out.println("First AbsolutePath : " + first.getAbsolutePath()); System.out.println("Last AbsolutePath : " + last.getAbsolutePath()); System.out.println("Diff PrimaryPath : " + getPrimaryPath(first, last)); System.out.println("--------------------------------------------------\n"); } } public static void recursifDelete(File path) throws IOException { if (!path.exists()) throw new IOException( "File not found '" + path.getAbsolutePath() + "'"); if (path.isDirectory()) { File[] children = path.listFiles(); for (int i=0; children != null && i<children.length; i++) recursifDelete(children[i]); if (!path.delete()) throw new IOException( "No delete path '" + path.getAbsolutePath() + "'"); } else if (!path.delete()) throw new IOException( "No delete file '" + path.getAbsolutePath() + "'"); } public static void copyFile(File src, File dest) throws IOException { FileInputStream fis = new FileInputStream(src); FileOutputStream fos = new FileOutputStream(dest); java.nio.channels.FileChannel channelSrc = fis.getChannel(); java.nio.channels.FileChannel channelDest = fos.getChannel(); channelSrc.transferTo(0, channelSrc.size() , channelDest); fis.close(); fos.close(); } public static File createSpecifiedFile(String path, String pattern, int base) { File file = new File(path); if (!file.isDirectory()) return null; for (int cur = base; ; cur++) { Object[] args = {new Integer(cur)}; String result = MessageFormat.format(pattern, args); file = new File(path, result); if (!file.exists()) return file; } } }

Auteur : iubito
Version : 14/01/2005
Une classe Helper pour simplifier l'envoi de mail.
Possibilité d'ajouter des destinataires, copie et copie cachée, de vérifier si une adresse est valide.
On peut appeler les fonctions avec un tableau de String en paramètre, ou avec une String toute seule.
Une string peut contenir plusieurs adresses mails séparées par un espace, une virgule ou un point virgule.

Notes :

  • une fonction spéciale à la fin permet de transformer un pseudo en mail.
  • un tout petit peu de config au début, le serveur smtp et l'adresse no-reply

Exemple:

//Envoi un message provenant de no-reply@societe.fr au webmaster, //à mail@exemple et no.spam Mail m = new Mail(); m.setTo("webmaster, mail@exemple.com;no.spam@thank.you"); m.setSujet("test"); m.setMessage("Ceci est un test"); m.send();
/* * Created on 10 nov. 2004 */ package xxxx.util; import java.util.Properties; import javax.mail.Message; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; /** * Classe pour simplifier les envois de mails * @author SMAC */ public class Mail { /** Type texte brut */ static public final int TEXT = 0; /** Type text/html */ static public final int HTML = 1; /** Adresse "no-reply" par défaut de l'entreprise */ private static final String NOREPLY = "noreply@societe.fr"; /** Adresse du serveur SMTP de l'entreprise */ private static final String SMTPHOST = "smtp.societe.fr"; private Properties props; private Session session; private MimeMessage mm; private int mimetype; /** * Si on n'appelle pas setFrom, met automatiquement noreply@societe.fr */ private boolean noreply = true; /** * Créateur d'un mail. */ public Mail() { //Par défaut en texte brut mimetype = TEXT; //Get system properties props = System.getProperties(); //Setup mail server props.put("mail.smtp.host", SMTPHOST); //Get session session = Session.getDefaultInstance(props, null); //Define message mm = new MimeMessage(session); } //############################################################ //Ajout d'expéditeur et destinataires //############################################################ /** * Ajoute un expéditeur * @param expediteur * @throws Exception */ public void setFrom(String expediteur) throws Exception { if (expediteur.trim().length() > 0) { mm.setFrom(checkMail(expediteur)); noreply = false; } } /** * Ajoute un destinataire * @param destinataire * @throws Exception */ public void setTo(String destinataire) throws Exception { if (destinataire.trim().length() > 0) { if (plusieursMails(destinataire)) setTo(decoupe(destinataire)); else { mm.addRecipient(Message.RecipientType.TO, checkMail(destinataire)); } } } /** * Ajoute plusieurs destinataires * @param dest * @throws Exception */ public void setTo(String[] dest) throws Exception { for (int i=0; i<dest.length; i++) setTo(dest[i]); } /** * Ajoute un destinataire en copie * @param cc * @throws Exception */ public void setCC(String cc) throws Exception { if (cc.trim().length() > 0) { if (plusieursMails(cc)) setCC(decoupe(cc)); else { mm.addRecipient(Message.RecipientType.CC, checkMail(cc)); } } } /** * Ajoute plusieurs destinataires en copie * @param cc * @throws Exception */ public void setCC(String[] cc) throws Exception { for (int i=0; i < cc.length; i++) setCC(cc[i]); } /** * Ajoute un destinataire en copie cachée. * @param bcc * @throws Exception */ public void setCopieCachee(String bcc) throws Exception { if (bcc.trim().length() > 0) { if (plusieursMails(bcc)) setCopieCachee(decoupe(bcc)); else { mm.addRecipient(Message.RecipientType.BCC, checkMail(bcc)); } } } /** * Ajoute plusieurs destinataires en copie cachée. * @param bcc * @throws Exception */ public void setCopieCachee(String[] bcc) throws Exception { for (int i=0; i < bcc.length; i++) setCopieCachee(bcc[i]); } //############################################################ //Champs avec destinataires multiples //############################################################ /** * Teste si y'a plusieurs mails dans la chaîne, séparés par un espace, une virgule ou un point-virgule * @param mails * @return */ static public boolean plusieursMails(String mails) { return ((mails.indexOf(' ') + mails.indexOf(',') + mails.indexOf(';')) > -1); } /** * Découpe la chaîne contenant plusieurs mails en String[] * @return */ static public String[] decoupe(String mails) { return mails.split(" |,|;"); } //############################################################ //Sujet et message //############################################################ /** * Ajoute le sujet * @param sujet * @throws Exception */ public void setSujet(String sujet) throws Exception { mm.setSubject(sujet); } /** * Choisir entre le type texte brut ({@link Mail#TEXT}) ou HTML ({@link Mail#HTML}). * @param mime * @throws Exception */ public void setMimeType(int mime) throws Exception { mimetype = mime; } /** * Ajoute le message * @param message * @throws Exception */ public void setMessage(String message) throws Exception { if (mimetype == HTML) mm.setContent(message, "text/html"); else mm.setText(message); } //############################################################ //Envoi //############################################################ /** * Envoie le mail * @throws Exception */ public void send() throws Exception { if (noreply) setFrom(NOREPLY); Transport.send(mm); } //############################################################ //Vérifications de la validité d'adresse e-mails //(fonctions pour l'extérieur : jsp ou WebServices...) //############################################################ /** * Vérifie si l'adresse passée en paramètre est valide. Si elle ne contient pas * de @, vérifie si elle correspond bien à un pseudo (voir nameToMail). * @param mail */ static public void isValide(String mail) throws Exception { if (plusieursMails(mail)) areValide(decoupe(mail)); else Mail.checkMail(mail); } /** * Vérifie si les adresses passées en paramètres sont valides. Si elles ne contient pas * de @, vérifie si elles correspondent à des pseudos (voir nameToMail). * <p>Vérifie chacune des adresse, et renvoie une exception global, contenant plusieurs * messages d'erreur si plusieurs adresses sont fausses, chaque message étant séparé * par un \n. * @param mails * @throws Exception */ static public void areValide(String[] mails) throws Exception { String msg = ""; for (int i=0; i<mails.length; i++) { try { isValide(mails[i]); } catch (Exception e) { msg += ((msg.length()>0)?"\n":"") + e.getMessage(); } } if (msg.length() > 0) { throw new Exception(msg); } } //############################################################ //Fonctions private, //statiques pour être appelés par les public isValide et areValide //############################################################ /** * Vérifie la validité d'une adresse e-mail, et renvoie sous forme d'InternetAdress * ou une exception en cas d'erreur. * @param mail * @throws Exception */ static private InternetAddress checkMail(String mail) throws Exception { //Pas de @, c'est peut-être un pseudonyme ?... if (mail.indexOf('@') == -1) { return new InternetAddress(nameToMail(mail)); } else { //le parse d'InternetAddress ne renvoie pas d'erreur sur adresse@mail //alors on fait un test simple pour savoir si y'a un point, après l'@ //adresse@mail.fr est OK, adresse@mail renvoie une exception. if (mail.lastIndexOf('.') < mail.indexOf('@')) { throw new Exception("Adresse email \""+mail+"\" invalide"); } else { return new InternetAddress(mail); } } } /** * Ici votre fonction perso, qui transforme des noms génériques en adresses e-mail. * <p>Par exemple : webmaster -> webmaster@societe.fr * @param name * @throws Exception si le pseudo est inconnu. */ static private String nameToMail(String name) throws Exception { //L'exemple du mail au webmaster, si on met juste "webmaster" sans mettre //@societe.fr, cette fonction transforme. if (name.equalsIgnoreCase("webmaster")) return "webmaster@societe.fr"; //else if.... //else if.... //else c'est une erreur else throw new Exception("Nom \""+name+"\" inconnu"); } }

Auteur : ThePills
Version : 14/01/2005
Boîte de dialogue pour appliquer un Look and Feel dynamiquement
Boîte de dialogue permettant de choisir et d'appliquer un Look and Feel à une application de manière dynamique.


new JLookAndFeelChooser(aFrame).setVisible(true);
Avantage

  • Prend en compte tous les look and feels du système -> réagit à l'installation de nouveaux L&F

Inconvénient

  • certains L&F non officiels sont relativement instables...

import java.awt.*; import java.awt.event.*; import javax.swing.*; public final class JLookAndFeelChooser extends JDialog implements ActionListener { private static final LookAndFeelInfo[] LIST_L_AND_F = UIManager.getInstalledLookAndFeels(); private Frame frame; private JButton boutonAnnuler = null; private JButton boutonOK = null; private JComboBox comboLandF = null; private JPanel jContentPane = null; private JPanel panelB = null; private JPanel panelH = null; public JLookAndFeelChooser(Frame frame) { super(frame, true); this.frame = frame; this.setTitle("Choisissez le Look & Feel..."); this.setSize(200, 110); this.setLocationRelativeTo(getParent()); this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); this.setContentPane(getJContentPane()); } public void actionPerformed(ActionEvent ae) { Object source = ae.getSource(); if (source == boutonOK) { closeAndApply(); } else if (source == boutonAnnuler) { close(); } } private JButton getBoutonAnnuler() { if (boutonAnnuler == null) { boutonAnnuler = new JButton("Annuler"); boutonAnnuler.addActionListener(this); } return boutonAnnuler; } private JButton getBoutonOK() { if (boutonOK == null) { boutonOK = new JButton("OK"); boutonOK.addActionListener(this); } return boutonOK; } private JComboBox getComboLandF() { if (comboLandF == null) { String[] names = new String[LIST_L_AND_F.length]; for (byte b = 0; b < LIST_L_AND_F.length; b++) { names[b] = LIST_L_AND_F[b].getName(); } comboLandF = new JComboBox(names); comboLandF.setSelectedItem(UIManager.getLookAndFeel().getName()); } return comboLandF; } private JPanel getJContentPane() { if (jContentPane == null) { jContentPane = new JPanel(); jContentPane.setLayout(new GridLayout(2, 1)); jContentPane.add(getPanelH()); jContentPane.add(getPanelB()); } return jContentPane; } private JPanel getPanelB() { if (panelB == null) { panelB = new JPanel(); panelB.setLayout(new FlowLayout()); panelB.add(getBoutonOK()); panelB.add(getBoutonAnnuler()); } return panelB; } private JPanel getPanelH() { if (panelH == null) { panelH = new JPanel(); panelH.setLayout(new FlowLayout()); panelH.add(getComboLandF()); } return panelH; } private void close() { this.setVisible(false); this.dispose(); } private void closeAndApply() { if (frame != null) { byte b = (byte) comboLandF.getSelectedIndex(); String lookAndFeel = LIST_L_AND_F[b].getClassName(); try { UIManager.setLookAndFeel(lookAndFeel); SwingUtilities.invokeLater(new Runnable() { public void run() { SwingUtilities.updateComponentTreeUI(frame); } }); } catch (Exception e) { e.printStackTrace(); } } close(); } }

Auteur : divxdede
Version : 14/01/2005
lister une catègorie de plugins disponible
Cet outil permet de lister une catègorie de plugins disponible;
Il permet l'abstraction de l'emplacement physiques des plugins.
Ceux-ci peuvent être dans plusieurs JAR, des repertoires etc..

La recherche des plugins se fait sur 3 criteres :

  • accessibles par le classpath de l'application
  • Doivent se trouver dans un package determiné (sous-packages inclus)
  • Doivent hériter d'une classe mère de plugin (definit par vos soin)

Cette classe à pour rôle de vous aider a réaliser un mécanisme de plugins au sein d'une application JAVA.

package org.XXXXXXXX; import java.util.*; import java.util.zip.*; import java.io.*; import java.net.*; /** * PluginInspector * Ce module s'occupe de dresser une liste des "plugins" disponibles au sein d'une application JAVA * Ce code n'est qu'a titre d'exemple sur comment faire un outils permettant d'ajouter des plugins. * * L'idée de cet inspecteur est d'imposer un package pour les plugins et d'utiliser le classLoader afin * de determiner toutes les classes. * Il est ainsi possible de rajouter par la suite un fichier JAR contenant de nouveaux plugins et qu'ils * soient automatiquement pris en comptes par l'application (pour peu que le fichier JAR soit rajouté correctement au classpath) * * Un "PluginInspector" s'appuie sur deux elements pour identifier les plugins * - Le package de recherche (ainsi que tous les sous-packages) * - La classe mère des plugins afin de s'assurer qu'une classe est effectivement un plugin * * Il est possible d'avoir plusieurs "PluginInspector" pour gérer differentes natures de plugins * * Exemple : * - les plugins sont installés dans le package org.myApplic.plugins * - La classe mère des plugins est org.myApplic.util.Plugin * * Récuperation des plugins de l'application : * Iterator plugins = new PluginInspector("org.myApplic.plugins",org.myApplic.util.Plugin.class).plugins(); * while( plugins.hasNext() ) * { Class plugin = (Class)plugins.next(); * System.out.println("Plugin Loaded : " + plugin); * } * * Remarque : le PluginInspector charge les classes lors de l'examen, ce qui n'est pas un mauvais choix pour * un mécanisme de plugins, mais ce mécanisme pourait être assez pénalisant pour un usage detourné * * @author André Sébastien */ public class PluginInspector { /** Nom du package des plugins **/ private String pluginPackage = null; /** Classe mere de tous les plugins **/ private Class pluginHomeClass = null; /** Repertoire (en terme de resource) des plugins **/ private String pluginResourceName = null; /** Repertoire (en terme de fileSystem) des plugins **/ private String pluginFileName = null; /** Liste des plugins **/ private List plugins = new ArrayList(); /** Filtre utilisé lors d'un examen de repertoire physique **/ private static final FileFilter filter = new FileFilter() { public boolean accept(File pathname) { if(pathname.isDirectory() ) return true; if(!pathname.isFile() ) return false; String path = pathname.getAbsolutePath(); if( ! path.endsWith(".class") ) return false; if( path.indexOf('$') >= 0 ) return false; return true; } }; /** Constructeur * @param packageName Package dont doivent faire partie les plugins (sous-packages compris) * @param pluginHomeClass Class mére de tous les plugins, si null alors, il sera considéré Object.class comme class mère de tous les plugins **/ public PluginInspector(String packageName , Class pluginHomeClass ) { /** Initialisation **/ this.pluginPackage = packageName; this.pluginHomeClass = pluginHomeClass; if( this.pluginHomeClass == null ) this.pluginHomeClass = Object.class; /** On calcul le repertoire d'acces aux repertoires **/ this.pluginResourceName = this.pluginPackage.replace('.','/'); this.pluginFileName = this.pluginPackage.replace('.', File.separatorChar ); /** Lance l'examen de l'application **/ this.examine(); } /** Retourne la liste des plugins accessiblent (objets "Class") **/ public Iterator plugins() { return this.plugins.iterator(); } /** Examine l'application pour determiner les plugins accessibles **/ private void examine() { try { Enumeration e = this.getClass().getClassLoader().getResources( this.pluginResourceName ); while( e.hasMoreElements() ) { URL url = (URL)e.nextElement(); String protocol = url.getProtocol(); if( protocol.equals("file") ) this.examineFromDirectory( new File(url.getFile() ) ); else if( protocol.equals("jar")) this.examineFromJar(url); } } catch(Exception e){ e.printStackTrace(); } } /** Examine les plugins à partir d'un repertoire physique **/ private void examineFromDirectory(File directory) { if( ! directory.isDirectory() ) return; try { File[] files = directory.listFiles( this.filter ); for(int i = 0 ; i < files.length ; i++) { File file = files[i]; if( file.isDirectory() ) { this.examineFromDirectory( file ); continue; } /** Transformer le chemin en package **/ String name = file.getAbsolutePath(); int pos = name.indexOf( this.pluginFileName ); if( pos == -1 ) continue; name = name.substring( pos , name.length() - 6 ).replace( File.separatorChar , '.'); /** Charger le plugin **/ Class plugin = this.getClass().forName(name); if( ! this.pluginHomeClass.isAssignableFrom( plugin ) ) continue; if( this.plugins.contains( plugin ) ) continue; this.plugins.add(plugin); } } catch(Exception e){ e.printStackTrace(); } } /** Examine les plugins à partir d'un JAR **/ private void examineFromJar(URL url) { String jarName = url.getFile(); jarName = jarName.substring( jarName.indexOf(':') ); jarName = jarName.substring(0 , jarName.indexOf('!' ) ); jarName = jarName.replace('/', File.separatorChar ); try { ZipFile zipFile = new ZipFile(jarName); Enumeration e = zipFile.entries(); while( e.hasMoreElements() ) { ZipEntry entry = (ZipEntry)e.nextElement(); String name = entry.getName(); if( ! name.endsWith(".class") ) continue; if( ! name.startsWith( this.pluginResourceName ) ) continue; if( name.indexOf('$') >= 0 ) continue; /** suppression du .class et remise sous forme de package **/ name = name.substring(0, name.length() - 6 ); name = name.replace('/','.'); /** Charger le plugin **/ Class plugin = this.getClass().forName(name); if( ! this.pluginHomeClass.isAssignableFrom( plugin ) ) continue; if( this.plugins.contains( plugin ) ) continue; this.plugins.add(plugin); } zipFile.close(); } catch(Exception e){ e.printStackTrace(); } } }


Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2005 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.