package de.superx.bin; import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.logging.Level; import javax.xml.transform.TransformerException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.SAXException; import de.memtext.util.DateUtils; import de.memtext.util.GetOpts; import de.memtext.util.GetOpts.Options; import de.memtext.util.LogUtils; import de.memtext.util.StringUtils; import de.memtext.util.XMLUtils; public class WebserviceClient extends AbstractWebserviceClient{ private boolean isDebug = false; private boolean isDBConnectionPossible = true; private Document document; private Set newOrUpdatedObjects = new HashSet(); private Set deletedObjects = new HashSet(); private String dbpropfile; private String objectClass, hsnr; private String changesURL, changesSOAP; private String xmlConfig; private String detailURL; private String detailSOAP, replaceNodeName; private String xsl, outfile; private String stammdatenstart=null; private boolean isDeleteTmpXmlFileWanted = true; private static final String FISTL_HIERARCHIE_INFO = " \n" + " \n" + " \n" + " \n" + " 000 \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " 0001 \n" + " \n" + " "; public static void main(String args[]) { System.out.println("SuperX-WebserviceClient Version 1.4 (2025-02-25)"); WebserviceClient tc = new WebserviceClient(); tc.run(args); } public WebserviceClient() { } public void run(String args[]) { try { initLogging(); GetOpts.setOpts(args); String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_dbprops, Options.opt_xmlconfig, Options.opt_xsl, Options.opt_hsnr, Options.opt_out}); if (isdrin != null) { System.err.println("Folgende Optionen fehlen: " + isdrin); // System.err.println(usage); System.exit(1); } readConfig(); readChanges(); if (isReplyOk()) { readObjectIdSets(); if (isDBConnectionPossible) toDeletedObjectsTable(); writeChangeXml(); } else { String msg = "Error: Aufruf von Webservice für " + xmlConfig + " fehlgeschlagen"; System.out.println(msg); logger.severe(msg); LogUtils.close("wc"); System.exit(-1); } } catch (Exception e) { logger.severe(e.getMessage()); System.out.println("Error " + e.getMessage()); e.printStackTrace(); LogUtils.close("wc"); System.exit(1); } finally { LogUtils.close("wc"); } } private void readChanges() throws Exception { String soapString = StringUtils.replace(changesSOAP, "XXOBJECT_CLASSXX", objectClass); String startDatum = getStartDatum(); logger.log(Level.INFO, "Startdatum " + startDatum); System.out.println("Startdatum " + startDatum); soapString = StringUtils.replace(soapString, "XXSTARTDATEXX", startDatum); soapString = StringUtils.replace(soapString, "XXTODAYXX", new java.sql.Date(new java.util.Date().getTime()).toString()); logger.fine("SOAP Aufruf:\n" + soapString); String result= readSOAP(soapString, changesURL).toString(); document = XMLUtils.buildDocumentFromString(result, false); logger.finest("Geaenderte Objekte Klasse " + objectClass); } private void readConfig() throws IOException, SAXException { dbpropfile = GetOpts.getValue(Options.opt_dbprops); xmlConfig = GetOpts.getValue(Options.opt_xmlconfig); outfile = GetOpts.getValue(Options.opt_out); xsl = GetOpts.getValue(Options.opt_xsl); hsnr = GetOpts.getValue(Options.opt_hsnr); System.out.println("\n" + DateUtils.getTodayString() + " " + DateUtils.getNowString() + "\nHochschulnummer " + hsnr); logger.info("\nHochschulnummer " + hsnr); if (GetOpts.isPresent(Options.opt_noDelete)) isDeleteTmpXmlFileWanted = false; if (GetOpts.isPresent(Options.opt_pause)) { String p = GetOpts.getValue(Options.opt_pause); pause = Integer.parseInt(p); System.out.println("Pause between soap calls " + pause); } logger.log(Level.INFO, "Verarbeite " + xmlConfig); System.out.println("Verarbeite " + xmlConfig); Document dconf = XMLUtils.buildDocument(new File(xmlConfig)); Node n = XMLUtils.getFirstNode(dconf, "webservice"); objectClass = XMLUtils.getAttribValue(n, "object_class"); n = XMLUtils.getFirstNode(dconf, "changesurl"); changesURL = XMLUtils.getTheValue(n); changesURL=adaptURL(changesURL); n = XMLUtils.getFirstNode(dconf, "changessoap"); changesSOAP = XMLUtils.getTheValue(n); changesSOAP = StringUtils.replace(changesSOAP, "XXOBJECTICLASSXX", objectClass); n = XMLUtils.getFirstNode(dconf, "detailurl"); detailURL = XMLUtils.getTheValue(n); detailURL=adaptURL(detailURL); n = XMLUtils.getFirstNode(dconf, "detailsoap"); detailSOAP = XMLUtils.getTheValue(n); n = XMLUtils.getFirstNode(dconf, "replacenode"); replaceNodeName = XMLUtils.getAttribValue(n, "from"); } private void readObjectIdSets() { Node changehead = XMLUtils.getFirstNode(document, "CHANGEHEAD"); Iterator it = (Iterator) XMLUtils.getChildNodeIterator(changehead); int i = 1; while (it.hasNext()) { Node item = (Node) it.next(); String objectid = XMLUtils.getChildNodeValue(item, "OBJECTID"); String change_ind = XMLUtils.getChildNodeValue(item, "CHANGE_IND"); if (change_ind != null && change_ind.equals("D")) deletedObjects.add(objectid); else newOrUpdatedObjects.add(objectid); i++; } System.out.println("Zu loeschen " + deletedObjects.size() + " neu/geaendert " + newOrUpdatedObjects.size()); logger.info("Anzahl zu loeschender Objekte " + deletedObjects.size()); logger.info("Anzahl zu neuer/geaenderter Objekte " + newOrUpdatedObjects.size()); } private boolean isJestWanted() { return objectClass.equals("PRPS"); } private void writeChangeXml() throws Exception { File f = File.createTempFile("webservicedata", ".xml"); File fjest=null; if (isJestWanted()) fjest=File.createTempFile("webservicedatajest",".xml"); if (!isDeleteTmpXmlFileWanted) { System.out.println("Temp Datei: " + f.getAbsolutePath()); logger.info("Temp Datei: " + f.getAbsolutePath()); if (isJestWanted()) { System.out.println("Temp Datei: " + fjest.getAbsolutePath()); logger.info("Temp Datei: " + fjest.getAbsolutePath()); } } if (f.exists()) f.delete(); if (fjest!=null&&fjest.exists()) fjest.delete(); BufferedWriter bfw= Files.newBufferedWriter(f.toPath()); bfw.write("\n"); BufferedWriter bfwjest=null; if (isJestWanted()) { bfwjest= Files.newBufferedWriter(fjest.toPath()); bfwjest.write("\n"); } int i = 0; int rownr=0; System.out.println(DateUtils.getTodayString() + " " + DateUtils.getNowString()); String reply=null,replyjest=null; for (Iterator it = newOrUpdatedObjects.iterator(); it.hasNext();) { String objectId = it.next(); //für Debugging Tests //if (objectId.indexOf("0000131400")==-1) continue; // Hier wird Detailrequest aufgerufen reply = getSoapDetailRequest(objectId, i); i++; if (i % 10 == 0) System.out.print(i + " "); //bei nicht vollstaendig angelegten Kostenarten ueberspringen if (objectClass.equals("KSTAR")&&reply.indexOf("")>-1) continue; if (reply.indexOf("Es wurden 0000")>-1) continue; //bei Finanzstellen ggfs. fehlende Hierarchieinformation durch Dummy ersetzen if (objectClass.equals("FMFCTR")) reply=patchMissingFistlHierarchieInfo(reply); if (isJestWanted()) { replyjest = adaptJestData(reply, objectId); } rownr++; if (!isDebug && reply.indexOf("I") == -1) { System.out.println("Fehler bei Lesen von Object " + objectId); System.out.println(reply); bfw.close(); if (f.exists()) f.delete(); if (isJestWanted()) { bfwjest.close();if (fjest.exists()) fjest.delete();}; System.exit(-1); } //Nachbearbeitung reply=StringUtils.replace(reply, "\n"); bfw.close(); if (isJestWanted()) { bfwjest.write("\n\n"); bfwjest.close(); } transformXmlToCSV(f, fjest); if (isDeleteTmpXmlFileWanted) {f.delete(); if (isJestWanted()) fjest.delete(); } System.out.println(" fertig: " + DateUtils.getTodayString() + " " + DateUtils.getNowString()); } private void transformXmlToCSV(File f, File fjest) throws TransformerException, Exception { SxTransformer sxTrans = new SxTransformer(logger, outfile); sxTrans.quellstring = f.getAbsolutePath(); sxTrans.stylesheet = xsl; sxTrans.params = "ignoreElements=EX_JEST"; sxTrans.transformFile("text"); if (isJestWanted()) { sxTrans = new SxTransformer(logger, StringUtils.replace(outfile,".","jest.")); sxTrans.quellstring = fjest.getAbsolutePath(); String xsljest=""; if (objectClass.equals("PRPS")) xsljest=StringUtils.replace(xsl, "soap_to_csv.xsl", "psp_jest.xsl"); sxTrans.stylesheet = xsljest; sxTrans.params = ""; sxTrans.transformFile("text"); } } private String adaptJestData(String reply, String objectId) { String replyjest; replyjest=purge(reply,false); replyjest=replyjest.replaceAll("",""); replyjest=replyjest.replaceAll("
",""); replyjest=replyjest.replaceAll("
",""); replyjest=StringUtils.replace(replyjest, "
", ""); replyjest=replyjest.replaceAll("",""); replyjest=replyjest.replaceAll("",""); replyjest=replyjest.replaceAll("",""); replyjest=replyjest.replaceAll("",""); replyjest=replyjest.replaceAll("",""); replyjest=purge(replyjest,"EX_PROJ"); replyjest=purge(replyjest,"EX_PRPS"); replyjest=purge(replyjest,"EX_PRHI"); replyjest=StringUtils.replace(replyjest,"", ""); replyjest=StringUtils.replace(replyjest,"", ""); replyjest=StringUtils.replace(replyjest,"", ""); replyjest=replyjest.replaceAll("","\n"+objectId+"\n"); //replyjest=replyjest.replaceAll("",""); return replyjest; } private String nachbearbeiten(String reply) { reply = purge(reply, true); reply=adaptDatePattern(reply); reply=removeXmlHeader(reply); reply=format(reply); return reply; } private String patchMissingFistlHierarchieInfo(String input) { return StringUtils.replace(input, "", FISTL_HIERARCHIE_INFO); } private String getStartDatum() throws Exception { String result = "2000-01-01"; if (isDBConnectionPossible) { SxConnection myConnection = new SxConnection(); myConnection.setPropfile(dbpropfile); Connection con = myConnection.getConnection(); Statement stm = con.createStatement(); ResultSet rs = stm .executeQuery("select datum from systeminfo where tid=170"); while (rs.next()) { Object o = rs.getDate(1); if (o != null) result = o.toString(); } rs.close(); stm.close(); con.close(); } if (System.getProperty("stammdatenstart")!=null) result=System.getProperty("stammdatenstart"); return result; } /** * to gxstage_delete_object Table * * @throws Exception * */ private void toDeletedObjectsTable() throws Exception { SxConnection myConnection = new SxConnection(); myConnection.setPropfile(dbpropfile); Connection con = myConnection.getConnection(); PreparedStatement pst = con .prepareStatement("insert into gxstage_delete_object (object_class,object_id) values (?,?)"); for (Iterator it = deletedObjects.iterator(); it.hasNext();) { String objectId = it.next(); pst.clearParameters(); pst.setString(1, objectClass); pst.setString(2, objectId); pst.execute(); } pst.close(); con.close(); } private String getSoapDetailRequest(String objectid, int i) throws Exception { String idpart1=""; if (objectid.length()>=4) idpart1=objectid.substring(0, 4); String idpart2 =""; if (objectid.length()>=5) idpart2=objectid.substring(4); String idpart3 = ""; if (objectid.length() > 8) idpart3 = objectid.substring(8); String soapxml = de.memtext.util.StringUtils.replace(detailSOAP, "IDPART1", idpart1); soapxml = de.memtext.util.StringUtils.replace(soapxml, "IDPART2", idpart2); soapxml = de.memtext.util.StringUtils.replace(soapxml, "IDPART3", idpart3); soapxml = de.memtext.util.StringUtils.replace(soapxml, "XXOBJECTIDXX", objectid); soapxml = de.memtext.util.StringUtils .replace(soapxml, "XXHSNRXX", hsnr); if (i == 0) logger.finest("1. SOAP Detailaufruf:\n" + soapxml); String res = readSOAP(soapxml, detailURL).toString(); String result = StringUtils.replace(res, replaceNodeName, "response"); return result; } private boolean isReplyOk() { boolean result = false; /** * TODO eigentlich sicherheitshalber gucken unter * I TYPE kommt aber nur einmal vor */ try { Node type = XMLUtils.getFirstNode(document, "TYPE"); if (XMLUtils.getTheValue(type).equals("I")) result = true;} catch (Exception e) { logger.severe("Kein Konten TYPE gefunden mit Value I - Result:\n"); try { logger.severe(XMLUtils.documentToString(document,null)); } catch (Exception ex) { logger.severe("Fehler bei XML Ausgabe "+ex); } } return result; } }