/******************************************************************************* * Copyright (c) 2014 MEDEVIT. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * T. Huster - initial API and implementation ******************************************************************************/ package ch.elexis.labortarif2009.data; import java.io.UnsupportedEncodingException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.elexis.core.exceptions.PersistenceException; import ch.elexis.data.Leistungsblock; import ch.elexis.data.PersistentObject; import ch.elexis.data.Query; import ch.rgw.compress.CompEx; import ch.rgw.tools.ExHandler; import ch.rgw.tools.JdbcLink; import ch.rgw.tools.JdbcLink.Stm; import ch.rgw.tools.TimeTool; public class EALBlocksCodeUpdater { private static final Logger logger = LoggerFactory.getLogger(EALBlocksCodeUpdater.class); private JdbcLink pj; protected static abstract class AbstractTarifResolver { abstract protected PersistentObject getTarif(String code, TimeTool date); } protected static class DefaultTarifResolver extends AbstractTarifResolver { @Override protected PersistentObject getTarif(String code, TimeTool date){ return Labor2009Tarif.getFromCode(code, date); } } protected static class AnalysenUpdateTarifResolver extends AbstractTarifResolver { @Override protected PersistentObject getTarif(String code, TimeTool date){ // look for .01 updated Tarif first if (code.endsWith(".00")) { String updateCode = code.substring(0, code.indexOf('.')); updateCode = updateCode + ".01"; Labor2009Tarif updateTarif = Labor2009Tarif.getFromCode(updateCode, date); if (updateTarif != null) { return updateTarif; } } return Labor2009Tarif.getFromCode(code, date); } } protected static class AnalysenOnlyTarifResolver extends AbstractTarifResolver { @Override protected PersistentObject getTarif(String code, TimeTool date){ // look for .01 updated Tarif first if (code.endsWith(".00")) { String updateCode = code.substring(0, code.indexOf('.')); updateCode = updateCode + ".01"; Labor2009Tarif updateTarif = Labor2009Tarif.getFromCode(updateCode, date); return updateTarif; } return null; } } public String updateBlockCodesAnalysen() { return updateBlocks(Labor2009Tarif.class.getName(), new AnalysenUpdateTarifResolver()); } /** * Update the codes in Blocks to valid Labor2009Tarif for today. * * @return a String containing a description of what was done */ public String updateBlockCodes(){ return updateBlocks(Labor2009Tarif.class.getName(), new DefaultTarifResolver()); } private String updateBlocks(String clazzName, AbstractTarifResolver resolver){ int absoluteCnt = 0; HashSet<String> problems = new HashSet<String>(); TimeTool today = new TimeTool(); pj = PersistentObject.getConnection(); try { Query<Leistungsblock> lQuery = new Query<Leistungsblock>(Leistungsblock.class); List<Leistungsblock> blocks = lQuery.execute(); for (Leistungsblock block : blocks) { StringBuilder newCodes = new StringBuilder(); // get blob byte[] compressed = getBinaryRaw(Leistungsblock.FLD_LEISTUNGEN, Leistungsblock.TABLENAME, block.getId()); if (compressed != null) { // get String representing all contained leistungen String storable = new String(CompEx.expand(compressed), "UTF-8"); //$NON-NLS-1$ // rebuild a String containing all updated leistungen for (String p : storable.split(",")) { if (p != null && !p.isEmpty()) { String[] parts = p.split("::"); if (parts[0].equals(clazzName)) { String code = getCodeFromId(parts[1]); PersistentObject leistung = resolver.getTarif(code, today); if (leistung != null) { absoluteCnt++; // add new string if (newCodes.length() > 0) newCodes.append(","); newCodes.append(leistung.storeToString()); } else { problems.add(block.getName() + " -> " + code); // set string old string if (newCodes.length() > 0) newCodes.append(","); newCodes.append(p); } } else { if (newCodes.length() > 0) newCodes.append(","); newCodes.append(p); } } } // write the updated String back setBinaryRaw(Leistungsblock.FLD_LEISTUNGEN, Leistungsblock.TABLENAME, block.getId(), CompEx.Compress(newCodes.toString(), CompEx.ZIP)); } } } catch (UnsupportedEncodingException e) { logger.error("Could not update " + clazzName + " in blocks." + e); } ArrayList<String> problemsList = new ArrayList<String>(problems); Collections.sort(problemsList); StringBuilder problemsString = new StringBuilder(); for (String string : problemsList) { problemsString.append("- ").append(string).append("\n"); } return absoluteCnt + " EAL codes angepasst.\nIn folgenden Blöcken sind noch fehlerhafte Leistungen\n" + problemsString.toString(); } /** * Get code by removing date * * @param string * @return */ private String getCodeFromId(String string){ Labor2009Tarif tarif = Labor2009Tarif.load(string); if (tarif != null && tarif.exists()) { return tarif.getCode(); } return ""; } /** * Copy of method from PersistentObject to get access to a binary field * * @param field * @return */ private byte[] getBinaryRaw(final String field, String tablename, String id){ StringBuilder sql = new StringBuilder(); sql.append("SELECT ").append(field).append(" FROM ").append(tablename) .append(" WHERE ID='").append(id).append("'"); Stm stm = null; try { stm = pj.getStatement(); ResultSet res = stm.query(sql.toString()); if ((res != null) && (res.next() == true)) { return res.getBytes(field); } } catch (Exception ex) { logger.error("Could not update Tarmed in blocks." + ex); } finally { if (stm != null) { pj.releaseStatement(stm); } } return null; } /** * Copy of method from PersistentObject to get access to a binary field * * @param field * @return */ private void setBinaryRaw(final String field, String tablename, String id, final byte[] value){ StringBuilder sql = new StringBuilder(1000); sql.append("UPDATE ").append(tablename).append(" SET ").append((field)).append("=?") .append(" WHERE ID='").append(id).append("'"); String cmd = sql.toString(); PreparedStatement stm = pj.prepareStatement(cmd); try { stm.setBytes(1, value); stm.executeUpdate(); } catch (Exception ex) { ex.printStackTrace(); ExHandler.handle(ex); } finally { try { stm.close(); } catch (SQLException e) { logger.error("Could not update Tarmed in blocks." + e); throw new PersistenceException("Could not close statement " + e.getMessage()); } } } }