package com.ejie.ab61.service.jms;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;
import javax.sql.DataSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlInOutParameter;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.xml.sax.InputSource;

import com.ejie.ab61.adaptadores.T65BDokusiAdaptadorService;
import com.ejie.ab61.adaptadores.X43ExpedienteElectronicoAdaptadorService;
import com.ejie.ab61.adaptadores.X43ToolkitAdaptadorService;
import com.ejie.ab61.clientesWS.X43ExpedienteElectronico.TBoolean;
import com.ejie.ab61.clientesWS.X43Toolkit.Exception_Exception;
import com.ejie.ab61.comun.Constantes;
import com.ejie.ab61.comun.utilidades.ClobUtils;
import com.ejie.ab61.comun.utilidades.DBUtils;
import com.ejie.ab61.comun.utilidades.DOMUtilis;
import com.ejie.ab61.comun.utilidades.DateUtils;
import com.ejie.ab61.dao.configuracionEventos.ConfigEventosDao;
import com.ejie.ab61.dao.expedientes.ExpedientesDao;
import com.ejie.ab61.dao.mensajesError.MensajesErrorDao;
import com.ejie.ab61.exceptions.Ab61Exception;
import com.ejie.ab61.model.configuracionEventos.ConfigEventos;
import com.ejie.ab61.model.expedientes.Expedientes;
import com.ejie.ab61.model.mensajesError.MensajesError;
import com.ejie.ab61.model.solicitudes.Configuracion;
import com.ejie.ab61.model.solicitudes.MensajesSolicitud;
import com.ejie.ab61.model.solicitudes.Solicitudes;
import com.ejie.ab61.service.expedientes.ExpedientesService;
import com.ejie.ab61.service.solicitudes.ConfiguracionService;
import com.ejie.ab61.service.solicitudes.MensajesSolicitudService;
import com.ejie.ab61.service.solicitudes.SolicitudesService;
import com.sun.org.apache.xpath.internal.XPathAPI;

/**
 * ExpedientesServiceImpl  
 * 
 *  
 */

@Service(value = "tratamientoJMSService")
public class TratamientoJMSServiceImpl implements TratamientoJMSService {

	private static final Logger logger = LoggerFactory.getLogger(TratamientoJMSServiceImpl.class);

	private JdbcTemplate jdbcTemplate;

	@Resource
	ReloadableResourceBundleMessageSource appMessageSource;

	@Autowired()
	private MensajesSolicitudService mensajesSolicitudService;

	@Autowired()
	private SolicitudesService solicitudesService;

	@Autowired()
	private ExpedientesService expedientesService;

	@Autowired()
	private X43ToolkitAdaptadorService x43ToolkitAdaptadorService;

	@Autowired()
	private T65BDokusiAdaptadorService t65BDokusiAdaptadorService;

	@Autowired()
	private ConfiguracionService configuracionService;

	@Autowired()
	private X43ExpedienteElectronicoAdaptadorService x43ExpedienteElectronicoAdaptadorService;

	@Autowired()
	private ExpedientesDao expedientesDao;

	@Autowired()
	private ConfigEventosDao configEventosDao;

	@Autowired()
	private MensajesErrorDao mensajesErrorDao;

	/**
	 * Method use to set the datasource.
	 * 
	 * @param dataSource
	 *            DataSource
	 * @return
	 */
	@Resource()
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	/**
	 * Inserts a single row in the Expedientes table.
	 *
	 * @param inMessage
	 *            Message
	 * @throws Exception
	 */

	public void tratarMensaje(String mensaje) throws Ab61Exception {

		TratamientoJMSServiceImpl.logger.info("Inicio tratarMensaje");
		TratamientoJMSServiceImpl.logger.info("Mensaje: " + mensaje);

		MensajesSolicitud mensajeSolicitud = new MensajesSolicitud();
		Solicitudes solicitudes = new Solicitudes();
		try {

			HashMap<String, String> resultadoRecogerDatosCola = this.recogerDatosCola(mensaje);
			if (!resultadoRecogerDatosCola.isEmpty()) {
				mensajeSolicitud.setTipomensaje(resultadoRecogerDatosCola.get(Constantes.EVENT_WHAT));
			}

			TratamientoJMSServiceImpl.logger
					.info("El tipo de mensaje que llega es = " + mensajeSolicitud.getTipomensaje());

			String plateaType = resultadoRecogerDatosCola.get(Constantes.PLATEA_TYPE);
			String plateaSubType = resultadoRecogerDatosCola.get(Constantes.PLATEA_SUBTYPE);
			String instanceId = resultadoRecogerDatosCola.get(Constantes.INSTANCEID);
			String folderID = resultadoRecogerDatosCola.get(Constantes.FOLDER_ID);
			String taskID = resultadoRecogerDatosCola.get(Constantes.TASK_ID);
			String status = resultadoRecogerDatosCola.get(Constantes.STATUS);
			String folderNumber = resultadoRecogerDatosCola.get(Constantes.FOLDER_NUMBER);
			String procedureId = resultadoRecogerDatosCola.get(Constantes.PROCEDURE_ID);
			String fechaRegistro = resultadoRecogerDatosCola.get(Constantes.FECHA_REGISTRO);
			String solicitudId = resultadoRecogerDatosCola.get(Constantes.SOLICITUD_ID);
			String oidDocumento = resultadoRecogerDatosCola.get(Constantes.ACCION_TELEMATICA_OID);

			TratamientoJMSServiceImpl.logger.info("Empezamos a tratar el mensaje de presentación de solicitud");
			TratamientoJMSServiceImpl.logger.info("plateaType = " + plateaType);
			TratamientoJMSServiceImpl.logger.info("plateaType = " + plateaSubType);
			TratamientoJMSServiceImpl.logger.info("instanceId = " + instanceId);
			TratamientoJMSServiceImpl.logger.info("folderID = " + folderID);
			TratamientoJMSServiceImpl.logger.info("taskID = " + taskID);
			TratamientoJMSServiceImpl.logger.info("status = " + status);
			TratamientoJMSServiceImpl.logger.info("procedureId = " + procedureId);
			TratamientoJMSServiceImpl.logger.info("fechaRegistro = " + fechaRegistro);

			/***********************************************************************
			 * PRIMERO BUSCAMOS LA CONFIGURACION DEL EVENTO EN LA TABLA
			 * (AB6141T00)
			 ***********************************************************************/

			TratamientoJMSServiceImpl.logger.info("Buscamos la configuración del evetno en la tabla (AB6141T00)");
			ConfigEventos configuracionEvento = new ConfigEventos();
			ConfigEventos filtroConfiguracion = new ConfigEventos();
			if (mensajeSolicitud.getTipomensaje().equalsIgnoreCase(Constantes.R02_REQUEST)) {
				filtroConfiguracion.setTipoEvento(mensajeSolicitud.getTipomensaje());
				filtroConfiguracion.setPlateaType(plateaType);
				filtroConfiguracion.setPlateaSubtype(plateaSubType);

				/**
				 * en los casos de aportacion en n-instancias(justicificacion,
				 * acpetacion de ayuda, ampliacion de informacion hay que tener
				 * en cuanta la instancia. Dependiendo de la instancia es una
				 * configuracion u otra)
				 */
				if (instanceId == null || instanceId.equals("")) {
					configuracionEvento = this.configEventosDao.findConfiguracion(filtroConfiguracion);
				} else {
					filtroConfiguracion.setInstanceId(Integer.parseInt(instanceId));
					configuracionEvento = this.configEventosDao.findConfiguracionPorInstancia(filtroConfiguracion);
				}
			} else if (mensajeSolicitud.getTipomensaje().equalsIgnoreCase(Constantes.R02_TASK)
					|| mensajeSolicitud.getTipomensaje().equalsIgnoreCase(Constantes.R02_NOTIFICATION)
					|| mensajeSolicitud.getTipomensaje().equalsIgnoreCase(Constantes.R02_SIGN)) {
				filtroConfiguracion.setTipoEvento(mensajeSolicitud.getTipomensaje());
				configuracionEvento = this.configEventosDao.findConfiguracionTareas(filtroConfiguracion);
			}

			if (configuracionEvento != null && configuracionEvento.getConfiguracion() != null) {
				TratamientoJMSServiceImpl.logger.info(
						"Configuracion del evento que se va a aplicar es = " + configuracionEvento.getConfiguracion());
				/***********************************************************************
				 * GUARDAMOS EL MENSAJE DEL EVENTO EN LA TABLA DE MENSAJES
				 * (AB6117T00) SOLO SI VIENE UNA CONFIGURACION.LOS EVENTOS QUE
				 * NO ESTAN EN LA TABLA DE CONFIGURACION DE EVENTOS (AB6141T00)
				 * NO SE GUARDAN NI SE REALIZARA NINGUNA ACCION SOBRE EL
				 ***********************************************************************/

				TratamientoJMSServiceImpl.logger
						.info("Iniciando guardar el mensaje en la tabla de mensajes (AB6117T00)");
				mensajeSolicitud = this.guardarMensajeEvento(mensajeSolicitud, resultadoRecogerDatosCola, mensaje);
				TratamientoJMSServiceImpl.logger.info("Guardardo el mensaje en la tabla de mensajes (AB6117T00)");

				/***********************************************************************
				 * Si la configruacion: 1 = Es una solicituid,obtenemos el
				 * ejgvDocument llamando al servicio getRequestInformation 2 =
				 * Es una accion telemataica, obtenemos el ejgvDocument
				 * recuperando de dokusi a traves 3 = Es un tarea 4 = Inicio de
				 * oficio
				 ***********************************************************************/
				String ejgvDocumentSolicitud = "";

				/*********************
				 * SOLICITUDES
				 **********************/
				if (configuracionEvento.getConfiguracion() == Constantes.CONFIG_EVENTO_EJGV_GETREQUESTINFORMATION) {

					try {

						TratamientoJMSServiceImpl.logger
								.info("Invocamos al servicio x43ToolkitAdaptadorService.getRequestInformation con el parámetro solicitudID = "
										+ solicitudId + "y folderId = " + folderID);
						ejgvDocumentSolicitud = this.x43ToolkitAdaptadorService.getRequestInformation(solicitudId,
								null);

					} catch (Exception_Exception e) {

						TratamientoJMSServiceImpl.logger
								.info("Error al invocar al servicio X43Toolkit:getRequestInformation" + e.getMessage());
					}

					/** Guardar la solicitud AB6118T00 */
					this.guardarSolicitud(solicitudes, mensajeSolicitud, ejgvDocumentSolicitud, folderID, procedureId,
							fechaRegistro);

					/** Invocar al PL/SQL de carga */
					String tituloExpediente = this.invocarPLCargaSolicitudes(procedureId, mensajeSolicitud, plateaType,
							plateaSubType, solicitudes);

					/** ACTUALIZAR TITULO DE EXPEDIENTE DE PLATEA */
					TBoolean resultadoUpdateTitulo = TBoolean.FALSE;
					try {
						if (tituloExpediente != "" && tituloExpediente != null) {
							resultadoUpdateTitulo = x43ExpedienteElectronicoAdaptadorService.updateFolderTitle(folderID,
									tituloExpediente, null);
						}
					} catch (Exception_Exception e) {
						TratamientoJMSServiceImpl.logger
								.error("Ha ocurrido un problemas al actualizar el titulo del expediente en platea. Método:updateFolderTitle, folderID = "
										+ folderID + " Titulo = " + tituloExpediente);
					}
					if (resultadoUpdateTitulo.equals(TBoolean.TRUE)) {
						TratamientoJMSServiceImpl.logger
								.info("EL titulo de expediente en platea se ha actualizado satisfactoriamente");
					} else {
						TratamientoJMSServiceImpl.logger
								.error("Ha ocurrido un problemas al actualizar el titulo del expediente en platea. Método:updateFolderTitle, folderID = "
										+ folderID + " Titulo = " + tituloExpediente);
					}

					/**
					 * Invocar al PL/SQL de ACTUALIZACION DE FECHAS PARA LA
					 * SOLICITUD, JUSTIFICACION Y SUBSANACION
					 */
					this.invocarPLTratarFechasSolJustifSubsanacion(mensajeSolicitud);

					/**
					 * Antes de terminar con el tratamiento del evento
					 * R02_REQUEST Comprobar si existe en el
					 * expediente(FolderId) en la tabla de mensajes de Error
					 * (AB6132T00). Si esta hay que lanzar de nuevo el proceso
					 * del tratamiento de tareas (R02_TASK) y borrar el registro
					 * de la tabla AB6132T00
					 */

					MensajesError msgError = new MensajesError();
					msgError.setFolderId(folderID);
					MensajesError mensajeTaskNoCompletado = this.mensajesErrorDao.find(msgError);
					if (mensajeTaskNoCompletado != null) {

						TratamientoJMSServiceImpl.logger.info(
								"Se ejecuta el proceso del tratamiento de los eventos R02_TASK. (EVENTO R02_TASK LLEGO ANTES QUE EL R02_REQUEST)");
						try {

							/**
							 * Tratamiento R02_TASK. Recuperamos el mensaje
							 * R02_TASK no completado de la tabla de mensajes
							 * (AB6117T00)
							 */
							String plateaTypeTask = "";
							String plateaSubTypeTask = "";
							String folderIDTask = "";
							String taskIDTask = "";
							String statusTask = "";
							String folderNumberTask = "";
							String procedureIdTask = "";
							String tipoMensajeTask = "";
							Integer idMensajeR02Task = 0;
							if (mensajeTaskNoCompletado.getMensajesSolicitud() != null) {
								MensajesSolicitud filtroIdMensajeR02Task = new MensajesSolicitud();
								idMensajeR02Task = mensajeTaskNoCompletado.getMensajesSolicitud().getIdMensaje();
								filtroIdMensajeR02Task.setIdMensaje(idMensajeR02Task);
								MensajesSolicitud mensajeR02Task = this.mensajesSolicitudService
										.find(filtroIdMensajeR02Task);
								HashMap<String, String> mensajeTarea = this
										.recogerDatosCola(ClobUtils.clobToString(mensajeR02Task.getMensaje()));
								plateaTypeTask = mensajeTarea.get(Constantes.PLATEA_TYPE);
								plateaSubTypeTask = mensajeTarea.get(Constantes.PLATEA_SUBTYPE);
								folderIDTask = mensajeTarea.get(Constantes.FOLDER_ID);
								taskIDTask = mensajeTarea.get(Constantes.TASK_ID);
								statusTask = mensajeTarea.get(Constantes.STATUS);
								folderNumberTask = mensajeTarea.get(Constantes.FOLDER_NUMBER);
								procedureIdTask = mensajeTarea.get(Constantes.PROCEDURE_ID);
								tipoMensajeTask = mensajeTarea.get(Constantes.EVENT_WHAT);

								TratamientoJMSServiceImpl.logger.info("plateaTypeTask = " + plateaTypeTask);
								TratamientoJMSServiceImpl.logger.info("plateaSubTypeTask = " + plateaSubTypeTask);
								TratamientoJMSServiceImpl.logger.info("folderIDTask = " + folderIDTask);
								TratamientoJMSServiceImpl.logger.info("taskIDTask = " + taskIDTask);
								TratamientoJMSServiceImpl.logger.info("statusTask = " + statusTask);
								TratamientoJMSServiceImpl.logger.info("folderNumberTask = " + folderNumberTask);
								TratamientoJMSServiceImpl.logger.info("procedureIdTask = " + procedureIdTask);
								TratamientoJMSServiceImpl.logger.info("tipoMensajeTask = " + tipoMensajeTask);
								TratamientoJMSServiceImpl.logger.info("idMensajeR02Task = " + idMensajeR02Task);

							}

							MensajesSolicitud mensajeSolicitudTask = new MensajesSolicitud();
							mensajeSolicitudTask.setTipomensaje(tipoMensajeTask);
							mensajeSolicitudTask.setIdMensaje(idMensajeR02Task);

							/*******************************************
							 * ******** LLAMADA AL PL/SQL **************
							 ******************************************/
							this.tratamientoR02TaskPlSql(procedureIdTask, mensajeSolicitudTask, plateaTypeTask,
									plateaSubTypeTask);

							if (taskIDTask.equalsIgnoreCase(Constantes.TASK_ID_APERTURA)
									&& plateaTypeTask.equalsIgnoreCase(Constantes.PLATEA_TYPE_APERTURA)
									&& statusTask.equalsIgnoreCase(Constantes.PLATEA_STATUS_APERTURA_FINALIZADA)) {

								/**********************************************
								 ** ACTUALIZAMOS EL TITULO DE EXPEDIENTE*******
								 **********************************************/

								this.tratamientoR02TaskAperturaTitulo(folderIDTask);

								/****************************************
								 ** ACTUALIZAMOS EL FOLDERNUMBER********
								 ****************************************/
								this.tratamientoR02TaskAperturaNumExpediente(folderIDTask, folderNumberTask);
							}

							/****************************************
							 ** ELIMINAMOS REGISTO TABLA AB6132T00***
							 ****************************************/
							/** Se elimina el registro de la tabla Ab6132T00 */
							this.mensajesErrorDao.remove(mensajeTaskNoCompletado);

						} catch (Exception e) {
							String sCodigoError = "error.tratamientoJMS.R02_Task";
							throw new Ab61Exception(sCodigoError,
									appMessageSource.getMessage(sCodigoError, null, new Locale("es")),
									appMessageSource.getMessage(sCodigoError, null, new Locale("eu")));

						}
					}

					/**************************************************
					 * ACCIONES TELEMATICAS SUBSANACION Y JUSTIFICACION
					 ***************************************************/
				} else if (configuracionEvento.getConfiguracion() == Constantes.CONFIG_EVENTO_EJGV_DOKUSI) {

					try {

						// recuperamos un documento de dokusi a partir del
						// Oid del documento de justificacion
						InputStream bIS = this.recuperarDocumentoDokusi(oidDocumento);
						ejgvDocumentSolicitud = recuperarEjgvDocumentSinHTML(bIS);

					} catch (Exception e) {
						TratamientoJMSServiceImpl.logger.error("error al invocar al recuperarDocumentoDokusi : " + e);
					}
					/**********************************
					 * Guardar la solicitud AB6118T00
					 ********************************/
					solicitudes = this.guardarSolicitud(solicitudes, mensajeSolicitud, ejgvDocumentSolicitud, folderID,
							procedureId, fechaRegistro);

					/** Invocar al PL/SQL de carga */
					this.invocarPLCargaAccionesTelematicas(procedureId, mensajeSolicitud, plateaType, plateaSubType,
							solicitudes);

					/** Invocar al PL/SQL de ACTUALIZACION DE FECHAS */
					this.invocarPLTratarFechasSolJustifSubsanacion(mensajeSolicitud);

					/*****************
					 * TAREAS
					 *******************/
				} else if (configuracionEvento.getConfiguracion() == Constantes.CONFIG_EVENTO_TAREAS) {

					/**
					 * Comprobar si se ha completado todo el proceso de carga de
					 * solcitud, para ello comprobar que si exsite el expediente
					 * en la tabla AB6102T00 (A veces llega antes el evento
					 * R02_TASK que el R02_RQUEST)
					 */

					TratamientoJMSServiceImpl.logger.info(
							"Ante de empezar con el proceso de los evetnos R02_TASK comprobar si se ha cargado el expediente : ");
					Expedientes expediente = expedientesDao.findByFolderId(folderID);
					if (expediente != null) {
						try {
							TratamientoJMSServiceImpl.logger
									.info("Existe el expediente en la tabla AB6102T00 con idExpediente =  "
											+ expediente.getIdExpediente());
							TratamientoJMSServiceImpl.logger.info("Comienza tratamiento del evento R02_TASK...");
							/**
							 * existe el expediente, por lo que se puede lanzar
							 * el tratamiento de los R02_task
							 */
							/*******************************************
							 * ******** LLAMADA AL PL/SQL **************
							 ******************************************/

							this.tratamientoR02TaskPlSql(procedureId, mensajeSolicitud, plateaType, plateaSubType);

							if (taskID.equalsIgnoreCase(Constantes.TASK_ID_APERTURA)
									&& plateaType.equalsIgnoreCase(Constantes.PLATEA_TYPE_APERTURA)
									&& status.equalsIgnoreCase(Constantes.PLATEA_STATUS_APERTURA_FINALIZADA)) {

								/**************************************************************
								 ******** ACTUALIZAMOS EL TITULO DE
								 * EXPEDIENTE/****************
								 ************************************************************/

								this.tratamientoR02TaskAperturaTitulo(folderID);

								/********************************************************
								 *********** ACTUALIZAMOS EL FOLDERNUMBER****************
								 ********************************************************/
								this.tratamientoR02TaskAperturaNumExpediente(folderID, folderNumber);

							}

							TratamientoJMSServiceImpl.logger.info("Termina tratamiento del evento R02_TASK...");

						} catch (Exception e) {
							String sCodigoError = "error.tratamientoJMS.R02_Task";
							throw new Ab61Exception(sCodigoError,
									appMessageSource.getMessage(sCodigoError, null, new Locale("es")),
									appMessageSource.getMessage(sCodigoError, null, new Locale("eu")));

						}
					} else {
						/**
						 * No exsite el expediente en la tabla AB6102T00, el
						 * tratamiento del R02_RQUEST no ha finalizado,
						 * guardamos el mensaje en la tabla AB6132T00
						 */
						TratamientoJMSServiceImpl.logger
								.info("No existe el expediente. No se puede realizar el tratamiento de R02_TASK");
						TratamientoJMSServiceImpl.logger
								.info("Guardamos el mensaje en la tabla AB6132T00 con el idMensaje = "
										+ mensajeSolicitud.getIdMensaje());
						MensajesError mensajeError = new MensajesError();
						mensajeSolicitud.setIdMensaje(mensajeSolicitud.getIdMensaje());
						mensajeError.setMensajesSolicitud(mensajeSolicitud);
						mensajeError.setFolderId(folderID);
						mensajeError.setFechaRegistro(new Date());
						// mensajeError.setUsuarioRegistro(usuarioRegistro);
						this.mensajesErrorDao.add(mensajeError);

					}

					/*****************
					 * INICIO DE OFICIO
					 *******************/
				} else if (configuracionEvento.getConfiguracion() == Constantes.CONFIG_EVENTO_INICIO_OFICIO) {

					/** Invocar al PL/SQL de carga de inicio de oficio */
					this.invocarPLCargaOficio(procedureId, mensajeSolicitud, plateaType, plateaSubType);

					/** Invocar al PL/SQL de ACTUALIZACION DE FECHAS */
					this.invocarPLTratarFechasSolJustifSubsanacion(mensajeSolicitud);

					/**
					 * Antes de terminar con el tratamiento del evento
					 * R02_REQUEST Comprobar si existe en el
					 * expediente(FolderId) en la tabla de mensajes de Error
					 * (AB6132T00). Si esta hay que lanzar de nuevo el proceso
					 * del tratamiento de tareas (R02_TASK) y borrar el registro
					 * de la tabla AB6132T00
					 */

					MensajesError msgError = new MensajesError();
					msgError.setFolderId(folderID);
					MensajesError mensajeTaskNoCompletado = this.mensajesErrorDao.find(msgError);
					if (mensajeTaskNoCompletado != null) {

						TratamientoJMSServiceImpl.logger.info(
								"Se ejecuta el proceso del tratamiento de los eventos R02_TASK. (EVENTO R02_TASK LLEGO ANTES QUE EL R02_REQUEST)");
						try {

							/**
							 * Tratamiento R02_TASK. Recuperamos el mensaje
							 * R02_TASK no completado de la tabla de mensajes
							 * (AB6117T00)
							 */
							String plateaTypeTask = "";
							String plateaSubTypeTask = "";
							String folderIDTask = "";
							String taskIDTask = "";
							String statusTask = "";
							String folderNumberTask = "";
							String procedureIdTask = "";
							String tipoMensajeTask = "";
							Integer idMensajeR02Task = 0;
							if (mensajeTaskNoCompletado.getMensajesSolicitud() != null) {
								MensajesSolicitud filtroIdMensajeR02Task = new MensajesSolicitud();
								idMensajeR02Task = mensajeTaskNoCompletado.getMensajesSolicitud().getIdMensaje();
								filtroIdMensajeR02Task.setIdMensaje(idMensajeR02Task);
								MensajesSolicitud mensajeR02Task = this.mensajesSolicitudService
										.find(filtroIdMensajeR02Task);
								HashMap<String, String> mensajeTarea = this
										.recogerDatosCola(ClobUtils.clobToString(mensajeR02Task.getMensaje()));
								plateaTypeTask = mensajeTarea.get(Constantes.PLATEA_TYPE);
								plateaSubTypeTask = mensajeTarea.get(Constantes.PLATEA_SUBTYPE);
								folderIDTask = mensajeTarea.get(Constantes.FOLDER_ID);
								taskIDTask = mensajeTarea.get(Constantes.TASK_ID);
								statusTask = mensajeTarea.get(Constantes.STATUS);
								folderNumberTask = mensajeTarea.get(Constantes.FOLDER_NUMBER);
								procedureIdTask = mensajeTarea.get(Constantes.PROCEDURE_ID);
								tipoMensajeTask = mensajeTarea.get(Constantes.EVENT_WHAT);

								TratamientoJMSServiceImpl.logger.info("plateaTypeTask = " + plateaTypeTask);
								TratamientoJMSServiceImpl.logger.info("plateaSubTypeTask = " + plateaSubTypeTask);
								TratamientoJMSServiceImpl.logger.info("folderIDTask = " + folderIDTask);
								TratamientoJMSServiceImpl.logger.info("taskIDTask = " + taskIDTask);
								TratamientoJMSServiceImpl.logger.info("statusTask = " + statusTask);
								TratamientoJMSServiceImpl.logger.info("folderNumberTask = " + folderNumberTask);
								TratamientoJMSServiceImpl.logger.info("procedureIdTask = " + procedureIdTask);
								TratamientoJMSServiceImpl.logger.info("tipoMensajeTask = " + tipoMensajeTask);
								TratamientoJMSServiceImpl.logger.info("idMensajeR02Task = " + idMensajeR02Task);

							}

							MensajesSolicitud mensajeSolicitudTask = new MensajesSolicitud();
							mensajeSolicitudTask.setTipomensaje(tipoMensajeTask);
							mensajeSolicitudTask.setIdMensaje(idMensajeR02Task);

							/*******************************************
							 * ******** LLAMADA AL PL/SQL **************
							 ******************************************/
							this.tratamientoR02TaskPlSql(procedureIdTask, mensajeSolicitudTask, plateaTypeTask,
									plateaSubTypeTask);

							if (taskIDTask.equalsIgnoreCase(Constantes.TASK_ID_APERTURA)
									&& plateaTypeTask.equalsIgnoreCase(Constantes.PLATEA_TYPE_APERTURA)
									&& statusTask.equalsIgnoreCase(Constantes.PLATEA_STATUS_APERTURA_FINALIZADA)) {

								/**********************************************
								 ** ACTUALIZAMOS EL TITULO DE EXPEDIENTE*******
								 **********************************************/

								this.tratamientoR02TaskAperturaTitulo(folderIDTask);

								/****************************************
								 ** ACTUALIZAMOS EL FOLDERNUMBER********
								 ****************************************/
								this.tratamientoR02TaskAperturaNumExpediente(folderIDTask, folderNumberTask);
							}

							/****************************************
							 ** ELIMINAMOS REGISTO TABLA AB6132T00***
							 ****************************************/
							/** Se elimina el registro de la tabla Ab6132T00 */
							this.mensajesErrorDao.remove(mensajeTaskNoCompletado);

						} catch (Exception e) {
							String sCodigoError = "error.tratamientoJMS.R02_Task";
							throw new Ab61Exception(sCodigoError,
									appMessageSource.getMessage(sCodigoError, null, new Locale("es")),
									appMessageSource.getMessage(sCodigoError, null, new Locale("eu")));

						}
					}

					/**************************************************************
					 * RESTO DE ACCIONES TELEMATICAS Y R02_NOTIFICATION Y
					 * R02_SIGN
					 **************************************************************/

				} else if (configuracionEvento.getConfiguracion() == Constantes.CONFIG_EVENTO_ACCIONES_TELEMATICAS) {

					/** Invocar al PL/SQL de ACTUALIZACION DE FECHAS */
					this.invocarPLTratarFechas(procedureId, mensajeSolicitud, plateaType, plateaSubType);

				}

			}

			TratamientoJMSServiceImpl.logger.info("Fin tratarMensaje");

		} catch (SQLException e) {
			TratamientoJMSServiceImpl.logger.error(e.getMessage());
		} catch (IOException e) {
			TratamientoJMSServiceImpl.logger.error(e.getMessage());
		}

	}

	/**
	 * 
	 * @param String
	 *            mensajeSolicitud
	 * 
	 * @return String
	 * 
	 * @throws IOException
	 *             IOException
	 */
	public HashMap<String, String> recogerDatosCola(String mensajeSolicitud) throws IOException {

		TratamientoJMSServiceImpl.logger.info("Inicio recogerTipoMensaje");

		Document datosDocumento = null;

		HashMap<String, String> myHash = new HashMap<String, String>();

		try {
			datosDocumento = DOMUtilis.createDocUTF8(mensajeSolicitud.toString());

		} catch (Exception e) {
			TratamientoJMSServiceImpl.logger.info("xmlColas error UTF8: " + e.getMessage());
		}

		try {

			NodeList nodosPadre = null;
			if (datosDocumento != null) {
				nodosPadre = datosDocumento.getElementsByTagName("NotificationBody");
			}
			if (nodosPadre != null) {
				int numNodosPadre = nodosPadre.item(Constantes.MAGIC_NUMBER_0).getChildNodes().getLength();

				if (numNodosPadre != Constantes.MAGIC_NUMBER_0) {
					for (int i = 0; i < numNodosPadre; i++) { // Vienen X
						NodeList nodos2 = nodosPadre.item(Constantes.MAGIC_NUMBER_0).getChildNodes().item(i)
								.getChildNodes();

						int numElementos = nodosPadre.item(Constantes.MAGIC_NUMBER_0).getChildNodes().item(i)
								.getChildNodes().getLength();

						String valorName = "";
						String valorDato = "";
						for (int f = 0; f < numElementos; f++) { // me vienen 2
																	// elementos
							Node nodoValorName = nodos2.item(f);

							String strValorName = nodos2.item(f).getNodeName();
							String strValorN = "0";

							if ("Name".equals(strValorName)) {
								if (nodoValorName.getFirstChild() != null && !"returnReceipt"
										.equalsIgnoreCase(nodoValorName.getFirstChild().getNodeValue())) {
									valorName = nodoValorName.getFirstChild().getNodeValue();
								} else {
									valorName = "";
									strValorN = "1";
								}

							}
							if ("Value".equals(strValorName)) {

								if (!"1".equalsIgnoreCase(strValorN)) {
									if (nodoValorName.getFirstChild() != null) {
										if (Constantes.VALUE.equalsIgnoreCase(valorName)
												|| Constantes.DELIVERED_INFO.equalsIgnoreCase(valorName)) {
											if (nodoValorName.getTextContent() != null) {
												valorDato = nodoValorName.getTextContent().toString();

											}
										} else {
											valorDato = nodoValorName.getFirstChild().getNodeValue();

										}
									}
								} else {
									valorDato = "";
								}

							}

						}

						if (!"".equalsIgnoreCase(valorName.trim())) {
							try {
								myHash.put(valorName, valorDato.toString().trim());
							} catch (Exception e) {
								// resultadoCola = "1";
								TratamientoJMSServiceImpl.logger.info("Error recogerdatos colas " + e);
							}
						}

					} // fin for

				}
			}

		} catch (Exception e) {
			TratamientoJMSServiceImpl.logger.info("Error obteniendo los valores de la solicitud:" + e.getMessage());
		}

		/////
		String tipoMensaje = "";
		if (!myHash.isEmpty()) {
			tipoMensaje = myHash.get(Constantes.EVENT_WHAT);
		}

		TratamientoJMSServiceImpl.logger.info("El tipo de mensaje que llega es = " + tipoMensaje);

		if (tipoMensaje.equalsIgnoreCase(Constantes.R02_REQUEST)) {
			String xmlTransformado = mensajeSolicitud.toString();
			xmlTransformado = xmlTransformado.replaceAll("&lt;", "<");
			xmlTransformado = xmlTransformado.replaceAll("&gt;", ">");
			Document documentoTrasformado;
			try {
				documentoTrasformado = TratamientoJMSServiceImpl.stringToDocument(xmlTransformado);
				String myFolderID = TratamientoJMSServiceImpl.buscarDomString(documentoTrasformado,
						"//xmlValue/contextSubmissionEvent/folderID/text()");
				TratamientoJMSServiceImpl.logger.info("FolderID:" + myFolderID);

				String solicitudID = TratamientoJMSServiceImpl.buscarDomString(documentoTrasformado,
						"//xmlValue/contextSubmissionEvent/solicitudID/text()");
				TratamientoJMSServiceImpl.logger.info("solicitudID:" + solicitudID);

				String fechaEntrada = TratamientoJMSServiceImpl.buscarDomString(documentoTrasformado,
						"//xmlValue/contextSubmissionEvent/registryTimestamp/text()");
				TratamientoJMSServiceImpl.logger.info("fechaEntrada:" + fechaEntrada);

				String instanceId = TratamientoJMSServiceImpl.buscarDomString(documentoTrasformado,
						"//xmlValue/contextSubmissionEvent/instanceId/text()");
				TratamientoJMSServiceImpl.logger.info("instanceId:" + instanceId);

				String oidSolicitudAccionTelematica = this.obtenerOidSolAccionesTelematicas(documentoTrasformado);

				myHash.put(Constantes.FOLDER_ID, myFolderID);
				myHash.put(Constantes.SOLICITUD_ID, solicitudID);
				myHash.put(Constantes.FECHA_REGISTRO, fechaEntrada);
				myHash.put(Constantes.INSTANCEID, instanceId);
				myHash.put(Constantes.ACCION_TELEMATICA_OID, oidSolicitudAccionTelematica);

			} catch (Exception e) {
				// TODO Auto-generated catch block
				TratamientoJMSServiceImpl.logger.info("Error transformando el mensaje a document:" + e.getMessage());
			}

		} else if (tipoMensaje.equalsIgnoreCase(Constantes.R02_TASK)) {
			String xmlTransformado = mensajeSolicitud.toString();
			xmlTransformado = xmlTransformado.replaceAll("&lt;", "<");
			xmlTransformado = xmlTransformado.replaceAll("&gt;", ">");
			Document documentoTrasformado;
			try {
				documentoTrasformado = TratamientoJMSServiceImpl.stringToDocument(xmlTransformado);
				String doTimestamp = TratamientoJMSServiceImpl.buscarDomString(documentoTrasformado,
						"//xmlValue/task/doTimestamp/text()");
				TratamientoJMSServiceImpl.logger.info("task doTimestamp:" + doTimestamp);
				myHash.put(Constantes.DO_TIMESTAMP, doTimestamp);

				String situacionID = TratamientoJMSServiceImpl.buscarDomString(documentoTrasformado,
						"//xmlValue/task/taskInfo/studyTaskData/situacionID/text()");
				TratamientoJMSServiceImpl.logger.info("task situacionID:" + situacionID);
				myHash.put(Constantes.ESTUDIO_situacionID, situacionID);

				String taskID = TratamientoJMSServiceImpl.buscarDomString(documentoTrasformado,
						"//xmlValue/task/taskID/text()");
				TratamientoJMSServiceImpl.logger.info("task taskID:" + taskID);
				myHash.put(Constantes.TASK_ID, taskID);

				String myFolderID = TratamientoJMSServiceImpl.buscarDomString(documentoTrasformado,
						"//xmlValue/task/folderID/text()");
				TratamientoJMSServiceImpl.logger.info("task FolderID:" + myFolderID);
				myHash.put(Constantes.FOLDER_ID, myFolderID);

				String myFolderNumber = TratamientoJMSServiceImpl.buscarDomString(documentoTrasformado,
						"//xmlValue/task/folderNumber/text()");
				TratamientoJMSServiceImpl.logger.info("task FolderNumber:" + myFolderNumber);
				myHash.put(Constantes.FOLDER_NUMBER, myFolderNumber);

			} catch (Exception e) {

				TratamientoJMSServiceImpl.logger.info("Error transformando el mensaje a document:" + e.getMessage());
			}

		}

		return myHash;

	}

	private MensajesSolicitud guardarMensajeEvento(MensajesSolicitud mensajeSolicitud,
			HashMap<String, String> resultadoRecogerDatosCola, String mensaje) throws SQLException, IOException {

		/***********************************************************************
		 * GUARDAMOS EL MENSAJE DEL EVENTO EN LA TABLA DE MENSAJES (AB6117T00)
		 ***********************************************************************/
		TratamientoJMSServiceImpl.logger.info("Inicio guardarMensajeEvento");

		mensaje = formatearMensaje(mensaje, resultadoRecogerDatosCola.get(Constantes.EVENT_WHAT));
		mensajeSolicitud.setMensaje(ClobUtils.stringToClob(mensaje));
		mensajeSolicitud.setFechaRegistro(new Date());
		mensajeSolicitud.setCodProcedureId(resultadoRecogerDatosCola.get(Constantes.PROCEDURE_ID));
		mensajeSolicitud.setPlateaType(resultadoRecogerDatosCola.get(Constantes.PLATEA_TYPE));
		mensajeSolicitud.setPlateaSubtype(resultadoRecogerDatosCola.get(Constantes.PLATEA_SUBTYPE));
		mensajeSolicitud = mensajesSolicitudService.add(mensajeSolicitud);

		TratamientoJMSServiceImpl.logger.info("Fin guardarMensajeEvento");
		return mensajeSolicitud;

	}

	/**
	 * invocacion a PL-SQL de carga, en algunos Pls se devuelve el titulo de
	 * expedietnes
	 * 
	 * @param procedureId
	 *            String
	 * @param mensajeSolicitud
	 *            MensajesSolicitud
	 * @param plateaType
	 *            String
	 * @param plateaSubType
	 *            String
	 * @param solicitudes
	 *            Solicitudes
	 * @return String
	 */
	private String invocarPLCargaSolicitudes(String procedureId, MensajesSolicitud mensajeSolicitud, String plateaType,
			String plateaSubType, Solicitudes solicitudes) {

		TratamientoJMSServiceImpl.logger.info("Inicio invocarPLCargaSolicitudes:");
		TratamientoJMSServiceImpl.logger.info("Parametro procedureId:" + procedureId);
		TratamientoJMSServiceImpl.logger.info("Parametro mensajeSolicitud:" + mensajeSolicitud);
		TratamientoJMSServiceImpl.logger.info("Parametro plateaType:" + plateaType);
		TratamientoJMSServiceImpl.logger.info("Parametro plateaSubType:" + plateaSubType);
		TratamientoJMSServiceImpl.logger.info("Parametro solicitudes.getIdSolicitud:" + solicitudes.getIdSolicitud());

		/**
		 * Primero obtenemos de la tabla configuracion el nombre del pl/sql
		 */

		String nombrePlSql = this.obtenerNombrePLSQL(procedureId, mensajeSolicitud.getTipomensaje(), plateaType,
				plateaSubType);

		TratamientoJMSServiceImpl.logger.info("PL/SQL al que se va a invocar:" + nombrePlSql);

		SqlParameter[] parameters = {

				new SqlInOutParameter("IN_ID_SOLICITUD", Types.VARCHAR),
				new SqlOutParameter("OUT_TITULO", Types.VARCHAR), };

		MapSqlParameterSource parameterSource = new MapSqlParameterSource();
		parameterSource.addValue("IN_ID_SOLICITUD", solicitudes.getIdSolicitud());

		Map<String, Object> m = null;
		String tituloExpediente = "";
		try {
			m = DBUtils.callPLSQL_R02REQUEST(this.jdbcTemplate, nombrePlSql, parameters, parameterSource);
			TratamientoJMSServiceImpl.logger.info("Titulo que devuelve el expediente:" + m);
			if (m.get("OUT_TITULO") != null) {
				tituloExpediente = m.get("OUT_TITULO").toString();
			}

		} catch (Exception e) {

			TratamientoJMSServiceImpl.logger.error("Error en el procesamiento del carga de la solicitud:"
					+ solicitudes.getIdSolicitud() + "-" + e.getMessage());
		}

		return tituloExpediente;

	}

	/**
	 * invocacion a PL-SQL de carga de inicio de oficio.
	 * 
	 * @param procedureId
	 *            String
	 * @param mensajeSolicitud
	 *            MensajesSolicitud
	 * @param plateaType
	 *            String
	 * @param plateaSubType
	 *            String
	 * @param solicitudes
	 *            Solicitudes
	 * @return String
	 */
	private void invocarPLCargaOficio(String procedureId, MensajesSolicitud mensajeSolicitud, String plateaType,
			String plateaSubType) {

		TratamientoJMSServiceImpl.logger.info("Inicio invocarPLCargaOficio:");
		TratamientoJMSServiceImpl.logger.info("Parametro procedureId:" + procedureId);
		TratamientoJMSServiceImpl.logger.info("Parametro mensajeSolicitud:" + mensajeSolicitud);
		TratamientoJMSServiceImpl.logger.info("Parametro plateaType:" + plateaType);
		TratamientoJMSServiceImpl.logger.info("Parametro plateaSubType:" + plateaSubType);

		/**
		 * Primero obtenemos de la tabla configuracion el nombre del pl/sql
		 */

		String nombrePlSql = this.obtenerNombrePLSQL(procedureId, mensajeSolicitud.getTipomensaje(), plateaType,
				plateaSubType);

		TratamientoJMSServiceImpl.logger.info("PL/SQL al que se va a invocar:" + nombrePlSql);

		SqlParameter[] parameters = { new SqlInOutParameter("IN_ID_MENSAJE", Types.NUMERIC) };

		MapSqlParameterSource parameterSource = new MapSqlParameterSource();
		parameterSource.addValue("IN_ID_MENSAJE", mensajeSolicitud.getIdMensaje());

		try {
			DBUtils.callPLSQL(this.jdbcTemplate, nombrePlSql, parameters, parameterSource);
			TratamientoJMSServiceImpl.logger.info("Fin invocarPLCargaOficio:");

		} catch (Exception e) {

			TratamientoJMSServiceImpl.logger.error("Error en la invocación del PL TRATAMIENTO_TAREAS"
					+ mensajeSolicitud.getIdMensaje() + "-" + e.getMessage());
		}

	}

	/**
	 * invocacion a PL-SQL de carga, en algunos Pls se devuelve el titulo de
	 * expedietnes
	 * 
	 * @param procedureId
	 *            String
	 * @param mensajeSolicitud
	 *            MensajesSolicitud
	 * @param plateaType
	 *            String
	 * @param plateaSubType
	 *            String
	 * @param solicitudes
	 *            Solicitudes
	 * @return String
	 */
	private void invocarPLCargaAccionesTelematicas(String procedureId, MensajesSolicitud mensajeSolicitud,
			String plateaType, String plateaSubType, Solicitudes solicitudes) {

		TratamientoJMSServiceImpl.logger.info("Inicio invocarPLCargaAccionesTelematicas:");
		TratamientoJMSServiceImpl.logger.info("Parametro procedureId:" + procedureId);
		TratamientoJMSServiceImpl.logger.info("Parametro tipo mensaje:" + mensajeSolicitud.getTipomensaje());
		TratamientoJMSServiceImpl.logger.info("Parametro plateaType:" + plateaType);
		TratamientoJMSServiceImpl.logger.info("Parametro plateaSubType:" + plateaSubType);
		TratamientoJMSServiceImpl.logger.info("Parametro IdSolicitud:" + solicitudes.getIdSolicitud());

		/**
		 * Primero obtenemos de la tabla configuracion el nombre del pl/sql
		 */

		String nombrePlSql = this.obtenerNombrePLSQL(procedureId, mensajeSolicitud.getTipomensaje(), plateaType,
				plateaSubType);

		TratamientoJMSServiceImpl.logger.info("PL/SQL al que se va a invocar:" + nombrePlSql);

		SqlParameter[] parameters = {

				new SqlInOutParameter("IN_ID_SOLICITUD", Types.VARCHAR) };

		MapSqlParameterSource parameterSource = new MapSqlParameterSource();
		parameterSource.addValue("IN_ID_SOLICITUD", solicitudes.getIdSolicitud());

		try {
			DBUtils.callPLSQL_R02REQUEST(this.jdbcTemplate, nombrePlSql, parameters, parameterSource);
			TratamientoJMSServiceImpl.logger.info("Fin invocarPLCargaAccionesTelematicas:");

		} catch (Exception e) {

			TratamientoJMSServiceImpl.logger.error("Error en el procesamiento del carga de la solicitud:"
					+ solicitudes.getIdSolicitud() + "-" + e.getMessage());
		}

	}

	/**
	 * invocacion a PL-SQL de para acciones telematicas, excepto solicitudes,
	 * justificaciones y subsanaciones
	 * 
	 * @param procedureId
	 *            String
	 * @param mensajeSolicitud
	 *            MensajesSolicitud
	 * @param plateaType
	 *            String
	 * @param plateaSubType
	 *            String
	 * @param solicitudes
	 *            Solicitudes
	 * @return String
	 */
	private void invocarPLTratarFechas(String procedureId, MensajesSolicitud mensajeSolicitud, String plateaType,
			String plateaSubType) {

		TratamientoJMSServiceImpl.logger.info("Inicio invocarPLTratarFechas:");
		TratamientoJMSServiceImpl.logger.info("Parametro procedureId:" + procedureId);
		TratamientoJMSServiceImpl.logger.info("Parametro tipo mensaje:" + mensajeSolicitud.getTipomensaje());
		TratamientoJMSServiceImpl.logger.info("Parametro plateaType:" + plateaType);
		TratamientoJMSServiceImpl.logger.info("Parametro plateaSubType:" + plateaSubType);

		/**
		 * Primero obtenemos de la tabla configuracion el nombre del pl/sql
		 */

		String nombrePlSql = this.obtenerNombrePLSQL(procedureId, mensajeSolicitud.getTipomensaje(), plateaType,
				plateaSubType);

		/*
		 * Si no devuelve ningun nombre de PL/SQL volvemos a repetir la busqueda
		 * solo por procedureId y mensajeSolicitud.getTipomensaje()
		 */
		if (nombrePlSql == null || nombrePlSql.equals("")) {
			nombrePlSql = this.obtenerNombrePLSQL(procedureId, mensajeSolicitud.getTipomensaje(), null, null);
		}
		TratamientoJMSServiceImpl.logger.info("PL/SQL al que se va a invocar:" + nombrePlSql);

		SqlParameter[] parameters = { new SqlInOutParameter("IN_ID_MENSAJE", Types.NUMERIC) };

		MapSqlParameterSource parameterSource = new MapSqlParameterSource();
		parameterSource.addValue("IN_ID_MENSAJE", mensajeSolicitud.getIdMensaje());

		try {
			DBUtils.callPLSQL(this.jdbcTemplate, nombrePlSql, parameters, parameterSource);
			TratamientoJMSServiceImpl.logger.info("Fin invocarPLTratarFechas:");

		} catch (Exception e) {

			TratamientoJMSServiceImpl.logger.error("Error en la invocación del PL = " + nombrePlSql
					+ "con el IDMENSAJE = " + mensajeSolicitud.getIdMensaje() + "-" + e.getMessage());
		}

	}

	/**
	 * invocacion a PL-SQL de tratamiento de fechas para caso de solicitudes,
	 * subsanaciones y justificaciones e inicio de oficio
	 * 
	 * @param procedureId
	 *            String
	 * @param mensajeSolicitud
	 *            MensajesSolicitud
	 * @param plateaType
	 *            String
	 * @param plateaSubType
	 *            String
	 * @param solicitudes
	 *            Solicitudes
	 * @return String
	 */
	private void invocarPLTratarFechasSolJustifSubsanacion(MensajesSolicitud mensajeSolicitud) {

		TratamientoJMSServiceImpl.logger.info("Inicio invocarPLTratarFechasSolJustifSubsanacion: TRATAMIENTO_FECHAS");
		TratamientoJMSServiceImpl.logger.info("Parametro IdMensaje() = " + mensajeSolicitud.getIdMensaje());

		SqlParameter[] parameters = { new SqlInOutParameter("IN_ID_MENSAJE", Types.NUMERIC) };

		MapSqlParameterSource parameterSource = new MapSqlParameterSource();
		parameterSource.addValue("IN_ID_MENSAJE", mensajeSolicitud.getIdMensaje());

		try {
			DBUtils.callPLSQL(this.jdbcTemplate, "TRATAMIENTO_FECHAS", parameters, parameterSource);
			TratamientoJMSServiceImpl.logger.info("Fin invocarPLTratarFechasSolJustifSubsanacion");

		} catch (Exception e) {

			TratamientoJMSServiceImpl.logger.error("Error en la invocación del PL TRATAMIENTO_TAREAS"
					+ mensajeSolicitud.getIdMensaje() + "-" + e.getMessage());
		}

	}

	/**
	 * Formatear el mensae recibido de R02TASK para quitar los esquemas
	 * 
	 * @param strToken
	 *            : token de sesion
	 * @return strValor : el token sin
	 */
	public String formatearMensaje(String mensaje, String tipoMensaje) {

		mensaje = mensaje.replace("&lt;", "<").replace("&gt;", ">");
		mensaje = this.eliminarComienzoToken(mensaje);
		/**
		 * Eliminamos de la etiqueta NotificationBody la propiedad
		 * com/ejie/notification/xml
		 */
		int posicionNB = mensaje.indexOf("NotificationBody");
		if (posicionNB != -1) {
			int posicionCierreNB = mensaje.indexOf(">", posicionNB + 16);
			String cadenaABorrarNB = mensaje.substring(posicionNB + 16, posicionCierreNB);
			mensaje = mensaje.replace(cadenaABorrarNB, "");
		}

		/**
		 * Eliminamos de la etiqueta task la propiedad
		 * com/ejie/notification/xml. En el mensaje R02_SIGN no buscar por la
		 * etiqueta task, ya que no hay pero si hay etiqueta taskoid, de esta
		 * manera quitariamos la palabra oid
		 */
		if (!tipoMensaje.equalsIgnoreCase(Constantes.R02_SIGN)) {
			int posicionTASK = mensaje.indexOf("task");
			if (posicionTASK != -1) {
				int posicionCierreTASK = mensaje.indexOf(">", posicionTASK + 4);
				String cadenaABorrarTASK = mensaje.substring(posicionTASK + 4, posicionCierreTASK);
				mensaje = mensaje.replace(cadenaABorrarTASK, "");
			}
		}

		/**
		 * Eliminamos de la etiqueta notificationEvent la propiedad
		 * xmlns="com/ejie/pnt/xml"
		 */
		int posicionNE = mensaje.indexOf("notificationEvent");
		if (posicionNE != -1) {
			int posicionCierreNE = mensaje.indexOf(">", posicionNE + 17);
			String cadenaABorrarNE = mensaje.substring(posicionNE + 17, posicionCierreNE);
			mensaje = mensaje.replace(cadenaABorrarNE, "");
		}

		/**
		 * Eliminamos de la etiqueta contextSubmissionEvent la propiedad
		 * xmlns="com/ejie/folderManagement/xml"
		 */
		int posicionCS = mensaje.indexOf("contextSubmissionEvent");
		if (posicionCS != -1) {
			int posicionCierreCS = mensaje.indexOf(">", posicionCS + 22);
			String cadenaABorrarCS = mensaje.substring(posicionCS + 22, posicionCierreCS);
			mensaje = mensaje.replace(cadenaABorrarCS, "");
		}

		/**
		 * Eliminamos de la etiqueta EventCorrelationId la propiedad
		 * xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 * En los mensajes de R02_SIGN no hay que quitarlo en el mensaje viene
		 * bien sin la propiedad xsi:nil="true"
		 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
		 */
		if (!tipoMensaje.equalsIgnoreCase(Constantes.R02_SIGN)) {
			int posicionEC = mensaje.indexOf("<Name>EventCorrelationId</Name><Value");
			if (posicionEC != -1) {
				int posicionCierreEC = mensaje.indexOf(">", posicionEC + 37);
				String cadenaABorrarEC = mensaje.substring(posicionEC + 37, posicionCierreEC);
				mensaje = mensaje.replace(cadenaABorrarEC, "");
			}
		}

		/**
		 * Eliminamos de la etiqueta instanceId la propiedad xsi:nil="true"
		 */
		int posicionIN = mensaje.indexOf("<instanceId xsi:nil=");
		if (posicionIN != -1) {
			int posicionCierreIN = mensaje.indexOf("/>", posicionIN);
			String cadenaABorrarIN = mensaje.substring(posicionIN, posicionCierreIN + 2);
			mensaje = mensaje.replace(cadenaABorrarIN, "");
		}

		/**
		 * Eliminamos de la etiqueta signEventInfo la propiedad
		 * xmlns="com/ejie/mbt/xml""
		 */
		int posicionSE = mensaje.indexOf("signEventInfo");
		if (posicionSE != -1) {
			int posicionCierreSE = mensaje.indexOf(">", posicionSE + 13);
			String cadenaABorrarSE = mensaje.substring(posicionSE + 13, posicionCierreSE);
			mensaje = mensaje.replace(cadenaABorrarSE, "");
		}

		return mensaje;
	}

	/**
	 * Quita el texto <?xml version='1.0' encoding='ISO-8859-1'?> del Token de
	 * sesion de la n38
	 * 
	 * @param strToken
	 *            : token de sesion
	 * @return strValor : el token sin
	 */
	public String eliminarComienzoToken(String strToken) {
		String strValor = null;

		int intValor = strToken.indexOf("?>");

		if (intValor != -1) {
			strValor = strToken.substring(intValor + 2);
		} else {
			strValor = strToken;
		}

		return strValor;
	}

	/**
	 * Funcion Convierte String a Document
	 * 
	 * @param textoXML
	 *            String
	 * 
	 * @return Document
	 * 
	 * @throws Exception
	 *             Exception
	 */

	public static Document stringToDocument(String textoXML) throws Exception {

		Document document = null;

		try {

			DocumentBuilderFactory factory = null;
			DocumentBuilder builder = null;

			factory = DocumentBuilderFactory.newInstance();
			factory.setValidating(false);
			factory.setIgnoringElementContentWhitespace(true);
			builder = factory.newDocumentBuilder();
			StringReader stringIn = new StringReader(textoXML);
			document = builder.parse(new InputSource(stringIn));

			// crear y añadir la pi

			ProcessingInstruction pi = document.createProcessingInstruction("xml",
					"version=\"1.0\" encoding=\"ISO-8859-1\"");
			document.appendChild(pi);

		} catch (Exception ex) {
			throw new Exception("Excepcion en stringToDocument:", ex);
		}

		return document;

	}

	/**
	 * Funcion que devuelte un Texto dado un XPath
	 * 
	 * @param docDom
	 *            Document
	 * @param strPath
	 *            String
	 * 
	 * @return String
	 */
	public static String buscarDomString(Document docDom, String strPath) {

		NodeList NodeLiResultado = null;
		String strValor = "";

		try {

			NodeLiResultado = XPathAPI.selectNodeList(docDom, strPath);

			if (NodeLiResultado.getLength() != 0) {
				strValor = (String) NodeLiResultado.item(0).getNodeValue();
			} else {
				strValor = "";
			}

		} catch (Exception ex) {
			ex.printStackTrace(System.out);
		}

		return strValor;
	}

	/**
	 * Metodo que obtiene de la tabla de configuracion (Ab6119T00 el nombre de
	 * BD
	 * 
	 * @param procedureId
	 * @param plateaType
	 * @param plateaSubType
	 * @return
	 */
	private String obtenerNombrePLSQL(String procedureId, String mensajeSolicitud, String plateaType,
			String plateaSubType) {

		Configuracion configuracion = new Configuracion();
		configuracion.setCodProcedureId(procedureId);
		configuracion.setTipoEvento(mensajeSolicitud);
		configuracion.setPlateaType(plateaType);
		configuracion.setPlateaSubType(plateaSubType);
		List<Configuracion> listConfiguracion = configuracionService.findAll(configuracion, null);
		String nombrePlSql = "";
		if (listConfiguracion.size() > 0) {
			nombrePlSql = listConfiguracion.get(0).getPlsqlCarga();
		}
		return nombrePlSql;

	};

	/**
	 * Metodo que recupera un documento de dokusi a partir del Oid del documento
	 * 
	 * @param oidDocument
	 *            string
	 * @return List<Object>
	 * @throws Exception
	 */
	private InputStream recuperarDocumentoDokusi(String documentID) throws Exception {

		TratamientoJMSServiceImpl.logger.info("recuperarDocumentoDokusi - " + documentID);
		try {

			InputStream datosDokusi = this.t65BDokusiAdaptadorService.retrieveDocument(documentID);

			return datosDokusi;
		} catch (Exception e_obtenerDocDokusi) {
			TratamientoJMSServiceImpl.logger.error("DokusiAdapterServiceImpl.retrieveDocument", e_obtenerDocDokusi);
			throw e_obtenerDocDokusi;
		} finally {
			TratamientoJMSServiceImpl.logger.info("DokusiAdapterServiceImpl.retrieveDocument - Final");
		}

	}

	/**
	 * Obtener del mensaje el oid de la solicitud de las acciones telematicas
	 * 
	 * @param documentoTrasformado
	 *            Document
	 * @return
	 */
	private String obtenerOidSolAccionesTelematicas(Document documentoTrasformado) {

		String oid = "";
		NodeList datosDocumento2 = documentoTrasformado.getElementsByTagName("documentsEvent");

		if (datosDocumento2 != null) {

			int numeroValores = datosDocumento2.item(0).getChildNodes().getLength();

			for (int contadorDocumentos = 0; contadorDocumentos < numeroValores; contadorDocumentos++) {

				Node nodoDocumento = datosDocumento2.item(0).getChildNodes().item(contadorDocumentos);

				if (nodoDocumento.getNodeName().equalsIgnoreCase("documentEvent")) {
					boolean documentoJustificacion = false;
					for (int contadorPropiedades = 0; contadorPropiedades < numeroValores; contadorPropiedades++) {

						Node nodoPropiedad = nodoDocumento.getChildNodes().item(contadorPropiedades);
						if (nodoPropiedad.getNodeName().equalsIgnoreCase("oid")) {
							if (nodoPropiedad.getChildNodes().getLength() > 0) {
								oid = nodoPropiedad.getChildNodes().item(0).getNodeValue();
							}
						} else if (nodoPropiedad.getNodeName().equalsIgnoreCase("roleId")) {
							if (nodoPropiedad.getChildNodes().getLength() > 0) {
								if (nodoPropiedad.getNodeValue() != null) {

									if (nodoPropiedad.getChildNodes().item(0).getNodeValue()
											.equalsIgnoreCase("ejgv_d_solicitud.0.0")) {
										documentoJustificacion = true;

									}
								}
							}
							break;

						}
					}

					if (documentoJustificacion) {
						break;
					}
				}

			}
		}

		return oid;
	}

	/**
	 * Guardar mensaje en la tabla AB6118T00
	 * 
	 * @param solicitudes
	 *            Solicitudes
	 * @throws IOException
	 * @throws SQLException
	 */
	private Solicitudes guardarSolicitud(Solicitudes solicitudes, MensajesSolicitud mensajeSolicitud,
			String ejgvDocumentSolicitud, String folderID, String procedureId, String fechaRegistro)
			throws SQLException, IOException {
		solicitudes.setMensajesSolicitud(mensajeSolicitud);
		solicitudes.setSolicitud(ClobUtils.stringToClob(ejgvDocumentSolicitud));
		solicitudes.setFechaRegistro(new Date());
		solicitudes.setFolderId(folderID);
		solicitudes.setCodProcedureId(procedureId);
		String fechaEntradaSol = fechaRegistro;
		TratamientoJMSServiceImpl.logger.info("fechaEntradaSol= " + fechaEntradaSol);
		solicitudes.setFechaEntradaStr(DateUtils.convertirStringEnStringFormateado(fechaEntradaSol));

		TratamientoJMSServiceImpl.logger
				.info("Iniciando guardar el mensaje en la tabla de solicitudes (AB6118T00) con el paramtero Solictud = "
						+ solicitudes.toString());

		solicitudes = solicitudesService.add(solicitudes);

		TratamientoJMSServiceImpl.logger.info("Guardardo el mensaje en la tabla de mensajes (AB6118T00)");

		return solicitudes;
	}

	/**
	 * Devuelve todo el html de la aportacion de la
	 * documentacion(justificacion,subsanacion, etc..), solo interesa recuperar
	 * el ejgvDocument
	 * 
	 * @param bIS
	 *            InputStream
	 * @return String
	 * @throws Exception
	 * 
	 */
	private String recuperarEjgvDocumentSinHTML(InputStream bIS) throws Exception {

		String ejgvDocumentSolicitud = "";
		String strFileContents = "";
		int numRead;
		final int bufferSize = 1024;
		byte[] buffer = new byte[bufferSize];
		ByteArrayOutputStream outString = new ByteArrayOutputStream();
		try {
			while ((numRead = bIS.read(buffer)) != -1) {
				outString.write(buffer, 0, numRead);
			}
		} finally {
			bIS.close();
		}
		strFileContents = new String(outString.toByteArray());

		int inicio = strFileContents.indexOf("<ejgvDocument>");
		int fin = strFileContents.indexOf("</ejgvDocument>");

		ejgvDocumentSolicitud = strFileContents.substring(inicio, fin + 15);
		return ejgvDocumentSolicitud;
	}

	/**
	 * Metodo que invoca al PL/sql de tratamiento de tareas (eventos R02_TASK)
	 * 
	 * @param procedureId
	 *            String
	 * @param mensajeSolicitud
	 *            MensajesSolicitud
	 * @param plateaType
	 *            String
	 * @param plateaSubType
	 *            String
	 */
	private void tratamientoR02TaskPlSql(String procedureId, MensajesSolicitud mensajeSolicitud, String plateaType,
			String plateaSubType) throws Ab61Exception {

		/**
		 * Primero obtenemos de la tabla configuracion el nombre del pl/sql
		 */

		String nombrePlSql = this.obtenerNombrePLSQL(procedureId, mensajeSolicitud.getTipomensaje(), plateaType,
				plateaSubType);
		SqlParameter[] parameters = { new SqlInOutParameter("IN_ID_MENSAJE", Types.NUMERIC) };

		/*
		 * Si no devuelve ningun nombre de PL/SQL volvemos a repetir la busqueda
		 * solo por procedureId y mensajeSolicitud.getTipomensaje()
		 */
		if (nombrePlSql == null || nombrePlSql.equals("")) {
			nombrePlSql = this.obtenerNombrePLSQL(procedureId, mensajeSolicitud.getTipomensaje(), null, null);
		}

		MapSqlParameterSource parameterSource = new MapSqlParameterSource();
		parameterSource.addValue("IN_ID_MENSAJE", mensajeSolicitud.getIdMensaje());

		try {
			DBUtils.callPLSQL(this.jdbcTemplate, nombrePlSql, parameters, parameterSource);

		} catch (Exception e) {

			TratamientoJMSServiceImpl.logger.error("Error en la invocación del PL TRATAMIENTO_TAREAS" + e.getMessage());
		}

		TratamientoJMSServiceImpl.logger.info("El PL TRATAMIENTO_TAREAS se ha invocado correctamente");

	}

	/**
	 * Método que actualiza en titulo del expediente en Platea
	 * 
	 * @param folderID
	 *            String
	 */
	private void tratamientoR02TaskAperturaTitulo(String folderID) {

		List<Expedientes> listaExpedientes = expedientesDao.obtenerTituloExpediente(folderID);
		if (listaExpedientes.size() > 0) {
			/**
			 * Actualizo el titulo del expediente en platea
			 */
			String tituloExpediente = listaExpedientes.get(0).getTitulo();
			TBoolean resultadoUpdateTitulo = TBoolean.FALSE;
			try {
				if (tituloExpediente != "") {
					resultadoUpdateTitulo = x43ExpedienteElectronicoAdaptadorService.updateFolderTitle(folderID,
							tituloExpediente, null);
				}
			} catch (Exception_Exception e) {
				TratamientoJMSServiceImpl.logger
						.info("Ha ocurrido un problemas al actualizar el titulo del expediente en platea. Método:updateFolderTitle, folderID = "
								+ folderID + " Titulo = " + tituloExpediente);
			}
			if (resultadoUpdateTitulo.equals(TBoolean.TRUE)) {
				TratamientoJMSServiceImpl.logger
						.info("EL titulo de expediente en platea se ha actualizado satisfactoriamente");
			} else {
				TratamientoJMSServiceImpl.logger
						.info("Ha ocurrido un problemas al actualizar el titulo del expediente en platea. Método:updateFolderTitle, folderID = "
								+ folderID + " Titulo = " + tituloExpediente);
			}
		} else {
			logger.info("Para el expediente con FOlderID = " + folderID + " no hay titulo en BD");
		}

	}

	/**
	 * Metodo que el numero de expediente (folderNumder) de la tabla Expediente
	 * a paritr del folderId
	 * 
	 * @param folderID
	 *            String
	 * @param folderNumber
	 *            String
	 */
	private void tratamientoR02TaskAperturaNumExpediente(String folderID, String folderNumber) {

		try {
			TratamientoJMSServiceImpl.logger
					.info("INICIO de actualizar el folderNumber pasando como parametros FOLDERID= " + folderID
							+ " y FOLDERNUMBER = " + folderNumber);
			Expedientes expedientes = new Expedientes();
			expedientes.setFolderNumber(folderNumber);
			expedientes.setFolderId(folderID);
			expedientesService.updateFolderNumber(expedientes);
			TratamientoJMSServiceImpl.logger.info("FIN de actualizar el folderNumber");

		} catch (Exception e) {
			TratamientoJMSServiceImpl.logger
					.error("Error al actualizar el folderNumber en la tarea de apertura = " + e.getMessage());
		}

	}

}
