package com.fitbank.web.uci; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import com.fitbank.common.FileHelper; import com.fitbank.common.helper.XMLParser; import com.fitbank.dto.GeneralResponse; import com.fitbank.dto.management.Criterion; import com.fitbank.dto.management.Detail; import com.fitbank.dto.management.Field; import com.fitbank.dto.management.Record; import com.fitbank.dto.management.Table; import com.fitbank.uci.client.UCIClient; import com.fitbank.util.Debug; import com.fitbank.web.data.PedidoWeb; import com.fitbank.web.data.RespuestaWeb; import com.fitbank.web.exceptions.ErrorWeb; import com.fitbank.web.procesos.Registro; import com.fitbank.web.providers.HardDiskWebPageProvider; import com.fitbank.web.servlets.Procesador; import com.fitbank.web.uci.db.TransporteDBUCI; import com.fitbank.webpages.WebPageEnviroment; public class EnlaceUCI { public RespuestaWeb procesar(PedidoWeb pedido) { TransporteDBUCI tdbuci = (TransporteDBUCI) pedido.getTransporteDB(); Detail detail = tdbuci.getDetail(); this.copiarEjecutadoPor(detail); if (WebPageEnviroment.getDebug()) { detail.findFieldByNameCreate("__DEBUG__").setValue("true"); } else { detail.removeField("__DEBUG__"); } tdbuci.save(); Registro.getRegistro().salvarDatosEntrada(pedido.getTransporteDB()); String mode = StringUtils.defaultIfEmpty(Procesador.getMode(), ""); if ("save".equals(mode)) { save(tdbuci); } TransporteDBUCI datosRespuesta; if ("replay".equals(mode)) { datosRespuesta = new TransporteDBUCI(load(detail)); } else { datosRespuesta = new TransporteDBUCI(fix(UCIClient.send(detail))); if ("save".equals(mode)) { save(detail, datosRespuesta); } } Registro.getRegistro().salvarDatosSalida(datosRespuesta); RespuestaWeb respuesta = new RespuestaWeb(datosRespuesta, pedido); respuesta.setTipoPedido(pedido.getTipoPedido()); this.limpiarEjecutadoPor(detail); this.limpiarEjecutadoPor(((TransporteDBUCI) respuesta.getTransporteDB()).getDetail()); return respuesta; } /** * En caso de que venga un Detail sin alias en campos asumir que son campos * de la tabla principal. * * @param detail Detail a ser procesado * * @return el mismo Detail despues de ser procesado */ private Detail fix(Detail detail) { GeneralResponse res = detail.getResponse(); if (res != null && res.getUserMessage() != null) { String code = res.getCode() + ": "; String mes = res.getUserMessage(); if (mes.startsWith(code)) { mes = mes.substring(code.length()); } if (res.getUserMessage().endsWith(" <*>")) { mes = mes.substring(0, mes.length() - 4); } res.setUserMessage(mes); } if (Conversor.JOIN_PROCESS_TYPE.equals(detail.getProcessType())) { for (Table table : detail.getTables()) { table.addMissing(); } } return detail; } private void save(TransporteDBUCI tdbuci) { save(tdbuci.toString(), tdbuci.getDetail(), "entrada"); } private void save(Detail detail, TransporteDBUCI datosRespuesta) { save(datosRespuesta.toString(), detail, "salida"); } private void save(String xml, Detail detail, String var) { File path = new File(HardDiskWebPageProvider.getPath( detail.getSubsystem(), detail.getTransaction(), "test.d")); path.mkdirs(); File file = new File(path, getSignature(detail) + "-" + var + ".xml"); try { IOUtils.write(xml, new FileOutputStream(file), "UTF-8"); } catch (Exception ex) { Debug.error(ex); } } private Detail load(Detail detail) { File path = new File(HardDiskWebPageProvider.getPath( detail.getSubsystem(), detail.getTransaction(), "test.d")); path.mkdirs(); File file = new File(path, getSignature(detail) + "-salida.xml"); try { String data = FileHelper.readStream(new FileInputStream(file)); return new Detail(new XMLParser(data)); } catch (Exception e) { throw new ErrorWeb("No se encontró el detail correspondiente", e); } } /** * Obtiene una firma del detail única para poder identificarlo. * * @param detail * @return */ private String getSignature(Detail detail) { int hash = 0; int i = 0; for (Table table : detail.getTables()) { // Tomar el alias, registro actual y página de la tabla para el cálculo hash += hash(table.getAlias()); hash += hash(table.getCurrentRecord()); hash += hash(table.getPageNumber()); hash += 1 << i++; for (Criterion criterion : table.getCriteria()) { // Tomar alias y nombre del criterio hash += hash(criterion.getAlias()); hash += hash(criterion.getName()); hash += hash(criterion.getValue()); hash += hash(criterion.getOrder()); hash += 1 << i++; } for (Record record : table.getRecords()) { // Tomar el número de registro hash += hash(record.getNumber()); hash += 1 << i++; for (Field field : record.getFields()) { // Tomar el alias y nombre del campo hash += hash(field.getAlias()); hash += hash(field.getName()); hash += hash(field.getFunctionName()); hash += hash(field.getValue()); hash += 1 << i++; } } } for (Field field : detail.getFields()) { // Tomar el alias y nombre del campo hash += hash(field.getName()); hash += hash(field.getValue()); hash += 1 << i++; } return String.format("%s%s-%s-%s", detail.getSubsystem(), detail. getTransaction(), detail.getType(), hash); } public int hash(Object o) { if (o == null) { return 0; } else { return o.hashCode(); } } /** * Asigna el valor de ejecutadoPor al detail basado en un campo de control * * @param detail */ private void copiarEjecutadoPor(Detail detail) { detail.setExecutedBy(detail.findFieldByNameCreate("EJECUTADOPOR") .getStringValue()); } private void limpiarEjecutadoPor(Detail detail) { detail.setExecutedBy("F"); detail.findFieldByNameCreate("EJECUTADOPOR").setValue("F"); } }