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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Comment instancier class avec pattern org.**.MyClass


Sujet :

Langage Java

  1. #1
    Membre expérimenté
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Points : 1 464
    Points
    1 464
    Par défaut Comment instancier class avec pattern org.**.MyClass
    Bonjour,

    Je souhaiterais instancier des classes à l'aide d'une string package + class name.

    Pour l'instant je ne gere le cas ou je renseigne le package + class name

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ClassLoader classLoader = ...
    String className = "org.akrogen.tkui.core.css.swt.properties.css2.border.CSSPropertyBorderHandler";
    Class clazz = classLoader.loadClass(className );
    Object instance = clazz.newInstance();
    Ce qui marche tres bien.

    Maintenant je souhaiterais gerer des patterns au niveau des package et pouvoir instancier une classe avec le pattern suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String className = "org.akrogen.tkui.core.css.swt.properties.css2.*.CSSPropertyBorderHandler"
    ou encore

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String className = "org.**.CSSPropertyBorderHandler"
    Donc pour faire cela je dois etre capable de recuperer l'arborsence des packages mais je ne sais pas comment faire.

    J'ai vu qu'il y avait la classe java.lang.Package mais je n'arrive pas bien a l'utiliser.

    Si vous connaissez uen API qui gère ca ou si vous pouvez me donner des pistes je suis preneur de l'information.

    Merci de votre aide.

    Angelo

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Ce n'est pas possible directement, tout simplement parce que selon le mode de distribution de ton application et son classloader tu ne peux pas connaitre à l'avance toutes les classes (par exemple elles peuvent être à distance sur un serveur HTTP et téléchargé à la demande).

    Enfin bref tout ca pour dire que ce n'est pas possible directement avec l'API standard.

    Maintenant si tu utilises ton propre classloader ou que tu spécifies le répertoire de base de ces classes cela pourrait se faire assez facilement...



    Sinon... détaille un peu les raisons de tout cela


    a++

  3. #3
    Membre expérimenté
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Points : 1 464
    Points
    1 464
    Par défaut
    Bonjour adiGuba,

    merci de ta reponse. Je me doutais que c'etait complique et je susi en train de regarder du cote ds classloader (j'en ai developpe un qui s'inspire du classloader ANT) et je vais essayer de gerer le cas des patterns.

    En fait je souhaiterais faire ca pour le moteur CSS Swing/SWT que je suis en train de developper.

    Pour appliquer un style CSS comme backround-color:red a une JTextField, le moteur CSS appelle la classe CSSBackgroundColorHandler (le moteur CSS transforme backround-color en CSSBackgroundColorHandler ).

    Apres il peut y avoir une classe CSSBackgroundColorHandler pour SWT et uen classe CSSBackgroundColorHandler pour Swing. Ceci se discerne par le package.

    Donc lorsque le moteur CSS doit s'appliquer sur du Swing j'indique que les classe CSS*Handler doivent etre recherche dans un package

    Ex : org.akrogen.tkui.core.css.swing.properties.css2.background

    Pour faire cela je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CSSEngineLazyHandlerImpl engine = new CSSEngineLazyHandlerImpl();
    engine.registerPackage("org.akrogen.tkui.core.css.swt.properties.css2.background");
    engine.registerPackage("org.akrogen.tkui.core.css.swt.properties.css2.border");
    ...
    Et donc quand la propriete backround-color:red doit etre applique ca appelle l aclasse org.akrogen.tkui.core.css.swt.properties.css2.background.CSSBackgroundColorHandler .

    En fait pour faciliter l'ecriture ce que je souhaiterais c'est pouvoir ecrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CSSEngineLazyHandlerImpl engine = new CSSEngineLazyHandlerImpl();
    engine.registerPackage("org.akrogen.tkui.core.css.swt.properties.css2.*");
    Angelo

  4. #4
    Membre expérimenté
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Points : 1 464
    Points
    1 464
    Par défaut
    Bonjour,

    Je ne sais pas si ca interesse quelqu'un mais j'ai enfin trouve une solution!!!
    Un grand merci a djo.mos qui m'a donné une piste avec son son billet sur Spring

    Le test que j'ai fait sont avec 2 classes Java qui sont stockes dans le package a et l'autre dans le package a.b.

    Mon but etant de retrouver a partir du pattern a** toutes les classes contenus dans les packages a et a.b :

    J'ai décortiqué les sources de Spring et voici le code qui permet de retrouver les classes du pacakge a et package a.b :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    import org.springframework.core.io.Resource;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.core.io.support.ResourcePatternResolver;
     
    public class TestPackage1 {
     
    	public static void main(String[] args) {
    		try {
    			String packageSearchPath = "classpath*:a**/**/*.class";
    			ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
    			Resource[] resources = resourcePatternResolver
    					.getResources(packageSearchPath);
    			for (int i = 0; i < resources.length; i++) {
    				Resource resource = resources[i];
    				System.out.println(resource);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    En sortie console , j'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    file [C:\Documents and Settings\Dev\workspace-tkui-new\testSpring\bin\a\b\MyClassAB.class]
    file [C:\Documents and Settings\Dev\workspace-tkui-new\testSpring\bin\a\MyClassA.class]
    Pour executer ce code, il faut les jars de Spring : spring-core.jar, commons-logging.jar, log4j.jar

    Maintenant pour avoir des informations plus fines comme le nom de la classe, le noms de ces interfaces, Spring utilise asm (objectweb). Malheursement ce code ne marche que sous Java5. Donc j'ai épuré le code et il faut creer la classe ClassMetadataReadingVisitor comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    import org.objectweb.asm.Opcodes;
    import org.objectweb.asm.commons.EmptyVisitor;
     
    import org.springframework.core.type.ClassMetadata;
    import org.springframework.util.ClassUtils;
     
    public class ClassMetadataReadingVisitor extends EmptyVisitor {
     
    	private String className;
     
    	private boolean isInterface;
     
    	private boolean isAbstract;
     
    	private String enclosingClassName;
     
    	private boolean independentInnerClass;
     
    	private String superClassName;
     
    	private String[] interfaces;
     
     
    	public void visit(int version, int access, String name, String signature, String supername, String[] interfaces) {
    		this.className = ClassUtils.convertResourcePathToClassName(name);
    		this.isInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
    		this.isAbstract = ((access & Opcodes.ACC_ABSTRACT) != 0);
    		if (supername != null) {
    			this.superClassName = ClassUtils.convertResourcePathToClassName(supername);
    		}
    		this.interfaces = new String[interfaces.length];
    		for (int i = 0; i < interfaces.length; i++) {
    			this.interfaces[i] = ClassUtils.convertResourcePathToClassName(interfaces[i]);
    		}
    	}
     
    	public void visitOuterClass(String owner, String name, String desc) {
    		this.enclosingClassName = ClassUtils.convertResourcePathToClassName(owner);
    	}
     
    	public void visitInnerClass(String name, String outerName, String innerName, int access) {
    		if (outerName != null && this.className.equals(ClassUtils.convertResourcePathToClassName(name))) {
    			this.enclosingClassName = ClassUtils.convertResourcePathToClassName(outerName);
    			this.independentInnerClass = ((access & Opcodes.ACC_STATIC) != 0);
    		}
    	}
     
     
    	public String getClassName() {
    		return this.className;
    	}
     
    	public boolean isInterface() {
    		return this.isInterface;
    	}
     
    	public boolean isAbstract() {
    		return this.isAbstract;
    	}
     
    	public boolean isConcrete() {
    		return !(this.isInterface || this.isAbstract);
    	}
     
    	public boolean isIndependent() {
    		return (this.enclosingClassName == null || this.independentInnerClass);
    	}
     
    	public boolean hasEnclosingClass() {
    		return (this.enclosingClassName != null);
    	}
     
    	public String getEnclosingClassName() {
    		return this.enclosingClassName;
    	}
     
    	public boolean hasSuperClass() {
    		return (this.superClassName != null);
    	}
     
    	public String getSuperClassName() {
    		return this.superClassName;
    	}
     
    	public String[] getInterfaceNames() {
    		return this.interfaces;
    	}
     
    }
    Il faut inclure les jar asm : asm-2.2.3.jar et asm-commons-2.2.3.jar
    que l'on peut trouver dans le download de Spring with dependencies.

    Ensuite on peut utiliser cette classe comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    import java.io.InputStream;
     
    import org.objectweb.asm.ClassReader;
    import org.springframework.core.io.Resource;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.core.io.support.ResourcePatternResolver;
     
    public class TestPackage2 {
     
    	public static void main(String[] args) {
    		try {
    			String packageSearchPath = "classpath*:a**/**/*.class";
    			ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
    			Resource[] resources = resourcePatternResolver
    					.getResources(packageSearchPath);
    			for (int i = 0; i < resources.length; i++) {
    				Resource resource = resources[i];
     
    				InputStream inputStream = null;
    				try {
    					inputStream = resource.getInputStream();
    					ClassReader classReader = new ClassReader(inputStream);
    					ClassMetadataReadingVisitor visitor = new ClassMetadataReadingVisitor();
    					classReader.accept(visitor, true);
     
    					System.out.println("ClassName=" + visitor.getClassName()
    							+ ", InterfaceNames().length=" + visitor.getInterfaceNames().length);
     
    				} finally {
    					if (inputStream != null)
    						inputStream.close();
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
     
    }
    Ce qui donne en sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ClassName=a.b.MyClassAB, InterfaceNames().length=0
    ClassName=a.MyClassA, InterfaceNames().length=0
    J'espere que ca pourra servir a quelqu'un.

    Angelo

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 26/03/2011, 20h40
  2. Créer un diag de classe avec api org.eclipse.uml2.uml
    Par fairyyoy dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 01/05/2009, 23h24
  3. comment structurer une modél. UML - projet J2EE avec pattern
    Par RocketArena dans le forum Architecture
    Réponses: 18
    Dernier message: 20/07/2007, 19h20
  4. Réponses: 6
    Dernier message: 01/05/2006, 19h05
  5. Réponses: 1
    Dernier message: 28/03/2006, 22h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo