SuperX-Kernmodul
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

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;
}
}