Code:
package com.bnpp.mcip.config;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
public abstract class BeanDefinitionParserUtil {
/**
* Cette méthode permet de positionner une propriété définie sous la forme
* d'un élément dont la valeur est de type texte, si elle existe. <br>
* Exemple :<br>
*
* <code>
* <...><br/>
* <m:desciption>le texte de la description</m:description><br/>
* </...><br/>
* </code>
*
* @param element
* l'élément de départ contenant le tagName à chercher
* @param property
* le nom de la propriété de l'objet à positionner avec la valeur
* du tag
* @param tagName
* le nom du tag à rechercher dans l'élément
* @param definition
* la définition courante dans laquelle ajouter la définition de
* la propriété
*/
public static void declare(Element element, String property,
String tagName, AbstractBeanDefinition definition) {
List l = DomUtils.getChildElementsByTagName(element, tagName);
if (l.size() == 1) {
Element e = (Element) l.get(0);
definition.getPropertyValues().addPropertyValue(property,
DomUtils.getTextValue(e));
}
}
/**
* Cette méthode permet de positionner une propriété définie sous la forme
* d'une <b>liste d'éléments</b>. Chaque élément de la liste est supposé
* avoir défini un attribut de nom <b>ref</b> correspondant à l'id d'un
* autre objet déclaré dans le fichier de configuration <br>
* Exemple :<br>
*
* <code>
* <...><br/>
* <m:responsables><br/>
* <m:responsable ref="id1"/><br/>
* <m:responsable ref="id2"/><br/>
* </m:responsables><br/>
* </...>
* </code>
*
* @param element
* l'élément de départ contenant le tagListName à chercher
* @param property
* le nom de la propriété de l'objet à positionner avec la valeur
* de tagListName
* @param tagListName
* le nom du tag représentant l'élément de type liste à
* rechercher
* @param tagName
* le nom du tag des éléments de type élement de la liste à
* rechercher
* @param definition
* la définition courante dans laquelle ajouter la définition de
* de la propriété
*
*/
public static void declareListRef(Element element, String property,
String tagListName, String tagName,
AbstractBeanDefinition definition) {
List l = DomUtils.getChildElementsByTagName(element, tagListName);
if (l.size() == 1) {
Element e = (Element) l.get(0);
List elts = DomUtils.getChildElementsByTagName(e, tagName);
ManagedList refs = new ManagedList();
RuntimeBeanReference ref;
for (int i = 0; i < elts.size(); i++) {
e = (Element) elts.get(i);
ref = new RuntimeBeanReference(e.getAttribute("ref"));
refs.add(ref);
}
definition.getPropertyValues().addPropertyValue(property, refs);
}
}
/**
* Cette méthode permet de positionner une propriété de type référence vers
* un autre objet et défini comme sous-élément d'un bean <br>
* Exemple :<br>
*
* <code>
* <...><br/>
* <m:parent ref="id1"/><br/>
* </...><br/>
* </code>
*
* @param element
* l'élément de départ contenant le tagName à chercher
* @param property
* le nom de la propriété de l'objet à positionner avec la valeur
* de Name
* @param tagName
* le tag à rechercher sous l'élément. Ce tag doit avoir un
* attribut <b>ref</b>
* @param definition
* la définition courante dans laquelle ajouter la définition de
* de la propriété
*/
public static void declareRef(Element element, String property,
String tagName, AbstractBeanDefinition definition) {
List l = DomUtils.getChildElementsByTagName(element, tagName);
if (l.size() == 1) {
Element e = (Element) l.get(0);
RuntimeBeanReference ref;
ref = new RuntimeBeanReference(e.getAttribute("ref"));
definition.getPropertyValues().addPropertyValue(property, ref);
}
}
public static void declareObjects(Element element, String property,
String tagName, Class clazz, HashMap mapping,
AbstractBeanDefinition definition) {
List l = DomUtils.getChildElementsByTagName(element, tagName);
RootBeanDefinition childDefinition;
ManagedList childs = new ManagedList();
for (int i = 0; i < l.size(); i++) {
Element e = (Element) l.get(i);
childDefinition = new RootBeanDefinition(clazz);
parseChild(e, mapping, childDefinition);
childs.add(childDefinition);
}
definition.getPropertyValues().addPropertyValue(property, childs);
}
public static void declareObjectsAsList(Element element, String property,
String tagListName, String tagName, Class clazz, HashMap mapping,
AbstractBeanDefinition definition) {
List l = DomUtils.getChildElementsByTagName(element, tagListName);
if (l.size()==1) {
Element e = (Element)l.get(0);
declareObjects(e,property,tagName,clazz,mapping,definition);
}
}
public static void declareObject(Element element, String property,
String tagName, Class clazz, HashMap mapping,
AbstractBeanDefinition definition) {
List l = DomUtils.getChildElementsByTagName(element, tagName);
if (l.size() == 1) {
Element e = (Element) l.get(0);
RootBeanDefinition childDefinition = new RootBeanDefinition(clazz);
parseChild(e, mapping, childDefinition);
definition.getPropertyValues().addPropertyValue(property,
childDefinition);
}
}
private static void parseChild(Element e, HashMap mapping,
AbstractBeanDefinition definition) {
NamedNodeMap attributes = e.getAttributes();
Node n;
String attrName, attrValue;
Class clazz = definition.getBeanClass();
for (int i = 0; i < attributes.getLength(); i++) {
n = attributes.item(i);
attrName = n.getNodeName();
attrValue = n.getNodeValue();
// Si on a une table de mapping pour les attributs, on change le nom
// de l'attribut avec sa correspondance dans le mapping si cette
// correspondance existe
if (mapping != null && mapping.get(attrName) != null)
attrName = (String) mapping.get(attrName);
try {
Class getterType = getGetter(clazz,attrName);
if (getterType!=null && getterType.isAssignableFrom(String.class)) {
definition.getPropertyValues().addPropertyValue(attrName,
attrValue);
} else {
// On part ici du principe que si la propriété de l'objet
// n'est pas de type String, il faut définir une référence
// vers un bean déclaré dans le fichier de configuration
definition.getPropertyValues().addPropertyValue(attrName,
new RuntimeBeanReference(attrValue));
}
} catch (SecurityException ex) {
ex.printStackTrace();
}
}
}
private static Class getGetter(Class clazz, String attrName) {
Method methods[] = clazz.getMethods();
String getterName="get"+attrName.substring(0,1).toUpperCase()+attrName.substring(1);
for (int i=0;i<methods.length;i++) {
if (getterName.equals(methods[i].getName()))
return methods[i].getReturnType();
}
return null;
}
}