package es.ejie.frmk.infraestructura.sms;
	
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import es.ejie.frmk.Q70Factoria;
import es.ejie.frmk.control.excepciones.Q70FrameworkException;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70TrazaInterface;
import es.ejie.frmk.infraestructura.utilidades.concurrencia.Q70Lock;
import es.ejie.frmk.infraestructura.utilidades.general.Q70UtilidadesGenerales;
import es.ejie.frmk.infraestructura.utilidades.xml.Q70UtilidadesXML;

/**
 * Clase base que ejecuta toda la logica de envio y sus respuestas de mensajes SMS, así como la recepcion de los 
 * mensajes.
 * Las tareas que realiza la clase son:
 * <ul>
 * <li> Configuración de la pasarela de envío SMS </li> 
 * <li> Comprobación de parametros de envío: </li>
 * <ul>
 * <li> Los permisos de usuario/aplicación sesión N38 no sean nulos</li>
 * <li> El nombre del remitente no sea nulo </li>
 * <li> Si el envío del SMS es por cliente/usuario y no por aplicación, que exista un email de remitente. </li>
 * <li> Que exista algun mensaje por enviar </li>
 * </ul>
 * <li> Construcción del fichero XML a enviar a partir de los datos de la peticion </li>
 * <li> Envío del fichero XML y gestionar la respuesta de éste (posibles errores: de envio, datos, permisos, etc...) </li>
 * <li> Lógica de recepcion del SMS: transformación a fichero XML y captura de los datos de recepcion: </li>
 * <ul>
 * <li>Identificador del SMS </li>
 * <li>Numero de telefono del que ha enviado el SMS </li>
 * <li>La fecha del mensaje </li>
 * <li>El texto del mensaje</li>
 * </ul>
 * </ul>
 * @version 2.0   Fecha: 07-jun-06
 */

public abstract class Q70GestorSMSBase implements Q70GestorSMSServidorInterface {
	
	private String urlPasarelaSMS=null;
	private String prefijoSMS=null;
	
	private Q70Lock lock = null;
	
	/**
	 * @return Returns the lock.
	 */
	protected Q70Lock getLock() {
		return lock;
	}
	
	/**
	 * @param lock The lock to set.
	 */
	protected void setLock(Q70Lock lock) {
		this.lock = lock;
	}
	
	/**
	 * Método al que pasándole un Q70SMSPeticion es capaz de enviar los SMS de dicha petición.
	 * @param smsPeticion Objeto que representa una petición de envío de mensajes SMS.
	 * @exception Q70SMSException
	 */
	public void dispatch(Q70SMSPeticion smsPeticion) throws Q70SMSException {

		getLock().entradaZonaCritica();
		
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		String xmlIn="";
		String xmlOut="";
		HttpURLConnection urlConnection = null;

		try {
			//configuración de la pasarela SMS
			smsPeticion.setUrlPasarelaSMS(valoresDefectos(smsPeticion.getUrlPasarelaSMS(),this.getUrlPasarelaSMS()));
			//comprobar parametros de envio
			comprobarParametros(smsPeticion);
			//construccíon del ficheor de envío SMS
			xmlIn=construirXML(smsPeticion);
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "XML enviado:\n"+xmlIn);
			}
			try {
				//obtener un descriptor de conexión a través de la URL pasarela SMS
				urlConnection = abrirConexion();
				//enviar Mensaje
				enviarMensaje (urlConnection,xmlIn);
				//recepción de mensaje de respuesta al envío del SMS
				xmlOut=Q70UtilidadesGenerales.readInputStream(urlConnection.getInputStream());
			} catch (Q70SMSException e) {
				if (traza.isTraceActive()) {
					traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se ha recibido una excepcion durante la cominucación con la pasarela de envío de SMS");
				}
				throw new Q70SMSException (this.getClass().getName(), "dispatch", "Se ha recibido una excepcion durante la cominucación con la pasarela de envío de SMS", e);
			} finally {
				if (null != urlConnection) {
					urlConnection.disconnect();
				}
			}
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "XML recibido:\n"+xmlOut);
			}
			//gestionar la recepcion del mensaje al envio del SMS
			gestionarInformacionRecibida(xmlOut, smsPeticion.getAllMensajes());			
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "SMS Enviado con éxito.");
			}
		} catch (Exception e) {
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se ha recibido una excepcion en el componente de envío de SMS");
			}
			throw new Q70SMSException (this.getClass().getName(), "dispatch", "Se ha recibido una excepcion en el componente de envío de SMS", e);
		} finally {
			getLock().salidaZonaCritica();
		}
	}
	
	/**
	 * Método al que pasándole la petición realizada por la pasarela SMS a la
	 * URL de la aplicación, es capaz de interpretar el el SMS recibido,
	 * transformando un XML y retornando una estructura de datos con los datos
	 * del SMS recibido.
	 * @param request Petición realizada por la pasarela SMS a la URL de la
	 * aplicación.
	 * @return HashMap Estructura de datos con los datos del SMS recibido.
	 * @exception Q70SMSException
	 */
	public HashMap interpretarSMSRecibido(HttpServletRequest request) throws Q70SMSException {
		getLock().entradaZonaCritica();
		
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		try {	
			HashMap resultado = new HashMap(5);
			// Leemos el XML
			String xml = Q70UtilidadesGenerales.readInputStream(request.getInputStream());
			// Lo convertimos en arbol dom
			Document documento = Q70UtilidadesXML.stringToDocument(xml);
			
			//Busco la respuesta
			NodeList listaRespuesta = documento.getElementsByTagName("RESPUESTA");
			
			// Recojemos el mensaje
			Element miRespuesta = (Element)listaRespuesta.item(0);
			resultado.put(Q70Constantes.SMS_RESPUESTA_ID, miRespuesta.getAttribute("IDMSG"));
			resultado.put(Q70Constantes.SMS_RESPUESTA_TELEFONO, miRespuesta.getElementsByTagName("TELEFONO").item(0).getFirstChild().getNodeValue());
			resultado.put(Q70Constantes.SMS_RESPUESTA_TIMESTAMP, miRespuesta.getElementsByTagName("TIMESTAMP").item(0).getFirstChild().getNodeValue());
			resultado.put(Q70Constantes.SMS_RESPUESTA_TEXTO, miRespuesta.getElementsByTagName("MENSAJE").item(0).getFirstChild().getNodeValue());			
			
			return resultado;
		} catch (Exception e) {
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se ha recibido una excepcion en el componente de recepción de SMS");
			}
			throw new Q70SMSException (this.getClass().getName(), "interpretarSMSRecibido", "Se ha recibido una excepcion en el componente de recepción de SMS", e);
		} finally {
			getLock().salidaZonaCritica();
		}
	}
	
	/**
	 * @param valor
	 * @param defecto
	 * @return
	 */
	private String valoresDefectos (String valor,String defecto)
	{
		return (null!=valor && valor.trim().length()>0)?valor:defecto;
	}

	/**
	 * @param urlPasarelaSMS
	 * @exception Q70SMSException
	 */
	public void setUrlPasarelaSMS(String urlPasarelaSMS) throws Q70SMSException {
		if (!getLock().isBloqueo()) {
			throw new Q70SMSException(this.getClass().toString(),"setSMTP","Se ha entrado por un método que necesita que el bloqueo del componente esté activo.",null);
		}
		this.urlPasarelaSMS=urlPasarelaSMS;
	}

	/**
	 * @return URL pasarela SMS
	 */
	public String getUrlPasarelaSMS() {
		getLock().entradaZonaCritica();		
		try {
			return urlPasarelaSMS;
		} catch (RuntimeException e) {
			throw e;
		} finally {
			getLock().salidaZonaCritica();
		}
	}

	public void inicializar() {
	}

	public void activar() {
		getLock().activar();
	}

	public void suspender() throws Q70FrameworkException{
		try {
			getLock().suspender();
		} catch (Q70FrameworkException e) {
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			if (traza.isTraceActive()){
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se ha producido un error en el método suspender de la clase Q70GestorSMSBase");
			}
			throw new Q70FrameworkException(Q70Constantes.ID_COMPONENTE,this.getClass().toString(),"suspender","Se ha producido un error en el método suspender.",e);
		}
	}

	public void liberar() {
	}
	
	protected abstract void doDestruir();
	
	public void destruir() throws Q70SMSException {
		try {
			liberar();
			doDestruir();
			activar();
		} catch (Throwable e) {
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			if (traza.isTraceActive()){
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se ha producido un error en el método destruir de la clase Q70GestorSMSBase");
			}
			throw new Q70SMSException(this.getClass().toString(),"destruir","Se ha producido un error en el método destruir.",e);
		}
	}
	
	/**
	 * Enviar SMS por el descriptor URL pasarela SMS
	 * @param urlConnection
	 * @param xml
	 * @throws Q70SMSException
	 */
	private void enviarMensaje (HttpURLConnection urlConnection,String xml) throws Q70SMSException
	{
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		PrintStream out = null;
		try {
			out = new PrintStream (urlConnection.getOutputStream());
			out.print(xml);			
		} catch (Exception e) {
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se ha recibido una excepcion al enviar un SMS");
			}
			throw new Q70SMSException (this.getClass().getName(), "enviarMensaje", "Se ha recibido una excepcion al enviar un SMS", e); 
		} finally {
			if (null != out) {
				out.close();
			}
		}
	}
	
	/**
	 * Abrir una conexión a la URL de envio SMS
	 * @return HtppURLConnection
	 * @throws Q70SMSException
	 */
	private HttpURLConnection abrirConexion () throws Q70SMSException
	{
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		URL url = null;
		HttpURLConnection urlConnection = null;
		try {
			url = new URL(urlPasarelaSMS);
			urlConnection = (HttpURLConnection) url.openConnection();
			urlConnection.setDoInput(true);
			urlConnection.setDoOutput(true);
			urlConnection.setUseCaches(false);
			urlConnection.setRequestMethod("POST");
		} catch (Exception e) {
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Error al establecer la conexión con la pasarelaSMS: "+urlPasarelaSMS);
			}
			throw new Q70SMSException (this.getClass().getName(), "abrirConexion", "Error al establecer la conexión con la pasarelaSMS: "+urlPasarelaSMS, e); 
		}
		return urlConnection;
	}
	
	/**
	 * Lógica de la respuesta recibida al envío del SMS. Gestión de los posibles errores de envío.
	 * @param xml
	 * @param listaMensajes
	 * @throws Q70SMSException
	 */
	private void gestionarInformacionRecibida(String xml, ArrayList listaMensajes) throws Q70SMSException
	{
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		try {
			Document documento = Q70UtilidadesXML.stringToDocument(xml);
			
			//se recogen los errores de envio SMS
			NodeList listaErrores = documento.getElementsByTagName("ERROR");
			
			if (listaErrores.getLength()>0) {
				rellenarErrores(listaErrores);
			} else {
				rellenarResultado(documento.getElementsByTagName("MENSAJE"), listaMensajes);
			}
		} catch(Exception e) {
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se han encontrado errores en la respuesta del envio");
			}
			throw new Q70SMSException (this.getClass().getName(), "gestionarInformacionRecibida", "Se han encontrado errores en la respuesta del envio", e);
		}
	}
	
	/**
	 * En caso de que no haya errores en el cuerpo del mensaje, es decir que el resultado es OK, se recoge el 
	 * identificador del mensaje. 
	 * En caso de error se añade a una lista de tipo Q70SMSTelefonoException, con el mensaje de error y su codigo,
	 * y finalmente se retorna una lista con todos los posibles errores mediante una excepción del tipo 
	 * Q70SMSTelefonosException
	 * @param nodoMensajes
	 * @param listaMensajes
	 * @throws Q70SMSTelefonosException
	 */
	private void rellenarResultado(NodeList nodoMensajes, ArrayList listaMensajes) throws Q70SMSTelefonosException
	{
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		Q70SMSTelefono smsTelefono = null;
		ArrayList lista=null;
		
		for (int i=0;i<nodoMensajes.getLength();i++)
		{
			Element elMensaje = (Element)nodoMensajes.item(i);
			NodeList nodoTelefonos = elMensaje.getElementsByTagName("TELEFONO");
			
			for (int j=0;j<nodoTelefonos.getLength();j++)
			{
				Element elTelefono = (Element)nodoTelefonos.item(j);
				//Recorremos los telefonos del mensaje.
				for (int k=0;k<((Q70SMSMessage)listaMensajes.get(i)).getAllTelefonos().size();k++)
				{
					//Obtenemos el telefono del mensaje
					smsTelefono = (Q70SMSTelefono)((Q70SMSMessage)listaMensajes.get(i)).getAllTelefonos().get(k);
					if (smsTelefono.getNumeroTelefono().toString().equals(elTelefono.getAttribute("NUM"))){
						if (elTelefono.getElementsByTagName("RESULTADO").item(0).getFirstChild().getNodeValue().equals("OK")){
							//Asignamos el identificador en caso de que nº de telefono sea OK
							smsTelefono.setIdentificador(elTelefono.getElementsByTagName("IDENTIFICADOR").item(0).getFirstChild().getNodeValue());
						}else{
							//Recogemos el mensaje y el codigo del error.
							String mensaje= elTelefono.getElementsByTagName("MENSAJE_ERROR").item(0).getFirstChild().getNodeValue();
							String codigo = elTelefono.getElementsByTagName("CODIGO_ERROR").item(0).getFirstChild().getNodeValue();
							if (traza.isTraceActive()) {
								traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "ERROR enviando SMS al número: "+smsTelefono.getNumeroTelefono());
							}
							//Añadimos en una lista el Q70SMSTelefonoException
							lista.add(new Q70SMSTelefonoException(this.getClass().getName(),"rellenarResultado",mensaje,smsTelefono.getNumeroTelefono(),new Integer(codigo)));
						}
					}
				}
			}
		}
		//En caso de algun error en el mensaje, se lanza una excepción de tipo Q70SMSTelefonosException
		if (lista.size()>0){
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Errores para los teléfonos a los que se ha enviado el SMS");
			}
			throw new Q70SMSTelefonosException(this.getClass().getName(),"rellenarResultado","Lista de Q70SMSTelefonoException al enviar SMS",(Q70SMSTelefonoException[])lista.toArray());
		}
	}
	
	/**
	 * Se lanza una excepcion Q70SMSPeticionException con los errores generados del envío SMS
	 * @param listaErrores
	 * @throws Q70SMSPeticionException
	 */
	private void rellenarErrores(NodeList listaErrores) throws Q70SMSPeticionException
	{
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		Node nodoError=listaErrores.item(0);
		Element miError = (Element)nodoError;
		String origen=null;
		String razon=null;
		String descripcion=null;
		
		if (miError.getElementsByTagName(Q70Constantes.TAG_ORIGEN).getLength()>0)
			origen=miError.getElementsByTagName(Q70Constantes.TAG_ORIGEN).item(0).getFirstChild().getNodeValue();
		if (miError.getElementsByTagName(Q70Constantes.TAG_RAZON).getLength()>0)
			razon=miError.getElementsByTagName(Q70Constantes.TAG_RAZON).item(0).getFirstChild().getNodeValue();
		if (miError.getElementsByTagName(Q70Constantes.TAG_DESCRIPCION).getLength()>0)
			descripcion=miError.getElementsByTagName(Q70Constantes.TAG_DESCRIPCION).item(0).getFirstChild().getNodeValue();

		if (traza.isTraceActive()) {
			traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, descripcion);
		}
		throw new Q70SMSPeticionException(origen, razon, this.getClass().getName(), "rellenarErrores", descripcion);
	}
	
	/**
	 * Se comprueban que existan los datos mínimos para enviar el SMS. En caso de no ser asi, se lanza una 
	 * excepcion Q70SMSException
	 * @param smsPeticion
	 * @throws Q70SMSException
	 */
	private void comprobarParametros(Q70SMSPeticion smsPeticion) throws Q70SMSException
	{
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		//La sesion N38 no este en blanco
		if (smsPeticion.getN38Sesion().equals(""))
		{
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "ERROR: No se ha validado como usuario de XL-NETS.");
			}
			throw new Q70SMSException (this.getClass().getName(), "comprobarParametros", "No se ha validado como usuario de XL-NETS.", null);
		}
		//Nombre remitente no sea nulo
		if (null==smsPeticion.getNombreRemitente().trim() || smsPeticion.getNombreRemitente().trim().length()==0)
		{
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "ERROR: Nombre del origen no introducido.");
			}
    		throw new Q70SMSException (this.getClass().getName(), "comprobarParametros", "Nombre del Origen no Introducido.", null);
		}
		//Envio SMS es por cliente/usuario que tenga un mail de recepcion de acuses
		if ((smsPeticion.getTipoRemitente().intValue()==0) && (null==smsPeticion.getMailRemitente() || smsPeticion.getMailRemitente().trim().length()==0))
		{
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "ERROR: Dirección de correo electrónico no introducido.");
			}
			throw new Q70SMSException (this.getClass().getName(), "comprobarParametros", "Dirección de correo electrónico no introducido.", null);
		}
		//El SMS tenga algún mensaje
		if (smsPeticion.getAllMensajes().size()==0)
		{
			if (traza.isTraceActive()) {
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "ERROR: No se ha introducido ningún mensaje a la petición.");
			}
			throw new Q70SMSException (this.getClass().getName(), "comprobarParametros", "No se ha introducido ningún mensaje a la petición.", null);    	  
		}
	}
	
	/**
	 * Construcción el fichero XML de envío
	 * @param smsPeticion
	 * @return
	 * @throws Q70SMSException
	 * @return cadena XML
	 */
	private String construirXML(Q70SMSPeticion smsPeticion) throws Q70SMSException
	{
		Q70SMSMessage smsMensaje = null;
		int j = smsPeticion.getN38Sesion().indexOf("<n38>");
		String n38SesionAux = smsPeticion.getN38Sesion().substring(j, smsPeticion.getN38Sesion().length());
		StringBuffer resultado = new StringBuffer("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
		resultado.append(Q70Constantes.TAG_START_APLICACION);
		resultado.append(n38SesionAux);
		resultado.append(Q70Constantes.TAG_START_PETICION);
		resultado.append(Q70Constantes.TAG_START_ORIGEN);
		resultado.append(Q70Constantes.TAG_START_TIPO).append(smsPeticion.getTipoRemitente().toString()).append(Q70Constantes.TAG_END_TIPO);
		resultado.append(Q70Constantes.TAG_START_NOMBRE).append(smsPeticion.getNombreRemitente()).append(Q70Constantes.TAG_END_NOMBRE);
		resultado.append(Q70Constantes.TAG_START_SMTP).append(smsPeticion.getMailRemitente()).append(Q70Constantes.TAG_END_SMTP);
		resultado.append(Q70Constantes.TAG_END_ORIGEN);
		resultado.append(Q70Constantes.TAG_START_MENSAJES);
		for (int i = 0; i < smsPeticion.getAllMensajes().size(); i++)
		{
			smsMensaje=(Q70SMSMessage)smsPeticion.getAllMensajes().get(i);
			if (smsMensaje.getAcuse())
				resultado = resultado.append("<MENSAJE ACUSE=\"S\">");
			else
				resultado = resultado.append("<MENSAJE ACUSE=\"N\">");
			if (smsMensaje.getTexto() == null) {
				Q70TrazaInterface traza = Q70Factoria.getTraza();
				if (traza.isTraceActive()) {
					traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "ERROR: No se ha introducido texto en un mensaje de la petición de envío.");
				}
				throw new Q70SMSException (this.getClass().getName(), "construirXML", "No se ha introducido texto en un mensaje de la petición de envío.", null);
			}
			String texto = smsMensaje.getTexto();
			texto = reemplazarTexto(texto, "&", "&amp;");
			texto = reemplazarTexto(texto, "<", "&lt;");
			texto = reemplazarTexto(texto, "'", "&apos;");
			texto = reemplazarTexto(texto, ">", "&gt;");
			texto = reemplazarTexto(texto, "\"", "&quot;");
			resultado.append(Q70Constantes.TAG_START_TEXTO).append(texto).append(Q70Constantes.TAG_END_TEXTO);
			if (null!=smsMensaje.getTVida() && smsMensaje.getTVida().intValue() > 0) {
				resultado.append(Q70Constantes.TAG_START_VIDA).append(smsMensaje.getTVida()).append(Q70Constantes.TAG_END_VIDA);
			} else if (null==smsMensaje.getFechaEnvio()) {
				// Si no tiene tiempo de vida ni facha de envío, inicializamos la fecha a la fecha actual.
				smsMensaje.setFechaEnvio(new Date());
			}
			if (null!=smsMensaje.getFechaEnvio()) {
				// Si la fecha de envío es antes que la fecha actual, inicializamos la fecha a la fecha actual.
				if (smsMensaje.getFechaEnvio().before(new Date())) {
					smsMensaje.setFechaEnvio(new Date());
				}
				String fechaTexto = (new SimpleDateFormat("ddMMyyHHmm")).format(smsMensaje.getFechaEnvio());
				resultado.append(Q70Constantes.TAG_START_TIMESTAMP).append(fechaTexto).append(Q70Constantes.TAG_END_TIMESTAMP);
			}
			if (smsMensaje.getAllTelefonos().size() == 0) {
				Q70TrazaInterface traza = Q70Factoria.getTraza();
				if (traza.isTraceActive()) {
					traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "ERROR: No se ha introducido ningún teléfono en un SMS de la petición de envío.");
				}
				throw new Q70SMSException (this.getClass().getName(), "construirXML", "No se ha introducido ningún teléfono en un SMS de la petición de envío", null);
			}
			resultado.append(Q70Constantes.TAG_START_TELEFONOS);
			for (int k = 0; k < smsMensaje.getAllTelefonos().size(); k++)
				resultado.append(Q70Constantes.TAG_START_TELEFONO).append(((Q70SMSTelefono)smsMensaje.getAllTelefonos().get(k)).getNumeroTelefono()).append(Q70Constantes.TAG_END_TELEFONO);
			resultado.append(Q70Constantes.TAG_END_TELEFONOS);
			resultado.append(Q70Constantes.TAG_END_MENSAJE);
		}
		resultado.append(Q70Constantes.TAG_END_MENSAJES);
		resultado.append(Q70Constantes.TAG_END_PETICION).append(Q70Constantes.TAG_END_APLICACION);
     
		return resultado.toString();
	}
	
	/**
	 * @param texto
	 * @param patron1
	 * @param patron2
	 * @return texto reemplazado
	 */
	private String reemplazarTexto(String texto, String patron1, String patron2) {
		return texto.replaceAll(patron1,patron2);
	}

	/**
	 * @return prefijo SMS
	 */
	public String getPrefijoSMS() {
		return prefijoSMS;
	}

	/**
	 * @param prefijoSMS
	 */
	public void setPrefijoSMS(String prefijoSMS) {
		this.prefijoSMS = prefijoSMS;
	}
}
