/*
 * Creado el 24-nov-03
 *
 * Para cambiar la plantilla para este archivo generado vaya a
 * Ventana&gt;Preferencias&gt;Java&gt;Generación de código&gt;Código y comentarios
 */
package es.ejie.frmk.presentacion.sesiondatos;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.beanutils.BasicDynaBean;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaClass;
import org.apache.commons.beanutils.DynaProperty;

import es.ejie.frmk.Q70Factoria;
import es.ejie.frmk.control.excepciones.Q70GestorDeExcepcionesServidor;
import es.ejie.frmk.infraestructura.seguridad.Q70InformacionSeguridadInterface;
import es.ejie.frmk.infraestructura.seguridad.Q70SeguridadException;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70TrazaInterface;
import es.ejie.frmk.presentacion.sesiondatos.contexto.persistencia.Q70ManejadorPersistenciaContextoEJIE;
import es.ejie.frmk.presentacion.sesiondatos.contexto.persistencia.Q70PersistenciaDesdeDynaBean;
import es.ejie.frmk.presentacion.sesiondatos.contexto.persistencia.Q70PersistenciaMalInicializadaException;
import es.ejie.frmk.presentacion.sesiondatos.utilidades.Q70ContextoUtilidades;

/**
 * @version 1.0
 * Fecha: 24-nov-03
 * 
 * Implementacion de un contexto basico sin lista de contexto de antecesores,
 * ademas, sirve de base para otras clases de contexto mas complejas.
 * 
 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoGlobal
 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoOperacion
 */
public class Q70ContextoBasico implements Q70ContextoJerarquicoEJIE, Externalizable
{
	private static final long serialVersionUID = 7589504504162055833L;

	private DynaBean contextoDynaBean;
	private String tipoContexto;
	private String idContexto;

	private List listaAtributosInformacionSeguridadInterface;

	protected static final String ID_COMPONENTE = "CONTEXTO";

	protected transient Q70ManejadorSeguridadContextoEJIE manejadorSeguridad = new Q70SeguridadNulaContextoEJIE();
	private transient Q70ManejadorPersistenciaContextoEJIE defaultManejadorPersistencia;
	private transient Q70ManejadorPersistenciaContextoEJIE manejadorPersistencia;

	/**
	 * Necesario porque es una clase Externalizable, debe tener un constructor sin argumentos
	 */
	public Q70ContextoBasico()
	{
		super();
	}

	/**
	 * Construye un nuevo <code>Q70ContextoBasico</code> asociado a la instancia de 
	 * <code>DynaClass</code> especificada.
	 *
	 * @param dynaClass La DynaClass asociada
	 */
	public Q70ContextoBasico(DynaClass dynaClass)
	{
		super();
		setContextoDynaBean(new Q70ContextoBasico(dynaClass));
	}

	/**
	 * Construye un nuevo <code>Q70ContextoBasico</code> a partir de una instancia de 
	 * <code>DynaBean</code> asignadole un tipo de contexto y un identificativo de contexto.
	 *
	 * @param aDynaBean Instancia de DynaBean con la que vamos a construir el Q70ContextoBasico
	 * @param aManejadorPersistencia Instancia de ManejadorPersistenciaContextoEJIE con la que vamos a construir el Q70ContextoBasico y va a manejar 
	 * la persistencia del mismo
	 * @param aTipoContexto El tipo de contexto correspondiente
	 * @param aIdContexto El identificativo correspondiente
	 */
	public Q70ContextoBasico(DynaBean aDynaBean, Q70ManejadorPersistenciaContextoEJIE aManejadorPersistencia, String aTipoContexto, String aIdContexto)
	{
		super();

		tipoContexto = aTipoContexto;
		idContexto = aIdContexto;
		manejadorPersistencia = aManejadorPersistencia;

		setContextoDynaBean(new BasicDynaBean(getDynaClassInstance(aDynaBean)));

		//Recorrer la estructura interna del parametro aDynaBean, es decir, su DynaClass
		// para cargar contextoDynaBean, que es la variable que usa el Q70ContextoBasico
		// para ese proposito
		DynaProperty[] propiedadesAux = aDynaBean.getDynaClass().getDynaProperties();
		for (int i = propiedadesAux.length - 1; i >= 0; i--)
		{
			String nameAux = propiedadesAux[i].getName();
			Object valorAtributo = aDynaBean.get(nameAux);
			getContextoDynaBean().set(nameAux, valorAtributo);
			doAddToInformacionSeguridad(propiedadesAux[i], nameAux);
		}

		getManejadorPersistencia().setContextoEJIEParent(this);
	}

	protected DynaClass getDynaClassInstance(DynaBean aDynaBean)
	{
		return new Q70ContextoEJIEDynaClass(null, getClass(), aDynaBean.getDynaClass().getDynaProperties(), null);
	}
	protected void setContextoDynaBean(DynaBean dynaBean)
	{
		contextoDynaBean = dynaBean;
	}
	protected DynaBean getContextoDynaBean()
	{
		return contextoDynaBean;
	}

	/**
	 * Implementacion basica: No hace nada
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#setContextoLista(java.util.List)
	 */
	public void setContextoLista(List listaSucesores)
	{}
	//TODO Nombres de atributos iguales, problemas: Si tengo nombre atributo igual al de un contexto global puedo modificar este modificando el primero. Por el orden de busqueda.

	/**
	 * Implementacion basica: No hace nada
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#getContextoLista()
	 */
	public List getContextoLista()
	{
		return null;
	}

	/**
	 * Implementacion basica: No hace nada
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#removeContextoSesion(es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE)
	 */
	public void removeContextoSesion(Q70ContextoJerarquicoEJIE contexto)
	{}

	/**
	 * Implementacion basica: No hace nada
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#addContextoSesion(es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE)
	 */
	public void addContextoSesion(Q70ContextoJerarquicoEJIE contexto)
	{}

	/**
	 * Implementacion basica: No hace nada
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#getContextoSesion(int)
	 */
	public Q70ContextoJerarquicoEJIE getContextoSesion(int i)
	{
		return null;
	}

	/**
	 * Devuelve el mismo objeto, en caso de que sea del tipo requerido, si no devuelve null
	 * @param tipoContexto Tipo de contexto preguntado
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#getContextoSesion(java.lang.String)
	 */
	public Q70ContextoJerarquicoEJIE getContextoSesion(String tipoContexto)
	{
		if (getTipoContexto().equals(tipoContexto))
			return this;

		return null;
	}

	/**
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#getTipoContexto()
	 */
	public String getTipoContexto()
	{
		return tipoContexto;
	}

	/**
	 * @see org.apache.commons.beanutils.DynaBean#contains(java.lang.String, java.lang.String)
	 */
	public boolean contains(String arg0, String arg1)
	{
		if (((Q70ContextoEJIEDynaClass) getContextoDynaClass()).getPropiedadDePrimerNivel(arg0) != null)
			return getContextoDynaBean().contains(arg0, arg1);

		throw new IllegalArgumentException(
			"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
	}

	/**
	 * @see org.apache.commons.beanutils.DynaBean#get(java.lang.String)
	 */
	public Object get(String arg0)
	{
		return get0(arg0);
	}

	/**
	 * @see org.apache.commons.beanutils.DynaBean#get(String arg0, int arg1)
	 */
	public Object get(String arg0, int arg1)
	{
		if (arg0 == null)
			throw new IllegalArgumentException(
					"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
			//throw new NullPointerException("No indexed value for '" + arg0 + "[" + arg1 + "]'");

		if (((Q70ContextoEJIEDynaClass) getContextoDynaClass()).getPropiedadDePrimerNivel(arg0) != null)
		{
			if (!manejadorSeguridad.isConsultable(this, arg0))
				throw new Q70ContextoEJIENoConsultableException(
					ID_COMPONENTE,
					this.getClass().toString(),
					"get(String arg0, int arg1)",
					"Usuario sin permiso para consultar este dato:'" + arg0 + "[" + arg1 + "]'",
					null);
			return getContextoDynaBean().get(arg0, arg1);
		}

		//throw new NullPointerException("No indexed value for '" + arg0 + "[" + arg1 + "]'");
		throw new IllegalArgumentException(
				"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
	}

	/**
	 * @see org.apache.commons.beanutils.DynaBean#get(String arg0, String arg1)
	 */
	public Object get(String arg0, String arg1)
	{
		if (arg0 == null)
			throw new IllegalArgumentException(
					"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
			//throw new NullPointerException("No mapped value for '" + arg0 + "(" + arg1 + ")'");

		if (((Q70ContextoEJIEDynaClass) getContextoDynaClass()).getPropiedadDePrimerNivel(arg0) != null)
		{
			if (!manejadorSeguridad.isConsultable(this, arg0))
				throw new Q70ContextoEJIENoConsultableException(
					ID_COMPONENTE,
					this.getClass().toString(),
					"get(String arg0, String arg1)",
					"Usuario sin permiso para consultar este dato:'" + arg0 + "(" + arg1 + ")'",
					null);
			return getContextoDynaBean().get(arg0, arg1);
		}

		//throw new NullPointerException("No mapped value for '" + arg0 + "(" + arg1 + ")'");
		throw new IllegalArgumentException(
				"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
	}

	private Object get0(String arg0)
	{
		if (((Q70ContextoEJIEDynaClass) getContextoDynaClass()).getPropiedadDePrimerNivel(arg0) != null)
		{
			try
			{
				if (!manejadorSeguridad.isConsultable(this, arg0))
				{
					throw new Q70ContextoEJIENoConsultableException(
						ID_COMPONENTE,
						this.getClass().toString(),
						"get(String arg0)",
						"Usuario sin permiso para consultar este dato:'" + arg0 + "'",
						null);
				}
				return getContextoDynaBean().get(arg0);
			}
			catch (IllegalArgumentException e)
			{}
		}
		return getInformacionSeguridadInterface(arg0);
	}

	private Object getInformacionSeguridadInterface(String arg0)
	{
		if (listaAtributosInformacionSeguridadInterface != null)
		{
			Iterator it = listaAtributosInformacionSeguridadInterface.iterator();
			while (it.hasNext())
			{
				try
				{
					Object info = get((String) it.next());
					if (info == null)
					{
						continue;
					}
					Object rdo = ((Q70InformacionSeguridadInterface) info).getSessionSecurityInf(arg0);
					if (rdo == null)
					{
						continue;
					}
					if (((List)rdo).size()==0)
					{
						continue;
					}
					return ((List)rdo).get(0);
				}
				catch (Q70SeguridadException se)
				{}
			}
		}

		throw new IllegalArgumentException(
			"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
	}

	/**
	 * @see org.apache.commons.beanutils.DynaBean#getDynaClass()
	 */
	public DynaClass getDynaClass()
	{
		return getContextoDynaClass();
	}

	/**
	 * @see org.apache.commons.beanutils.DynaBean#remove(String arg0, String arg1)
	 */
	public void remove(String arg0, String arg1)
	{
		if (((Q70ContextoEJIEDynaClass) getContextoDynaClass()).getPropiedadDePrimerNivel(arg0) != null)
		{
			if (!manejadorSeguridad.isModificable(this, arg0))
				throw new Q70ContextoEJIENoModificableException(
					ID_COMPONENTE,
					this.getClass().toString(),
					"remove(String arg0, String arg1)",
					"Usuario sin permiso para borrar este dato:'" + arg0 + "(" + arg1 + ")'",
					null);
			if (getContextoDynaBean().contains(arg0, arg1))
			{
				if (!isMantenible())
				{
					throw new Q70ContextoEJIENoMantenibleException(
						ID_COMPONENTE,
						this.getClass().toString(),
						"remove(String arg0, String arg1)",
						"Dato perteneciente a contexto('" + getTipoContexto() + "') no modificable:'" + arg0 + "(" + arg1 + ")'",
						null);
				}
				getContextoDynaBean().remove(arg0, arg1);
				notifyChanges(arg0, get(arg0), null);
			}
			return;
		}

		throw new IllegalArgumentException(
			"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
	}

	/**
	 * @see org.apache.commons.beanutils.DynaBean#set(java.lang.String, int, java.lang.Object)
	 */
	public void set(String arg0, int arg1, Object arg2)
	{
		if (arg0 == null)
			throw new IllegalArgumentException(
					"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");

		if (((Q70ContextoEJIEDynaClass) getContextoDynaClass()).getPropiedadDePrimerNivel(arg0) != null)
		{
			if (!manejadorSeguridad.isModificable(this, arg0))
				throw new Q70ContextoEJIENoModificableException(
					ID_COMPONENTE,
					this.getClass().toString(),
					"set(String arg0, int arg1, Object arg2)",
					"Usuario sin permiso para modificar este dato:'" + arg0 + "[" + arg1 + "]' con este valor:'" + arg2 + "'",
					null);
			if (getContextoDynaBean().get(arg0, arg1) == null || !getContextoDynaBean().get(arg0, arg1).equals(arg2))
			{
				if (!isMantenible())
				{
					throw new Q70ContextoEJIENoMantenibleException(
						ID_COMPONENTE,
						this.getClass().toString(),
						"set(String arg0, int arg1, Object arg2)",
						"Dato perteneciente a contexto('"
							+ getTipoContexto()
							+ "') no modificable:'"
							+ arg0
							+ "["
							+ arg1
							+ "]' con este valor:'"
							+ arg2
							+ "'",
						null);
				}
				getContextoDynaBean().set(arg0, arg1, arg2);
				notifyChanges(arg0, arg2, null);
			}
			return;
		}

//		throw new NullPointerException(
//			"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
		throw new IllegalArgumentException(
				"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
	}

	/**
	 * @see org.apache.commons.beanutils.DynaBean#set(java.lang.String, java.lang.Object)
	 */
	public void set(String arg0, Object arg1)
	{
		set0(arg0, arg1, null);
	}

	/**
	 * @see org.apache.commons.beanutils.DynaBean#set(java.lang.String, java.lang.String, java.lang.Object)
	 */
	public void set(String arg0, String arg1, Object arg2)
	{
		if (arg0 == null)
			throw new IllegalArgumentException(
					"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");

		if (((Q70ContextoEJIEDynaClass) getContextoDynaClass()).getPropiedadDePrimerNivel(arg0) != null)
		{
			if (!manejadorSeguridad.isModificable(this, arg0))
				throw new Q70ContextoEJIENoModificableException(
					ID_COMPONENTE,
					this.getClass().toString(),
					"set(String arg0, String arg1, Object arg2)",
					"Usuario sin permiso para modificar este dato:'" + arg0 + "(" + arg1 + ")' con este valor:'" + arg2 + "'",
					null);
			if (getContextoDynaBean().get(arg0, arg1) == null || !getContextoDynaBean().get(arg0, arg1).equals(arg2))
			{
				if (!isMantenible())
				{
					throw new Q70ContextoEJIENoMantenibleException(
						ID_COMPONENTE,
						this.getClass().toString(),
						"set(String arg0, String arg1, Object arg2)",
						"Dato perteneciente a contexto('"
							+ getTipoContexto()
							+ "') no modificable:'"
							+ arg0
							+ "("
							+ arg1
							+ ")' con este valor:'"
							+ arg2
							+ "'",
						null);
				}
				getContextoDynaBean().set(arg0, arg1, arg2);
				notifyChanges(arg0, arg2, null);
			}
			return;
		}

//		throw new NullPointerException("No mapped value for '" + arg0 + "(" + arg1 + ")'");
		throw new IllegalArgumentException(
				"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
	}

	public void setSinNotificacion(String arg0, Object arg1, List listaSinNoficacion)
	{
		set0(arg0, arg1, listaSinNoficacion);
	}

	private void set0(String arg0, Object arg1, List listaSinNoficacion)
	{
		if (((Q70ContextoEJIEDynaClass) getContextoDynaClass()).getPropiedadDePrimerNivel(arg0) != null)
		{
			if (getContextoDynaBean().get(arg0) == null || !getContextoDynaBean().get(arg0).equals(arg1))
			{
				if (!isMantenible())
				{
					throw new Q70ContextoEJIENoMantenibleException(
						ID_COMPONENTE,
						this.getClass().toString(),
						"set(String arg0, Object arg1)",
						"Dato perteneciente a contexto('" + getTipoContexto() + "') no modificable:'" + arg0 + "' con este valor:'" + arg1 + "'",
						null);
				}
				//Para poder hacer modificaciones de los contextos globales sin tener en cuenta la seguridad
				if (listaSinNoficacion==null){
					if (!manejadorSeguridad.isModificable(this, arg0))
						throw new Q70ContextoEJIENoModificableException(
							ID_COMPONENTE,
							this.getClass().toString(),
							"set(String arg0, Object arg1)",
							"Usuario sin permiso para modificar este dato:'" + arg0 + "' con este valor:'" + arg1 + "'",
							null);
				}
				getContextoDynaBean().set(arg0, arg1);
				notifyChanges(arg0, arg1, listaSinNoficacion);
			}
			return;
		}

		throw new IllegalArgumentException(
			"tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "', nombreAtributo:'" + arg0 + "'");
	}

	/**
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#getListaModificados()
	 */
	public Set getListaModificados()
	{
		return null;
	}

	/**
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoEJIE#getIdContexto()
	 */
	public String getIdContexto()
	{
		return idContexto;
	}

	/**
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#isMantenible()
	 */
	public boolean isMantenible()
	{
		return getManejadorPersistencia().isMantenible();
	}

	/**
	 * Compara la estructura interna y valores del Q70ContextoBasico con el pasado
	 * por parametro, para comprobar que son identicos.
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object obj)
	{
		if (this == obj)
			return true;
		if (obj == null)
			return false;

		Q70ContextoJerarquicoEJIE contextoAux;
		try
		{
			contextoAux = (Q70ContextoJerarquicoEJIE) obj;
		}
		catch (ClassCastException e)
		{
			return false;
		}

		if (!this.tipoContexto.equals(contextoAux.getTipoContexto()))
			return false;
		if (!this.idContexto.equals(contextoAux.getIdContexto()))
			return false;
		//if ( !Arrays.equals(this.getDynaClass().getDynaProperties(),contextoAux.getDynaClass().getDynaProperties()) )
		//	return false;
		// TODO equals() Si contexto this tiene nombres iguales de campos puede devolver true, porq el otro contexto puede tener esos campos mas otros q no tiene el primero !!!
		DynaProperty[] propiedadesAux = getDynaClass().getDynaProperties();
		if (propiedadesAux.length != contextoAux.getDynaClass().getDynaProperties().length)
		{
			return false;
		}
		Q70ManejadorSeguridadContextoEJIE manejadorActualContexto = manejadorSeguridad;
		for (int i = propiedadesAux.length - 1; i >= 0; i--)
		{
			manejadorSeguridad = new Q70SeguridadNulaContextoEJIE();
			if (((Q70ContextoEJIEDynaClass) getContextoDynaClass()).getPropiedadDePrimerNivel(propiedadesAux[i].getName()) != null)
			{

				if (!Q70ContextoUtilidades.compare(get(propiedadesAux[i].getName()), contextoAux.get(propiedadesAux[i].getName())))
				{
					manejadorSeguridad = manejadorActualContexto;
					return false;
				}
				/*
				if ((get(propiedadesAux[i].getName()) == null && contextoAux.get(propiedadesAux[i].getName()) != null)
					|| (get(propiedadesAux[i].getName()) != null && contextoAux.get(propiedadesAux[i].getName()) == null)) {
					manejadorSeguridad = manejadorActualContexto;
					return false;
				}
				if (get(propiedadesAux[i].getName()) != null && contextoAux.get(propiedadesAux[i].getName()) != null) {
					if (!get(propiedadesAux[i].getName()).equals(contextoAux.get(propiedadesAux[i].getName()))) {
						manejadorSeguridad = manejadorActualContexto;
						return false;
					}
				}
				*/
			}
		}
		manejadorSeguridad = manejadorActualContexto;
		return true;
	}

	protected void setIdContexto(String string)
	{
		idContexto = string;
	}
	protected void setTipoContexto(String string)
	{
		tipoContexto = string;
	}

	/**
	 * Devuelve toda la informacion del Q70ContextoBasico con una apariencia XML.
	 * 
	 * @see java.lang.Object#toString()
	 */
	public String toString()
	{
		StringBuffer strAux = new StringBuffer(100);

		strAux.append("<contexto>");
		strAux.append("\n");
		strAux = toStringValoresClase(strAux);
		strAux.append("\n");

		if (getContextoDynaBean() != null)
		{
			strAux = toStringListaAtributos(strAux, getContextoDynaClass());
			strAux.append("\n");
		}

		strAux.append("</contexto>");
		return strAux.toString();
	}

	protected StringBuffer toStringValoresClase(StringBuffer strAux)
	{
		strAux.append("<claseContexto>");
		strAux.append(getClass().getName());
		strAux.append("</claseContexto>");
		strAux.append("\n");
		strAux.append("<hashCode>");
		strAux.append(hashCode());
		strAux.append("</hashCode>");
		strAux.append("\n");
		strAux.append("<tipoContexto>");
		strAux.append(getTipoContexto());
		strAux.append("</tipoContexto>");
		strAux.append("\n");
		strAux.append("<idContexto>");
		strAux.append(getIdContexto());
		strAux.append("</idContexto>");
		return strAux;
	}
	protected StringBuffer toStringListaAtributos(StringBuffer strAux, DynaClass dynaClass)
	{
		strAux.append("<listaAtributos>");
		strAux.append("\n");
		DynaProperty[] propiedadesAux = dynaClass.getDynaProperties();
		for (int i = propiedadesAux.length - 1; i >= 0; i--)
		{
			String nameProp = propiedadesAux[i].getName();
			strAux = toStringAtributo(strAux, nameProp);
			strAux.append("\n");
		}
		strAux.append("</listaAtributos>");
		return strAux;
	}
	protected StringBuffer toStringAtributo(StringBuffer strAux, String nameProp)
	{
		strAux.append("<atributo>");
		strAux.append("\n");
		strAux.append("<nombreAtributo>");
		strAux.append(nameProp);
		strAux.append("</nombreAtributo>");
		strAux.append("\n");
		try
		{
			Object aux = get(nameProp);
			strAux.append("<valorAtributo>");
			strAux.append(aux);
			strAux.append("</valorAtributo>");
		}
		catch (Q70ContextoEJIENoConsultableException e)
		{
			strAux.append("<excepcion>");
			strAux.append(e.getClass() + ":" + e.getMessage());
			strAux.append("</excepcion>");
		}
		strAux.append("\n");
		strAux.append("<tipoAtributo>");
		strAux.append(getDynaClass().getDynaProperty(nameProp).getType().getName());
		strAux.append("</tipoAtributo>");
		strAux.append("\n");
		strAux.append("</atributo>");
		return strAux;
	}

	protected DynaClass getContextoDynaClass()
	{
		if (getContextoDynaBean() == null)
		{
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			if (traza.isTraceActive())
			{
				traza.trace(ID_COMPONENTE, Q70TraceLevel.ERROR, "Contexto mal construido: tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "'");
			}
			throw new IllegalArgumentException(
					"Contexto mal construido: tipoContexto:'" + getTipoContexto() + "', idContexto:'" + getIdContexto() + "'");
		}
		return getContextoDynaBean().getDynaClass();
	}

	protected void trazaSerializable()
	{
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		if (traza.isTraceActive())
		{
			traza.trace(ID_COMPONENTE, Q70TraceLevel.INFO, "Serializando Q70ContextoEJIE..." + this.getClass() + "..." + this.getIdContexto());
		}
	}
	protected void trazaDeserializable()
	{
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		if (traza.isTraceActive())
		{
			traza.trace(ID_COMPONENTE, Q70TraceLevel.INFO, "Deserializando Q70ContextoEJIE..." + this.getClass() + "..." + this.getIdContexto());
		}
	}

	/**
	 * 
	 * @serialData Only the serializable fields of the class are written.
	 *             No optional data written. 
	 */
	public void writeExternal(ObjectOutput out) throws IOException
	{
		trazaSerializable();
		out.writeObject(getTipoContexto());
		out.writeObject(getIdContexto());
		out.writeObject(listaAtributosInformacionSeguridadInterface);
		out.writeObject(getContextoDynaBean());
	}

	/**
	 *
	 * @serialData No optional data is read.
	 */
	public void readExternal(ObjectInput is) throws IOException, ClassNotFoundException
	{
		setTipoContexto((String) is.readObject());
		setIdContexto((String) is.readObject());
		listaAtributosInformacionSeguridadInterface = (List) is.readObject();
		setContextoDynaBean((DynaBean) is.readObject());
		trazaDeserializable();
	}
	/**
	 * Implementacion basica: No hace nada
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#addContextoListener(es.ejie.frmk.presentacion.sesiondatos.Q70ContextoEJIEObservador)
	 */
	public void addContextoListener(Q70ContextoEJIEObservador aListener)
	{}

	/**
	 * Implementacion basica: No hace nada
	 * @see es.ejie.frmk.presentacion.sesiondatos.Q70ContextoJerarquicoEJIE#removeContextoListener(es.ejie.frmk.presentacion.sesiondatos.Q70ContextoEJIEObservador)
	 */
	public void removeContextoListener(Q70ContextoEJIEObservador aListener)
	{}

	protected void notifyChanges(String nombreCampoModificado, Object nuevoValorCampoModificado, List listaSinNotificar)
	{}

	/**
	 * @return
	 */
	public Q70ManejadorPersistenciaContextoEJIE getManejadorPersistencia()
	{
		if (manejadorPersistencia == null)
		{
			if (defaultManejadorPersistencia == null)
			{
				try
				{
					defaultManejadorPersistencia = new Q70PersistenciaDesdeDynaBean(this);
					defaultManejadorPersistencia.setContextoEJIEParent(this);
				}
				catch (Q70PersistenciaMalInicializadaException e)
				{
					Q70TrazaInterface traza = Q70Factoria.getTraza();
					if (traza.isTraceActive())
					{
						traza.trace(
							ID_COMPONENTE,
							Q70TraceLevel.ERROR,
							"Error en crear persistencia por defecto, Q70PersistenciaDesdeDynaBean en clase:'"
								+ this.getClass()
								+ "','"
								+ this.getTipoContexto()
								+ "','"
								+ this.getIdContexto()
								+ "'");
					}
					Q70GestorDeExcepcionesServidor.getSingleton().recogerThrowable(e);
				}
			}
			return defaultManejadorPersistencia;
		}
		return manejadorPersistencia;
	}

	/**
	 * @param contextoEJIE
	 */
	protected void setManejadorPersistencia(Q70ManejadorPersistenciaContextoEJIE contextoEJIE)
	{
		manejadorPersistencia = contextoEJIE;
	}

	private void doAddToInformacionSeguridad(DynaProperty propiedad, String nombreAtributo)
	{
		Class[] interfaces = propiedad.getType().getInterfaces();
		for (int i = interfaces.length - 1; i >= 0; i--)
		{
			if (interfaces[i].getName().equals(Q70InformacionSeguridadInterface.class.getName()))
			{
				if (listaAtributosInformacionSeguridadInterface == null)
				{
					listaAtributosInformacionSeguridadInterface = new ArrayList(1);
				}
				listaAtributosInformacionSeguridadInterface.add(nombreAtributo);
			}
		}
	}
}
