394 lines
17 KiB
JavaScript
394 lines
17 KiB
JavaScript
// ******************************************
|
||
// * $Id$
|
||
// *
|
||
// * UserException()
|
||
// * RaiseAnError()
|
||
// * TestAndRaiseAnXMLError()
|
||
// * SafeLoadTextXML()
|
||
// * SafeLoadFileXSL()
|
||
// * XML2HTML()
|
||
// * fetchXMLContent()
|
||
// * mergeXMLAttachments()
|
||
// * Hexify()
|
||
// *
|
||
// * XML en XSL functies.
|
||
// *
|
||
// ******************************************
|
||
//
|
||
function UserException(number, source, message)
|
||
{
|
||
this.number = number;
|
||
this.source = source;
|
||
this.description = message;
|
||
}
|
||
|
||
function RaiseAnError(e, p)
|
||
{
|
||
throw new UserException(e + 1000, "UserException", p);
|
||
}
|
||
|
||
function TestAndRaiseAnXMLError(p, iXml, xmltext) // xmltext is optional for error logging
|
||
{
|
||
if (iXml.parseError.errorCode != 0)
|
||
{
|
||
if (xmltext)
|
||
LogString2File(1, "Failed_XML", xmltext, "xml");
|
||
RaiseAnError( iXml.parseError.errorCode
|
||
, p + "\n" + iXml.parseError.reason
|
||
+ " regel " + iXml.parseError.line
|
||
+ "(" + iXml.parseError.filepos + ")"
|
||
);
|
||
}
|
||
}
|
||
|
||
function SafeLoadTextXML(xmlText)
|
||
{
|
||
var iXml = new ActiveXObject("Msxml2.DOMDocument.6.0");
|
||
iXml.async = false;
|
||
iXml.loadXML(xmlText);
|
||
TestAndRaiseAnXMLError("Error in xmlData", iXml);
|
||
|
||
return iXml;
|
||
}
|
||
|
||
function SafeLoadFileXSL(xslPath)
|
||
{
|
||
var iXsl = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.6.0"); // Moet FreeThreaded voor XSLTemplate
|
||
iXsl.async = false;
|
||
iXsl.setProperty("AllowXsltScript", true);
|
||
iXsl.load(custabspath + "/" + xslPath);
|
||
iXsl.resolveExternals = true; // anders SOAP problemen om de template functie te vinden
|
||
TestAndRaiseAnXMLError("Error loading file " + xslPath, iXsl);
|
||
|
||
return iXsl;
|
||
}
|
||
|
||
// Vergelijk shared.inc versie
|
||
var protectQS =
|
||
{
|
||
create: function (url, params)
|
||
{
|
||
var splitter = url.split("?");
|
||
var pad = splitter[0];
|
||
var qs = splitter.length>1?splitter[1]:"x=x";
|
||
var padsplitter = pad.split("/");
|
||
var file = padsplitter[padsplitter.length-1]; // laatste component
|
||
// Let op dat protectQS.wsc hetzelfde doet voor Facmgt
|
||
var str = file.toUpperCase() + "?" + qs;
|
||
|
||
//var hmacced = protectHMAC.create(data, params);
|
||
var ts = String(Math.round((new Date).getTime() / 1000));
|
||
var data = ts + ":" + str
|
||
Log2File(2, "hmacdata: " + data);
|
||
//__Log("sleutel: "+ params.sleutel);
|
||
var oCrypto = new ActiveXObject("SLNKDWF.Crypto");
|
||
var sig = oCrypto.hex_hmac_sha1(params.sleutel, data);
|
||
var hmac = oCrypto.hex2base64(sig, false, true); // no padding, urlsafe
|
||
oCrypto = null; // Caching klinkt leuk maar Oracle sessies blijven langer hangen?
|
||
var hmacced = ts+":"+hmac;
|
||
|
||
var newurl = pad + "?" + qs + "&hmac="+encodeURIComponent(hmacced);
|
||
|
||
return newurl;
|
||
|
||
}
|
||
}
|
||
|
||
function XML2HTML( xmlDoc
|
||
, xslPath
|
||
, srtnotificatie
|
||
, mode
|
||
, p_bedrijfadres
|
||
)
|
||
{
|
||
// Transform body=xml according to xslPath=xslfilenaam with optionel srtnotification parameter (e.g. RESBEV)
|
||
// Output is supposed to be a HTML string but really depends on the XSL content
|
||
var xslt = new ActiveXObject("Msxml2.XSLTemplate.6.0");
|
||
var xslProc;
|
||
|
||
var xslDoc = SafeLoadFileXSL(xslPath);
|
||
var result = "";
|
||
|
||
xslDoc.resolveExternals = true; // anders op de volgende regel al:
|
||
// A reference to variable or parameter 'srtnotificatiecode' cannot be resolved
|
||
xslt.stylesheet = xslDoc;
|
||
|
||
var xslProc = xslt.createProcessor();
|
||
xslProc.input = xmlDoc;
|
||
xslProc.addParameter("srtnotificatiecode", srtnotificatie);
|
||
xslProc.addParameter("mode", mode);
|
||
xslProc.transform();
|
||
result = xslProc.output;
|
||
|
||
// Let op: dezelfde code in xml_converter.inc
|
||
// eerst lockeduser(xmlnode,key,bedrijf_key) vervangen
|
||
// lockeduser(opdracht,12345,910) met 12345 opdracht_key en 910 bedrijf_key
|
||
var hmacs = result && result.match(/(lockeduser\([^\)]*\))/g); // heeft nu array van lockeduser(opdracht,12345,910)
|
||
for (var i =0; hmacs && i < hmacs.length; i++)
|
||
{
|
||
var params = hmacs[i].match(/\(([^,]+)\,(\d+),(\d+)\)/);
|
||
if (!params)
|
||
throw { description: "lockeduser is used in xsl but empty opdracht_key or bedrijf_key" };
|
||
if (params.length == 4)
|
||
{
|
||
var xmlnode = params[1]; // We ondersteunen alleen nog maar 'opdracht'
|
||
var key = parseInt(params[2], 10);
|
||
var bedrijf_key = parseInt(params[3], 10);
|
||
// Let op: we pakken altijd het eerste bedrijfadres
|
||
var sql = "SELECT prs_bedrijfadres_key,"
|
||
+ " prs_bedrijfadres_locksecret"
|
||
+ " FROM prs_bedrijfadres"
|
||
+ " WHERE prs_bedrijf_key = " + bedrijf_key
|
||
+ " AND prs_bedrijfadres_locksecret IS NOT NULL"
|
||
+ " AND prs_bedrijfadres_lockuser_key IS NOT NULL";
|
||
var oRs = Oracle.Execute(sql);
|
||
if (oRs.Eof)
|
||
{ // Ergens in de bon staat
|
||
// <xsl:attribute name="href">https://aqqa.facilitor.nl/lockeduser(opdracht,<xsl:value-of select="key"/>,
|
||
// <xsl:value-of select="uitvoerende/bedrijf/key"/>)</xsl:attribute>
|
||
// maar bij de leverancier is geen 'Vaste gebruiker' en 'Gedeeld geheim' ingevuld
|
||
throw { description: "lockeduser is used in xsl but missing prs_bedrijfadres_locksecret/prs_bedrijfadres_lockuser_key" };
|
||
}
|
||
var bdradr_key = oRs("prs_bedrijfadres_key").Value;
|
||
var locksecret = oRs("prs_bedrijfadres_locksecret").Value;
|
||
oRs.Close();
|
||
var url = "?u={0}&k={1}&lbdr={2}".format(xmlnode, key, bdradr_key);
|
||
var newurl = protectQS.create(url, { sleutel: locksecret, no_user_key: true });
|
||
|
||
result = result.replace(hmacs[i], newurl);
|
||
}
|
||
}
|
||
|
||
// Let op: dezelfde code in xml_converter.inc
|
||
// nu fclttoegang(xmlnode,key) vervangen
|
||
// xmlnode mag zijn 'reservering', 'afspraak' of 'opdracht' zonder de quotes
|
||
// fclttoegang(reservering,12345) geeft toegang tot rsv_ruimte_key 12345 (wat niet reservering 12345/1 hoeft te zijn)
|
||
var hmacs = result && result.match(/(fclttoegang\([^\)]*\))/g); // heeft nu array van fclttoegang(reservering,12345)
|
||
for (var i =0; hmacs && i < hmacs.length; i++)
|
||
{
|
||
var params = hmacs[i].match(/\(([^,]+)\,(\d+)\)/);
|
||
if (!params)
|
||
throw { description: "fclttoegang is used in xsl but empty xmlnode or key" };
|
||
if (params.length == 3)
|
||
{
|
||
var xmlnode = params[1]; // We ondersteunen alleen nog maar 'opdracht'
|
||
var key = parseInt(params[2], 10);
|
||
// Let op: zoek de laagste fac_tracking_key als (onderdeel van) de 'sleutel'
|
||
var sql = "SELECT MIN(fac_tracking_key) fac_tracking_key,"
|
||
+ " MIN(fac_tracking_datum) fac_tracking_datum"
|
||
+ " FROM fac_tracking ft, fac_srtnotificatie fsn"
|
||
+ " WHERE ft.fac_srtnotificatie_key = fsn.fac_srtnotificatie_key"
|
||
+ " AND fac_srtnotificatie_xmlnode = " + safe.quoted_sql(xmlnode)
|
||
+ " AND fac_tracking_refkey = " + key;
|
||
var oRs = Oracle.Execute(sql);
|
||
if (oRs.Eof)
|
||
{ // Ergens in de bon staat zo'n fclttoegang maar geen tracking gevonden?
|
||
throw { description: "fclttoegang is used in xsl but no tracking found for " + xmlnode + "/" + key};
|
||
}
|
||
var locksecret = String(oRs("fac_tracking_key").Value) + "|" + toDateTimeString(new Date(oRs("fac_tracking_datum").Value));
|
||
oRs.Close();
|
||
var url = "?u=toegang&k={1}&xmlnode={0}".format(xmlnode, key);
|
||
var newurl = protectQS.create(url, { sleutel: locksecret, no_user_key: true });
|
||
|
||
result = result.replace(hmacs[i], newurl);
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
// Resultaat is een xmlDoc object of null bij errors
|
||
// <20><>n niveau van caching, is efficienter als 13 keer dezelfde MLD2BO
|
||
var prev_XMLContent = {};
|
||
function fetchXMLContent( node
|
||
, refkey
|
||
, xrefkey
|
||
, where
|
||
, userlang
|
||
)
|
||
{
|
||
if (prev_XMLContent.node == node &&
|
||
prev_XMLContent.refkey == refkey &&
|
||
prev_XMLContent.xrefkey == xrefkey &&
|
||
prev_XMLContent.where == where &&
|
||
prev_XMLContent.userlang == userlang)
|
||
{
|
||
Log2File(2, "Re-using cached xmlDoc");
|
||
return prev_XMLContent.xmlDoc;
|
||
}
|
||
var xml_content = "";
|
||
|
||
try
|
||
{
|
||
// we geven de gewenste taal mee aan de Oracle sessie, die dat verder zal gebruiken
|
||
var sql = "BEGIN lcl.setuserlanguage (" + safe.quoted_sql(userlang) + "); END;"
|
||
Log2File(3, sql);
|
||
Oracle.Execute(sql);
|
||
//
|
||
var sql_params = safe.quoted_sql(node)
|
||
+ ", " + refkey
|
||
+ ", " + safe.quoted_sql(customerId)
|
||
+ ", '$PutOrdersSession$'"
|
||
+ ", " + (xrefkey > 0? xrefkey: "NULL")
|
||
+ ", " + safe.quoted_sql(where);
|
||
|
||
var sql = "SELECT xml.make_xml2(" + sql_params + ") xml_blob, sys_context('USERENV','SID') mysid FROM dual";
|
||
Log2File(typeof PUO_LOGPATH == "undefined"?2:1, sql);
|
||
var tmstart = new Date();
|
||
var oRs = Oracle.Execute(sql);
|
||
var tmend = new Date();
|
||
var xml_content = oRs("xml_blob").Value||"";
|
||
var mysid = oRs("mysid").Value||"";
|
||
oRs.Close();
|
||
Oracle.Execute("BEGIN DBMS_SESSION.free_unused_user_memory; END;");
|
||
if (xml_content)
|
||
Log2File(typeof PUO_LOGPATH == "undefined"?2:1, "XML blob is {0} karakters in {1}ms for SID {2}.".format(xml_content.length, tmend.getTime() - tmstart.getTime(), mysid));
|
||
else
|
||
Log2File(1, "XML blob is leeg. Verwijderd record?");
|
||
}
|
||
catch(e)
|
||
{
|
||
Log2File(0, "fetchXMLContent error: " + e.description, "W");
|
||
xml_content = "";
|
||
}
|
||
finally
|
||
{
|
||
LogString2File(3, "make_xml", xml_content, "xml");
|
||
}
|
||
var xmlDoc = xml_content?SafeLoadTextXML(xml_content):null;
|
||
|
||
prev_XMLContent.node = node;
|
||
prev_XMLContent.refkey = refkey;
|
||
prev_XMLContent.xrefkey = xrefkey;
|
||
prev_XMLContent.where = where;
|
||
prev_XMLContent.userlang = userlang;
|
||
prev_XMLContent.xmlDoc = xmlDoc;
|
||
|
||
return xmlDoc;
|
||
}
|
||
|
||
|
||
function mergeXMLAttachments(iXml, p_xslPath)
|
||
{
|
||
mergeXMLAttachments2(iXml, p_xslPath, "//FCLTmeldingattachment", "meldingkey", "M");
|
||
mergeXMLAttachments2(iXml, p_xslPath, "//FCLTopdrachtattachment", "opdrachtkey", "O");
|
||
}
|
||
|
||
function mergeXMLAttachments2(iXml, p_xslPath, xmltag, keynaam, pNiveau)
|
||
{
|
||
// Doorzoek iXml op <!FCLTmeldingattachment>345</FCLTmeldingattachment>
|
||
// en vervang die door alle flexkenmerken er onder
|
||
// <Iattachements> <-- nodename = Iattachements
|
||
// <attachment>...hexdata...</attachtment>
|
||
// <name>naam</name>
|
||
// <size>1235</size>
|
||
// </Iattachments>
|
||
var NodeList = iXml.documentElement.selectNodes(xmltag);
|
||
if (NodeList.length > 0)
|
||
{
|
||
Log2File(2, "*> mergeXMLAttachments");
|
||
|
||
for (var index=0; index < NodeList.length; index++)
|
||
{
|
||
var node = NodeList[index];
|
||
var meldingopdrachtkey = trimall(node.attributes.getNamedItem(keynaam).text);
|
||
var kenmerkkey = trimall(node.attributes.getNamedItem("kenmerkkey").text);
|
||
var bijlagekey = node.attributes.getNamedItem("bijlagekey")?trimall(node.attributes.getNamedItem("bijlagekey").text):"";
|
||
var nodename = trimall(node.attributes.getNamedItem("nodename").text);
|
||
var node_encoding = node.attributes.getNamedItem("encoding"); // als die NIET is gevuld doen we default "hex"
|
||
var encoding = "hex";
|
||
if (node_encoding){
|
||
encoding = trimall(node_encoding.text);
|
||
}
|
||
var node_templatenodename = node.attributes.getNamedItem("templatenodename"); // als die is gevuld doen we een post-parse met de stylesheet
|
||
var templatenodename = '';
|
||
if (node_templatenodename){
|
||
templatenodename = trimall(node_templatenodename.text);
|
||
}
|
||
Log2File(1, "Searching attachments {0}{1} kenmerk {2}".format(pNiveau, meldingopdrachtkey, kenmerkkey));
|
||
var att_list = [];
|
||
var sql = "SELECT r.fac_bijlagen_disk_directory"
|
||
+ " , r.fac_bijlagen_filename"
|
||
+ " , r.fac_bijlagen_file_size"
|
||
+ " FROM fac_bijlagen r"
|
||
+ " , fac_bijlagen b"
|
||
+ " WHERE b.fac_bijlagen_root_key = r.fac_bijlagen_key"
|
||
+ " AND b.fac_bijlagen_verwijder IS NULL"
|
||
+ " AND r.fac_bijlagen_verwijder IS NULL"
|
||
+ " AND b.fac_bijlagen_module = 'MLD'"
|
||
+ " AND b.fac_bijlagen_refkey = " + meldingopdrachtkey
|
||
+ (kenmerkkey ? " AND b.fac_bijlagen_kenmerk_key = " + kenmerkkey : "")
|
||
+ (bijlagekey ? " AND b.fac_bijlagen_key = " + bijlagekey : "");
|
||
var oRs = Oracle.Execute(sql);
|
||
while (!oRs.eof)
|
||
{
|
||
att_list.push( { f_disk: oRs("fac_bijlagen_disk_directory").Value
|
||
, f_name: oRs("fac_bijlagen_filename").Value
|
||
, f_size: oRs("fac_bijlagen_file_size").Value
|
||
, f_path: S("flexfilespath") + "/" + oRs("fac_bijlagen_disk_directory").Value + "/" + oRs("fac_bijlagen_filename").Value
|
||
}
|
||
);
|
||
oRs.MoveNext();
|
||
}
|
||
oRs.Close();
|
||
for (a=0; a< att_list.length; a++)
|
||
{
|
||
Log2File(1, "Embedding attachment: " + att_list[a].f_path + " (" + att_list[a].f_size + " bytes)");
|
||
// en hier de rest voor het invoegen van de bijlagen.
|
||
var elemAttachments = iXml.createElement(nodename);
|
||
var elemAtt = iXml.createElement("attachment");
|
||
switch (encoding)
|
||
{
|
||
case "hex": elemAtt.text = Hexify(att_list[a].f_path);
|
||
break;
|
||
case "base64": elemAtt.text = Base64fy(att_list[a].f_path);
|
||
break;
|
||
}
|
||
Log2File(1, "{0} encoded it becomes {1} bytes".format(encoding, elemAtt.text.length));
|
||
elemAttachments.appendChild(elemAtt);
|
||
elemAtt = iXml.createElement("encoding");
|
||
elemAtt.text = encoding;
|
||
elemAttachments.appendChild(elemAtt);
|
||
elemAtt = iXml.createElement("name");
|
||
elemAtt.text = att_list[a].f_name;
|
||
elemAttachments.appendChild(elemAtt);
|
||
elemAtt = iXml.createElement("size");
|
||
elemAtt.text = att_list[a].f_size;
|
||
elemAttachments.appendChild(elemAtt);
|
||
|
||
if (templatenodename != '') // post processing met de stylesheet
|
||
{
|
||
var elemWrapper = iXml.createElement(templatenodename);
|
||
elemWrapper.appendChild(elemAttachments);
|
||
var tmp_xmlDoc = SafeLoadTextXML(elemWrapper.xml);
|
||
LogString2File(3, "PostProces", tmp_xmlDoc.xml, "xml");
|
||
var tmp_xmlResult = XML2HTML( tmp_xmlDoc
|
||
, p_xslPath
|
||
, ""
|
||
, "processattachments"
|
||
);
|
||
var tmp_xmlDoc = SafeLoadTextXML(tmp_xmlResult);
|
||
LogString2File(3, "PostProcesAttach", tmp_xmlResult, "xml");
|
||
|
||
var NodeList2 = tmp_xmlDoc.documentElement.childNodes;
|
||
for (var i=0; i < NodeList2.length; i++)
|
||
{
|
||
var tmp_node = NodeList2[i];
|
||
//Let op: niet appendChild gebruikt, want die voegt achteraan toe aan de parentnode, waardoor de volgorde wordt aangepast.
|
||
//Door gebruikt van insertBefore blijft de volgorde intact, die wezenlijk voor Validatie tegen XSD (van externe partijen) kan zijn!
|
||
node.parentNode.insertBefore(tmp_node, node);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
node.parentNode.appendChild(elemAttachments);
|
||
}
|
||
}
|
||
node.parentNode.removeChild(node); // dummy fcltattachments weg
|
||
}
|
||
Log2File(2, "*< mergeXMLAttachments");
|
||
}
|
||
return iXml;
|
||
}
|