/*
 * Fichero:     MensajeSOAP.java
 * Fecha:       20/10/06
 * Autor:       Alvaro Sarmiento Losada
 * Asignatura:  Proyecto Fin de Carrera
 * Descripción: Contiene la clase MensajeSOAP, que encapsula documentos SOAP
 *              y los envía y recibe a través de un objeto SoporteMensajesSOAP.
 *
 * Este fichero pertenece al proyecto fin de carrera del autor,
 * consistente en el estudio de JXTA y su aplicación al comercio 
 * electrónico b2b.
 */

package com.pfc.lib.soap;


import com.pfc.lib.xml.DocumentoXML;
import com.pfc.lib.xml.ExcepcionMensajeXML;
import com.pfc.lib.xml.SoporteMensajesXML;
import java.io.*;
import javax.xml.soap.*;
import javax.xml.transform.stream.StreamSource;


/**
 * Esta clase representa a un mensaje que actúa como contenedor para el envío y recepción de objetos . La implementación  específica del método de envío y recepción (en cualquier protocolo) del mensaje se deja a cargo de un objeto denominado soporte de  <code>MensajeSOAP</code>, cuya clase debe implementar la interfaz {@link SoporteMensajesSOAP} . Esta clase proporciona además métodos para establecer y recuperar los objetos contenidos en el mensaje. <br> Es importante usar en el orden adecuado los métodos de esta clase. A  continuación se resumen los pasos: <br> 1.- Registrar el soporte de <code>MensajeSOAP</code>, mediante el método estático. <code>registrarSoporteMensajes(SoporteMensajesSOAP soporte)</code> de esta clase.<br> 2.- Crear una instancia de la clase <code>MensajeSOAP</code>. <br> <b>Para enviar:</b>  <br> 3.- Establecer el contenido SOAP del mensaje mediante el método <code>setDocumentoSOAP con los distintos tipos de peticiones SOAP</code>. <br> 4.- Enviar el mensaje mediante el método: <code>enviarMensajeSOAP()</code>. <br> <b>Para recibir:</b> <br> 3.- Recibir un mensaje mediante el método:  <code>recibirMensajeSOAP()</code>. <br> 4.- Obtener el contenido XML del mensaje mediante el método <code>getDocumentoSOAP()</code>. <br><br> <b>Nota:</b> <br> <i>Es muy recomendable usar una nueva instancia de <code>MensajeSOAP</code> cada vez que se quiera enviar o recibir un nuevo mensaje.
 * @author   Alvaro Sarmiento Losada
 * @see SoporteMensajesXML
 * @see ExcepcionMensajeXML
 * @see  DocumentoXML
 */
public class MensajeSOAP extends Object{
	
	protected static SoporteMensajesSOAP soporteMensajesSoap;
	
	 /**
     * Array para operaciones internas. Almacena la serialización de un
     * objeto <code>DocumentoSOAP</code>
     */
    public byte[] array;
    
    /**
     * Constante que determina el tamaño de <code>array</code>.
     */
    private final static int TAMANO_BUFFER = 30*1024;
	
    /** Instanciacion del objeto*/
	public MensajeSOAP() {
		array= new byte[TAMANO_BUFFER];
	}
	
	/** Permite estabecer el soporte de los mensajes SOAP*/
	 public static void registrarSoporteMensajesSOAP(SoporteMensajesSOAP soporte) {
	        soporteMensajesSoap = soporte;    
	 }
	  
	 /** Obtiene el mensaje SOAP contenido en el objeto
	  * 
	  * @return EL SOAPMessage buscado
	  */
	 public SOAPMessage getDocumentoSOAP() {        
	        SOAPMessage resultado=null;
	        
	        try {
	            
	        	MessageFactory mf = MessageFactory.newInstance();
	    		SOAPMessage soapInput = mf.createMessage();
	    		
	    		int contador=0;
				for(int i=0;array[i]!=0;i++){
					contador++;
				}
				byte[] otro=new byte[contador];
					
				for(int i=0;array[i]!=0;i++)
					otro[i]=array[i];
				
	    		ByteArrayInputStream stm = new ByteArrayInputStream(otro);
	    		StreamSource sis = new StreamSource(stm);

	    		SOAPPart soapPart = soapInput.getSOAPPart();
	    		soapPart.setContent(sis);
	    		
	    		soapInput.writeTo(System.out);
	    		resultado=soapInput;
	        	
	        } catch (Exception e) {
	            resultado = null;
	            System.out.println("Error en el getDocumentoSOAP");
	        }
	        
	     return resultado;
	 }
	 
	 
	    /**
	     * Establece el objeto <code>DocumentoSOAP</code> contenido en este
	     * mensaje <code>MensajeSOAP</code>.
	     * 
	     * @param msg el <code>SOAPMessage</code> que se quiere incluir 
	     *                  como contenido de este <code>MensajeSOAP</code>.
	     */    
	    public void setDocumentoSOAP(SOAPMessage mensaje)  {
	        
	    	try{
	    		ByteArrayOutputStream flujoByte = new ByteArrayOutputStream();
		       
	            //Se serializa el objeto
	            
	        	mensaje.writeTo(flujoByte);
	            //Se guarda el objeto serializado en el array
	            array=flujoByte.toByteArray();
	            String cadena= new String(array);
	            System.out.println();
	            System.out.println("El mensaje SOAP es:"+cadena);
	            flujoByte.close();
		    }catch(Exception e){
	            array = null;
	            System.out.println("Error en el setDocumentoSOAP");
	            e.printStackTrace(System.out);
	        }
	    }
	    
	    /** Colocar un objeto ya serializado en nuestro MensajeSOAP
	     * 
	     * @param otro La serialización de un objeto
	     */
	    public void colocarEnMensaje(byte[] otro){
	    	array=otro;
	    }
	    
	   
	    
	    /**
	     * Envia este <code>MensajeSOAP</code> usando el objeto 
	     * <code>SoporteMensajesSOAP</code> previamente registrado.
	     *
	     * @throws ExcepcionMensajeSOAP si ocurre algún error durante el envío
	     *                             usando el <code>SoporteMensajesSOAP</code>
	     *                             registrado.
	     */
	    public void enviarMensajeSOAP() throws ExcepcionMensajeSOAP {
	        InputStream flujo = new ByteArrayInputStream(array);        
	        try {
	            //Se envia el objeto DocumentoXML serializado usando el soporte
	            soporteMensajesSoap.enviar(flujo);
	        } catch (Exception e) {
	            /*
	             * Se captura cualquier posible tipo de excepción generada por
	             * el SoporteMensajesXML y se considera fatal, relanzándola con
	             * la excepción asociada a MensajeXML.
	             */
	            throw new ExcepcionMensajeSOAP("Excepcion al enviar MensajeSOAP", e);
	        }
	    }
	    
	    /**
	     * Recibe un nuevo <code>MensajeSOAP</code> usando el objeto
	     * <code>SoporteMensajesSOAP</code> previamente registrado.
	     *
	     * @throws ExcepcionMensajeSOAP si ocurre algún error durante la recepción
	     *                             usando el <code>SoporteMensajesSOAP</code>
	     *                             registrado.
	     */    
	    public void recibirMensajeSOAP() throws ExcepcionMensajeSOAP {
	        try {
	            //Se recibe a través del soporte
	            InputStream flujo = soporteMensajesSoap.recibir();
	            //EL flujo recibido se guarda en el array
	            flujo.read(array);
	        } catch (Exception e) {
	            /*
	             * Se captura cualquier posible tipo de excepción generada por
	             * el SoporteMensajesXML y se considera fatal, relanzándola con
	             * la excepción asociada a MensajeXML.
	             */
	            throw new ExcepcionMensajeSOAP("Excepcion al recibir MensajeSOAP", e);
	        }
	    }
	    
	
}
