package q02b.exe.arquitectura.utils.xml;



/*

 * XMLSerializer.java

 *

 * Created on 25 de febrero de 2002, 12:32

 */



import java.beans.BeanInfo;

import java.beans.PropertyDescriptor;

//import java.io.IOException;

import java.lang.reflect.Array;

import java.lang.reflect.Method;



import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

//import org.xml.sax.SAXException;



import q02b.exe.arquitectura.valueobjects.Q02bValueObject;







/** Clase que permite serializar un ValueObject en formato XML y viceversa <p>

 *

 * @author sergio.navarro

 * @version 1.0

 */

public class Q02bXMLSerializer {

    

    

    protected static javax.xml.parsers.DocumentBuilderFactory builderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();

    

    /** Permite ver trazas */

    protected static boolean debug = false;

    

    

    /**

     * Permite establecer el valor de la propiedad debug

     * @param debugValue

     */

    public static void setDebug(boolean debugValue){

        debug = debugValue;

    }

    

    public static String toXMLAsString(Q02bValueObject o) throws Exception{

        return toXMLAsString(o , false);

    }

    

    public static void toXMLAsTag(Q02bValueObject o , Node doc)throws Exception{

        Q02bDefaultXMLFormatter dxf = (Q02bDefaultXMLFormatter)o.getXmlFormatter().newInstance();

        Object value = null;

        Class returnType = null;

        Element rootTag = null;

        Element tag = null;

        

        //Obtenemos el objeto beaninfo

        BeanInfo bi = java.beans.Introspector.getBeanInfo(o.getClass());

        

        //Las propiedades

        PropertyDescriptor[] props = bi.getPropertyDescriptors();

        

        java.lang.reflect.Method m = null;

        

        //Creamos un tag raíz con el nombre de la clase (el que viene del descriptor)

        if(doc instanceof org.w3c.dom.Document){

            rootTag = ((org.w3c.dom.Document)doc).createElement( bi.getBeanDescriptor().getName() );

        }else{

            rootTag = doc.getOwnerDocument().createElement( bi.getBeanDescriptor().getName() );

        }

        

        doc.appendChild( rootTag );

        

        

        

        //Recorremos las propiedades

        for(int i=0;i<props.length;i++){

            

            

            if (props[i]!=null){

                

                //No procesamos las propiedades class ni xmlFormatter

                if(props[i].getName().equals("class")){ continue;}

                if(props[i].getName().equals("xmlFormatter")){ continue;}

                

                //Obtenemos el método read

                m = props[i].getReadMethod();

                

                if (m!=null){

                    

                    

                    //Y lo invocamos

                    value = m.invoke(o,new Object[]{});

                    

                    returnType = m.getReturnType();

                    

                    if (debug){

                        

                    }

                    

                    

                    //Si es de tipo ValueObject (o hijo de ValueObject)

                    if(Q02bValueObject.class.isAssignableFrom(returnType)){

                        toXMLAsTag((Q02bValueObject)value , rootTag );

                        

                    }else{

                        if(returnType.isArray()){//Si es un array

                            toXMLAsTag((Object[])value,props[i].getName(),dxf , rootTag);

                            

                        }else{

                            if(java.util.List.class.isAssignableFrom(returnType)){//Si es un list

                                java.util.List list = (java.util.List) value;

                                

                                

                                if (list!=null){

                                    toXMLAsTag(list.toArray(),props[i].getName(),dxf , rootTag);
                                }
                                

                            }else{

                                //Si no

                                tag = rootTag.getOwnerDocument().createElement(props[i].getName());

                                tag.appendChild( rootTag.getOwnerDocument().createCDATASection( dxf.format(props[i].getName(),value) ) );

                                rootTag.appendChild( tag );

                            }

                        }

                    }

                    

                }//el de m

            }//el de props[i]

        }

    }

    

    /**

     * Devuelve un objeto XML representando un array.

     * @param array Array a procesar

     * @param nombre Nombre de la propiedad correspondiente al array

     * @param Q02bDefaultXMLFormatter Clase formateadora para el contenido del array

     * @return Objeto XML resultante

     */

    public static void toXMLAsTag(Object[] array,String nombre,Q02bDefaultXMLFormatter dxf,Node doc)throws Exception{

        //Creamos un tag con el nombre recibido

        Node rootTag = doc.getOwnerDocument().createElement( nombre );

        

        doc.appendChild( rootTag );

        

        if(array!=null){

            Object o= null;

            //Obtenemos el número de elementos del array

            int limite = array.length;

            //Recorremos los elementos del array, añadiendo elementos a rootTag

            for(int i=0;i<limite;i++){

                o = array[i];

                //Si es un valueObject

                if (Q02bValueObject.class.isAssignableFrom(o.getClass())){

                    toXMLAsTag((Q02bValueObject)o , rootTag);

                }else{//Si no es un ValueObject

                    toXMLAsTag(o,"element",dxf , rootTag);

                }

            }

        }

        

    }

    

    /**

     * Procesa un objeto (que no debería ser un ValueObject) y devuelve el tag resultante

     * @param rootTag Tag en el que insertar el objeto

     * @param o Objeto a procesar

     * @param nombre Nombre para el objeto en el xml resultante

     * @param dxf Clase formateadora para el objeto

     * @return Objeto XML resultante. Es el objeto rootTag que recibe como parámetro

     */

    public static void toXMLAsTag(Object o,String nombre,Q02bDefaultXMLFormatter dxf , Node doc) throws Exception{

        Element rootTag = doc.getOwnerDocument().createElement( nombre );

        doc.appendChild( rootTag );

        rootTag.appendChild( doc.getOwnerDocument().createTextNode( dxf.format(nombre,o) ));

    }

    

    

    /**

     * Procesa un array de objetos de tipo ValueObject y lo transforma en un String en formato XML.

     * @param o Array de ValueObject a procesar

     * @param nombreTag Nombre del tag que incluirá los tags correspondientes a los valueobjects

     * @return String con la estructura XML correspondiente al ValueObject recibido.

     */

    public static void toXMLAsTag(Q02bValueObject[] o,String nombreTag , Node doc) throws Exception{

        Element rootTag = doc.getOwnerDocument().createElement( nombreTag );

        doc.appendChild( rootTag );

        

        if(o != null){

            int limite = o.length;

            for(int i=0;i<limite;i++){

                toXMLAsTag(o[i] , rootTag);

            }

        }

        

    }

    

    /**

     * Procesa un objeto de tipo ValueObject y lo transforma en un String en formato XML.

     * @param o ValueObject a procesar

     * @return String con la estructura XML correspondiente al ValueObject recibido.

     */

    public static String toXMLAsString(Q02bValueObject o,boolean incluirCabecera) throws Exception{

        javax.xml.parsers.DocumentBuilder builder = builderFactory.newDocumentBuilder();

        org.w3c.dom.Document document = builder.newDocument();

        

        

        toXMLAsTag(o , document );

        

        java.io.StringWriter out = new java.io.StringWriter();

        org.apache.xml.serialize.OutputFormat format = new org.apache.xml.serialize.OutputFormat( document );

        format.setEncoding("ISO-8859-1");

        format.setIndenting(false);

        format.setOmitXMLDeclaration( !incluirCabecera );

        

        org.apache.xml.serialize.XMLSerializer serializer = new org.apache.xml.serialize.XMLSerializer( out , format );

        serializer.serialize( document );

        

        

        return out.getBuffer().toString();

    }

    

    

    /*******************************/

    

    

    

    /**

     * Da valores a las propiedades de un ValueObject, a partir de un String en formato XML.<p>

     * Los tags del XML deben corresponderse con las propiedades del objeto o, teniendo en cuenta las

     * mayúsculas y minúsuculas.<p>

     * Permite propiedades de los siguientes tipos:

     * <ul>

     * <li>int/Integer

     * <li>short/Short

     * <li>long/Long

     * <li>double/Double

     * <li>float/Float

     * <li>byte/Byte

     * <li>boolean/Boolean

     * <li>String

     * <li>BigDecimal

     * <li>BigInteger

     * <li>ValueObject

     * <li>java.util.ArrayList

     * </ul>

     * <p>

     * En el caso de las propiedades de tipo ArrayList, deberá existir otra propiedad con el mismo nombre más

     * el sufijo <b>ElementType</b>, de tipo Class, que representa el tipo de objetos que contiene el ArrayList.<br>

     * Por ejemplo, para una propiedad <b>nombres</b> de tipo ArrayList, que contendrá una lista de objetos de tipo

     * String, habrá que crear otra propiedad llamada nombresElementType de tipo Class, que devuelva String.class.

     * <p>

     * Para que un ValueObject pueda ser rellenado con datos procedentes de un XML, deberá existir la clase BeanInfo

     * correspondiente a ese valueObject.

     * @param o ValueObject a rellenar

     * @param xml XML con los datos

     * @return ValueObject relleno

     * @throw java.beans.IntrospectionException

     * @throw java.io.IOException

     * @throw org.xml.sax.SAXException

     * @throw java.lang.reflect.InvocationTargetException

     * @throw java.lang.IllegalAccessException

     * @throw java.lang.InstantiationException

     */

    public static Q02bValueObject loadFromXML(Q02bValueObject o,String xml) throws java.beans.IntrospectionException,org.xml.sax.SAXException,java.io.IOException,java.lang.reflect.InvocationTargetException,java.lang.IllegalAccessException,java.lang.InstantiationException{

        //Obtenemos el beanInfo de la clase

        java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(o.getClass());

        

        //Parseamos el XML

        Document doc = null;

        

        try{

            doc = builderFactory.newDocumentBuilder().parse( new org.xml.sax.InputSource( new java.io.StringReader(xml) ));

        }catch(Exception ex){

            throw new org.xml.sax.SAXException( ex );

        }

        

        //Obtenemos el nodo raíz

        org.w3c.dom.Node rootNode = doc.getFirstChild();

        org.w3c.dom.Node node = null;

        

        //Obtenemos los hijos del nodo raíz

        org.w3c.dom.NodeList nl = rootNode.getChildNodes();

        

        //Los recorremos

        for(int i=0;i<nl.getLength();i++){

            node = nl.item(i);

            //Para cada nodo hijo del raíz (cada uno representa una propiedad de un valueobject)

            loadFromXML(o,node,bi);

        }

        

        //Devolvemos el objeto relleno

        return o;

    }

    

    /**

     * Crea un ValueObject y lo rellena, a partir de un String en formato XML.<p>

     * Los tags del XML deben corresponderse con las propiedades del objeto o, teniendo en cuenta las

     * mayúsculas y minúsuculas.<p>

     * Permite propiedades de los siguientes tipos:

     * <ul>

     * <li>int/Integer

     * <li>short/Short

     * <li>long/Long

     * <li>double/Double

     * <li>float/Float

     * <li>byte/Byte

     * <li>boolean/Boolean

     * <li>String

     * <li>BigDecimal

     * <li>BigInteger

     * <li>ValueObject

     * <li>java.util.ArrayList

     * </ul>

     * <p>

     * En el caso de las propiedades de tipo ArrayList, deberá existir otra propiedad con el mismo nombre más

     * el sufijo <b>ElementType</b>, de tipo Class, que representa el tipo de objetos que contiene el ArrayList.<br>

     * Por ejemplo, para una propiedad <b>nombres</b> de tipo ArrayList, que contendrá una lista de objetos de tipo

     * String, habrá que crear otra propiedad llamada nombresElementType de tipo Class, que devuelva String.class.

     * <p>

     * Para que un ValueObject pueda ser rellenado con datos procedentes de un XML, deberá existir la clase BeanInfo

     * correspondiente a ese valueObject.

     * @param clase Clase del ValueObject a instanciar

     * @param xml XML con los datos

     * @return ValueObject relleno

     * @throw java.beans.IntrospectionException

     * @throw java.io.IOException

     * @throw org.xml.sax.SAXException

     * @throw java.lang.reflect.InvocationTargetException

     * @throw java.lang.IllegalAccessException

     * @throw java.lang.InstantiationException

     */

    public static Q02bValueObject loadFromXML(Class clase,String xml) throws java.beans.IntrospectionException,org.xml.sax.SAXException,java.io.IOException,java.lang.reflect.InvocationTargetException,java.lang.IllegalAccessException,java.lang.InstantiationException{

        return loadFromXML((Q02bValueObject)clase.newInstance(),xml);

    }

    

    /**

     * Da valores a un ValueObject, a partir de los datos almacenado en un objeto Node

     * @param o ValueObject a rellenar

     * @param rootNode Nodo a partir del cual obtener los datos

     * @throw java.beans.IntrospectionException

     * @throw java.lang.InstantiationException

     * @throw java.lang.reflect.InvocationTargetException

     */

    public static void loadFromXML(Q02bValueObject o,org.w3c.dom.Node rootNode) throws java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException,java.lang.IllegalAccessException,java.lang.InstantiationException{

        //Obtenemos el beaninfo para la clase correpondiente al objeto

        java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(o.getClass());

        

        //Obtenemos los hijos del nodo recibido

        org.w3c.dom.NodeList nl = rootNode.getChildNodes();

        org.w3c.dom.Node node = null;

        

        //Para cada nodo....

        for(int i=0;i<nl.getLength();i++){

            node = nl.item(i);

            loadFromXML(o,node,bi);

        }

        

        

    }

    

    /**

     * Asigna un valor a una propiedad de un objeto. El tipo de la propiedad será de tipo primitivo o uno de

     * sus wrappers. También podrá ser de tipo BigDecimal o BigInteger

     * @param o ValueObject al cual asingar la propiedad

     * @param m Método que nos permite asignar la propiedad al valueObject

     * @param value Valor a asignar a la propiedad

     * @param type Tipo de la propiedad

     * @throw java.lang.IllegalAccessException

     * @throw java.lang.reflect.InvocationTargetException

     */

    public static void setValueToObject(Q02bValueObject o,Method m,String value,Class type) throws java.lang.IllegalAccessException,java.lang.reflect.InvocationTargetException{

       

        //Si es de un tipo primitivo....

        if(type.isPrimitive()){

            if(type.getName().equals("int")){

                m.invoke(o,new Object[]{new Integer("0"+value)});

            }

            

            if(type.getName().equals("long")){

                m.invoke(o,new Object[]{new Long("0"+value)});

            }

            

            if(type.getName().equals("short")){

                m.invoke(o,new Object[]{new Short("0"+value)});

            }

            

            if(type.getName().equals("char")){

                m.invoke(o,new Object[]{new Character( value.length()>0?value.charAt(0):' ' )});

            }

            

            if(type.getName().equals("float")){

                m.invoke(o,new Object[]{new Float("0"+value)});

            }

            

            if(type.getName().equals("double")){

                m.invoke(o,new Object[]{new Double("0"+value)});

            }

            

            if(type.getName().equals("boolean")){

                m.invoke(o,new Object[]{Boolean.valueOf((value.equalsIgnoreCase("true")))});

            }

            

            if(type.getName().equals("byte")){

                m.invoke(o,new Object[]{new Byte(value)});

            }

            

            return;

        }

        

        //Si no es de tipo primitivo.....

        

        if(String.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{value});

            return;

        }

        

        

        if(Integer.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{new Integer("0"+value)});

            return;

        }

        

        if(Character.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{new Character( value.length()>0?value.charAt(0):' ' )});

            return;

        }

        

        if(Double.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{new Double("0"+value)});

            return;

        }

        

        if(Float.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{new Float("0"+value)});

            return;

        }

        

        if(Long.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{new Long("0"+value)});

            return;

        }

        

        if(Short.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{new Short("0"+value)});

            return;

        }

        

        if(java.math.BigDecimal.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{new java.math.BigDecimal("0"+value)});

            return;

        }

        

        if(java.math.BigInteger.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{new java.math.BigInteger("0"+value)});

            return;

        }

        

        

        if(Byte.class.isAssignableFrom(type)){

            m.invoke(o,new Object[]{new Byte(value)});

            return;

        }

        

    }

    

    /**

     * Rellena un ArrayList con objetos de tipo <i>clase</i>, a partir de los valores almacenados en rootNode

     * @param clase Tipo de objetos que almacenaremos en el ArrayList

     * @param rootNode Nodo a partir del cual obtenemos los valores.

     * @throw java.lang.InstantiationException

     * @throw java.beans.IntrospectionException

     * @throw java.lang.IllegalAccessException

     * @throw java.lang.reflect.InvocationTargetException

     */

    public static void loadFromXML(Class clase,java.util.ArrayList list,org.w3c.dom.Node rootNode) throws java.lang.InstantiationException,java.beans.IntrospectionException,java.lang.IllegalAccessException,java.lang.reflect.InvocationTargetException{

        //Obtenemos los nodos hijos del recibido.

        org.w3c.dom.NodeList nl = rootNode.getChildNodes();

        org.w3c.dom.Node node = null;

        Object objeto = null;

        

        //Para cada uno de ellos...

        for(int i=0;i<nl.getLength();i++){

            node = nl.item(i);

            if(node.getNodeType()==org.w3c.dom.Node.TEXT_NODE){

                continue;

            }

            

            

            //Si es de tipo ValueObject

            if( Q02bValueObject.class.isAssignableFrom(clase) ){

                //Instanciamos un objeto de tipo clase

                objeto = clase.newInstance();

                //Lo cargamos con los datos del nodo actual

                loadFromXML((Q02bValueObject)objeto,node);

                //Y lo metemos en la lista

                list.add(objeto);

            }else{

                //Si es de tipo ArrayList

                if( java.util.ArrayList.class.isAssignableFrom(clase) ){

                    //No implementado!!!

                }else{//Si no es valueObject ni ArrayList

                    //Obtenemos el valor almacenado en el nodo actual

                    String strValor = node.getFirstChild().getNodeValue();

                    

                    //Almacenamos ese valor en la variable objeto, dependiendo del tipo que sea.

                    if(String.class.isAssignableFrom(clase)){

                        objeto = strValor;

                    }

                    

                    if(Integer.class.isAssignableFrom(clase)){

                        objeto = new Integer("0"+strValor);

                    }

                    

                    if(Character.class.isAssignableFrom(clase)){

                        objeto = new Character( strValor.length()>0?strValor.charAt(0):' ' );

                    }

                    

                    if(Double.class.isAssignableFrom(clase)){

                        objeto = new Double("0"+strValor);

                    }

                    

                    if(Float.class.isAssignableFrom(clase)){

                        objeto = new Float("0"+strValor);

                    }

                    

                    if(Long.class.isAssignableFrom(clase)){

                        objeto = new Long("0"+strValor);

                    }

                    

                    if(Short.class.isAssignableFrom(clase)){

                        objeto = new Short("0"+strValor);

                    }

                    

                    if(java.math.BigDecimal.class.isAssignableFrom(clase)){

                        objeto = new java.math.BigDecimal("0"+strValor);

                    }

                    

                    if(java.math.BigInteger.class.isAssignableFrom(clase)){

                        objeto = new java.math.BigInteger("0"+strValor);

                    }

                    

                    if(Byte.class.isAssignableFrom(clase)){

                        objeto = new Byte(strValor);

                    }

                    

                    //Finalmente lo añandimos a la lista

                    list.add(objeto);

                }

            }

            

        }

    }

    

    /**

     * Da valores a un ValueObject, a partir de los datos almacenado en un objeto Node, utilizando un objeto

     * beaninfo.

     * @param o ValueObject a rellenar

     * @param rootNode Nodo a partir del cual obtener los datos

     * @throw java.beans.IntrospectionException

     * @throw java.lang.InstantiationException

     * @throw java.lang.reflect.InvocationTargetException

     */

    public static void loadFromXML(Q02bValueObject o,org.w3c.dom.Node node,java.beans.BeanInfo bi) throws java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException,java.lang.IllegalAccessException,java.lang.InstantiationException{

        java.lang.reflect.Method m = null;

        

        //Obtenemos la lista de propiedades, a partir del beaninfo

        java.beans.PropertyDescriptor[] props = bi.getPropertyDescriptors();

        Class tipo = null;

        String nombre = null;

        

        //Recorremos las propiedades

        for(int i=0;i<props.length;i++){

            //Obtenemos el nombre de la propiedad

            nombre = props[i].getDisplayName();

            if (nombre == null || nombre.length() == 0){

                nombre = props[i].getName();
            }
            

            //Si coincide con el nombre del nodo

            if(nombre.equals(node.getNodeName())){

                //Obtenemos el método set de la propiedad

                m = props[i].getWriteMethod();

                //Obtenemos el tipo de la propiedad

                tipo = props[i].getReadMethod().getReturnType();

                //Si es de tipo valueObject

                /*

                if(ValueObject.class.isAssignableFrom(tipo)){

                    loadFromXML(o,node);

                    continue;

                }*/

                

                //Si es de tipo Array

                if(tipo.isArray()){

                    if(node.getFirstChild()==null){ continue;}

                    

                    java.util.ArrayList lista = new java.util.ArrayList();

                    Class claseObjetoArray = tipo.getComponentType();

                    

                    loadFromXML(claseObjetoArray,lista,node);

                    

                    Object[] arrayFinal = (Object[])Array.newInstance(claseObjetoArray,lista.size());



                    m.invoke(o,new Object[]{lista.toArray(arrayFinal)});

                    lista.clear();

                    continue;

                }

                

                //Si es de tipo ArrayList

                if(java.util.ArrayList.class.isAssignableFrom(tipo)){

                    Method m2 = null;

                    String busqueda = props[i].getName()+"ElementType";

                    //Buscamos una propiedad que se llame como la propiedad actual más ElementType

                    //Almacenando su método set en m2

                    for(int j=0;j<props.length;j++){

                        if ( props[j].getName().equals( busqueda ) ){

                            m2 = props[j].getReadMethod();

                            break;

                        }

                    }

                    

                    //Si hemos encontrado el método

                    if(m2 != null){

                        //Creamos un ArrayList

                        java.util.ArrayList lista = new java.util.ArrayList();

                        //Lo cargamos con los datos del nodo

                        loadFromXML((Class)m2.invoke(o,null),lista,node);

                        //Y se lo asignamos al valueObject

                        props[i].getWriteMethod().invoke(o,new Object[]{lista});

                    }

                    

                    

                    continue;

                }

                

                if(q02b.exe.arquitectura.valueobjects.Q02bValueObject.class.isAssignableFrom(tipo)){

                    

                    q02b.exe.arquitectura.valueobjects.Q02bValueObject objeto = (q02b.exe.arquitectura.valueobjects.Q02bValueObject) tipo.newInstance();

                    loadFromXML(objeto,node);

                    m.invoke(o,new Object[]{objeto});

                    continue;

                }

                //Si es de cualquier otro tipo

                if(node.getFirstChild()!=null){

                    setValueToObject(o,m,node.getFirstChild().getNodeValue(),tipo);

                }

                

                

                break;

            }

        }

        

        

    }

    

    

    /** Parsea un String en formato xml y devuelve un objeto Document con su contenido

     * @param xml Contenido xml

     * @throws IOException Si hay algún error en la lectura del xml

     * @throws SAXException Si hay algun error de parseo

     * @return Objeto Document

     */

    public static Document parseXML(String xml) throws java.io.IOException,org.xml.sax.SAXException{

        try{

            return builderFactory.newDocumentBuilder().parse( new org.xml.sax.InputSource( new java.io.StringReader( xml )) );

        }catch(Exception ex){

            throw new org.xml.sax.SAXException( ex );

        }

    }

    

    /** Parsea un String en formato xml y devuelve un objeto Document con su contenido

     * @param stream Stream de donde leer el contenido xml

     * @throws IOException Si hay algún error en la lectura del xml

     * @throws SAXException Si hay algun error de parseo

     * @return Objeto Document

     */

    public static Document parseXML(java.io.InputStream stream) throws java.io.IOException,org.xml.sax.SAXException {

        try{

            return builderFactory.newDocumentBuilder().parse( stream );

        }catch(Exception ex){

            throw new org.xml.sax.SAXException( ex );

        }

    }

    

    /** Parsea un String en formato xml y devuelve un objeto Document con su contenido

     * @param reader Reader de donde leer el contenido xml

     * @throws IOException Si hay algún error en la lectura del xml

     * @throws SAXException Si hay algun error de parseo

     * @return Objeto Document

     */

    public static Document parseXML(java.io.Reader reader) throws java.io.IOException,org.xml.sax.SAXException{

        try{

            return builderFactory.newDocumentBuilder().parse( new org.xml.sax.InputSource( reader ));

        }catch(Exception ex){

            throw new org.xml.sax.SAXException( ex );

        }

    }

    

    



    

    

    public static void main(String[] args) throws Exception{

        

        

        //new XMLSerializer().probar();

        

        

    }

    

    

    



    

}

