package com.ejie.ab04b.service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ejie.ab04b.constantes.ConstantesDocumentos;
import com.ejie.ab04b.constantes.ConstantesNum;
import com.ejie.ab04b.exception.AB04BException;
import com.ejie.ab04b.model.VdatosReqApe;
import com.ejie.ab04b.model.VdatosReqOs;
import com.ejie.ab04b.model.VmotivosSubsanacionExp;
import com.ejie.ab04b.model.VmotivosSubsanacionExpOs2;
import com.ejie.ab04b.model.VmotivosSubsanacionExpOs3;
import com.ejie.ab04b.util.CaracteresRarosUtil;
import com.ejie.ab04b.util.Utilities;

/**
 * GeneracionPDFSubsanacionImpl generated by UDA, 11-Jan-2017 12:23:08.
 * 
 * @author UDA
 */

@Service(value = "generacionPDFSubsanacionImpl")
public class GeneracionPDFSubsanacionImpl
		implements GeneracionPDFSubsanacionService {

	@Autowired
	private VdatosReqApeService vdatosReqApeService;
	@Autowired
	private VdatosReqOsService vdatosReqOsService;
	@Autowired
	private VmotivosSubsanacionExpService vmotivosSubsanacionExpService;
	@Autowired
	private VmotivosSubsanacionExpOs2Service vmotivosSubsanacionExpOs2Service;
	@Autowired
	private VmotivosSubsanacionExpOs3Service vmotivosSubsanacionExpOs3Service;

	/**
	 * Crea el PDF y devuelve la ruta donde lo aloja.
	 * 
	 * folderNumber String procedureId String String
	 * 
	 * @param folderNumber
	 *            the folder number
	 * @param procedureId
	 *            the procedure id
	 * @return the pdf
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	public InputStream getPDF(String folderNumber, String procedureId,
			Long idTramite) throws AB04BException {
		String folderNumberAux = folderNumber;
		try {
			folderNumberAux = folderNumberAux.replace("/", "-");
			String xslFichero = "";

			if (procedureId.equals(ConstantesDocumentos.APERTURA_CENTRO)) {
				xslFichero = ConstantesDocumentos.MOTIVOSSUBSANACION_APERTURA_CENTRO_XSL;
			} else if (procedureId
					.equals(ConstantesDocumentos.COMUNICACION_OS2)) {
				xslFichero = ConstantesDocumentos.MOTIVOSSUBSANACION_COMUNICACION_XSL;
			} else if (procedureId
					.equals(ConstantesDocumentos.COMUNICACION_OS3)) {
				xslFichero = ConstantesDocumentos.MOTIVOSSUBSANACION_COMUNICACION_XSL;
			}

			InputStream inputStream = null;

			StringBuffer xmlPdf = getXml(folderNumberAux, procedureId,
					idTramite);
			String xml = CaracteresRarosUtil.htmlEscape(xmlPdf.toString());

			StringReader lxmlReader = new StringReader(xml);

			// Inicializo transformer
			Transformer transformer = pdfTransformacionInit(xslFichero);
			// Ejecuto transformación
			ByteArrayOutputStream byteOut = pdfTransformacionExec(transformer,
					lxmlReader, org.apache.fop.apps.Driver.RENDER_PDF);

			byte[] bytes = byteOut.toByteArray();
			inputStream = new ByteArrayInputStream(bytes);

			byteOut.close();

			return inputStream;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * Devuelve un InputStream con el documento pdf.
	 * 
	 * listadoFolderNumber String[] procedureId String Inputstream
	 * 
	 * @param listadoFolderNumber
	 *            the listado folder number
	 * @param procedureId
	 *            the procedure id
	 * @return the pdf
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	public InputStream getPDF(String[] listadoFolderNumber, String procedureId,
			Long idTramite) throws AB04BException {
		try {

			String xslFichero = "";
			if (procedureId.equals(ConstantesDocumentos.APERTURA_CENTRO)) {
				xslFichero = ConstantesDocumentos.IMPRIMIR_MOTIVOSSUBSANACION_APERTURA_CENTRO_XSL;
			} else if (procedureId
					.equals(ConstantesDocumentos.COMUNICACION_OS2)) {
				xslFichero = ConstantesDocumentos.IMPRIMIR_MOTIVOSSUBSANACION_COMUNICACION_XSL;
			} else if (procedureId
					.equals(ConstantesDocumentos.COMUNICACION_OS3)) {
				xslFichero = ConstantesDocumentos.IMPRIMIR_MOTIVOSSUBSANACION_COMUNICACION_XSL;
			}

			InputStream inputStream = null;

			StringBuffer xmlPdf = getXml(listadoFolderNumber, procedureId,
					idTramite);
			String xml = CaracteresRarosUtil.htmlEscape(xmlPdf.toString());
			StringReader lxmlReader = new StringReader(xml);
			// Inicializo transformer
			Transformer transformer = pdfTransformacionInit(xslFichero);
			// Ejecuto transformación
			ByteArrayOutputStream byteOut = pdfTransformacionExec(transformer,
					lxmlReader, org.apache.fop.apps.Driver.RENDER_PDF);

			byte[] bytes = byteOut.toByteArray();
			inputStream = new ByteArrayInputStream(bytes);

			byteOut.close();

			return inputStream;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * Inicializa la transformacion a PDF.
	 * 
	 * xslFichero String Transformer
	 * 
	 * @param xslFichero
	 *            the xsl fichero
	 * @return the transformer
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	private Transformer pdfTransformacionInit(String xslFichero)
			throws AB04BException {
		try {

			TransformerFactory tFactory = TransformerFactory.newInstance();

			// org.apache.fop.configuration.Configuration.put("baseDir", "c:/");

			return tFactory.newTransformer(new StreamSource(xslFichero));
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}

	}

	/**
	 * Ejecuta la transformación PDF.
	 * 
	 * transformer transformer strReader strReader renderer renderer
	 * ByteArrayOutputStream
	 * 
	 * @param transformer
	 *            the transformer
	 * @param strReader
	 *            the str reader
	 * @param renderer
	 *            the renderer
	 * @return the byte array output stream
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	private ByteArrayOutputStream pdfTransformacionExec(Transformer transformer,
			StringReader strReader, int renderer) throws AB04BException {
		try {

			DOMResult domResultado = new DOMResult();

			transformer.transform(new StreamSource(strReader), domResultado);

			org.apache.fop.apps.Driver driver = new org.apache.fop.apps.Driver();

			driver.setRenderer(renderer);

			ByteArrayOutputStream byteOut = new ByteArrayOutputStream();

			driver.setOutputStream(byteOut);
			driver.render((org.w3c.dom.Document) domResultado.getNode());
			driver.reset();

			return byteOut;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * Obtiene los datos y genera el XML.
	 * 
	 * folderNumber String procedureId String String
	 * 
	 * @param folderNumber
	 *            the folder number
	 * @param procedureId
	 *            the procedure id
	 * @return the xml
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	private StringBuffer getXml(String folderNumber, String procedureId,
			Long idTramite) throws AB04BException {
		try {
			String terAper = folderNumber.substring(0, ConstantesNum.NUM_2);
			String anioAper = folderNumber.substring(ConstantesNum.NUM_3,
					ConstantesNum.NUM_7);
			String numAper = folderNumber.substring(ConstantesNum.NUM_8,
					folderNumber.length());

			String municipio = "";
			// String provincia = folderNumber.substring(0, 2);
			Date fechaPres = null;
			String pie1 = "";
			String pie2 = "";
			String fechaPresEusk = "";
			// String firma = "";
			// String fichero = "";
			HashMap<String, String> datosMap = getDatos(procedureId,
					folderNumber);
			HashMap<Character, String[]> apartados = new HashMap<Character, String[]>();
			ArrayList<String> motivos = null;
			ArrayList<String> motivosEusk = null;
			VdatosReqOs datosOs = null;
			VdatosReqApe datosReq = null;

			// Se obtiene los datos dependiendo del tipo de documento desde la
			// BBDD
			if (procedureId.equals(ConstantesDocumentos.APERTURA_CENTRO)) {
				datosReq = new VdatosReqApe();
				datosReq.setAnoape(anioAper);
				datosReq.setTerape(terAper);
				datosReq.setNumape(Integer.parseInt(numAper));
				datosReq = vdatosReqApeService.find(datosReq);

				VmotivosSubsanacionExp motivosAper = new VmotivosSubsanacionExp();

				motivosAper.setAnoape(anioAper);
				motivosAper.setTerape(terAper);
				motivosAper.setNumape(Integer.parseInt(numAper));
				motivosAper.setIdTramite(idTramite);

				List<VmotivosSubsanacionExp> motivosSub = vmotivosSubsanacionExpService
						.findAll(motivosAper, null);

				motivos = obtenerMotivosEs(motivosSub, procedureId);
				motivosEusk = obtenerMotivosEu(motivosSub, procedureId);

				apartados = obtenerApartados(motivosSub);
			} else if (procedureId
					.equals(ConstantesDocumentos.COMUNICACION_OS2)) {
				datosOs = new VdatosReqOs();
				datosOs.setAnoos(anioAper);
				datosOs.setTeros(terAper);
				datosOs.setNumos(Integer.parseInt(numAper));
				datosOs.setTipoos("OS2");
				datosOs = vdatosReqOsService.find(datosOs);

				VmotivosSubsanacionExpOs2 motivOS2 = new VmotivosSubsanacionExpOs2();
				motivOS2.setAnoos(anioAper);
				motivOS2.setTeros(terAper);
				motivOS2.setNumos(Integer.parseInt(numAper));
				motivOS2.setIdTramite(idTramite);
				List<VmotivosSubsanacionExpOs2> motivosSub = vmotivosSubsanacionExpOs2Service
						.findAll(motivOS2, null);

				motivos = obtenerMotivosEs(motivosSub, procedureId);
				motivosEusk = obtenerMotivosEu(motivosSub, procedureId);
			} else if (procedureId
					.equals(ConstantesDocumentos.COMUNICACION_OS3)) {
				datosOs = new VdatosReqOs();
				datosOs.setAnoos(anioAper);
				datosOs.setTeros(terAper);
				datosOs.setNumos(Integer.parseInt(numAper));
				datosOs.setTipoos("OS3");
				datosOs = vdatosReqOsService.find(datosOs);

				VmotivosSubsanacionExpOs3 motivOS3 = new VmotivosSubsanacionExpOs3();
				motivOS3.setAnoos(anioAper);
				motivOS3.setTeros(terAper);
				motivOS3.setNumos(Integer.parseInt(numAper));
				motivOS3.setIdTramite(idTramite);
				List<VmotivosSubsanacionExpOs3> motivosSub = vmotivosSubsanacionExpOs3Service
						.findAll(motivOS3, null);

				motivos = obtenerMotivosEs(motivosSub, procedureId);
				motivosEusk = obtenerMotivosEu(motivosSub, procedureId);
			}

			StringBuffer xml = new StringBuffer("");
			// Inicio de datos para todos
			xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			xml.append("<motivosSubsanacion>");
			xml.append("<procedureId>");
			xml.append(procedureId);
			xml.append("</procedureId>");
			xml.append("<anio>");
			xml.append(datosMap.get("campoAnio"));
			xml.append("</anio>");
			xml.append("<mes>");
			xml.append(datosMap.get("mes"));
			xml.append("</mes>");
			xml.append("<mesEu>");
			xml.append(datosMap.get("mesEu"));
			xml.append("</mesEu>");
			xml.append("<dia>");
			xml.append(datosMap.get("campoDia"));
			xml.append("</dia>");
			xml.append("<provinciaCast>");
			xml.append(datosMap.get("provCast"));
			xml.append("</provinciaCast>");
			xml.append("<provinciaEusk>");
			xml.append(datosMap.get("provEusk"));
			xml.append("</provinciaEusk>");
			xml.append("<lugarCast>");
			xml.append(datosMap.get("lugarCast"));
			xml.append("</lugarCast>");
			xml.append("<lugarEusk>");
			xml.append(datosMap.get("lugarEusk"));
			xml.append("</lugarEusk>");
			xml.append("<tipoDocumento>");
			xml.append(datosMap.get("tipoDocumento"));
			xml.append("</tipoDocumento>");

			if (motivos != null) {
				for (int i = 0; i < motivos.size(); i++) {
					xml.append("<motivos>");
					xml.append("<cast>");
					xml.append("<desc>");
					xml.append(motivos.get(i));
					xml.append("</desc>");
					xml.append("</cast>");
					xml.append("<eusk>");
					xml.append("<desc>");
					xml.append(motivosEusk.get(i));
					xml.append("</desc>");
					xml.append("</eusk>");
					xml.append("</motivos>");
				}
			}

			xml.append("<tipoDocumentoEusk>");
			xml.append(datosMap.get("tipoDocumentoEusk"));
			xml.append("</tipoDocumentoEusk>");
			xml.append("<numExp>");
			xml.append(folderNumber);
			xml.append("</numExp>");
			// fin de datos para todos

			// Exclusivos para OS
			if (ConstantesDocumentos.COMUNICACION_OS2.equals(procedureId)
					|| ConstantesDocumentos.COMUNICACION_OS2
							.equals(procedureId)) {
				xml.append(obtenerDatosOS(datosOs));
				municipio = (datosOs.getDescmuni() != null)
						? datosOs.getDescmuni() : "";
				fechaPres = datosOs.getFecpre();

				// para la firma
				xml.append("<firma>");
				xml.append(datosOs.getDescfirma());
				xml.append("</firma>");
				xml.append("<fichero>");
				String url = ConstantesDocumentos.RUTA_FIRMA_IMAGEN + "/"
						+ datosOs.getFirma();
				xml.append("url(" + url + ")");
				xml.append("</fichero>");
				// fin para la firma
			}
			// Fin Exclusivos para OS

			// Exclusivos para apertura
			if (procedureId.equals(ConstantesDocumentos.APERTURA_CENTRO)) {
				xml.append(obtenerDatosApertura(datosOs, datosReq, apartados,
						motivos));
				municipio = datosReq.getDesmunctr();
				fechaPres = datosReq.getFecpre();
				// Pie
				pie1 = datosReq.getPie1();
				pie2 = datosReq.getPie2();
				xml.append("<piePagina>");
				xml.append(pie1);
				xml.append("</piePagina>");
				xml.append("<piePagina2>");
				xml.append(pie2);
				xml.append("</piePagina2>");

				// para la firma
				xml.append("<firma>");
				xml.append(datosReq.getDescfirma());
				xml.append("</firma>");
				xml.append("<fichero>");
				String url = ConstantesDocumentos.RUTA_FIRMA_IMAGEN + "/"
						+ datosReq.getFirma();
				xml.append("url(" + url + ")");
				xml.append("</fichero>");
				// fin para la firma
			}
			// Fin Exclusivos para apertura
			// municipio
			xml.append("<municipio>");
			xml.append(municipio);
			xml.append("</municipio>");
			// fin municipio

			// fecha en euskera
			if (fechaPres != null) {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
				fechaPresEusk = sdf.format(fechaPres);
			}
			xml.append("<fecha_presEusk>");
			xml.append(fechaPresEusk);
			xml.append("</fecha_presEusk>");
			// fin fecha en euskera

			xml.append("</motivosSubsanacion>");
			return xml;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}

	}

	/**
	 * Obtiene los datos y genera el XML.
	 * 
	 * listadoFolderNumber String[] procedureId String String
	 * 
	 * @param listadoFolderNumber
	 *            the listado folder number
	 * @param procedureId
	 *            the procedure id
	 * @return the xml
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	private StringBuffer getXml(String[] listadoFolderNumber,
			String procedureId, Long idTramite) throws AB04BException {
		try {

			StringBuffer xml = new StringBuffer();
			xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			xml.append("<impresiones>");
			for (int j = 0; j < listadoFolderNumber.length; j++) {
				String folderNumber = listadoFolderNumber[j];
				String terAper = folderNumber.substring(0, ConstantesNum.NUM_2);
				String anioAper = folderNumber.substring(ConstantesNum.NUM_3,
						ConstantesNum.NUM_7);
				String numAper = folderNumber.substring(ConstantesNum.NUM_8,
						folderNumber.length());

				String municipio = "";
				// String provincia = folderNumber.substring(0, 2);
				Date fechaPres = null;
				String pie1 = "";
				String pie2 = "";
				String fechaPresEusk = "";
				// String firma = "";
				// String fichero = "";
				HashMap<String, String> datosMap = getDatos(procedureId,
						folderNumber);
				HashMap<Character, String[]> apartados = new HashMap<Character, String[]>();
				ArrayList<String> motivos = null;
				ArrayList<String> motivosEusk = null;
				VdatosReqOs datosOs = null;
				VdatosReqApe datosReq = null;

				// Se obtiene los datos dependiendo del tipo de documento desde
				// la
				// BBDD
				if (procedureId.equals(ConstantesDocumentos.APERTURA_CENTRO)) {
					datosReq = new VdatosReqApe();
					datosReq.setAnoape(anioAper);
					datosReq.setTerape(terAper);
					datosReq.setNumape(Integer.parseInt(numAper));
					datosReq = vdatosReqApeService.find(datosReq);

					VmotivosSubsanacionExp motivosAper = new VmotivosSubsanacionExp();

					motivosAper.setAnoape(anioAper);
					motivosAper.setTerape(terAper);
					motivosAper.setNumape(Integer.parseInt(numAper));
					motivosAper.setIdTramite(idTramite);
					List<VmotivosSubsanacionExp> motivosSub = vmotivosSubsanacionExpService
							.findAll(motivosAper, null);

					motivos = obtenerMotivosEs(motivosSub, procedureId);
					motivosEusk = obtenerMotivosEu(motivosSub, procedureId);

					apartados = obtenerApartados(motivosSub);
				} else if (procedureId
						.equals(ConstantesDocumentos.COMUNICACION_OS2)) {
					datosOs = new VdatosReqOs();
					datosOs.setAnoos(anioAper);
					datosOs.setTeros(terAper);
					datosOs.setNumos(Integer.parseInt(numAper));
					datosOs.setTipoos("OS2");
					datosOs = vdatosReqOsService.find(datosOs);

					VmotivosSubsanacionExpOs2 motivOS2 = new VmotivosSubsanacionExpOs2();
					motivOS2.setAnoos(anioAper);
					motivOS2.setTeros(terAper);
					motivOS2.setNumos(Integer.parseInt(numAper));
					motivOS2.setIdTramite(idTramite);
					List<VmotivosSubsanacionExpOs2> motivosSub = vmotivosSubsanacionExpOs2Service
							.findAll(motivOS2, null);

					motivos = obtenerMotivosEs(motivosSub, procedureId);
					motivosEusk = obtenerMotivosEu(motivosSub, procedureId);
				} else if (procedureId
						.equals(ConstantesDocumentos.COMUNICACION_OS3)) {
					datosOs = new VdatosReqOs();
					datosOs.setAnoos(anioAper);
					datosOs.setTeros(terAper);
					datosOs.setNumos(Integer.parseInt(numAper));
					datosOs.setTipoos("OS3");
					datosOs = vdatosReqOsService.find(datosOs);

					VmotivosSubsanacionExpOs3 motivOS3 = new VmotivosSubsanacionExpOs3();
					motivOS3.setAnoos(anioAper);
					motivOS3.setTeros(terAper);
					motivOS3.setNumos(Integer.parseInt(numAper));
					motivOS3.setIdTramite(idTramite);
					List<VmotivosSubsanacionExpOs3> motivosSub = vmotivosSubsanacionExpOs3Service
							.findAll(motivOS3, null);

					motivos = obtenerMotivosEs(motivosSub, procedureId);
					motivosEusk = obtenerMotivosEu(motivosSub, procedureId);
				}

				// Inicio de datos para todos
				xml.append("<motivosSubsanacion>");
				xml.append("<procedureId>");
				xml.append(procedureId);
				xml.append("</procedureId>");
				xml.append("<anio>");
				xml.append(datosMap.get("campoAnio"));
				xml.append("</anio>");
				xml.append("<mes>");
				xml.append(datosMap.get("mes"));
				xml.append("</mes>");
				xml.append("<mesEu>");
				xml.append(datosMap.get("mesEu"));
				xml.append("</mesEu>");
				xml.append("<dia>");
				xml.append(datosMap.get("campoDia"));
				xml.append("</dia>");
				xml.append("<provinciaCast>");
				xml.append(datosMap.get("provCast"));
				xml.append("</provinciaCast>");
				xml.append("<provinciaEusk>");
				xml.append(datosMap.get("provEusk"));
				xml.append("</provinciaEusk>");
				xml.append("<lugarCast>");
				xml.append(datosMap.get("lugarCast"));
				xml.append("</lugarCast>");
				xml.append("<lugarEusk>");
				xml.append(datosMap.get("lugarEusk"));
				xml.append("</lugarEusk>");
				xml.append("<tipoDocumento>");
				xml.append(datosMap.get("tipoDocumento"));
				xml.append("</tipoDocumento>");

				if (motivos != null) {
					for (int i = 0; i < motivos.size(); i++) {
						xml.append("<motivos>");
						xml.append("<cast>");
						xml.append("<desc>");
						xml.append(motivos.get(i));
						xml.append("</desc>");
						xml.append("</cast>");
						xml.append("<eusk>");
						xml.append("<desc>");
						xml.append(motivosEusk.get(i));
						xml.append("</desc>");
						xml.append("</eusk>");
						xml.append("</motivos>");
					}
				}

				xml.append("<tipoDocumentoEusk>");
				xml.append(datosMap.get("tipoDocumentoEusk"));
				xml.append("</tipoDocumentoEusk>");
				xml.append("<numExp>");
				xml.append(folderNumber);
				xml.append("</numExp>");
				// fin de datos para todos

				// Exclusivos para OS
				if (ConstantesDocumentos.COMUNICACION_OS2.equals(procedureId)
						|| ConstantesDocumentos.COMUNICACION_OS2
								.equals(procedureId)) {
					xml.append(obtenerDatosOS(datosOs));
					municipio = (datosOs.getDescmuni() != null)
							? datosOs.getDescmuni() : "";
					fechaPres = datosOs.getFecpre();

					// para la firma
					xml.append("<firma>");
					xml.append(datosOs.getDescfirma());
					xml.append("</firma>");
					xml.append("<fichero>");
					String url = ConstantesDocumentos.RUTA_FIRMA_IMAGEN + "/"
							+ datosOs.getFirma();
					xml.append("url(" + url + ")");
					xml.append("</fichero>");
					// fin para la firma
				}
				// Fin Exclusivos para OS

				// Exclusivos para apertura
				if (procedureId.equals(ConstantesDocumentos.APERTURA_CENTRO)) {
					xml.append(obtenerDatosApertura(datosOs, datosReq,
							apartados, motivos));
					municipio = datosReq.getDesmunctr();
					fechaPres = datosReq.getFecpre();
					// Pie
					pie1 = datosReq.getPie1();
					pie2 = datosReq.getPie2();
					xml.append("<piePagina>");
					xml.append(pie1);
					xml.append("</piePagina>");
					xml.append("<piePagina2>");
					xml.append(pie2);
					xml.append("</piePagina2>");

					// para la firma
					xml.append("<firma>");
					xml.append(datosReq.getDescfirma());
					xml.append("</firma>");
					xml.append("<fichero>");
					String url = ConstantesDocumentos.RUTA_FIRMA_IMAGEN + "/"
							+ datosReq.getFirma();
					xml.append("url(" + url + ")");
					xml.append("</fichero>");
					// fin para la firma
				}
				// Fin Exclusivos para apertura
				// municipio
				xml.append("<municipio>");
				xml.append(municipio);
				xml.append("</municipio>");
				// fin municipio

				// fecha en euskera
				if (fechaPres != null) {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
					fechaPresEusk = sdf.format(fechaPres);
				}
				xml.append("<fecha_presEusk>");
				xml.append(fechaPresEusk);
				xml.append("</fecha_presEusk>");
				// fin fecha en euskera

				xml.append("</motivosSubsanacion>");
				// return xml;
			}
			xml.append("</impresiones>");
			return xml;
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * Obtiene los datos de apertura.
	 * 
	 * datosOs VdatosReqOs datosReq VdatosReqApe apartados HashMap<Character,
	 * String[]> motivos ArrayList<String> Object
	 * 
	 * @param datosOs
	 *            the datos os
	 * @param datosReq
	 *            the datos req
	 * @param apartados
	 *            the apartados
	 * @param motivos
	 *            the motivos
	 * @return the object
	 */
	private Object obtenerDatosApertura(VdatosReqOs datosOs,
			VdatosReqApe datosReq, HashMap<Character, String[]> apartados,
			ArrayList<String> motivos) {
		String mascara = Utilities.getInstance().getDateMask();
		StringBuffer xml = new StringBuffer("");
		xml.append("<fecha_pres>");
		if (datosReq.getFecpre() != null) {
			SimpleDateFormat sdf = new SimpleDateFormat(mascara);
			xml.append(sdf.format(datosReq.getFecpre()));
		} else {
			xml.append("");
		}
		xml.append("</fecha_pres>");
		xml.append("<direccion>");
		if (datosReq.getDirctr() != null) {
			xml.append(datosReq.getDirctr());
		} else {
			xml.append("");
		}
		xml.append("</direccion>");
		xml.append("<descCentro>");
		if (datosReq.getNomctr() != null) {
			xml.append(datosReq.getNomctr());
		} else {
			xml.append("");
		}
		xml.append("</descCentro>");
		xml.append("<empresa>");
		if (datosReq.getNomemp() != null) {
			xml.append(datosReq.getNomemp());
		} else {
			xml.append("");
		}
		xml.append("</empresa>");

		String[] apartadoB = (String[]) apartados.get('B');
		String[] apartadoC = (String[]) apartados.get('C');
		String[] apartadoD = (String[]) apartados.get('D');
		String[] apartadoE = (String[]) apartados.get('E');
		String[] apartadoF = (String[]) apartados.get('F');
		String[] apartadoG = (String[]) apartados.get('G');
		String[] apartadoH = (String[]) apartados.get('H');

		if (apartadoB != null) {
			xml.append("<apartadoB>");
			xml.append("* " + apartadoB[0]);
			xml.append("</apartadoB>");
			xml.append("<apartadoBEusk>");
			xml.append("* " + apartadoB[1]);
			xml.append("</apartadoBEusk>");
		} else {
			xml.append(
					"<apartadoB></apartadoB><apartadoBEusk></apartadoBEusk>");
		}
		if (apartadoC != null) {
			xml.append("<apartadoC>");
			xml.append("* " + apartadoC[0]);
			xml.append("</apartadoC>");
			xml.append("<apartadoCEusk>");
			xml.append("* " + apartadoC[1]);
			xml.append("</apartadoCEusk>");
		} else {
			xml.append(
					"<apartadoC></apartadoC><apartadoCEusk></apartadoCEusk>");
		}
		if (apartadoD != null) {
			xml.append("<apartadoD>");
			xml.append("* " + apartadoD[0]);
			xml.append("</apartadoD>");
			xml.append("<apartadoDEusk>");
			xml.append("* " + apartadoD[1]);
			xml.append("</apartadoDEusk>");
		} else {
			xml.append(
					"<apartadoD></apartadoD><apartadoDEusk></apartadoDEusk>");
		}
		if (apartadoE != null) {
			xml.append("<apartadoE>");
			xml.append("* " + apartadoE[0]);
			xml.append("</apartadoE>");
			xml.append("<apartadoEEusk>");
			xml.append("* " + apartadoE[1]);
			xml.append("</apartadoEEusk>");
		} else {
			xml.append(
					"<apartadoE></apartadoE><apartadoEEusk></apartadoEEusk>");
		}
		if (apartadoF != null) {
			xml.append("<apartadoF>");
			xml.append("* " + apartadoF[0]);
			xml.append("</apartadoF>");
			xml.append("<apartadoFEusk>");
			xml.append("* " + apartadoF[1]);
			xml.append("</apartadoFEusk>");
		} else {
			xml.append(
					"<apartadoF></apartadoF><apartadoFEusk></apartadoFEusk>");
		}
		if (apartadoG != null) {
			xml.append("<apartadoG>");
			xml.append("* " + apartadoG[0]);
			xml.append("</apartadoG>");
			xml.append("<apartadoGEusk>");
			xml.append("* " + apartadoG[1]);
			xml.append("</apartadoGEusk>");
		} else {
			xml.append(
					"<apartadoG></apartadoG><apartadoGEusk></apartadoGEusk>");
		}
		if (apartadoH != null) {
			xml.append("<apartadoH>");
			xml.append("* " + apartadoH[0]);
			xml.append("</apartadoH>");
			xml.append("<apartadoHEusk>");
			xml.append("* " + apartadoH[1]);
			xml.append("</apartadoHEusk>");
		} else {
			xml.append(
					"<apartadoH></apartadoH><apartadoHEusk></apartadoHEusk>");

			xml.append("<apartadoAVacio>");
			if (motivos != null) {
				xml.append("No");
			} else {
				xml.append("Si");
			}
			xml.append("</apartadoAVacio>");
		}
		// 20140519 nuevos campos con comentarios
		String[] apartadoJ = (String[]) apartados.get('J');
		String[] apartadoK = (String[]) apartados.get('K');
		if (apartadoJ != null || apartadoK != null) {
			xml.append("<apartadoJ>");
			xml.append("* " + apartadoJ[0]);
			xml.append("</apartadoJ>");
			xml.append("<apartadoK>");
			xml.append("* " + apartadoK[0]);
			xml.append("</apartadoK>");
		} else {
			xml.append("<apartadoJ></apartadoJ><apartadoK></apartadoK>");
		}
		return xml.toString();
	}

	/**
	 * Obtiene los datos de OS.
	 * 
	 * datosOs VdatosReqOs Object
	 * 
	 * @param datosOs
	 *            the datos os
	 * @return the object
	 */
	private Object obtenerDatosOS(VdatosReqOs datosOs) {
		String mascara = Utilities.getInstance().getDateMask();
		StringBuffer xml = new StringBuffer("");
		xml.append("<empresa>");
		if (datosOs.getNomemp() != null) {
			xml.append(datosOs.getNomemp());
		} else {
			xml.append("");
		}
		xml.append("</empresa>");
		xml.append("<fecha_pres>");
		if (datosOs.getFecpre() != null) {
			SimpleDateFormat sdf = new SimpleDateFormat(mascara);
			xml.append(sdf.format(datosOs.getFecpre()));
		} else {
			xml.append("");
		}
		xml.append("</fecha_pres>");
		xml.append("<direccion>");
		if (datosOs.getDirctr() != null) {
			xml.append(datosOs.getDirctr());
		} else {
			xml.append("");
		}
		xml.append("</direccion>");

		return xml.toString();
	}

	/**
	 * Obtiene los datos generales del documento sin consultar a la BBDD.
	 * 
	 * pId String folderNumber String HashMap<String, String>
	 * 
	 * @param pId
	 *            the id
	 * @param folderNumber
	 *            the folder number
	 * @return the datos
	 */
	private static HashMap<String, String> getDatos(String pId,
			String folderNumber) {
		String folderNumberAux = folderNumber;
		String mascara = Utilities.getInstance().getDateMask();
		SimpleDateFormat sdf = new SimpleDateFormat(mascara);
		String fechaObtencion = sdf.format(new java.util.Date());
		String campoDia = fechaObtencion.substring(0, ConstantesNum.NUM_2);
		String campoMes = fechaObtencion.substring(ConstantesNum.NUM_3,
				ConstantesNum.NUM_5);
		String campoAnio = fechaObtencion.substring(ConstantesNum.NUM_6,
				ConstantesNum.NUM_10);
		String tipoDocumento = "";
		String tipoDocumentoEusk = "";
		String provincia = "";

		folderNumberAux = folderNumberAux.replaceAll("/", "-");

		StringTokenizer token = new StringTokenizer(folderNumberAux, "-");
		if (token.hasMoreTokens()) {
			provincia = (String) token.nextToken();
		}
		String provCast = "";
		String lugarCast = "";
		String provEusk = "";
		String lugarEusk = "";
		if ("01".equals(provincia) || "1".equals(provincia)) {
			provCast = "Alava";
			provEusk = "Araba";
			lugarCast = "Vitoria-Gasteiz";
			lugarEusk = "Vitoria-Gasteizen";
		} else if ("48".equals(provincia)) {
			provCast = "Bizkaia";
			provEusk = "Bizkaia";
			lugarCast = "Bilbao";
			lugarEusk = "Bilbon";
		} else if ("20".equals(provincia)) {
			provCast = "Gipuzkoa";
			provEusk = "Gipuzkoa";
			lugarCast = "San Sebastián";
			lugarEusk = "Donostian";
		}

		String mes = "";
		String mesEusk = "";
		switch (Integer.parseInt(campoMes)) {
		case 1: {
			mesEusk = "Urtarrila";
			mes = "Enero";
		}
			break;
		case ConstantesNum.NUM_2: {
			mesEusk = "Otsaila";
			mes = "Febrero";
		}
			break;
		case ConstantesNum.NUM_3: {
			mesEusk = "Martxoa";
			mes = "Marzo";
		}
			break;
		case ConstantesNum.NUM_4: {
			mesEusk = "Apirila";
			mes = "Abril";
		}
			break;
		case ConstantesNum.NUM_5: {
			mesEusk = "Maiatza";
			mes = "Mayo";
		}
			break;
		case ConstantesNum.NUM_6: {
			mesEusk = "Ekaina";
			mes = "Junio";
		}
			break;
		case ConstantesNum.NUM_7: {
			mesEusk = "Uztaila";
			mes = "Julio";
		}
			break;
		case ConstantesNum.NUM_8: {
			mesEusk = "Abuztua";
			mes = "Agosto";
		}
			break;
		case ConstantesNum.NUM_9: {
			mesEusk = "Iraila";
			mes = "Septiembre";
		}
			break;
		case ConstantesNum.NUM_10: {
			mesEusk = "Urria";
			mes = "Octubre";
		}
			break;
		case ConstantesNum.NUM_11: {
			mesEusk = "Azaroa";
			mes = "Noviembre";
		}
			break;
		case ConstantesNum.NUM_12: {
			mesEusk = "Abendua";
			mes = "Diciembre";
		}
			break;
		default: {
			break;
		}
		}

		if (pId.equals(ConstantesDocumentos.APERTURA_CENTRO)) {
			tipoDocumento = ConstantesDocumentos.TIPO_APERTURAS;
			tipoDocumentoEusk = ConstantesDocumentos.TIPO_APERTURAS_EU;
		} else if (pId.equals(ConstantesDocumentos.COMUNICACION_OS2)) {
			tipoDocumento = ConstantesDocumentos.TIPO_COMUNICACION_OS2;
			tipoDocumentoEusk = ConstantesDocumentos.TIPO_COMUNICACION_OS2_EU;
		} else if (pId.equals(ConstantesDocumentos.COMUNICACION_OS3)) {
			tipoDocumento = ConstantesDocumentos.TIPO_COMUNICACION_OS3;
			tipoDocumentoEusk = ConstantesDocumentos.TIPO_COMUNICACION_OS3_EU;
		}

		HashMap<String, String> datosMap = new HashMap<String, String>();
		datosMap.put("campoAnio", campoAnio);
		datosMap.put("mesEu", mesEusk);
		datosMap.put("mes", mes);
		datosMap.put("campoDia", campoDia);
		datosMap.put("tipoDocumento", tipoDocumento);
		datosMap.put("tipoDocumentoEusk", tipoDocumentoEusk);
		datosMap.put("provCast", provCast);
		datosMap.put("provEusk", provEusk);
		datosMap.put("lugarCast", lugarCast);
		datosMap.put("lugarEusk", lugarEusk);

		return datosMap;
	}

	/**
	 * Obtiene los motivos en Castellano dependiendo del tipo de documento de la
	 * BBDD.
	 * 
	 * motivosSub List tipoProc String HashMap<String, String>
	 * 
	 * @param motivosSub
	 *            the motivos sub
	 * @param tipoProc
	 *            the tipo proc
	 * @return the array list
	 */
	private ArrayList<String> obtenerMotivosEs(List motivosSub,
			String tipoProc) {
		ArrayList<String> motivosEs = null;
		if (motivosSub != null && motivosSub.size() > 0) {
			motivosEs = new ArrayList<String>();
			for (int i = 0; i < motivosSub.size(); i++) {
				if (tipoProc.equals(ConstantesDocumentos.APERTURA_CENTRO)) {
					String codMotivo = ((VmotivosSubsanacionExp) motivosSub
							.get(i)).getCodmotivo();
					int codM = Integer.parseInt(codMotivo);
					if (codM >= 0 && codM < ConstantesNum.NUM_400) {
						motivosEs.add(
								((VmotivosSubsanacionExp) motivosSub.get(i))
										.getDescripcionEs());
					}
				} else if (tipoProc
						.equals(ConstantesDocumentos.COMUNICACION_OS2)) {
					String codMotivo = ((VmotivosSubsanacionExpOs2) motivosSub
							.get(i)).getCodmotivo();
					int codM = Integer.parseInt(codMotivo);
					if (codM >= 0 && codM < ConstantesNum.NUM_400) {
						motivosEs.add(
								((VmotivosSubsanacionExpOs2) motivosSub.get(i))
										.getDescripcionEs());
					} else if (codM == ConstantesNum.NUM_500) {
						motivosEs.add(
								(((VmotivosSubsanacionExpOs2) motivosSub.get(i))
										.getDescOtrosEs() != null)
												? ((VmotivosSubsanacionExpOs2) motivosSub
														.get(i)).getDescOtrosEs()
												: "");
					}
				} else if (tipoProc
						.equals(ConstantesDocumentos.COMUNICACION_OS3)) {
					String codMotivo = ((VmotivosSubsanacionExpOs3) motivosSub
							.get(i)).getCodmotivo();
					int codM = Integer.parseInt(codMotivo);
					if (codM >= 0 && codM < ConstantesNum.NUM_400) {
						motivosEs.add(
								((VmotivosSubsanacionExpOs3) motivosSub.get(i))
										.getDescripcionEs());
					} else if (codM == ConstantesNum.NUM_500) {
						motivosEs.add(
								(((VmotivosSubsanacionExpOs3) motivosSub.get(i))
										.getDescOtrosEs() != null)
												? ((VmotivosSubsanacionExpOs3) motivosSub
														.get(i)).getDescOtrosEs()
												: "");
					}
				}
			}

		}

		return motivosEs;
	}

	/**
	 * Obtiene los motivos en Euskera dependiendo del tipo de documento de la
	 * BBDD.
	 * 
	 * motivosSub List tipoProc String HashMap<String, String>
	 * 
	 * @param motivosSub
	 *            the motivos sub
	 * @param tipoProc
	 *            the tipo proc
	 * @return the array list
	 */
	private ArrayList<String> obtenerMotivosEu(List motivosSub,
			String tipoProc) {
		ArrayList<String> motivosEu = new ArrayList<String>();
		if (motivosSub != null && motivosSub.size() > 0) {
			for (int i = 0; i < motivosSub.size(); i++) {
				if (tipoProc.equals(ConstantesDocumentos.APERTURA_CENTRO)) {
					String codMotivo = ((VmotivosSubsanacionExp) motivosSub
							.get(i)).getCodmotivo();
					int codM = Integer.parseInt(codMotivo);
					if (codM >= 0 && codM < ConstantesNum.NUM_400) {
						motivosEu.add(
								((VmotivosSubsanacionExp) motivosSub.get(i))
										.getDescripcionEus());
					}
				} else if (tipoProc
						.equals(ConstantesDocumentos.COMUNICACION_OS2)) {
					String codMotivo = ((VmotivosSubsanacionExpOs2) motivosSub
							.get(i)).getCodmotivo();
					int codM = Integer.parseInt(codMotivo);
					if (codM >= 0 && codM < ConstantesNum.NUM_400) {
						motivosEu.add(
								((VmotivosSubsanacionExpOs2) motivosSub.get(i))
										.getDescripcionEus());
					} else if (codM == ConstantesNum.NUM_500) {
						motivosEu.add(
								(((VmotivosSubsanacionExpOs2) motivosSub.get(i))
										.getDescOtrosEu() != null)
												? ((VmotivosSubsanacionExpOs2) motivosSub
														.get(i)).getDescOtrosEu()
												: "");
					}
				} else if (tipoProc
						.equals(ConstantesDocumentos.COMUNICACION_OS3)) {
					String codMotivo = ((VmotivosSubsanacionExpOs3) motivosSub
							.get(i)).getCodmotivo();
					int codM = Integer.parseInt(codMotivo);
					if (codM >= 0 && codM < ConstantesNum.NUM_400) {
						motivosEu.add(
								((VmotivosSubsanacionExpOs3) motivosSub.get(i))
										.getDescripcionEus());
					} else if (codM == ConstantesNum.NUM_500) {
						motivosEu.add(
								(((VmotivosSubsanacionExpOs3) motivosSub.get(i))
										.getDescOtrosEu() != null)
												? ((VmotivosSubsanacionExpOs3) motivosSub
														.get(i)).getDescOtrosEu()
												: "");
					}
				}
			}

		}

		return motivosEu;
	}

	/**
	 * Obtiene los apartados para el documento de Apertura desde la BBDD.
	 * 
	 * motivosSub List<VmotivosSubsanacionExp> HashMap<Character, String[]>
	 * 
	 * @param motivosSub
	 *            the motivos sub
	 * @return the hash map
	 */
	private HashMap<Character, String[]> obtenerApartados(
			List<VmotivosSubsanacionExp> motivosSub) {
		HashMap<Character, String[]> apartados = new HashMap<Character, String[]>();
		String[] descB = null;
		String[] descC = null;
		String[] descD = null;
		String[] descE = null;
		String[] descF = null;
		String[] descG = null;
		String[] descH = null;
		String[] descJ = null;
		String[] descK = null;
		apartados.put('B', descB);
		apartados.put('C', descC);
		apartados.put('D', descD);
		apartados.put('E', descE);
		apartados.put('F', descF);
		apartados.put('G', descG);
		apartados.put('H', descH);
		apartados.put('J', descJ);
		apartados.put('K', descK);

		if (motivosSub != null && motivosSub.size() > 0) {
			for (VmotivosSubsanacionExp motivo : motivosSub) {
				int codMotivo = Integer.parseInt(motivo.getCodmotivo());
				switch (codMotivo) {
				case ConstantesNum.NUM_400:
					descB = new String[ConstantesNum.NUM_2];
					descB[0] = motivo.getDescripcionEs();
					descB[1] = motivo.getDescripcionEus();
					apartados.put('B', descB);
					break;
				case ConstantesNum.NUM_401:
					descC = new String[ConstantesNum.NUM_2];
					descC[0] = motivo.getDescripcionEs();
					descC[1] = motivo.getDescripcionEus();
					apartados.put('C', descC);
					break;
				case ConstantesNum.NUM_402:
					descD = new String[ConstantesNum.NUM_2];
					descD[0] = motivo.getDescripcionEs();
					descD[1] = motivo.getDescripcionEus();
					apartados.put('D', descD);
					break;
				case ConstantesNum.NUM_403:
					descE = new String[ConstantesNum.NUM_2];
					descE[0] = motivo.getDescripcionEs();
					descE[1] = motivo.getDescripcionEus();
					apartados.put('E', descE);
					break;
				case ConstantesNum.NUM_404:
					descF = new String[ConstantesNum.NUM_2];
					descF[0] = motivo.getDescripcionEs();
					descF[1] = motivo.getDescripcionEus();
					apartados.put('F', descF);
					break;
				case ConstantesNum.NUM_405:
					descG = new String[ConstantesNum.NUM_2];
					descG[0] = motivo.getDescripcionEs();
					descG[1] = motivo.getDescripcionEus();
					apartados.put('G', descG);
					break;
				case ConstantesNum.NUM_406:
					descH = new String[ConstantesNum.NUM_2];
					descH[0] = motivo.getDescripcionEs();
					descH[1] = motivo.getDescripcionEus();
					apartados.put('H', descH);
					break;
				case ConstantesNum.NUM_500:
					descJ = new String[1];
					descJ[0] = motivo.getDescOtrosEs() == null ? ""
							: motivo.getDescOtrosEs();
					apartados.put('J', descJ);
					descK = new String[1];
					descK[0] = motivo.getDescOtrosEu() == null ? ""
							: motivo.getDescOtrosEu();
					apartados.put('K', descK);
					break;
				default:
					break;
				}

			}

		}
		return apartados;
	}
}
