package de.superx.bin; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Iterator; import java.util.Locale; import java.util.StringTokenizer; import java.util.logging.ConsoleHandler; import java.util.logging.LogManager; import java.util.logging.Logger; import javax.servlet.http.HttpServletResponse; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockServletConfig; import de.memtext.baseobjects.coll.NamedIdObjectList; import de.memtext.util.GetOpts; import de.memtext.util.ServletHelper; import de.memtext.util.StringUtils; import de.memtext.util.TimeUtils; import de.memtext.util.TransletUtils; import de.superx.common.FieldContainer; import de.superx.common.Maske; import de.superx.common.SxResultRow; import de.superx.common.SxResultSet; import de.superx.common.SxUser; import de.superx.sec.InputCheckRegistry; import de.superx.servlet.ServletUtils; import de.superx.servlet.SuperXManager; import de.superx.servlet.SxPools; import de.superx.servlet.UserInitializer; import de.superx.servlet.XmlTransformer; import net.sf.jasperreports.engine.JRException; public class ExecuteMask { /** * Kommandozeilen-Interface für Ausführung von Masken und Export des Ergebnis * als Datei * * @param args * @param -logger:Pfad zu logging.properties, normalerweise * $SUPERX_DIR/db/conf * @param -tid:Nummer der Maske * @param -out:Ausgabedatei * @param -user:Benutzerkennung, unter der Maske laufen soll * @param -locale:Locale (optional) * @param -params:Parameter für die Maske, jeweils mit "&" getrennt in * einem String * * Sollte im Arbeitsverzeichnis webapps/superx/WEB-INF laufen * * Beispiele: HTML Druckversion (Default): java * de.superx.bin.ExecuteMask -tid:16000 -out:test.htm -user:admin * "-params:Köpfe oder Fälle ?=1=1&Stichtag=1" * -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties * PDF Datei: java de.superx.bin.ExecuteMask -tid:16000 * -out:test.pdf -user:admin "-params:Köpfe oder Fälle * ?=1=1&Stichtag=1&stylesheet=tabelle_fo_pdf.xsl&contenttype=application/pdf" * -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties * Excel-Datei java de.superx.bin.ExecuteMask -tid:16000 * -out:test.xls -user:admin "-params:Köpfe oder Fälle * ?=1=1&Stichtag=1&stylesheet=tabelle_xls.xsl&contenttype=application/vnd.ms-excel" * -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties */ private static String mandantenID = "default"; private static TimeUtils tutil = new TimeUtils(); private static String myLocale; private static String myParams = ""; private static Object adminUser; private static Integer userid; private static FieldContainer myFieldContainer; private static String myWEBINFFilePath = System.getProperty("user.dir"); private static Logger log; private static String usage = " Kommandozeilen-Interface für Ausführung von Masken und Export des Ergebnis als Datei\n" + " Parameter:\n" + " -logger:Pfad zu logging.properties, normalerweise $SUPERX_DIR/db/conf\n" + " -tid:Nummer der Maske\n" + " -out:Ausgabedatei\n" + " -user:Benutzerkennung, unter der Maske laufen soll\n" + " -locale:Locale (optional)\n" + " -params:Parameter für die Maske, jeweils mit \"&\" getrennt in einem String\n" + " \n" + " Sollte im Arbeitsverzeichnis webapps/superx/WEB-INF laufen\n" + " \n" + " Beispiele:\n" + " HTML Druckversion (Default): \n" + " java de.superx.bin.ExecuteMask -tid:16000 -out:test.htm -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n" + " PDF Datei:\n" + " java de.superx.bin.ExecuteMask -tid:16000 -out:test.pdf -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&stylesheet=tabelle_fo_pdf.xsl&contenttype=application/pdf\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n" + " Excel-Datei\n" + " java de.superx.bin.ExecuteMask -tid:16000 -out:test.xls -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&stylesheet=tabelle_xls.xsl&contenttype=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n" + " java de.superx.bin.ExecuteMask -tid:16000 -out:test.xls -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&stylesheet=tabelle_xls.xsl&contenttype=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n" + " CSV-Datei\n" + " java de.superx.bin.ExecuteMask -tid:16000 -out:test.csv -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&contenttype=test/csv\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n" + " -fopxconf (Pfad dazu - optional)"; static MockHttpServletRequest mock ; static MockHttpServletResponse mockResponse = new MockHttpServletResponse(); static MockServletConfig mockServletConfig = new MockServletConfig(); static SxUser user; private static File fopxconfFile = null; public static void main(String[] args) throws IllegalArgumentException, SecurityException { //SuperXManager.initKettleEnv(); // mock muss neu intialisiert werden, sonst Fehlschläge bei mehreren Aufrufen // von ExecuteMaske in JUnitTest Batterie mittels ant mock = new MockHttpServletRequest(); GetOpts.setOpts(args); String isdrin = GetOpts.isAllRequiredOptionsPresent("-logger,-tid,-out,-user"); if (isdrin != null) { System.err.println(usage); System.exit(1); } String userName = GetOpts.getValue("-user"); String loggingProperties = GetOpts.getValue("-logger"); myWEBINFFilePath= de.superx.util.PathAndFileUtils.getWebinfDirectory(); if (GetOpts.isPresent("-fopxconf")) { fopxconfFile = new File(GetOpts.getOpt("-fopxconf").replaceAll("-fopxconf:", "")); } else { fopxconfFile = new File(myWEBINFFilePath+ File.separator + "conf"+ File.separator +"fop.xconf"); } try { FileInputStream ins; ins = new FileInputStream(loggingProperties); LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); MyLogManager.readConfiguration(ins); log = Logger.getLogger(ExecuteMask.class.getName()); log.addHandler(new ConsoleHandler()); System.out.println("Using Loggging-Level " + log.getLevel()); } catch (FileNotFoundException e2) { System.err.println("Datei " + loggingProperties + " nicht gefunden:" + e2.toString()); System.exit(1); } catch (IOException e) { System.err.println("Datei " + loggingProperties + " kann nicht gelesen werden:" + e.toString()); System.exit(1); } tutil.start(); try { SuperXManager.initKettleEnv(); SxPools.init(); SxPools.get(mandantenID).init(); SxPools.get(mandantenID).initLogging(true); SxPools.resetAllPools(); userid = getUserID(userName, mandantenID); adminUser = getUserAdmin(userName, mandantenID); user = UserInitializer.initUser(mandantenID, userName, userid, adminUser); } catch (Exception e) { log.severe("Fehler beim Aufbau der Connection: " + e.toString()); System.exit(1); } String tidString = GetOpts.getValue("-tid"); String outfile = GetOpts.getValue("-out"); if (GetOpts.isPresent("-locale")) myLocale = GetOpts.getValue("-locale"); else myLocale = de.superx.util.SqlStringUtils.getEncoding(); if (GetOpts.isPresent("-params")) myParams = GetOpts.getValue("-params"); Locale desiredLocale = new Locale(myLocale); SuperXManager.maxRows = 1000000; Maske maske = null; InputCheckRegistry.registerDefaultChecks(); try { maske = new Maske(mandantenID, user, new Integer(tidString), desiredLocale); /*NamedIdObjectList fields = maske.readFelderFromDb(user); myFieldContainer = maske.getIndividualFields(); myFieldContainer.addAll(fields);*/ setParams(mock, myParams); maske.setFieldDefaults(user, mock, true); exportTable(mock, mockResponse, maske, user, outfile, desiredLocale); System.out.println("Datei " + outfile + " für Maske " + tidString + " erzeugt in " + tutil.getSinceStart()); } catch (Exception e) { e.printStackTrace(); log.severe("Fehler beim Ausführen der Maske " + tidString + ": " + e.toString()); System.exit(1); } System.exit(0); } public static HttpServletResponse getHttpResponse() { return mockResponse; } /** * Ermittelt die user-id aus dem Login-Namen * * * @param userName Login Kennung * @param mandantenID_par Mandanten-ID * @return userID */ private static Integer getUserID(String userName, String mandantenID_par) { String query = "select tid from userinfo where benutzer='" + userName + "';"; Integer userID = null; SxResultSet rs = null; try { rs = ServletUtils.execute("Ermittle ID für " + userName, query, mandantenID_par); } catch (Exception e) { log.severe("Fehler beim Ermitteln der ID für " + userName + ": " + e.toString()); } for (Iterator it = rs.iterator(); it.hasNext();) { SxResultRow row = it.next(); userID = (Integer) row.get(0); } if (userID == null) { System.err.println("User " + userName + "unbekannt"); System.exit(1); } return userID; } /** * Ermittelt, ob ein user Admin-Rechte hat * * * @param userName Login Kennung * @param mandantenID_par Mandanten-ID * @return admin ("1" oder "0") */ private static String getUserAdmin(String userName, String mandantenID_par) { String query = "select administration from userinfo where benutzer='" + userName + "';"; String admin = null; SxResultSet rs = null; try { rs = ServletUtils.execute("Ermittle Admin-Flag für " + userName, query, mandantenID_par); } catch (Exception e) { log.severe("Fehler beim Ermitteln der Admin-Rechte für " + userName + ": " + e.toString()); } if (rs == null) { return admin; } for (Iterator it = rs.iterator(); it.hasNext();) { SxResultRow row = it.next(); admin = row.get(0).toString(); } return admin; } /** * Überführt einen String mit Parametern ("&"-getrennt) ins request Objekt) * * * @param mock Request Objekt * @param paramsString String mit Parametern (Achtung: Umlaute und Sonderzeichen * nicht encodiert) * */ private static void setParams(MockHttpServletRequest mock, String paramsString) { StringTokenizer st = new StringTokenizer(paramsString, "&"); for (; st.hasMoreTokens();) { String paramString = st.nextToken(); String paramName = paramString.substring(0, paramString.indexOf("=")); String paramVal = paramString.substring(paramString.indexOf("=") + 1); mock.addParameter(paramName, paramVal); //System.out.println(paramName+"-"+paramVal); } } /** * Führt eine Maske aus und speichert das Ergebnis in einer Datei * * * @param mock_par Request Objekt * @param maske Masken-Objekt * @param user_par User-Objekt * @param outfile Name Ausgabedatei * @param desiredLocale Locale für Ausgabedatei * */ private static void exportTable(MockHttpServletRequest mock_par, MockHttpServletResponse mockResponse_par, Maske maske, SxUser user_par, String outfile, Locale desiredLocale) { String currentXml_local = null; String method = "html"; String stylesheet = ServletHelper.getParameter(mock_par, "stylesheet"); // Default ist html Druckversion: if (stylesheet == null || stylesheet.equals("")) stylesheet = "tabelle_html_p.xsl"; log.info("Stylesheet " + stylesheet + " wird genutzt"); String contenttype = ServletHelper.getParameter(mock_par, "contenttype"); // Default ist html: if (contenttype == null || contenttype.equals("")) contenttype = "text/html"; if (contenttype.indexOf("pdf") > -1) method = "pdf"; if (contenttype.indexOf("xml") > -1) method = "xml"; if (contenttype.indexOf("excel") > -1) method = "xls"; // if // (contenttype.indexOf("vnd.openxmlformats-officedocument.spreadsheetml.sheet") // > -1) method = "xlsx"; log.info("Contenttype " + contenttype + " wird erzeugt"); maske.setMaxOffset(10000000); maske.setReuseResult(false); maske.resetTableStylesheet(); maske.setSelectedTableStylesheetFileAndContenttype(stylesheet); maske.setDesiredContenttype(contenttype); log.info("Start Maskengenerierung"); try { currentXml_local = maske.runQuery(user_par, mock_par, null).toString(); System.out.println("Ausgabe Maskenprotokoll\n" + SuperXManager.activityLog.toString()); log.info("Maskenergebnis wird lokalisiert"); currentXml_local = SxPools.get(mandantenID).localize(currentXml_local, desiredLocale); } catch (Exception e) { log.severe("Fehler beim Erstellen des XML für Maske " + e.toString()); } String ausgabedatei = ""; if (stylesheet.equals("tabelle_xml.xsl")) ausgabedatei = writeTextFile(currentXml_local, outfile); else if (contenttype.equals("text/csv")) try { ausgabedatei = writeTextFile(maske.getCSV(mandantenID).toString(), outfile); } catch (IOException e) { System.out.println("Fehler beim Erstellen der datei " + outfile); e.printStackTrace(); } else { ausgabedatei = writeTextFile(currentXml_local, null); if (stylesheet.endsWith(".jrxml")) exportJR(mock_par, mockResponse_par, maske, user_par, outfile, stylesheet, contenttype, mandantenID, myWEBINFFilePath + "/reports/", currentXml_local); else transformFile(maske, ausgabedatei, stylesheet, contenttype, outfile, mockResponse_par, method); } log.info("Datei " + ausgabedatei + " erzeugt"); } private static void exportJR(MockHttpServletRequest mock_par, MockHttpServletResponse mockResponse_par, Maske maske, SxUser user_par, String outfile, String stylesheet, String contentType, String mandantenID_par, String reports_dir, String currentXml_par) { if ((currentXml_par.indexOf("Insgesamt 0 Sätze gefunden") < 1 // im Makro immer ausführen: || currentXml_par.indexOf("ergebnis ordnr=\"1\"") > -1) && currentXml_par.indexOf("Zeilen liegen über max. Grenze") < 1) { try { de.superx.servlet.JasperCreator jc = new de.superx.servlet.JasperCreator(mock_par, mockResponse_par, user_par, maske, stylesheet, contentType, reports_dir); if (maske.getSelectedTableStylesheetFilename().indexOf("_xmlsource") > -1) { jc.perform(mandantenID_par, currentXml_par, outfile); } else { jc.perform(mandantenID_par, maske, outfile); } } catch (JRException | IOException e) { log.severe("Fehler bei JasperReport-Erzeugung " + e.toString()); } } else log.info("Keine Daten für JR verfügbar"); } /** * Erzeugt Text-Datei, bei temp. Datei wird der absolute Pfad zurückgegeben * * * @param content Inhalt der Text-Datei * @param filename Name Ausgabedatei * @return targetfilename Aboluter Pfad zur Datei, die erzeugt wurde */ private static String writeTextFile(String content, String filename) { String targetfilename = ""; try { File temp = File.createTempFile("tabelle", ".xml"); FileWriter f1 = new FileWriter(temp); f1.write(content); f1.flush(); f1.close(); targetfilename = temp.getAbsolutePath(); Path tmpPath = Paths.get(targetfilename); if (filename != null) { Path destPath = Paths.get(filename); Path resultPath = Files.move(tmpPath, destPath, StandardCopyOption.REPLACE_EXISTING); targetfilename = resultPath.toString(); // dest.getAbsolutePath(); } } catch (IOException e) { log.severe("Fehler beim Erstellen der Datei " + filename + " " + e.toString()); } return targetfilename; } /** * Erzeugt Excel- oder PDF aus XML-Datei * * * @param xmlfile Pfad zur XML-Datei * @param stylesheet Pfad zur XSL-Datei * @param contenttype MIME Type * @param filename Name Ausgabedatei * */ private static void transformFile(Maske maske, String xmlfile, String stylesheet, String contenttype, String filename, MockHttpServletResponse mockResponse_par, String method) { TransletUtils.initFactory("net.sf.saxon.TransformerFactoryImpl", null); String stylesheetPath = myWEBINFFilePath + File.separator + ".." + File.separator + "xml" + File.separator + stylesheet; if (method.equals("xls")) { try { XmlTransformer xt = new XmlTransformer(mockServletConfig, mock, mockResponse_par, null, null); xt.setMandantenID(mandantenID); xt.setMaske(maske); String xml = StringUtils.readFile(new File(xmlfile)); if (contenttype.indexOf("excel") > -1) { if (maske.isNewExcelExport()) { xml = XmlTransformer.stripXml(xml); } xt.createExcelStandalone(xml, stylesheetPath, filename); log.info("Datei " + filename + " erzeugt"); } } catch (Exception e) { log.severe("Fehler bei der Transformation:"); e.printStackTrace(); } } else { SxTransformer myTransformer = new SxTransformer(log); try { myTransformer.quellstring = xmlfile; myTransformer.stylesheet = stylesheetPath; myTransformer.outfile = filename; if (fopxconfFile != null) myTransformer.setFopxconfFile(fopxconfFile); myTransformer.transformFile(method); } catch (Exception e) { log.severe("Fehler bei der Transformation:"); e.printStackTrace(); } } } public static String getMyWEBINFFilePath() { return myWEBINFFilePath; } public static void setMyWEBINFFilePath(String myWEBINFFilePath) { ExecuteMask.myWEBINFFilePath = myWEBINFFilePath; } public static String getMandantenID() { return mandantenID; } public static void setMandantenID(String mandantenID) { ExecuteMask.mandantenID = mandantenID; } }