/******************************************************************************* * Copyright (c) 2013-2015 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: * MEDEVIT <office@medevit.at> - initial API and implementation ******************************************************************************/ package at.medevit.ch.artikelstamm; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.math.BigInteger; import java.net.MalformedURLException; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; import at.medevit.ch.artikelstamm.ARTIKELSTAMM.ITEMS.ITEM; import at.medevit.ch.artikelstamm.ArtikelstammConstants.TYPE; public class ArtikelstammHelper { private static Logger log = LoggerFactory.getLogger(ArtikelstammHelper.class); public static String PHARMA_XSD_LOCATION = "Elexis_Artikelstamm_v4.xsd"; private static URL schemaLocationUrl = null; private static SchemaFactory schemaFactory = SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); static DateFormat dateFormat = new SimpleDateFormat("ddMMyy"); public static DateFormat monthAndYearWritten = new SimpleDateFormat("MMM yyyy"); static { try { schemaLocationUrl = new URL("platform:/plugin/at.medevit.ch.artikelstamm/lib/" + PHARMA_XSD_LOCATION); } catch (MalformedURLException e) { log.error("Error resolving Artikelstamm schema", e); } } /** * * @param year * the creation year of the dataset * @param month * the creation month of the dataset (jan = 1, dec = 12) * @return the cummulated version number */ public static int getCummulatedVersionNumber(int year, int month){ return ((year - 2013) * 12) + month; } /** * @param cumulatedVersionNo * @return the date value represented by the given cumulatedVersionNo */ public static Date getDateFromCumulatedVersionNumber(int cumulatedVersionNo){ int year = 2013 + (cumulatedVersionNo / 12); int month = (cumulatedVersionNo % 12) - 1; return new GregorianCalendar(year, month, 1).getTime(); } /** * The deterministic id of an {@link ArtikelstammItem} item. Fixed length 25 chars. Assembled as * follows:<br> * <li>Characters 0-13: GTIN, if gtin less 14 chars, left padded with zeros <li>Characters * 14-20: Pharmacode, if Pharmacode less 7 chars, left padded with zeros <li>Character 21: P or * N, depending on {@link ArtikelstammConstants.TYPE} <li>Character 22-24: cummulatedVersion, if * >9999 or <0 set to 0 <br> * * @param cummulatedVersion * @param type * @param gtin * @param phar * @return deterministic uuid of an {@link ARTIKELSTAMM} item */ public static String createUUID(int version, String gtin, BigInteger phar){ return createUUID(version, gtin, phar, true); } /** * For importer usage, for regular usage see {@link #createUUID(int, TYPE, String, BigInteger)} * * @param version * @param gtin * @param phar * @param includeVersion * include the version number of the dataset * @return deterministic uuid of an {@link ARTIKELSTAMM} item */ public static String createUUID(int version, String gtin, BigInteger phar, final boolean includeVersion){ StringBuilder sb = new StringBuilder(); if (gtin.length() > 0) { sb.append(String.format("%014d", Long.parseLong(gtin))); } else { sb.append("00000000000000"); } if (phar != null) { sb.append(String.format("%07d", phar)); } else { sb.append("0000000"); } if (version > 9999 || version < 0) version = 0; if (includeVersion) sb.append(String.format("%04d", version)); return sb.toString(); } public static ARTIKELSTAMM unmarshallInputStream(InputStream xmlFileIs) throws JAXBException, SAXException{ Unmarshaller u = JAXBContext.newInstance(ARTIKELSTAMM.class).createUnmarshaller(); Schema schema = schemaFactory.newSchema(schemaLocationUrl); u.setSchema(schema); return (ARTIKELSTAMM) u.unmarshal(xmlFileIs); } /** * * @param xmlFile * @return {@link ARTIKELSTAMM} * @throws JAXBException * @throws SAXException * @throws FileNotFoundException */ public static ARTIKELSTAMM unmarshallFile(File xmlFile) throws JAXBException, SAXException, FileNotFoundException{ return unmarshallInputStream(new FileInputStream(xmlFile)); } public static void marshallToFileSystem(Object newData, File outputFile) throws SAXException, JAXBException{ // Schema validationSchema = schemaFactory.newSchema(schemaLocationUrl); Marshaller m = JAXBContext.newInstance(ARTIKELSTAMM.class).createMarshaller(); // m.setSchema(validationSchema); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); m.marshal(newData, outputFile); } /** * Determine an output file for a given input dataset and filename, use this to maintain * consistent output file names. Output file is in the same directory as input file * * @param converted * @param inboundFileObj * @param string * @return */ public static File determineOutputFileName(ARTIKELSTAMM converted, File inboundFileObj, String string){ Date outputDate = converted.getCREATIONDATETIME().toGregorianCalendar().getTime(); String filename; if (string != null) { filename = "artikelstamm_" + dateFormat.format(outputDate) + "_" + string + ".xml"; } else { filename = "artikelstamm_" + dateFormat.format(outputDate) + ".xml"; } return new File(inboundFileObj.getParent(), filename); } private static HashMap<String, ITEM> itemPharmacodeCache = null; /** * WARNING do not change parameter artikelstamm after first calling of this method, cache will * not be re-initialized! * * @param artikelstamm * @param pharmacode * @return the {@link ITEM} or <code>null</code> if not found */ // public static ITEM getItemInListByPharmacode(ARTIKELSTAMM.ITEMS artikelstamm, String pharmacode){ // if (itemPharmacodeCache == null) { // if (artikelstamm.getTYPE().equals(ArtikelstammConstants.TYPE.N)) // throw new IllegalArgumentException("Trying to enrich Non-Pharma artikelstamm data"); // // itemPharmacodeCache = new HashMap<String, ITEM>(artikelstamm.getITEM().size()); // for (ITEM item : artikelstamm.getITEM()) { // itemPharmacodeCache.put(item.getPHAR().toString(), item); // } // } // if (itemPharmacodeCache.containsKey(pharmacode)) // return itemPharmacodeCache.get(pharmacode); // return null; // } private static HashMap<String, ITEM> itemGTINCache = null; /** * WARNING do not change parameter artikelstamm after first calling of this method, cache will * not be re-initialized! * * @param artikelstamm * @param gtin * @return */ public static ITEM getItemInListByGTIN(ARTIKELSTAMM.ITEMS artikelstamm, String gtin){ if (itemGTINCache == null) { itemGTINCache = new HashMap<String, ITEM>(artikelstamm.getITEM().size()); for (ITEM item : artikelstamm.getITEM()) { itemGTINCache.put(item.getGTIN(), item); } } if (itemGTINCache.containsKey(gtin)) { System.out.println("[INFO] Resolved over GTIN " + gtin); return itemGTINCache.get(gtin); } return null; } /** * Returns the SwissmedicNo8 if the article is registered by GTIN for Switzerland ("76") and * Swissmedic ("80"). * * @param item * @return an 8-char-length string with the SwissmedicNo8, if not applicable <code>null</code> */ public String getSwissmedicNo8ForArtikelstammItem(ARTIKELSTAMM.ITEMS.ITEM item){ String gtin = item.getGTIN(); if (gtin != null && gtin.startsWith("7680")) return gtin.substring(4, 12); return null; } }