3 ** pz2.js - pazpar2's javascript client library.
6 //since explorer is flawed
8 window.Node = new Object();
10 Node.ATTRIBUTE_NODE = 2;
12 Node.CDATA_SECTION_NODE = 4;
13 Node.ENTITY_REFERENCE_NODE = 5;
15 Node.PROCESSING_INSTRUCTION_NODE = 7;
16 Node.COMMENT_NODE = 8;
17 Node.DOCUMENT_NODE = 9;
18 Node.DOCUMENT_TYPE_NODE = 10;
19 Node.DOCUMENT_FRAGMENT_NODE = 11;
20 Node.NOTATION_NODE = 12;
23 // prevent execution of more than once
24 if(typeof window.pz2 == "undefined") {
25 window.undefined = window.undefined;
27 var pz2 = function ( paramArray )
30 // at least one callback required
32 throw new Error("Pz2.js: Array with parameters has to be supplied.");
34 //supported pazpar2's protocol version
35 this.suppProtoVer = '1';
36 if (typeof paramArray.pazpar2path != "undefined")
37 this.pz2String = paramArray.pazpar2path;
39 this.pz2String = "/pazpar2/search.pz2";
40 this.useSessions = true;
42 this.stylesheet = paramArray.detailstylesheet || null;
43 //load stylesheet if required in async mode
44 if( this.stylesheet ) {
46 var request = new pzHttpRequest( this.stylesheet );
47 request.get( {}, function ( doc ) { context.xslDoc = doc; } );
50 this.errorHandler = paramArray.errorhandler || null;
51 this.showResponseType = paramArray.showResponseType || "xml";
54 this.initCallback = paramArray.oninit || null;
55 this.statCallback = paramArray.onstat || null;
56 this.showCallback = paramArray.onshow || null;
57 this.termlistCallback = paramArray.onterm || null;
58 this.recordCallback = paramArray.onrecord || null;
59 this.bytargetCallback = paramArray.onbytarget || null;
60 this.resetCallback = paramArray.onreset || null;
63 this.termKeys = paramArray.termlist || "subject";
65 // some configurational stuff
66 this.keepAlive = 50000;
68 if ( paramArray.keepAlive < this.keepAlive )
69 this.keepAlive = paramArray.keepAlive;
71 this.sessionID = null;
72 this.serviceId = paramArray.serviceId || null;
73 this.initStatusOK = false;
74 this.pingStatusOK = false;
75 this.searchStatusOK = false;
76 this.mergekey = paramArray.mergekey || null;
77 this.rank = paramArray.rank || null;
80 this.currentSort = "relevance";
83 this.currentStart = 0;
84 // currentNum can be overwritten in show
87 // last full record retrieved
88 this.currRecID = null;
91 this.currQuery = null;
93 //current raw record offset
94 this.currRecOffset = null;
97 this.pingTimer = null;
98 this.statTime = paramArray.stattime || 1000;
99 this.statTimer = null;
100 this.termTime = paramArray.termtime || 1000;
101 this.termTimer = null;
102 this.showTime = paramArray.showtime || 1000;
103 this.showTimer = null;
104 this.showFastCount = 4;
105 this.bytargetTime = paramArray.bytargettime || 1000;
106 this.bytargetTimer = null;
107 this.recordTime = paramArray.recordtime || 500;
108 this.recordTimer = null;
110 // counters for each command and applied delay
111 this.dumpFactor = 500;
112 this.showCounter = 0;
113 this.termCounter = 0;
114 this.statCounter = 0;
115 this.bytargetCounter = 0;
116 this.recordCounter = 0;
118 // active clients, updated by stat and show
119 // might be an issue since bytarget will poll accordingly
120 this.activeClients = 1;
122 // if in proxy mode no need to init
123 if (paramArray.usesessions != undefined) {
124 this.useSessions = paramArray.usesessions;
125 this.initStatusOK = true;
127 // else, auto init session or wait for a user init?
128 if (this.useSessions && paramArray.autoInit !== false) {
129 this.init(this.sessionID, this.serviceId);
132 this.version = paramArray.version || null;
137 //error handler for async error throws
138 throwError: function (errMsg, errCode)
140 var err = new Error(errMsg);
141 if (errCode) err.code = errCode;
143 if (this.errorHandler) {
144 this.errorHandler(err);
151 // stop activity by clearing tiemouts
154 clearTimeout(this.statTimer);
155 clearTimeout(this.showTimer);
156 clearTimeout(this.termTimer);
157 clearTimeout(this.bytargetTimer);
160 // reset status variables
163 if ( this.useSessions ) {
164 this.sessionID = null;
165 this.initStatusOK = false;
166 this.pingStatusOK = false;
167 clearTimeout(this.pingTimer);
169 this.searchStatusOK = false;
172 if ( this.resetCallback )
173 this.resetCallback();
176 init: function (sessionId, serviceId)
180 // session id as a param
181 if (sessionId && this.useSessions ) {
182 this.initStatusOK = true;
183 this.sessionID = sessionId;
185 // old school direct pazpar2 init
186 } else if (this.useSessions) {
188 var request = new pzHttpRequest(this.pz2String, this.errorHandler);
189 var opts = {'command' : 'init'};
190 if (serviceId) opts.service = serviceId;
194 if ( data.getElementsByTagName("status")[0]
195 .childNodes[0].nodeValue == "OK" ) {
196 if ( data.getElementsByTagName("protocol")[0]
197 .childNodes[0].nodeValue
198 != context.suppProtoVer )
200 "Server's protocol not supported by the client"
202 context.initStatusOK = true;
204 data.getElementsByTagName("session")[0]
205 .childNodes[0].nodeValue;
206 if (data.getElementsByTagName("keepAlive").length > 0) {
207 context.keepAlive = data.getElementsByTagName("keepAlive")[0].childNodes[0].nodeValue;
216 if ( context.initCallback )
217 context.initCallback();
220 context.throwError('Init failed. Malformed WS resonse.',
224 // when through proxy no need to init
226 this.initStatusOK = true;
229 // no need to ping explicitly
232 // pinging only makes sense when using pazpar2 directly
233 if( !this.initStatusOK || !this.useSessions )
235 'Pz2.js: Ping not allowed (proxy mode) or session not initialized.'
239 clearTimeout(context.pingTimer);
241 var request = new pzHttpRequest(this.pz2String, this.errorHandler);
243 { "command": "ping", "session": this.sessionID, "windowid" : window.name },
245 if ( data.getElementsByTagName("status")[0]
246 .childNodes[0].nodeValue == "OK" ) {
247 context.pingStatusOK = true;
257 context.throwError('Ping failed. Malformed WS resonse.',
262 search: function (query, num, sort, filter, showfrom, addParamsArr)
264 clearTimeout(this.statTimer);
265 clearTimeout(this.showTimer);
266 clearTimeout(this.termTimer);
267 clearTimeout(this.bytargetTimer);
269 this.showCounter = 0;
270 this.termCounter = 0;
271 this.bytargetCounter = 0;
272 this.statCounter = 0;
273 this.activeClients = 1;
276 if( !this.initStatusOK )
277 throw new Error('Pz2.js: session not initialized.');
279 if( query !== undefined )
280 this.currQuery = query;
282 throw new Error("Pz2.js: no query supplied to the search command.");
284 if ( showfrom !== undefined )
285 var start = showfrom;
291 "query": this.currQuery,
292 "session": this.sessionID,
293 "windowid" : window.name
296 if( sort !== undefined ) {
297 this.currentSort = sort;
298 searchParams["sort"] = sort;
300 if (filter !== undefined) searchParams["filter"] = filter;
301 if (this.mergekey) searchParams["mergekey"] = this.mergekey;
302 if (this.rank) searchParams["rank"] = this.rank;
304 // copy additional parmeters, do not overwrite
305 if (addParamsArr != undefined) {
306 for (var prop in addParamsArr) {
307 if (!searchParams.hasOwnProperty(prop))
308 searchParams[prop] = addParamsArr[prop];
313 var request = new pzHttpRequest(this.pz2String, this.errorHandler);
317 if ( data.getElementsByTagName("status")[0]
318 .childNodes[0].nodeValue == "OK" ) {
319 context.searchStatusOK = true;
321 context.show(start, num, sort);
322 if (context.statCallback)
324 if (context.termlistCallback)
326 if (context.bytargetCallback)
330 context.throwError('Search failed. Malformed WS resonse.',
337 if( !this.initStatusOK )
338 throw new Error('Pz2.js: session not initialized.');
340 // if called explicitly takes precedence
341 clearTimeout(this.statTimer);
344 var request = new pzHttpRequest(this.pz2String, this.errorHandler);
346 { "command": "stat", "session": this.sessionID, "windowid" : window.name },
348 if ( data.getElementsByTagName("stat") ) {
350 Number( data.getElementsByTagName("activeclients")[0]
351 .childNodes[0].nodeValue );
352 context.activeClients = activeClients;
354 var stat = Element_parseChildNodes(data.documentElement);
356 context.statCounter++;
357 var delay = context.statTime
358 + context.statCounter * context.dumpFactor;
360 if ( activeClients > 0 )
368 context.statCallback(stat);
371 context.throwError('Stat failed. Malformed WS resonse.',
376 show: function(start, num, sort, query_state)
378 if( !this.searchStatusOK && this.useSessions )
380 'Pz2.js: show command has to be preceded with a search command.'
383 // if called explicitly takes precedence
384 clearTimeout(this.showTimer);
386 if( sort !== undefined )
387 this.currentSort = sort;
388 if( start !== undefined )
389 this.currentStart = Number( start );
390 if( num !== undefined )
391 this.currentNum = Number( num );
394 var request = new pzHttpRequest(this.pz2String, this.errorHandler);
395 var requestParameters =
398 "session": this.sessionID,
399 "start": this.currentStart,
400 "num": this.currentNum,
401 "sort": this.currentSort,
403 "type": this.showResponseType,
404 "windowid" : window.name
407 requestParameters["query-state"] = query_state;
408 if (this.version && this.version > 0)
409 requestParameters["version"] = this.version;
412 function(data, type) {
414 var activeClients = 0;
415 if (type === "json") {
417 activeClients = Number(data.activeclients[0]);
418 show.activeclients = activeClients;
419 show.merged = Number(data.merged[0]);
420 show.total = Number(data.total[0]);
421 show.start = Number(data.start[0]);
422 show.num = Number(data.num[0]);
423 show.hits = data.hit;
424 } else if (data.getElementsByTagName("status")[0]
425 .childNodes[0].nodeValue == "OK") {
426 // first parse the status data send along with records
427 // this is strictly bound to the format
429 Number(data.getElementsByTagName("activeclients")[0]
430 .childNodes[0].nodeValue);
432 "activeclients": activeClients,
434 Number( data.getElementsByTagName("merged")[0]
435 .childNodes[0].nodeValue ),
437 Number( data.getElementsByTagName("total")[0]
438 .childNodes[0].nodeValue ),
440 Number( data.getElementsByTagName("start")[0]
441 .childNodes[0].nodeValue ),
443 Number( data.getElementsByTagName("num")[0]
444 .childNodes[0].nodeValue ),
447 // parse all the first-level nodes for all <hit> tags
448 var hits = data.getElementsByTagName("hit");
449 for (i = 0; i < hits.length; i++)
450 show.hits[i] = Element_parseChildNodes(hits[i]);
452 context.throwError('Show failed. Malformed WS resonse.',
456 var approxNode = data.getElementsByTagName("approximation");
457 if (approxNode && approxNode[0] && approxNode[0].childNodes[0] && approxNode[0].childNodes[0].nodeValue)
458 show['approximation'] =
459 Number( approxNode[0].childNodes[0].nodeValue);
462 data.getElementsByTagName("")
463 context.activeClients = activeClients;
464 context.showCounter++;
465 var delay = context.showTime;
466 if (context.showCounter > context.showFastCount)
467 delay += context.showCounter * context.dumpFactor;
468 if ( activeClients > 0 )
469 context.showTimer = setTimeout(
474 context.showCallback(show);
478 record: function(id, offset, syntax, handler)
480 // we may call record with no previous search if in proxy mode
481 if(!this.searchStatusOK && this.useSessions)
483 'Pz2.js: record command has to be preceded with a search command.'
486 if( id !== undefined )
491 "session": this.sessionID,
492 "id": this.currRecID,
493 "windowid" : window.name
496 this.currRecOffset = null;
497 if (offset != undefined) {
498 recordParams["offset"] = offset;
499 this.currRecOffset = offset;
502 if (syntax != undefined)
503 recordParams['syntax'] = syntax;
505 //overwrite default callback id needed
506 var callback = this.recordCallback;
507 var args = undefined;
508 if (handler != undefined) {
509 callback = handler['callback'];
510 args = handler['args'];
514 var request = new pzHttpRequest(this.pz2String, this.errorHandler);
522 if (context.currRecOffset !== null) {
523 record = new Array();
524 record['xmlDoc'] = data;
525 record['offset'] = context.currRecOffset;
526 callback(record, args);
528 } else if ( recordNode =
529 data.getElementsByTagName("record")[0] ) {
530 // if stylesheet was fetched do not parse the response
531 if ( context.xslDoc ) {
532 record = new Array();
533 record['xmlDoc'] = data;
534 record['xslDoc'] = context.xslDoc;
536 recordNode.getElementsByTagName("recid")[0]
537 .firstChild.nodeValue;
540 record = Element_parseChildNodes(recordNode);
543 Number( data.getElementsByTagName("activeclients")[0]
544 .childNodes[0].nodeValue );
545 context.activeClients = activeClients;
546 context.recordCounter++;
547 var delay = context.recordTime + context.recordCounter * context.dumpFactor;
548 if ( activeClients > 0 )
549 context.recordTimer =
552 context.record(id, offset, syntax, handler);
556 callback(record, args);
559 context.throwError('Record failed. Malformed WS resonse.',
567 if( !this.searchStatusOK && this.useSessions )
569 'Pz2.js: termlist command has to be preceded with a search command.'
572 // if called explicitly takes precedence
573 clearTimeout(this.termTimer);
576 var request = new pzHttpRequest(this.pz2String, this.errorHandler);
579 "command": "termlist",
580 "session": this.sessionID,
581 "name": this.termKeys,
582 "windowid" : window.name,
583 "version" : this.version
587 if ( data.getElementsByTagName("termlist") ) {
589 Number( data.getElementsByTagName("activeclients")[0]
590 .childNodes[0].nodeValue );
591 context.activeClients = activeClients;
592 var termList = { "activeclients": activeClients };
593 var termLists = data.getElementsByTagName("list");
595 for (i = 0; i < termLists.length; i++) {
596 var listName = termLists[i].getAttribute('name');
597 termList[listName] = new Array();
598 var terms = termLists[i].getElementsByTagName('term');
599 //for each term in the list
600 for (j = 0; j < terms.length; j++) {
603 (terms[j].getElementsByTagName("name")[0]
605 ? terms[j].getElementsByTagName("name")[0]
606 .childNodes[0].nodeValue
610 .getElementsByTagName("frequency")[0]
611 .childNodes[0].nodeValue || 'ERROR'
614 // Only for xtargets: id, records, filtered
616 terms[j].getElementsByTagName("id");
617 if(terms[j].getElementsByTagName("id").length)
619 termIdNode[0].childNodes[0].nodeValue;
620 termList[listName][j] = term;
622 var recordsNode = terms[j].getElementsByTagName("records");
623 if (recordsNode && recordsNode.length)
624 term["records"] = recordsNode[0].childNodes[0].nodeValue;
626 var filteredNode = terms[j].getElementsByTagName("filtered");
627 if (filteredNode && filteredNode.length)
628 term["filtered"] = filteredNode[0].childNodes[0].nodeValue;
633 context.termCounter++;
634 var delay = context.termTime
635 + context.termCounter * context.dumpFactor;
636 if ( activeClients > 0 )
645 context.termlistCallback(termList);
648 context.throwError('Termlist failed. Malformed WS resonse.',
656 if( !this.initStatusOK && this.useSessions )
658 'Pz2.js: bytarget command has to be preceded with a search command.'
661 // no need to continue
662 if( !this.searchStatusOK )
665 // if called explicitly takes precedence
666 clearTimeout(this.bytargetTimer);
669 var request = new pzHttpRequest(this.pz2String, this.errorHandler);
672 "command": "bytarget",
673 "session": this.sessionID,
675 "windowid" : window.name,
676 "version" : this.version
679 if ( data.getElementsByTagName("status")[0]
680 .childNodes[0].nodeValue == "OK" ) {
681 var targetNodes = data.getElementsByTagName("target");
682 var bytarget = new Array();
683 for ( i = 0; i < targetNodes.length; i++) {
684 bytarget[i] = new Array();
685 for( j = 0; j < targetNodes[i].childNodes.length; j++ ) {
686 if ( targetNodes[i].childNodes[j].nodeType
687 == Node.ELEMENT_NODE ) {
689 targetNodes[i].childNodes[j].nodeName;
690 if (targetNodes[i].childNodes[j].firstChild != null)
692 var nodeText = targetNodes[i].childNodes[j]
693 .firstChild.nodeValue;
694 bytarget[i][nodeName] = nodeText;
697 bytarget[i][nodeName] = "";
703 if (bytarget[i]["state"]=="Client_Disconnected") {
704 bytarget[i]["hits"] = "Error";
705 } else if (bytarget[i]["state"]=="Client_Error") {
706 bytarget[i]["hits"] = "Error";
707 } else if (bytarget[i]["state"]=="Client_Working") {
708 bytarget[i]["hits"] = "...";
710 if (bytarget[i].diagnostic == "1") {
711 bytarget[i].diagnostic = "Permanent system error";
712 } else if (bytarget[i].diagnostic == "2") {
713 bytarget[i].diagnostic = "Temporary system error";
715 var targetsSuggestions = targetNodes[i].getElementsByTagName("suggestions");
716 if (targetsSuggestions != undefined && targetsSuggestions.length>0) {
717 var suggestions = targetsSuggestions[0];
718 bytarget[i]["suggestions"] = Element_parseChildNodes(suggestions);
722 context.bytargetCounter++;
723 var delay = context.bytargetTime
724 + context.bytargetCounter * context.dumpFactor;
725 if ( context.activeClients > 0 )
726 context.bytargetTimer =
734 context.bytargetCallback(bytarget);
737 context.throwError('Bytarget failed. Malformed WS resonse.',
743 // just for testing, probably shouldn't be here
744 showNext: function(page)
746 var step = page || 1;
747 this.show( ( step * this.currentNum ) + this.currentStart );
750 showPrev: function(page)
752 if (this.currentStart == 0 )
754 var step = page || 1;
755 var newStart = this.currentStart - (step * this.currentNum );
756 this.show( newStart > 0 ? newStart : 0 );
759 showPage: function(pageNum)
761 //var page = pageNum || 1;
762 this.show(pageNum * this.currentNum);
767 ********************************************************************************
768 ** AJAX HELPER CLASS ***********************************************************
769 ********************************************************************************
771 var pzHttpRequest = function ( url, errorHandler ) {
772 this.maxUrlLength = 2048;
775 this.errorHandler = errorHandler || null;
777 this.requestHeaders = {};
778 this.isXDomain = false;
779 this.domainRegex = /https?:\/\/([^:/]+).*/;
781 var xhr = new XMLHttpRequest();
782 if ("withCredentials" in xhr) {
783 // XHR for Chrome/Firefox/Opera/Safari.
784 } else if (typeof XDomainRequest != "undefined") {
785 // XDomainRequest for IE.
786 xhr = new XDomainRequest();
787 this.isXDomain = true;
789 // CORS not supported.
795 pzHttpRequest.prototype =
797 safeGet: function ( params, callback )
799 var encodedParams = this.encodeParams(params);
800 var url = this._urlAppendParams(encodedParams);
801 if (url.length >= this.maxUrlLength) {
802 this.requestHeaders["Content-Type"]
803 = "application/x-www-form-urlencoded";
804 this._send( 'POST', this.url, encodedParams, callback );
806 this._send( 'GET', url, '', callback );
810 get: function ( params, callback )
812 this._send( 'GET', this._urlAppendParams(this.encodeParams(params)),
816 post: function ( params, data, callback )
818 this._send( 'POST', this._urlAppendParams(this.encodeParams(params)),
825 this.request.open( 'GET', this.url, this.async );
826 this.request.send('');
827 if ( this.request.status == 200 )
828 return this.request.responseXML;
831 encodeParams: function (params)
835 for (var key in params) {
836 if (params[key] != null) {
837 encoded += sep + key + '=' + encodeURIComponent(params[key]);
844 _getDomainFromUrl: function (url)
846 var m = this.domainRegex.exec(url);
847 return (m && m.length > 1) ? m[1] : null;
850 _strEndsWith: function (str, suffix)
852 return str.indexOf(suffix, str.length - suffix.length) !== -1;
855 _isCrossDomain: function (domain)
857 return !this._strEndsWith(domain, document.domain);
860 getCookie: function (sKey) {
861 return decodeURI(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*"
862 + encodeURI(sKey).replace(/[\-\.\+\*]/g, "\\$&")
863 + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
866 setCookie: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
867 if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
872 switch (vEnd.constructor) {
874 sExpires = vEnd === Infinity
875 ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT"
876 : "; max-age=" + vEnd;
879 sExpires = "; expires=" + vEnd;
882 sExpires = "; expires=" + vEnd.toGMTString();
886 document.cookie = encodeURI(sKey) + "=" + encodeURI(sValue)
888 + (sDomain ? "; domain=" + sDomain : "")
889 + (sPath ? "; path=" + sPath : "")
890 + (bSecure ? "; secure" : "");
894 _send: function ( type, url, data, callback)
897 this.callback = callback;
899 //we never do withCredentials, so if it's CORS and we have
900 //session cookie, resend it
901 var domain = this._getDomainFromUrl(url);
902 if (domain && this._isCrossDomain(domain) &&
903 this.getCookie(domain+":SESSID")) {
905 var sessparam = ';jsessionid=' + this.getCookie(domain+":SESSID");
906 var q = url.indexOf('?');
910 url = url.substring(0, q) + sessparam + url.substring(q);
913 this.request.open( type, url, this.async );
914 if (!this.isXDomain) {
915 //setting headers is only allowed with XHR
916 for (var key in this.requestHeaders)
917 this.request.setRequestHeader(key, this.requestHeaders[key]);
919 if (this.isXDomain) {
920 this.request.onload = function () {
922 context.request.status = 200;
923 context.request.readyState = 4;
925 context._handleResponse(url);
927 this.request.onerror = function () {
929 context.request.status = 417; //not really, but what can we do
930 context.request.readyState = 4;
932 context._handleResponse(url);
935 this.request.onreadystatechange = function () {
936 context._handleResponse(url); /// url used ONLY for error reporting
939 this.request.send(data);
942 _urlAppendParams: function (encodedParams)
945 return this.url + "?" + encodedParams;
950 _handleResponse: function (requestUrl)
952 if ( this.request.readyState == 4 ) {
953 // pick up appplication errors first
955 // xdomainreq does not have responseXML
956 if (this.isXDomain) {
957 if (this.request.contentType.match(/\/xml/)){
958 var dom = new ActiveXObject('Microsoft.XMLDOM');
960 dom.loadXML(this.request.responseText);
961 this.request.responseXML = dom;
963 this.request.responseXML = null;
966 if (this.request.responseXML &&
967 (errNode = this.request.responseXML.documentElement)
968 && errNode.nodeName == 'error') {
969 var errMsg = errNode.getAttribute("msg");
970 var errCode = errNode.getAttribute("code");
972 if (errNode.childNodes.length)
973 errAddInfo = ': ' + errNode.childNodes[0].nodeValue;
975 var err = new Error(errMsg + errAddInfo);
978 if (this.errorHandler) {
979 this.errorHandler(err);
985 else if (this.request.status == 200 &&
986 this.request.responseXML === null) {
987 if (this.request.responseText !== null) {
990 var text = this.request.responseText;
991 if (typeof window.JSON == "undefined") {
992 json = eval("(" + text + ")");
995 json = JSON.parse(text);
999 this.callback(json, "json");
1001 var err = new Error("XML/Text response is empty but no error " +
1002 "for " + requestUrl);
1004 if (this.errorHandler) {
1005 this.errorHandler(err);
1010 } else if (this.request.status == 200) {
1011 //set cookie manually only if cross-domain
1012 var domain = this._getDomainFromUrl(requestUrl);
1013 if (domain && this._isCrossDomain(domain)) {
1014 var jsessionId = this.request.responseXML
1015 .documentElement.getAttribute('jsessionId');
1017 this.setCookie(domain+":SESSID", jsessionId);
1019 this.callback(this.request.responseXML);
1021 var err = new Error("HTTP response not OK: "
1022 + this.request.status + " - "
1023 + this.request.statusText );
1024 err.code = '00' + this.request.status;
1025 if (this.errorHandler) {
1026 this.errorHandler(err);
1037 ********************************************************************************
1038 ** XML HELPER FUNCTIONS ********************************************************
1039 ********************************************************************************
1044 if ( window.ActiveXObject) {
1045 var DOMDoc = document;
1047 var DOMDoc = Document.prototype;
1050 DOMDoc.newXmlDoc = function ( root )
1054 if (document.implementation && document.implementation.createDocument) {
1055 doc = document.implementation.createDocument('', root, null);
1056 } else if ( window.ActiveXObject ) {
1057 doc = new ActiveXObject("MSXML2.DOMDocument");
1058 doc.loadXML('<' + root + '/>');
1060 throw new Error ('No XML support in this browser');
1067 DOMDoc.parseXmlFromString = function ( xmlString )
1071 if ( window.DOMParser ) {
1072 var parser = new DOMParser();
1073 doc = parser.parseFromString( xmlString, "text/xml");
1074 } else if ( window.ActiveXObject ) {
1075 doc = new ActiveXObject("MSXML2.DOMDocument");
1076 doc.loadXML( xmlString );
1078 throw new Error ("No XML parsing support in this browser.");
1084 DOMDoc.transformToDoc = function (xmlDoc, xslDoc)
1086 if ( window.XSLTProcessor ) {
1087 var proc = new XSLTProcessor();
1088 proc.importStylesheet( xslDoc );
1089 return proc.transformToDocument(xmlDoc);
1090 } else if ( window.ActiveXObject ) {
1091 return document.parseXmlFromString(xmlDoc.transformNode(xslDoc));
1093 alert( 'Unable to perform XSLT transformation in this browser' );
1099 Element_removeFromDoc = function (DOM_Element)
1101 DOM_Element.parentNode.removeChild(DOM_Element);
1104 Element_emptyChildren = function (DOM_Element)
1106 while( DOM_Element.firstChild ) {
1107 DOM_Element.removeChild( DOM_Element.firstChild )
1111 Element_appendTransformResult = function ( DOM_Element, xmlDoc, xslDoc )
1113 if ( window.XSLTProcessor ) {
1114 var proc = new XSLTProcessor();
1115 proc.importStylesheet( xslDoc );
1116 var docFrag = false;
1117 docFrag = proc.transformToFragment( xmlDoc, DOM_Element.ownerDocument );
1118 DOM_Element.appendChild(docFrag);
1119 } else if ( window.ActiveXObject ) {
1120 DOM_Element.innerHTML = xmlDoc.transformNode( xslDoc );
1122 alert( 'Unable to perform XSLT transformation in this browser' );
1126 Element_appendTextNode = function (DOM_Element, tagName, textContent )
1128 var node = DOM_Element.ownerDocument.createElement(tagName);
1129 var text = DOM_Element.ownerDocument.createTextNode(textContent);
1131 DOM_Element.appendChild(node);
1132 node.appendChild(text);
1137 Element_setTextContent = function ( DOM_Element, textContent )
1139 if (typeof DOM_Element.textContent !== "undefined") {
1140 DOM_Element.textContent = textContent;
1141 } else if (typeof DOM_Element.innerText !== "undefined" ) {
1142 DOM_Element.innerText = textContent;
1144 throw new Error("Cannot set text content of the node, no such method.");
1148 Element_getTextContent = function (DOM_Element)
1150 if ( typeof DOM_Element.textContent != 'undefined' ) {
1151 return DOM_Element.textContent;
1152 } else if (typeof DOM_Element.text != 'undefined') {
1153 return DOM_Element.text;
1155 throw new Error("Cannot get text content of the node, no such method.");
1159 Element_parseChildNodes = function (node)
1162 var hasChildElems = false;
1163 var textContent = '';
1165 if (node.hasChildNodes()) {
1166 var children = node.childNodes;
1167 for (var i = 0; i < children.length; i++) {
1168 var child = children[i];
1169 switch (child.nodeType) {
1170 case Node.ELEMENT_NODE:
1171 hasChildElems = true;
1172 var nodeName = child.nodeName;
1173 if (!(nodeName in parsed))
1174 parsed[nodeName] = [];
1175 parsed[nodeName].push(Element_parseChildNodes(child));
1177 case Node.TEXT_NODE:
1178 textContent += child.nodeValue;
1180 case Node.CDATA_SECTION_NODE:
1181 textContent += child.nodeValue;
1187 var attrs = node.attributes;
1188 for (var i = 0; i < attrs.length; i++) {
1189 hasChildElems = true;
1190 var attrName = '@' + attrs[i].nodeName;
1191 var attrValue = attrs[i].nodeValue;
1192 parsed[attrName] = attrValue;
1195 // if no nested elements/attrs set value to text
1197 parsed['#text'] = textContent;
1199 parsed = textContent;
1204 /* do not remove trailing bracket */