Introspection en Java

FormateurDot_2

Il formate les données des structures avec une seul réplique de chaque entité :

Lire la suite

FormateurDot

Il formate les données des structures :

Lire la suite

StructureDonneeMembre

Il Structure les données propre aux données membres recueilli par les Inspecteurs :

Lire la suite

StructureClasse

Il structure les données propre à la classe recueilli par les Inspecteurs :

Lire la suite

StructureObjet

Il structure les données propre à l'objet recueilli par les Inspecteurs :

Lire la suite

StructureMethode

Il structure les données propre aux méthodes recueilli par les Inspecteurs :

Lire la suite

InspecteurMethode

Il inspecte les méthodes :

Lire la suite

InspecteurDonneeMembre

Il inspecte les données membres :

Lire la suite

InspecteurClasse

Il inspecte les classe :

Lire la suite

InspecteurObjet

Il inspecte les objets :

Lire la suite

Notre Programme d'introspection

Nous avons choisi de présenter notre programme en lui demandant de d'introspecter lui-même, classe par classe.

Lire la suite

Résultat des classes précédentes

En utilisant les classes précédentes, nous pouvons réaliser le graphique d'un objet. Sur ce graphique nous voyons, les méthodes qu'il utilise, les types et les visibilités. Chaque caractéristique est représentée une seule fois mais elle peut être pointée par toutes les entités qui partage la même caractéristique :

Lire la suite

Structure des objets

Il ne nous manquait plus que les objets, nous mettons en ligne la classe permettant de structurer toutes les données extraites des objets par les classes précédentes :

Lire la suite

Structure des méthodes

C'est le même principe que pour les classes et les données membres. Ces structures nous sont utile pour organiser le *.dot qui sera former grâce à la classe "FormateurDot_2" :

Lire la suite

Structure des données membres

Même utilité que pour les classes :

Lire la suite

Structure de Classe

La structure de classe doit nous permettre de structurer les données extraites des classes. Pour cela nous avons écrit la classe suivante :

Lire la suite

Inspecteur Objet

Nous avons étudié les classes et les méthodes, il ne nous manquait plus que les objets, c'est chose faite ! La classe suivante nous permet d'extraire toutes les informations, sur les objets, dont nous avons besoin :

Lire la suite

Inspecteur méthode 2

Nous avons amélioré la première mouture de l'inspecteur de méthode pour pouvoir l'utiliser dans notre programme général :

Lire la suite

Inspecter les données membres

Nous nous sommes intéressé aux données membres, dans le but de pouvoir décrire les objets de manière plus précise. Pour cela nous avons écrit la classe suivante qui extrait toutes ces informations :

Lire la suite

Lire une classe

Comme nous l'avons fait pour les méthodes, nous nous sommes intéressé l'introspection d'une classe. Nous avons écrit pour cela une classe contenant toutes les méthodes utiles :

Lire la suite

Créer un fichier *.dot

Nous nous sommes penché sur la manière de créer un fichier *.dot, ce fichier sera ouvert par Graphviz ou tout autre logiciel du même type. Pour créer ces fichiers nous avons écrit la classe suivante (c'est une amélioration de la classe postée précédemment) :
package introspection.formateur;

import introspection.structure.StructureClasse;
import introspection.structure.StructureDonneeMembre;
import introspection.structure.StructureMethode;
import introspection.structure.StructureObjet;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Iterator;

public class FormateurDot_2 {
	private Object o = null;
	private String noeudPackage = "", noeudClasse = "", noeudObjet = "",
			noeudMethode = "", noeudVisibilite = "", noeudType = "",
			noeudAttribut = "", noeudParametre = "";
	private String lien = "", lienClasseInterface = "", lienSecondaire = "";
	private ArrayList listeElement = new ArrayList();

	// Constructeur par défaut
	public FormateurDot_2() {
	}

	// Constructeur
	public FormateurDot_2(Object o) {
		this.o = o;
	}

	// Méthode qui retourne l'objet qui est à la base de l'introspection
	public Object obtenirObjet() {
		return this.o;
	}

	// Méthode qui initialise l'objet à la base de l'introspection
	public void indiquerObjet(Object o) {
		this.o = o;
	}

	// Construction du fichier.dot

	public String formaterStructure() {
		int indexPackage = -1, indexClasse = -1, indexObjet = -1;
		int indexMethode = -1, indexVisibilite = -1, indexType = -1;
		int indexAttribut = -1, indexParametere = -1;
		Object tampon;
		int _hashCode;
		int alpha;        // memoire index
		int beta;

		// Liste des structures d'objets
		
		ArrayList strcObjet = new StructureObjet(this.o).structureObjet();
		tampon = strcObjet.get(0);
		_hashCode = tampon.hashCode();
		alpha = _hashCode;
		if (!this.listeElement.contains(_hashCode)) {
			this.listeElement.add(_hashCode);
			this.noeudObjet += "\t\t" + _hashCode + " [label=\"" + tampon
					+ "\"];\n";
		}

		tampon = strcObjet.get(1);
		_hashCode = tampon.hashCode();
		beta = _hashCode;
		if (!this.listeElement.contains(_hashCode)) {
			this.listeElement.add(_hashCode);
			this.noeudClasse += "\t\t" + _hashCode + " [label=\""
					+ ((Class) tampon).getName() + "\"];\n";
		}
		this.lien += "\t\t" + alpha + " -> " + _hashCode + ";\n";

		// Liste des structures de classes
		ArrayList strcClasse = new StructureClasse((Class) tampon)
				.structureClasse();
		tampon = strcClasse.get(1);
		for (int i = 0; i < ((Class[]) tampon).length; i++) {
			_hashCode = ((Class[]) tampon)[i].hashCode();
			if (!this.listeElement.contains(_hashCode)) {
				this.listeElement.add(_hashCode);
				this.noeudClasse += "\t\t" + _hashCode + " [label=\""
						+ ((Class[]) tampon)[i].getName() + "\"];\n";
			}
			this.lienClasseInterface += "\t\t" + beta + " -> " + _hashCode
					+ ";\n";
		}
		tampon = strcClasse.get(2);
		_hashCode = tampon.hashCode();
		if (!this.listeElement.contains(_hashCode)) {
			this.listeElement.add(_hashCode);
			this.noeudClasse += "\t\t" + _hashCode + " [label=\""
					+ ((Class) tampon).getName() + "\"];\n";
		}
		this.lien += "\t\t" + beta + " -> " + _hashCode + ";\n";
		tampon = strcClasse.get(3);
		_hashCode = tampon.hashCode();
		if (!this.listeElement.contains(_hashCode)) {
			this.listeElement.add(_hashCode);
			this.noeudPackage += "\t\t" + _hashCode + " [label=\""
					+ ((Package) tampon).getName() + "\"];\n";
		}
		this.lien += "\t\t" + beta + " -> " + _hashCode + ";\n";

		Field[] tamponFs = (Field[]) strcObjet.get(2);
		for (int i = 0; i < tamponFs.length; i++) {
			_hashCode = tamponFs[i].hashCode();
			beta = _hashCode;
			if (!this.listeElement.contains(_hashCode)) {
				this.listeElement.add(_hashCode);
				this.noeudObjet += "\t\t" + _hashCode + " [label=\""
						+ tamponFs[i].toGenericString() + "\"];\n";
			}
			this.lien += "\t\t" + alpha + " -> " + _hashCode + ";\n";

			// Liste des données membres
			ArrayList strcDonneeMembre = new StructureDonneeMembre(tamponFs[i])
					.structureDonneeMembre();
			tampon = strcDonneeMembre.get(1);
			_hashCode = tampon.hashCode();
			if (!this.listeElement.contains(_hashCode)) {
				this.listeElement.add(_hashCode);
				this.noeudType += "\t\t" + _hashCode + " [label=\""
						+ ((Type) tampon).toString() + "\"];\n";
			}
			this.lien += "\t\t" + beta + " -> " + _hashCode + ";\n";
			tampon = strcDonneeMembre.get(2);
			_hashCode = tampon.hashCode();
			if (!this.listeElement.contains(_hashCode)) {
				this.listeElement.add(_hashCode);
				this.noeudVisibilite += "\t\t" + _hashCode + " [label=\""
						+ ((String) tampon).toString() + "\"];\n";
			}
			this.lienSecondaire += "\t\t" + beta + " -> " + _hashCode + ";\n";
			tampon = strcDonneeMembre.get(3);
			for (Iterator it = ((ArrayList) tampon).iterator(); it
					.hasNext();) {
				String temporaire = (String) it.next();
				_hashCode = temporaire.hashCode();
				if (!this.listeElement.contains(_hashCode)) {
					this.listeElement.add(_hashCode);
					this.noeudAttribut += "\t\t" + _hashCode + "[label=\""
							+ temporaire.toString() + "\"];\n";
				}
				this.lienSecondaire += "\t\t" + beta + " -> " + _hashCode
						+ ";\n";
			}
		}

		Method[] tamponMs = (Method[]) strcObjet.get(3);
		for (int i = 0; i < tamponMs.length; i++) {
			_hashCode = tamponMs[i].hashCode();
			beta = _hashCode;
			if (!this.listeElement.contains(_hashCode)) {
				this.listeElement.add(_hashCode);
				this.noeudMethode += "\t\t" + _hashCode + " [label=\""
						+ tamponMs[i].getName() + "\"];\n";
			}
			this.lien += "\t\t" + alpha + " -> " + _hashCode + ";\n";

			// Liste des structures de méthodes
			ArrayList strcMethode = new StructureMethode(tamponMs[i])
					.structureMethode();
			tampon = strcMethode.get(1);
			_hashCode = tampon.hashCode();
			if (!this.listeElement.contains(_hashCode)) {
				this.listeElement.add(_hashCode);
				this.noeudType += "\t\t" + _hashCode + " [label=\""
						+ ((Class) tampon).getName() + "\"];\n";
			}
			this.lien += "\t\t" + beta + " -> " + _hashCode + ";\n";
			tampon = strcMethode.get(2);
			_hashCode = tampon.hashCode();
			if (!this.listeElement.contains(_hashCode)) {
				this.listeElement.add(_hashCode);
				this.noeudVisibilite += "\t\t" + _hashCode + " [label=\""
						+ ((String) tampon).toString() + "\"];\n";
			}
			this.lienSecondaire += "\t\t" + beta + " -> " + _hashCode + ";\n";
			tampon = strcMethode.get(3);
			for (Iterator it = ((ArrayList) tampon).iterator(); it
					.hasNext();) {
				String temporaire = (String) it.next();
				_hashCode = temporaire.hashCode();
				if (!this.listeElement.contains(_hashCode)) {
					this.listeElement.add(_hashCode);
					this.noeudAttribut += "\t\t" + _hashCode + "[label=\""
							+ temporaire.toString() + "\"];\n";
				}
				this.lienSecondaire += "\t\t" + beta + " -> " + _hashCode
						+ ";\n";
			}
			tampon = strcMethode.get(4);
			for (int j = 0; j < ((Class[]) tampon).length; j++) {
				_hashCode = ((Class[]) tampon)[j].hashCode();
				if (!this.listeElement.contains(_hashCode)) {
					this.listeElement.add(_hashCode);
					this.noeudClasse += "\t\t" + _hashCode + " [label=\""
							+ ((Class[]) tampon)[j].getName() + "\"];\n";
				}
				this.lien += "\t\t" + beta + " -> " + _hashCode + ";\n";
			}
		}

		tampon = "digraph {\n" + "\t/*mise en forme du graph*/\n"
				+ "\t\t	graph [rankdir = LR];\n"
				+ "\n\t/*mise en forme des noeuds*/\n"
				+ "\tnode [shape=box];\n" + this.noeudPackage
				+ "\tnode [shape=octagon];\n" + this.noeudObjet
				+ "\tnode [shape=parallelogram];\n" + this.noeudMethode
				+ "\tnode [shape=polygon,sides=5];\n" + this.noeudClasse
				+ "\tnode [color=orange]\n" + this.noeudType
				+ "\tnode [shape=ellipse, color=red];\n" + this.noeudVisibilite
				+ "\tnode [color=blue];\n" + this.noeudAttribut +

				this.lien + "\tedge[color=lightgray];\n" + this.lienSecondaire
				+ "\tedge[style=dotted, color=black];\n"
				+ this.lienClasseInterface + "}";

		return (String) tampon;
	}

}
		
		
		
	
	

Première esquisse

Voici le résultat d'une première esquisse de notre programme d'introspection. Pour sa réalisation nous avons décomposé le programme en 3 grandes parties :
- les Inspecteurs; ils nous permettent de recueillir les différentes informations sur les entités.
- les Structures; elles permettent de stocker et d'ordonner les données collectées par les Inspecteurs.
- les Formateurs; ce sont eux qui vont transcrire les Structures en un langage de description, dans notre cas ils nous permettent de générer un fichier.dot exécutable avec Graphviz.

Image indisponible
Cliquez sur l'image pour agrandir.

Schéma de base

Notre choix c'est porté sur Graphviz pour la représentation des Graphs car il est simple d'utilisation et lit les fichiers.dot, format de description de Graphs que nous avons retenu.
La structure de schéma réalisé pour représenter les informations issues de la classe Reflect est la suivante :
Image Indisponible

Le fichier.dot permettant de générer ce graphe est le suivant :

digraph {
	/*mise en forme du graph*/
	graph [rankdir = LR];

	/*mise en forme des noeuds*/
	node [shape=box];
		Package;

	node [shape=octagon];
		objet;
		"donnee membre";

	node [shape=parallelogram];
		methode;

	node [shape=ellipse, color=red];
		visibilite_dm [label="visibilite"];
		visibilite_m [label="visibilite"];

	node [shape=ellipse, color=blue];
		mot_clef_modifieur_dm [label="mot clef\nmodifieur"];
		mot_clef_modifieur_m [label="mot clef\nmodifieur"];
		node [shape=polygon,sides=5, color=orange];
		Type;
		"Type de retour";

	node [color=black];
		Classe;
		SuperClasse;
		Interface;

	node [shape=polygon,sides=5];
		parametre;

	/*mise en forme des liens*/
		objet -> Classe;
		Classe -> SuperClasse;
		Classe -> Package;

	edge[style=dotted];
		Classe -> Interface;

	edge[style=filled];
		objet -> "donnee membre";
		"donnee membre" -> visibilite_dm;
		"donnee membre" -> mot_clef_modifieur_dm;
		"donnee membre" -> Type;

		objet -> methode;
		methode -> visibilite_m;
		methode -> mot_clef_modifieur_m;
		methode -> "Type de retour";
		methode -> parametre;

	/*alignement*/
	{ rank = same; Package; objet;}

}

Visualiser le resultat

Pour pouvoir exploiter les informations que nous retourne la classe Reflect, nous avons choisi de les visualiser sous forme de Graph. Nous avons commencé par la recherche de programme de visualisation de Graph :
- Graphviz (http://www.graphviz.org)
- Prefuse (http://prefuse.org)
- Walrus (http://www.caida.org/tools/visualization/walrus/)

et nous analysons actuellement leur différents modes d'utilisations :
- langage de description de Graph supporté
- possibilité de manipulation en lignes de commandes
- affichage 2D, 3D
- ...


Nous avons également recherché comment exécuter un programme « *.exe » à partir d'un programme en Java. Le code que nous avons écrit pour réussir cette action est le suivant :


import java.io.InputStream;

public class Executable 

	// passage par argument de la commande à lancer

	
	public Executable(String command){
		StartCommand(command);
	}

	public void StartCommand(String command) {
		try {
			// creation du processus
			
			Process p = Runtime.getRuntime().exec(command);
			InputStream in = p.getInputStream();

			// on récupère le flux de sortie du programme

			StringBuilder build = new StringBuilder();
			char c = (char) in.read();

			while (c != (char) -1) {
				build.append(c);
				c = (char) in.read();
			}

			String response = build.toString();

			// on l'affiche
			
			System.out.println(response);
		} catch (Exception e) {
			System.out.println("\n" + command + ": commande inconnue ");
		}
	}
}


Retour à la page principale

La visibilité, les attributs, et les types d'une méthode

Cette séance nous avons travaillé à identifier la visibilité, le type de retour, les types des arguments en paramètre, et le nom de la méthode. Nous vous proposons les solutions suivantes :
        // Le type de retour	
        public String returnType(Method m) {
		return m.getReturnType().toString();
	}

        // La liste des types en paramètre
	public Class[] TypeParameter(Method m) {
		return m.getParameterTypes();
	}

        // La visibilité
	public String visibilite(Method m) {
		String met = m.toString();
		String visi = "";
		StringTokenizer st = new StringTokenizer(met, " ");
		while (st.hasMoreTokens()) {
			String next = st.nextToken();
			if (next.equals("public"))
				visi = "public";
			if (next.equals("protected"))
				visi = "protected";
			if (next.equals("private"))
				visi = "private";
		}
		return visi;
	}


        // Les attributs
	public String attribute(Method m) {
		String meth = m.toString();
		String att = "";
		String next = "";
		StringTokenizer st = new StringTokenizer(meth, " ()");

		while (st.hasMoreTokens()) {
			next = st.nextToken();

			if (next.equals("static")) {
				att += "static ";
			}

			if (next.equals("final")) {
				att += "final ";
			}
		}
		return att;
	}

        // Le nom de la méthode
	public String nameMethod(Method m){
		return m.getName();
	}

La classe Reflect intégrée dans Java

La classe Reflect permet de lire le nom, les méthodes et les objets d'une classe en cours d'exécution. Nous avons écrit une classe pour en utiliser les fonctions principales :

package afficheur;

import java.io.IOException;
import java.lang.reflect.*;

public class InspecteurClasse {
	
	private Class cl;
	private static Method[] m = null;
	private static Field[] f = null;

	// Constructeur
	
	public InspecteurClasse(Class cl){
		this.cl=cl;
	}
	
	// Java permet de récupérer le nom complet d'une classe
	
	public String getName(){
		return this.cl.getName();
	}
	
	// Java permet de récupérer la liste des méthodes
           contenues dans une classe
	
	public Method[] getMethod(){
		return this.cl.getDeclaredMethods();
	}
	
	// Java permet de récupérer la liste des objets
           contenues dans une classe
	
	public Field[] getField(){
		return this.cl.getDeclaredFields();
	}

}

Bibliographie

http://java.sun.com/
http://fr.sun.com/
http://fr.wikipedia.org/
http://www.developpez.com/
http://www.graphviz.org



Retour à la page principale

L’Introspection


Qu’est ce que l’introspection ?

L’introspection permet d’examiner, voir de modifier, les structures de haut niveau (les objets, les classes, etc.). Un programme examine alors son propre état. L’introspection n’est possible que si le langage est dit réflexif. Un langage est réflexif quand son architecture est implémentée par un concept de méta-objet. Ce concept permet de représenter des éléments de programme orientés objet (Classes, objets, méthodes, etc.). La réflexivité permet ainsi de concevoir des codes plus génériques puisque les entités ne sont plus manipulées nominativement, grâce à cela la compilation ne fige plus le devenir de l'application et rend la programmation plus souple.

Les langages dits réflexifs sont les suivants :
- SmallTalk
- CLOS
- Python
- Ruby
- Java©
- Objective-C
- PHP, depuis la version 5
- Les langages qui fonctionnent avec l'architecture .NET (comme le C#)


Nous nous intéressons plus spécifiquement à l’introspection avec le langage orienté objet Java©.

L’introspection en Java© :

L’introspection en Java© donne la possibilité de découvrir dynamiquement les propriétés des classes et des objets. Java© donne des outils pour l’introspection, notamment pour les classes avec le package java.lang.reflect


© Java est la propriété de Sun Microsystems : http://fr.sun.com/


Retour à la page principale

Nous contacter par courriel


projet.dg@gmail.com
ou
yves.delvaux@uha.fr
nelson.guimaraes@uha.fr


Retour à la page principale

Guimarães Nelson

Née le 24 avril 1986 à Mulhouse.

Formation

Rentée scolaire 2007 : 1° Année en filière Informatique & Réseaux à l'ENSISA MULHOUSE (68)

Années 2004-2007: Classe Préparatoire aux Grandes Ecoles section Mathématiques-Physique au Lycée Schweitzer à MULHOUSE (68)

Année 2004 : Baccalauréat S (SVT) option Physique-Chimie, mention Assez Bien au Lycée Lambert à MULHOUSE (68)

Langues : Notion d’Allemand et d’Anglais. Portugais lu, écrit et parler couramment.

Expérience professionnelle

22/12/06-02/01/07 : Auchan Mulhouse :

05/04/07-07/04/07 : conseiller de vente à la poissonnerie

Loisir

Karaté : ceinture verte

Club ENSISA M'BOT : participation à la Coupe de France de Robotique

Musique : clarinettiste

Retour à la page principale

CV de Delvaux Yves

PageRank du Blog

PageRank Actuel Indisponible


Retour à la page principale


Consulter les Statistiques

Liste des liens Indexés par Google

Delvaux Yves

Delvaux Yves né le 10 novembre 1986 à Toulouse

Cursus scolaire :

1992 – 1996 : Ecole primaire Notre Dame des Anges (Toulouse)

1996 – 2002 : Collège Saint Joseph (Toulouse)

2002 – 2003 : Seconde général et technologique au lycée Saint Joseph (Toulouse)

2003 – 2005 : Première et Terminale Science et Technique Industrielle option génie électronique au lycée Saint Joseph (Rodez)

2005 – 2007 : Classe préparatoire aux grandes écoles Technique des Sciences de l’Ingénieur au lycée Louis Vincent (Metz)

Depuis 2007 : Ecole Nationale Supérieur d’Ingénieur de Sud Alsace option Informatique et Réseau (Mulhouse)

Diplômes scolaires obtenus

2002 : Brevet des collèges

2005 : Bac Science et Technologie Industrielle option génie électronique mention Très Bien

Savoir faire :

Programmation en Java et C#

Notion dans les langages objets

Hobbys

Pratique de l’escrime

Chef scout

Club café théâtre

Retour à la page principale

CV de Guimarães Nelson