package es.ejie.frmk.infraestructura.utilidades.configurador;

import java.util.ArrayList;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import es.ejie.frmk.Q70Factoria;
import es.ejie.frmk.control.arranque.Q70GestorArranqueConfiguracionServidor;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70TrazaInterface;
import es.ejie.frmk.infraestructura.utilidades.constantes.Q70UtilidadesConstantes;
import es.ejie.frmk.infraestructura.utilidades.excepciones.Q70UtilidadesExcepcion;
import es.ejie.frmk.infraestructura.utilidades.general.Q70UtilidadesGenerales;

/**
 * 	Clase manejador base de los ficheros de configuración de componentes
 * para XML SAX que accede a los metodos de la interfaz configurable del componente <br>
 * 
 * @author UFRM005
 * @version 1.0
 * 
 */

public class Q70ManejadorBaseConfiguracion extends DefaultHandler
 {

	// variables miembro
	private String codigoAplicacion = null;
	
	private Q70Configurable objComponente = null;
	private String strNivel = "";
	private String strPath = "";
	private ArrayList arryPilaLIFOLista = new  ArrayList();
	private ArrayList arryPilaLIFOEstructura = new  ArrayList();
	private ArrayList arryPilaLIFOPropiedad = new  ArrayList();
	private boolean aplicarIndireccion = true;
	private boolean estaEjecutandoseDesdeAplicacion = false;
	
	// metodos 
	
	/**
	  * Constructor de la clase alternativo
	  * @param newObjComponent Object Objeto componente a configurar
	  * @param aplicarIndireccion boolean indica si hay que resolver indirecciones al fichero de properties
	  */
	 
	public Q70ManejadorBaseConfiguracion(Q70Configurable newObjComponent, boolean aplicarIndireccion, String aplicacionCodigo) {
		this.objComponente = newObjComponent;
		this.aplicarIndireccion=aplicarIndireccion;
		codigoAplicacion = aplicacionCodigo;
		if (Q70Factoria.isFactoriaKey()){
			estaEjecutandoseDesdeAplicacion  = true;
		}
	}
	
	/**
	 * Inicio de documento
	 * 
	 * @throws SAXException
	 */
	public void startDocument() throws SAXException {
		objComponente.beginConfiguration();
	}

	/**
	 * Fin de documento
	 * 
	 * @throws SAXException
	 */

	public void endDocument() throws SAXException {
		objComponente.endConfiguration();
	}
	
	/**
	 * Inicio de elemento
	 * 
	 * @param uri
	 *            String url del espacio de nombres
	 * @param localName
	 *            String nombre del elemento
	 * @param qName
	 *            String nombre del elemento con prefijo
	 * @param attributes
	 *            Attributes colección de atributos
	 * @throws SAXException
	 */
	public void startElement(String uri, String localName, String qName, Attributes attributes)
			throws SAXException {

		if (qName.equalsIgnoreCase(Q70UtilidadesConstantes.ELEMENTO_LISTA)) {

			strNivel = strNivel + Q70UtilidadesConstantes.SEPARADOR_PATH_XML
					+ Q70UtilidadesConstantes.ELEMENTO_LISTA;
			String strNombre = attributes.getValue(Q70UtilidadesConstantes.ATRIBUTO_NAME);
			strPath = strPath + Q70UtilidadesConstantes.SEPARADOR_PATH_XML + strNombre;
			arryPilaLIFOLista.add(strNombre);
			objComponente.beginList(strNombre, strNivel, strPath);

		} else if (qName.equalsIgnoreCase(Q70UtilidadesConstantes.ELEMENTO_ESTRUCTURA)) {

			strNivel = strNivel + Q70UtilidadesConstantes.SEPARADOR_PATH_XML
					+ Q70UtilidadesConstantes.ELEMENTO_ESTRUCTURA;
			String strNombre = attributes.getValue(Q70UtilidadesConstantes.ATRIBUTO_NAME);
			strPath = strPath + Q70UtilidadesConstantes.SEPARADOR_PATH_XML + strNombre;
			arryPilaLIFOEstructura.add(strNombre);
			objComponente.beginStructure(strNombre, strNivel, strPath);

		} else if (qName.equalsIgnoreCase(Q70UtilidadesConstantes.ELEMENTO_PROPIEDAD)) {

			strNivel = strNivel + Q70UtilidadesConstantes.SEPARADOR_PATH_XML
					+ Q70UtilidadesConstantes.ELEMENTO_PROPIEDAD;
			String strNombre = attributes.getValue(Q70UtilidadesConstantes.ATRIBUTO_NAME);
			strPath = strPath + Q70UtilidadesConstantes.SEPARADOR_PATH_XML + strNombre;
			String strValor = attributes.getValue(Q70UtilidadesConstantes.ATRIBUTO_VALUE);
			arryPilaLIFOPropiedad.add(strNombre);

			if (aplicarIndireccion) {
				try {
					if (Q70UtilidadesGenerales.bolIsPreSub(strValor,
							Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX,
							Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX)) {
						String strValorOrig = strValor;
						// Primero se realiza la búsqueda en el fichero de propiedades Global de Geremua
						strValor = Q70GestorArranqueConfiguracionServidor
								.getGlobalProperty(
										Q70UtilidadesGenerales.strExtractString(
												strValorOrig,
												Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX,
												Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX));
						// Después se realiza la búsqueda de la propiedad en el fichero de propiedades de la aplicación
						if (strValor == null) {
							if (codigoAplicacion == null) {
								strValor = Q70GestorArranqueConfiguracionServidor
										.getApplicationProperty(
												Q70GestorArranqueConfiguracionServidor.ID_COMPONENTE,
												null,
												Q70UtilidadesGenerales
														.strExtractString(
																strValorOrig,
																Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX,
																Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX),
												estaEjecutandoseDesdeAplicacion);
							} else {
								strValor = Q70GestorArranqueConfiguracionServidor
										.getProperty(
												null,
												Q70UtilidadesGenerales
														.strExtractString(
																strValorOrig,
																Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX,
																Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX),
												codigoAplicacion,
												estaEjecutandoseDesdeAplicacion);
							}
						}
					}

				} catch (Exception e) {

					Q70TrazaInterface clsTraza = Q70Factoria.getTraza();
					if (clsTraza.isTraceActive()) {
						clsTraza.trace(Q70Configurador.COMPONENTE, Q70TraceLevel.ERROR, e.getMessage());
					}
					
					try {
						strValor = Q70UtilidadesGenerales.strExtractString(strValor,
								Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX,
								Q70UtilidadesConstantes.PROPIEDAD_SENSIBLE_ENTORNO_PREFIX_SUBFIX);

					} catch (Q70UtilidadesExcepcion ue) {
						if (clsTraza.isTraceActive()) {
							clsTraza.trace(Q70Configurador.COMPONENTE, Q70TraceLevel.ERROR, ue.getMessage());
						}
						throw new SAXException("Error al recuperar el valor de la propiedad '"
								+ strValor + "' de un fichero de properties", ue);
					}
				}
			}
			objComponente.beginProperty(strNombre, strValor, strNivel, strPath);
		}
	}
	
	/**
	  * Final de elemento
	  * @param uri String url del espacio de nombres
	  * @param localName String nombre del elemento
	  * @param qName String nombre del elemento con prefijo
	  * @throws SAXException
	  */
	public void endElement(String uri, String localName, String qName) throws SAXException {

		if (qName.equalsIgnoreCase(Q70UtilidadesConstantes.ELEMENTO_LISTA)) {

			int num = arryPilaLIFOLista.size();
			objComponente.endList((String) arryPilaLIFOLista.get(num - 1), strNivel, strPath);
			strNivel = strNivel.substring(0,
					(strNivel.length() - (Q70UtilidadesConstantes.ELEMENTO_LISTA.length() + 1)));
			strPath = strPath.substring(0, (strPath.length() - (((String) arryPilaLIFOLista
					.get(num - 1)).length() + 1)));
			arryPilaLIFOLista.remove(num - 1);

		} else if (qName.equalsIgnoreCase(Q70UtilidadesConstantes.ELEMENTO_ESTRUCTURA)) {

			int num = arryPilaLIFOEstructura.size();
			objComponente.endStructure((String) arryPilaLIFOEstructura.get(num - 1), strNivel,
					strPath);
			strNivel = strNivel
					.substring(0, (strNivel.length() - (Q70UtilidadesConstantes.ELEMENTO_ESTRUCTURA
							.length() + 1)));
			strPath = strPath.substring(0, (strPath.length() - (((String) arryPilaLIFOEstructura
					.get(num - 1)).length() + 1)));
			arryPilaLIFOEstructura.remove(num - 1);

		} else if (qName.equalsIgnoreCase(Q70UtilidadesConstantes.ELEMENTO_PROPIEDAD)) {

			int num = arryPilaLIFOPropiedad.size();
			objComponente.endProperty((String) arryPilaLIFOPropiedad.get(num - 1), strNivel,
					strPath);
			strNivel = strNivel
					.substring(0, (strNivel.length() - (Q70UtilidadesConstantes.ELEMENTO_PROPIEDAD
							.length() + 1)));
			strPath = strPath.substring(0, (strPath.length() - (((String) arryPilaLIFOPropiedad
					.get(num - 1)).length() + 1)));
			arryPilaLIFOPropiedad.remove(num - 1);
		}
	}
}
