master
js 189 lines 11.3 KB
Raw
1 /*
2 Copyright 2018-2021 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { }
18
19
20 // Parse XML and return JSON
21 module.exports.ParseWsman = function (xml) {
22 try {
23 if (!xml.childNodes) xml = _turnToXml(xml);
24 var r = { Header: {} }, header = xml.getElementsByTagName("Header")[0], t;
25 if (!header) header = xml.getElementsByTagName("a:Header")[0];
26 if (!header) return null;
27 for (var i = 0; i < header.childNodes.length; i++) {
28 var child = header.childNodes[i];
29 r.Header[child.localName] = child.textContent;
30 }
31 var body = xml.getElementsByTagName("Body")[0];
32 if (!body) body = xml.getElementsByTagName("a:Body")[0];
33 if (!body) return null;
34 if (body.childNodes.length > 0) {
35 t = body.childNodes[0].localName;
36 var x = t.indexOf('_OUTPUT');
37 if ((x != -1) && (x == (t.length - 7))) { t = t.substring(0, t.length - 7); }
38 r.Header['Method'] = t;
39 r.Body = _ParseWsmanRec(body.childNodes[0]);
40 }
41 return r;
42 } catch (e) {
43 console.error("Unable to parse XML: " + xml, e);
44 return null;
45 }
46 }
47
48 // Private method
49 function _ParseWsmanRec(node) {
50 var data, r = {};
51 for (var i = 0; i < node.childNodes.length; i++) {
52 var child = node.childNodes[i];
53 if ((child.childElementCount == null) || (child.childElementCount == 0)) { data = child.textContent; } else { data = _ParseWsmanRec(child); }
54 if (data == 'true') data = true; // Convert 'true' into true
55 if (data == 'false') data = false; // Convert 'false' into false
56 if ((parseInt(data) + '') === data) data = parseInt(data); // Convert integers
57
58 var childObj = data;
59 if ((child.attributes != null) && (child.attributes.length > 0)) {
60 childObj = { 'Value': data };
61 for (var j = 0; j < child.attributes.length; j++) {
62 childObj['@' + child.attributes[j].name] = child.attributes[j].value;
63 }
64 }
65
66 if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); }
67 else if (r[child.localName] == null) { r[child.localName] = childObj; }
68 else { r[child.localName] = [r[child.localName], childObj]; }
69 }
70 return r;
71 }
72
73 function _PutObjToBodyXml(resuri, putObj) {
74 if (!resuri || putObj == null) return '';
75 var objname = obj.GetNameFromUrl(resuri);
76 var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
77
78 for (var prop in putObj) {
79 if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
80 if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
81 if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
82 result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
83 var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
84 if (Array.isArray(selectorArray)) {
85 for (var i = 0; i < selectorArray.length; i++) {
86 result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
87 }
88 }
89 else {
90 result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
91 }
92 result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
93 }
94 else {
95 if (Array.isArray(putObj[prop])) {
96 for (var i = 0; i < putObj[prop].length; i++) {
97 result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
98 }
99 } else {
100 result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
101 }
102 }
103 }
104
105 result += '</r:' + objname + '>';
106 return result;
107 }
108
109 // This is a drop-in replacement to _turnToXml() that works without xml parser dependency.
110 function _treeBuilder() {
111 this.tree = [];
112 this.push = function (element) { this.tree.push(element); };
113 this.pop = function () { var element = this.tree.pop(); if (this.tree.length > 0) { var x = this.tree.peek(); x.childNodes.push(element); x.childElementCount = x.childNodes.length; } return (element); };
114 this.peek = function () { return (this.tree.peek()); }
115 this.addNamespace = function (prefix, namespace) { this.tree.peek().nsTable[prefix] = namespace; if (this.tree.peek().attributes.length > 0) { for (var i = 0; i < this.tree.peek().attributes; ++i) { var a = this.tree.peek().attributes[i]; if (prefix == '*' && a.name == a.localName) { a.namespace = namespace; } else if (prefix != '*' && a.name != a.localName) { var pfx = a.name.split(':')[0]; if (pfx == prefix) { a.namespace = namespace; } } } } }
116 this.getNamespace = function (prefix) { for (var i = this.tree.length - 1; i >= 0; --i) { if (this.tree[i].nsTable[prefix] != null) { return (this.tree[i].nsTable[prefix]); } } return null; }
117 }
118 function _turnToXml(text) { if (text == null) return null; return ({ childNodes: [_turnToXmlRec(text)], getElementsByTagName: _getElementsByTagName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS }); }
119 function _getElementsByTagNameNS(ns, name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name && (node.namespace == ns || ns == '*')) { ret.push(node); } }); return ret; }
120 function _getElementsByTagName(name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name) { ret.push(node); } }); return ret; }
121 function _getChildElementsByTagName(name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name) { ret.push(this.childNodes[node]); } } } return (ret); }
122 function _getChildElementsByTagNameNS(ns, name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name && (ns == '*' || this.childNodes[node].namespace == ns)) { ret.push(this.childNodes[node]); } } } return (ret); }
123 function _xmlTraverseAllRec(nodes, func) { for (var i in nodes) { func(nodes[i]); if (nodes[i].childNodes) { _xmlTraverseAllRec(nodes[i].childNodes, func); } } }
124 function _turnToXmlRec(text) {
125 try {
126 if (text == null) return null;
127 var elementStack = new _treeBuilder(), lastElement = null, x1 = text.split('<'), ret = [], element = null, currentElementName = null;
128 for (var i in x1) {
129 var x2 = x1[i].split('>'), x3 = x2[0].split(' '), elementName = x3[0];
130 if ((elementName.length > 0) && (elementName[0] != '?')) {
131 if (elementName[0] != '/') {
132 var attributes = [], localName, localname2 = elementName.split(' ')[0].split(':'), localName = (localname2.length > 1) ? localname2[1] : localname2[0];
133 Object.defineProperty(attributes, "get",
134 {
135 value: function () {
136 if (arguments.length == 1) {
137 for (var a in this) { if (this[a].name == arguments[0]) { return (this[a]); } }
138 }
139 else if (arguments.length == 2) {
140 for (var a in this) { if (this[a].name == arguments[1] && (arguments[0] == '*' || this[a].namespace == arguments[0])) { return (this[a]); } }
141 }
142 else {
143 throw ('attributes.get(): Invalid number of parameters');
144 }
145 }
146 });
147 elementStack.push({ name: elementName, localName: localName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS, getChildElementsByTagNameNS: _getChildElementsByTagNameNS, attributes: attributes, childNodes: [], nsTable: {} });
148 // Parse Attributes
149 if (x3.length > 0) {
150 var skip = false;
151 for (var j in x3) {
152 if (x3[j] == '/') {
153 // This is an empty Element
154 elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
155 elementStack.peek().textContent = '';
156 lastElement = elementStack.pop();
157 skip = true;
158 break;
159 }
160 var k = x3[j].indexOf('=');
161 if (k > 0) {
162 var attrName = x3[j].substring(0, k);
163 var attrValue = x3[j].substring(k + 2, x3[j].length - 1);
164 var attrNS = elementStack.getNamespace('*');
165
166 if (attrName == 'xmlns') {
167 elementStack.addNamespace('*', attrValue);
168 attrNS = attrValue;
169 } else if (attrName.startsWith('xmlns:')) {
170 elementStack.addNamespace(attrName.substring(6), attrValue);
171 } else {
172 var ax = attrName.split(':');
173 if (ax.length == 2) { attrName = ax[1]; attrNS = elementStack.getNamespace(ax[0]); }
174 }
175 var x = { name: attrName, value: attrValue }
176 if (attrNS != null) x.namespace = attrNS;
177 elementStack.peek().attributes.push(x);
178 }
179 }
180 if (skip) { continue; }
181 }
182 elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
183 if (x2[1]) { elementStack.peek().textContent = x2[1]; }
184 } else { lastElement = elementStack.pop(); }
185 }
186 }
187 } catch (ex) { return null; }
188 return lastElement;
189 }