package q02b.exe.utils;



import java.io.File;



import java.io.ByteArrayInputStream;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.StringReader;

import java.io.StringWriter;



import java.text.MessageFormat;

import java.util.HashMap;

import java.util.StringTokenizer;



import org.apache.xpath.XPathAPI;

import org.w3c.dom.*;



import org.xml.sax.EntityResolver;

import org.xml.sax.InputSource;

import org.xml.sax.SAXException;

import org.xml.sax.XMLReader;



import org.xml.sax.SAXParseException;

import org.xml.sax.helpers.DefaultHandler;



import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;

import es.ejie.frmk.infraestructura.traza.Q70Traza;

import es.ejie.frmk.listeners.base.Q70ListenerUtils;



import javax.xml.parsers.*;

import javax.xml.transform.*;

import javax.xml.transform.stream.*;

import javax.xml.transform.dom.*;



public class Q02bDocumentoXmlUtils

{

	  //Traza a mostrar

	  private static Q70Traza tr = Q70Traza.getSingleton();

	  private static final String COMPONENTE = "Q02bDocumentoXmlUtils";

	 //Variables que no se modifican

	  private static final String SCHEMA_LANGUAGE 	= "http://java.sun.com/xml/jaxp/properties/schemaLanguage",

	               XML_SCHEMA 		= "http://www.w3.org/2001/XMLSchema",

	               SCHEMA_SOURCE 	= "http://java.sun.com/xml/jaxp/properties/schemaSource";

	  //Ruta donde se encuentran los .xsd en la aplicación

	  private final String RUTA_XSD 		 				= Q70ListenerUtils.getApplicationProperty("S99B_RUTA_FICHERO_XSD");

	  //Schemas necesarios IKS

	  private final String RUTA_FICHERO_IKS_L03  			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_IKS_L03");

	  private final String RUTA_FICHERO_IKS_SA  			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_IKS_SA");

	  private final String RUTA_FICHERO_IKS_DA 	 			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_IKS_DA");

	  private final String RUTA_FICHERO_IKS_DSC  			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_IKS_DSC");

	  private final String NOMBRE_FICHERO_IKS_L03  			= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_IKS_L03");

	  private final String NOMBRE_FICHERO_IKS_SA  			= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_IKS_SA");

	  private final String NOMBRE_FICHERO_IKS_DA 	 		= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_IKS_DA");

	  private final String NOMBRE_FICHERO_IKS_DSC  			= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_IKS_DSC");

	  //Schemas necesarios L03

	  private final String RUTA_FICHERO_E3L  				= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_V1_1");

	  private final String RUTA_FICHERO_E3L_AIR  			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_AIR_V1_1");

	  private final String RUTA_FICHERO_E3L_COMMON 	 		= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_COMMON_V1_1");

	  private final String RUTA_FICHERO_E3L_DOC  			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_DOC_V1_1");

	  private final String RUTA_FICHERO_E3L_EPRTR  			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_EPRTR_V1_1");

	  private final String RUTA_FICHERO_E3L_MASTER  		= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_MASTER_V1_1");

	  private final String RUTA_FICHERO_E3L_SOILS  			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_SOILS_V1_1");

	  private final String RUTA_FICHERO_E3L_WASTE  			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_WASTE_V1_1");

	  private final String RUTA_FICHERO_E3L_WASTESUPPORT  	= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_WASTESUPPORT_V1_1");

	  private final String RUTA_FICHERO_E3L_WATER  			= Q02bConstantes.getString("Q02B_RUTA_FICHERO_XSD_CIRCUITOS_E3L_WATER_V1_1");

	  private final String NOMBRE_FICHERO_E3L  				= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_V1_1");

	  private final String NOMBRE_FICHERO_E3L_AIR  			= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_AIR_V1_1");

	  private final String NOMBRE_FICHERO_E3L_COMMON 	 	= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_COMMON_V1_1");

	  private final String NOMBRE_FICHERO_E3L_DOC  			= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_DOC_V1_1");

	  private final String NOMBRE_FICHERO_E3L_EPRTR  		= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_EPRTR_V1_1");

	  private final String NOMBRE_FICHERO_E3L_MASTER  		= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_MASTER_V1_1");

	  private final String NOMBRE_FICHERO_E3L_SOILS  		= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_SOILS_V1_1");

	  private final String NOMBRE_FICHERO_E3L_WASTE  		= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_WASTE_V1_1");

	  private final String NOMBRE_FICHERO_E3L_WASTESUPPORT  = Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_WASTESUPPORT_V1_1");

	  private final String NOMBRE_FICHERO_E3L_WATER  		= Q02bConstantes.getString("Q02B_NOMBRE_FICHERO_XSD_CIRCUITOS_E3L_WATER_V1_1");

	  

	  private Document 	document = null;

	  private Element 	root	 = null;

	  private InputStream is 	 = null;

	  

	  /**

	   * Contructor

	   * */

	  public Q02bDocumentoXmlUtils()

	  { 

		  try{

	      	  DocumentBuilder 		 builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

	      	  this.document 				 = builder.newDocument();

		  }catch(Exception e){}

	  }

	  

	  /**

	   * Contructor que genera un objeto Document a partir de un String con implementación

	   * XML.

	   * @param String cadXML - Cadena que contiene un String con contenido XML

	   * */

	  public Q02bDocumentoXmlUtils(String cadXML)

	  { 

		  try{

		      DocumentBuilder 	builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

		      this.document				= builder.parse(new InputSource(new StringReader(cadXML)));

		  }catch(Exception e){}

	  }

	  

	  /**

	   * Contructor que genera un objeto Document a partir de un InputStream con implementación

	   * XML.

	   * @param InputStream is - Stream que contiene un XML

	   * */

	  public Q02bDocumentoXmlUtils(InputStream is)

	  { 

		  try{

		      DocumentBuilder 	builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

		      this.document 			= builder.parse(is);

		  }catch(Exception ex){

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

			  java.io.PrintWriter out = new java.io.PrintWriter(sw);

			  ex.printStackTrace(out);

		  }

	  }

	    

	  /**

	   * Devuelve el valor del Documento Xml

	   * @return  Document

	   * */

	  public Document getDocumentoXml(){return this.document;}

	

	  /**

	   * Carga el valor del Documento Xml

	   * @return  Document

	   * */

	  public void setDocumentoXml(Document document){this.document=document;}

	  

	  /**

	   * Devuelve el valor del Documento Xml en inputstream

	   * @return  InputStream

	   * */

	  public InputStream getInputStream(){return this.is;}

	

	  /**

	   * Carga el valor del Documento Xml en InputStream

	   * */

	  public void setInputStream(InputStream is){this.is=is;}

	

	  /**

	   * Metodos para tratar el Nodo Padre-ROOT

	   */

	  public void generarNodoRootInicio(String etiquetaRoot)

	  {

	    this.root=this.document.createElement(etiquetaRoot);

	  }

	  public void generarNodoRootCierre()

	  {

	    document.appendChild(this.root);

	  }	

	  public Element getRoot(){return root;}

	  

	  /**

	   * Método que elimina los hijos de una rama concreta

	   */

	  public void borrarHijos(Node eHijo)

	  {

			int j;

			//Obtenemos los hijos de la rama concreta

			NodeList nodeList=eHijo.getChildNodes();

			//Recorremos la lista de nodos

			for(j=0;j<nodeList.getLength();j++)

			{

				//Obtengo el elemento hijo concreto

				Node eHijoBorrar = (Node)nodeList.item(j);

				//Si tiene más hijos queremos que los borre

				if(eHijoBorrar.hasChildNodes())

				{

					//Llamamos a la función de manera recursiva

					borrarHijos(eHijoBorrar);

				}

				//Eliminamos del nodo su hijo

				eHijo.removeChild(eHijoBorrar);

				//Obtenemos nuevamente la lista de nodos porque hemos eliminado uno de ellos

				//y necesitamos que se refresque

				nodeList=eHijo.getChildNodes();

				//Ponemos la variable a -1 porque al volver al for hacemos un j++ y 

				//se quiere que empiece desde j=0 para que obtenga el primer registro de la "nueva" lista

				j=(-1);

			}

	  }

	  

	  /**

	   * Devuelve un boolean indicando si el documento contiene elementos con un tag

	   * determinado que se pasa como parámetro.

	   * @return  boolean

	   * */

	  public boolean existElementsByTagName(String tagName)

	  {

		  //Valor a devolver

		  boolean existe = false;

		  //Obtenemos el listado de elementos del tag que nos han pasado

	      NodeList nodeList  = this.document.getElementsByTagName(tagName);

	      if(nodeList.getLength()>0){

	    	  existe = true;

	      }

	      return existe;

	  }

	  

	/**

     * Recupera el valor del nodo de un elemento    

     * @param nodo Nodo del que se recuperar el valor

     * @return String Valor del nodo

     * @throws

     */ 

	public  String recuperarValorNodo(Node nodo){

		try{

			return nodo.getChildNodes().item(0).getNodeValue();

		}catch(Exception e){

			return "";

		}

	}//Fin recuperarValorNodo

	  

	  /**

	   * Devuelve el valor del Documento Xml en string

	   * @return  String

	   * */

	  public String getDocumentoXmlString()

	  {

		  try{

			  DOMSource 		 domSource 		= new DOMSource(this.document);

			  StringWriter 		 writer 		= new StringWriter();

		      StreamResult 		 result 		= new StreamResult(writer);

		      TransformerFactory tf 			= TransformerFactory.newInstance();

		      Transformer 		 transformer 	= tf.newTransformer();

		      transformer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");

		      transformer.transform(domSource, result);

		      return writer.toString();

		  }catch(Exception ex){			  

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

			  java.io.PrintWriter out = new java.io.PrintWriter(sw);

			  ex.printStackTrace(out);

			  return null;

		  }

	  }

	  

	  /**

	   * Devuelve el valor del Documento Xml en string

	   * @return  String

	   * */

	  public String getDocumentoXmlStringWithoutEncoding()

	  {

		  try{

			  DOMSource 		 domSource 		= new DOMSource(this.document);

			  StringWriter 		 writer 		= new StringWriter();

		      StreamResult 		 result 		= new StreamResult(writer);

		      TransformerFactory tf 			= TransformerFactory.newInstance();

		      Transformer 		 transformer 	= tf.newTransformer();	

		      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

		      transformer.transform(domSource, result);

		      return writer.toString();

		  }catch(Exception ex){			  

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

			  java.io.PrintWriter out = new java.io.PrintWriter(sw);

			  ex.printStackTrace(out);

			  return null;

		  }

	  }

	  

	  /**

	   * Devuelve el valor de una objeto Element que se le pase como parámetro a String

	   * @param		Element  element

	   * @return  	String

	   * */

	  public String getElementXmlStringWithoutEncoding(Element  element)

	  {

		  try{

			  DOMSource 		 domSource 		= new DOMSource(element);

			  StringWriter 		 writer 		= new StringWriter();

		      StreamResult 		 result 		= new StreamResult(writer);

		      TransformerFactory tf 			= TransformerFactory.newInstance();

		      Transformer 		 transformer 	= tf.newTransformer();	

		      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

		      transformer.transform(domSource, result);

		      return writer.toString();

		  }catch(Exception ex){			  

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

			  java.io.PrintWriter out = new java.io.PrintWriter(sw);

			  ex.printStackTrace(out);

			  return null;

		  }

	  }

	  

	  /**

	   * Devuelve un boolean (true or false) en función de si ha ido bien

	   * o mal la validación respecto de un .xsd

	   * 

	   * @param String schemaUrl - Ruta donde se encuentra el schema .xsd

	   * 

	   * @return boolean - Indica si la validación ha sido correcta

	   * 

	   * */

	  public boolean checkSchemaXml(String schemaUrl) throws Exception{

		  //Variable que determinará si la validación ha sido correcta

		  boolean validacion = true;

		  try{

			    //Fichero que contiene el .xsd

			    File schema = new File(schemaUrl);

			    //Se indica que se va a validar

			  	SAXParserFactory spf = SAXParserFactory.newInstance();

		        spf.setNamespaceAware(true);

		        spf.setValidating(true);

		        //Se crea el parseador

		        SAXParser parser = spf.newSAXParser();

		        parser.setProperty(SCHEMA_LANGUAGE,XML_SCHEMA);

		        parser.setProperty(SCHEMA_SOURCE,schema);

		        //Se crea el error

		        ErrorPrinter ep = new ErrorPrinter();

		        //Se realiza el parseo respecto el .xsd

		        parser.parse(this.is, ep);

		        //Se asigna a la variable el resultado

		        if(ep.getError()){

		        	validacion = false;

		        }

		  }catch (Exception ex) {

			  validacion = false;

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

			  java.io.PrintWriter out = new java.io.PrintWriter(sw);

			  ex.printStackTrace(out);

			  throw ex;

	      }

		  //Se devuelve una variable que indica si todo ha ido bien

		  return validacion;

	  }

	    

	  /**

	   * Devuelve un boolean (true or false) en función de si ha ido bien

	   * o mal la validación respecto de un .xsd de la IKS

	   * 

	   * @param String schemaUrl - Ruta donde se encuentra el schema .xsd

	   * 

	   * @return boolean - Indica si la validación ha sido correcta

	   * 

	   * */

	  public boolean checkSchemaIKSXml(String schemaUrl) throws Exception{

		  //Variable que determinará si la validación ha sido correcta

		  boolean validacion = true;

		  try{

			    //Fichero que contiene el .xsd

			    File schema = new File(schemaUrl);

			    //Se indica que se va a validar

			  	SAXParserFactory spf = SAXParserFactory.newInstance();

		        spf.setNamespaceAware(true);

		        spf.setValidating(true);

		        //Se crea el parseador

		        SAXParser parser = spf.newSAXParser();

		        parser.setProperty(SCHEMA_LANGUAGE,XML_SCHEMA);

		        parser.setProperty(SCHEMA_SOURCE,schema);        

		        //Se crea el error

		        ErrorPrinter ep = new ErrorPrinter();

		        //Se obtiene el XMLReader del documento

		        XMLReader xmlReader = parser.getXMLReader();

		        xmlReader.setEntityResolver(new IKSResolver());

		        xmlReader.setErrorHandler(ep);

		        xmlReader.parse(new InputSource(this.is));

		        if(ep.getError()){

		        	validacion = false;

		        }	        

		  }catch (Exception ex) {

			  validacion = false;

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

			  java.io.PrintWriter out = new java.io.PrintWriter(sw);

			  ex.printStackTrace(out);

			  throw ex;

	      }

		  //Se devuelve una variable que indica si todo ha ido bien

		  return validacion;

	  }

	  

	  /**

	   * Devuelve un boolean (true or false) en función de si ha ido bien

	   * o mal la validación respecto de un .xsd de la E3L

	   * 

	   * @param String schemaUrl - Ruta donde se encuentra el schema .xsd

	   * 

	   * @return boolean - Indica si la validación ha sido correcta

	   * 

	   * */

	  public boolean checkSchemaE3lXml(String schemaUrl) throws Exception{

		  //Variable que determinará si la validación ha sido correcta

		  boolean validacion = true;

		  try{

			    //Fichero que contiene el .xsd

			    File schema = new File(schemaUrl);

			    //Se indica que se va a validar

			  	SAXParserFactory spf = SAXParserFactory.newInstance();

		        spf.setNamespaceAware(true);

		        spf.setValidating(true);

		        //Se crea el parseador

		        SAXParser parser = spf.newSAXParser();

		        parser.setProperty(SCHEMA_LANGUAGE,XML_SCHEMA);

		        parser.setProperty(SCHEMA_SOURCE,schema);

		        //Se crea el error

		        ErrorPrinter ep = new ErrorPrinter();

		        //Se obtiene el XMLReader del documento

		        XMLReader xmlReader = parser.getXMLReader();

		        xmlReader.setEntityResolver(new E3LResolver());

		        xmlReader.setErrorHandler(ep);

		        xmlReader.parse(new InputSource(this.is));

		        if(ep.getError()){

		        	validacion = false;

		        }		        

		  }catch (Exception ex) {

			  validacion = false;

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

			  java.io.PrintWriter out = new java.io.PrintWriter(sw);

			  ex.printStackTrace(out);

			  throw ex;

	      }

		  //Se devuelve una variable que indica si todo ha ido bien

		  return validacion;

	  }

	  

	  /**

	   * Clase que hereda de la clase DefaultHandler y que permite monitorizar

	   * los errores producidos durante un parseo de un XML.

	   * */

	  private class ErrorPrinter extends DefaultHandler

	  {

		   private static final String TRACE_METODO = "ErrorPrinter";

		   

		   private boolean error = false;

		   

		   public boolean getError(){return this.error;}

		  

		   private MessageFormat message =

			      new MessageFormat("({0}: {1}, {2}): {3}");



		   private void print(SAXParseException x)

		   {

		      String msg = message.format(new Object[]

		                                  {

		                                     x.getSystemId(),

		                                     new Integer(x.getLineNumber()),

		                                     new Integer(x.getColumnNumber()),

		                                     x.getMessage()

		                                  });



		      if (tr.isTraceActive()) {

	                tr.trace(COMPONENTE, Q70TraceLevel.ERROR,

	                    TRACE_METODO + ": PARSEO XML : " + msg);

	          }

		   }



		   public void warning(SAXParseException ex)

		   {

			   print(ex);

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

			   java.io.PrintWriter out = new java.io.PrintWriter(sw);

			   ex.printStackTrace(out);

		   }

	

		   public void error(SAXParseException ex)

		   {

			   print(ex);

			   error = true;

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

			   java.io.PrintWriter out = new java.io.PrintWriter(sw);

			   ex.printStackTrace(out);

		   }

	

		   public void fatalError(SAXParseException ex)

		      throws SAXParseException

		   {

			  print(ex);

			  error = true;

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

			  java.io.PrintWriter out = new java.io.PrintWriter(sw);

			  ex.printStackTrace(out);

		      throw ex;

		   }

	  }

	  

	  /**

	   * Clase que implementa el interfaz EntityResolver.

	   * Se invoca su método "resolveEntity" cada vez que se parsea un documento XML

	   * con formato E3L y necesita resolver una fuente (import).

	   * Esta invocación se realiza cuando "salta" un evento en el parser.

	   * */

	  class E3LResolver implements EntityResolver {

		  /**

		   * Devuelve la fuente concreta que necesita el parseador

		   * @param  String publicID - ID público

		   * @param  String systemID - ID de la fuente

		   * @return InputSource 	 - Devuelve la fuente concreta a procesar

		   * */

		    public InputSource resolveEntity(String publicID, String systemID) throws IOException

		    {	    	

		    	if(NOMBRE_FICHERO_E3L.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_E3L_AIR.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L_AIR+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_E3L_COMMON.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L_COMMON+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_E3L_DOC.equals(systemID.toLowerCase())){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L_DOC+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_E3L_EPRTR.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L_EPRTR+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_E3L_MASTER.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L_MASTER+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_E3L_SOILS.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L_SOILS+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_E3L_WASTE.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L_WASTE+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_E3L_WASTESUPPORT.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L_WASTESUPPORT+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_E3L_WATER.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_E3L_WATER+systemID));		    		

		    		return source;

		    	}else{

		    		return null;

		    	}

		    }

	  }

	  

	  /**

	   * Clase que implementa el interfaz EntityResolver.

	   * Se invoca su método "resolveEntity" cada vez que se parsea un documento XML

	   * con formato IKS y necesita resolver una fuente (import).

	   * Esta invocación se realiza cuando "salta" un evento en el parser.

	   * */

	  class IKSResolver implements EntityResolver {

		  /**

		   * Devuelve la fuente concreta que necesita el parseador

		   * @param  String publicID - ID público

		   * @param  String systemID - ID de la fuente

		   * @return InputSource 	 - Devuelve la fuente concreta a procesar

		   **/

		  	public InputSource resolveEntity(String publicID, String systemID) throws IOException

		    {

		  		if(NOMBRE_FICHERO_IKS_L03.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_IKS_L03+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_IKS_SA.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_IKS_SA+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_IKS_DA.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_IKS_DA+systemID));		    		

		    		return source;

		    	}else if(NOMBRE_FICHERO_IKS_DSC.equals(systemID)){

		    		InputSource source = new InputSource(new FileInputStream(RUTA_XSD+RUTA_FICHERO_IKS_DSC+systemID));		    		

		    		return source;

		    	}else{

		    		return null;

		    	}

		    }

	  }

	  

	  

	  /**

		  * Método que recupera el valor de un elemento

		  */

		 public HashMap obtenerHashMapTokenSesion(Document xml, String campo) throws Exception {			

			 final String TRACE_METODO 				= ":obtenerDniTokenSesion:";

			 if (tr.isTraceActive()) { 

				 tr.trace(COMPONENTE, Q70TraceLevel.DEBUG,TRACE_METODO + " :entrando.");                

			 }  

			HashMap hmCampo = stringIntoHashMap(XPathAPI.selectSingleNode(xml,"//parent::elemento/parametro[@id=\""+campo+"\"]/valor/text()").getNodeValue());

			

			 if (tr.isTraceActive()) {

				 tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, TRACE_METODO + " :saliendo.");                

			 }  

			 return hmCampo;				

		 }

		 

		 /**

		  * Método que recupera el valor de un elemento

		  */

		 public String obtenerStringTokenSesion(Document xml, String campo) throws Exception {			

			 final String TRACE_METODO 				= ":obtenerDniTokenSesion:";

			 if (tr.isTraceActive()) {

				 tr.trace(COMPONENTE, Q70TraceLevel.DEBUG,TRACE_METODO + " :entrando.");                

			 }  

			String strCampo= (XPathAPI.selectSingleNode(xml,"//parent::elemento/parametro[@id=\""+campo+"\"]/valor/text()").getNodeValue());

			 

			 if (tr.isTraceActive()) {

				 tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, TRACE_METODO + " :saliendo.");                

			 }  

			 return strCampo;				

		 }

		 

		 /**

		  * Método que hace un cast de String a HashMap

		  */

		 public HashMap stringIntoHashMap(String strOrigen) throws Exception {			

			 final String TRACE_METODO 				= ":obtenerDniTokenSesion:";

			 if (tr.isTraceActive()) {

				 tr.trace(COMPONENTE, Q70TraceLevel.DEBUG,TRACE_METODO + " :entrando.");                

			 }  

			 HashMap hmDestino = new HashMap();

			 StringTokenizer st= new StringTokenizer(strOrigen.toString(),",");

			 while(st.hasMoreTokens())

				{

					String[] tmp = st.nextToken().split("=");

					hmDestino.put(tmp[0].trim(),tmp[1]);

				}

			 

			 return hmDestino;

		 } 

		 /**

		     * Recupera la lista de nodos de una etiqueta  

		     * @param document El documento del que se recupera la lista de nodos

		     * @param rutaElemento Ruta de la etiqueta dentro del documento, separado por '.'

		     * @return NodeList Lista de nodos

		     * @throws Exception

		     */	

			public  NodeList recuperarListaElementos(Document document,String rutaElemento)throws Exception{

				NodeList listaResultado = null;

				StringTokenizer tokCadena = null;

				String bloque = null;

				NodeList listaNodos = null;

				Element elemento = null;

				int contador = 0;		

					tokCadena = new StringTokenizer(rutaElemento,".");

					while (tokCadena.hasMoreTokens()){

						bloque = tokCadena.nextToken();

						

						if (contador == 0){

							listaNodos = document.getElementsByTagName(bloque);

						}

						else{

							listaNodos = elemento.getElementsByTagName(bloque);

						}

						elemento = (Element)listaNodos.item(0);

						contador++;

					}

					if (listaNodos != null)

					{

					listaResultado = listaNodos;

					}

					return listaResultado;		

			}//Fin recuperarListaElementos

			

			/**

		     * Devuelve un nodo de una lista de nodos    

		     * @param listaNodos Lista de nodos

		     * @param elemento Entero con el elemento de la lista de nodos

		     * @return nodo El nodo dentro del elemento

		     * @throws Exception

		     */

			public Node recuperarNodo(NodeList listaNodos,int elemento, int nodo)throws Exception{

				return listaNodos.item(elemento).getChildNodes().item(nodo);

			}//Fin recuperarNodo

			

			/**

		     * Recupera la lista de nodos de una etiqueta  

		     * @param document El documento del que se recupera la lista de nodos

		     * @param rutaElemento Ruta de la etiqueta dentro del documento, separado por '.'

		     * @return NodeList Lista de nodos

		     * @throws Exception

		     */	

			public String recuperarElemento(Document document,String nombreElemento)throws Exception{

				

				Element elemento = null;

				elemento = (Element)(((NodeList)document.getElementsByTagName(nombreElemento)).item(0));

				String strValorElemento=elemento.getChildNodes().item(0).getNodeValue();

				

					return strValorElemento;		

			}//Fin recuperarListaElementos

			/**

			 * Recupera el valor de una etiqueta (nodo) de un documento

			 * @param document Documento del que se recupera el valor de la etiqueta

			 * @param rutaElemento Ruta del nodo dentro del documento, separado por '.'

			 * @return String Valor de la etiqueta (nodo)

			 * @throws Exception

			 */

			public String recuperarValorElemento(Document document, String rutaElemento) throws Exception {

				String resultado = null;

				StringTokenizer tokCadena = null;

				String bloque = null;

				NodeList listaNodos = null;

				Element elemento = null;

				int contador = 0;

					tokCadena = new StringTokenizer(rutaElemento, ".");

					while (tokCadena.hasMoreTokens()) {

						bloque = tokCadena.nextToken();

						if (contador == 0) {

							listaNodos = document.getElementsByTagName(bloque);

						} else {

							listaNodos = elemento.getElementsByTagName(bloque);

						}

						elemento = (Element)listaNodos.item(0);

						contador++;

					}	

					if (listaNodos.item(0).getChildNodes().item(0) != null) {

						resultado = (listaNodos.item(0).getChildNodes().item(0)).getNodeValue();

					}			

					return(resultado);

			}

			/**

		     * Crea un objeto de la clase Document a partir del String XML que recibe como parámetro  

		     * @param xml String que contiene el XML

		     * @return Document Objeto de la clase Document

		     * @throws Exception

		     */    

			public Document crearDoc(String xml) throws Exception {		

				return buildDocument(xml,"8859_1");

			}//Fin fncCrearDoc

			

			/**

		     * Crea un objeto de la clase Document a partir del String XML que recibe como parámetro   

		     * @param xml String que contiene el XML UTF-8

		     * @return Document Objeto de la clase Document

		     * @throws Exception

		     */	

			public Document crearDocUTF8(String xml) throws Exception {			

				return buildDocument(xml,"UTF-8");

			}//Fin fncCrearDocUTF8

			

			/**

			 * Crea un objeto document a partir de XML con la codificación enviada

			 * @param strPfXML String con el XML

			 * @param strPfEnconding Codificacion enviada

			 * @return Document Objeto de la clase Document

			 * @throws ParserConfigurationException, UnsupportedEncodingException, IOException, SAXException

			 */	

			private Document buildDocument(String strPfXML, String strPfEnconding) throws Exception{

				Document doc = null;		

				DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();		

				DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

				try{

					doc = documentBuilder.parse((InputStream)new ByteArrayInputStream(strPfXML.getBytes(strPfEnconding)));		

				}

				catch(SAXException sax){

					if (tr.isTraceActive()) {

			           tr.trace(COMPONENTE, Q70TraceLevel.ERROR,"XML mal construido: "+strPfXML);                

			        }   				

					throw sax;

				}

				return doc;	

			}//Fin fncBuildDocument

	  

			



}