You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
456 lines
14 KiB
456 lines
14 KiB
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<String> newOrUpdatedObjects = new HashSet<String>(); |
|
private Set<String> deletedObjects = new HashSet<String>(); |
|
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 = "<EX_FMHISV> \n" + |
|
" <item> \n" + |
|
" <MANDT></MANDT> \n" + |
|
" <FIKRS></FIKRS> \n" + |
|
" <HIVARNT>000</HIVARNT> \n" + |
|
" <FISTL></FISTL> \n" + |
|
" <HIROOT_ST></HIROOT_ST> \n" + |
|
" <PARENT_ST/> \n" + |
|
" <NEXT_ST/> \n" + |
|
" <CHILD_ST/> \n" + |
|
" <HILEVEL>0001</HILEVEL> \n" + |
|
" </item> \n" + |
|
" </EX_FMHISV>"; |
|
|
|
|
|
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("<newdata>\n"); |
|
BufferedWriter bfwjest=null; |
|
if (isJestWanted()) |
|
{ |
|
bfwjest= Files.newBufferedWriter(fjest.toPath()); |
|
bfwjest.write("<newdata>\n"); |
|
} |
|
|
|
|
|
int i = 0; |
|
int rownr=0; |
|
System.out.println(DateUtils.getTodayString() + " " |
|
+ DateUtils.getNowString()); |
|
String reply=null,replyjest=null; |
|
for (Iterator<String> 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("<EX_CSKB/>")>-1) |
|
continue; |
|
if (reply.indexOf("<MESSAGE>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("<TYPE>I</TYPE>") == -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, "<Envelope","<Envelope rownr=\""+rownr+"\" "); |
|
reply = nachbearbeiten(reply); |
|
bfw.write(reply); |
|
if (isJestWanted()) |
|
{ |
|
|
|
replyjest=purge(replyjest,"RETURN"); |
|
replyjest=nachbearbeiten(replyjest); |
|
bfwjest.write(replyjest); |
|
} |
|
} |
|
System.out.println(""); |
|
bfw.write("\n</newdata>\n"); |
|
bfw.close(); |
|
|
|
if (isJestWanted()) |
|
{ |
|
bfwjest.write("\n</newdata>\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("<Envelope>",""); |
|
replyjest=replyjest.replaceAll("<Header>",""); |
|
replyjest=replyjest.replaceAll("</Header>",""); |
|
replyjest=StringUtils.replace(replyjest, "<Header/>", ""); |
|
replyjest=replyjest.replaceAll("</Envelope>",""); |
|
replyjest=replyjest.replaceAll("<SOAP:Body>",""); |
|
replyjest=replyjest.replaceAll("</SOAP:Body>",""); |
|
replyjest=replyjest.replaceAll("<response>",""); |
|
replyjest=replyjest.replaceAll("</response>",""); |
|
|
|
replyjest=purge(replyjest,"EX_PROJ"); |
|
replyjest=purge(replyjest,"EX_PRPS"); |
|
replyjest=purge(replyjest,"EX_PRHI"); |
|
replyjest=StringUtils.replace(replyjest,"<EX_JEST>", ""); |
|
replyjest=StringUtils.replace(replyjest,"<EX_JEST/>", ""); |
|
replyjest=StringUtils.replace(replyjest,"</EX_JEST>", ""); |
|
replyjest=replyjest.replaceAll("<item>","<item>\n<POSID>"+objectId+"</POSID>\n"); |
|
//replyjest=replyjest.replaceAll("</item>","</EX_JEST>"); |
|
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, "<EX_FMHISV/>", 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<String> 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 <RETURN> <item> |
|
* <TYPE>I</TYPE> 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; |
|
} |
|
|
|
} |