1 /* 2 * Copyright ©2012 SARA bv, The Netherlands 3 * 4 * This file is part of js-webdav-client. 5 * 6 * js-webdav-client is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published 8 * by the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * js-webdav-client is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with js-webdav-client. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 "use strict"; 20 21 // If nl.sara.webdav.Response is already defined, we have a namespace clash! 22 if (nl.sara.webdav.Response !== undefined) { 23 throw new nl.sara.webdav.Exception('Namespace nl.sara.webdav.Response already taken, could not load JavaScript library for WebDAV connectivity.', nl.sara.webdav.Exception.NAMESPACE_TAKEN); 24 } 25 26 /** 27 * @class a WebDAV response 28 * 29 * @param {Node} [xmlNode] Optional; the xmlNode describing the response object (should be compliant with RFC 4918) 30 * @property {String} href The path of the resource 31 * @property {String} status The (HTTP) status code 32 * @property {String} error The error text 33 * @property {String} responsedescription The response description 34 * @property {String} location In case of a 3XX response, the value that would normally be in the 'Location' header 35 */ 36 nl.sara.webdav.Response = function(xmlNode) { 37 // First define private attributes 38 Object.defineProperty(this, '_namespaces', { 39 'value': {}, 40 'enumerable': false, 41 'configurable': false, 42 'writable': true 43 }); 44 // Second define public attributes 45 Object.defineProperty(this, 'href', { 46 'value': null, 47 'enumerable': true, 48 'configurable': false, 49 'writable': true 50 }); 51 Object.defineProperty(this, 'status', { 52 'value': null, 53 'enumerable': true, 54 'configurable': false, 55 'writable': true 56 }); 57 Object.defineProperty(this, 'error', { 58 'value': null, 59 'enumerable': true, 60 'configurable': false, 61 'writable': true 62 }); 63 Object.defineProperty(this, 'responsedescription', { 64 'value': null, 65 'enumerable': true, 66 'configurable': false, 67 'writable': true 68 }); 69 Object.defineProperty(this, 'location', { 70 'value': null, 71 'enumerable': true, 72 'configurable': false, 73 'writable': true 74 }); 75 76 // Constructor logic 77 if (typeof xmlNode !== 'undefined') { 78 if ((xmlNode.namespaceURI !== 'DAV:') || (nl.sara.webdav.Ie.getLocalName(xmlNode) !== 'response')) { 79 throw new nl.sara.webdav.Exception('Node is not of type DAV:response', nl.sara.webdav.Exception.WRONG_XML); 80 } 81 var data = xmlNode.childNodes; 82 for (var i = 0; i < data.length; i++) { 83 var child = data.item(i); 84 if ((child.namespaceURI === null) || (child.namespaceURI !== 'DAV:')) { // Skip if not from the right namespace 85 continue; 86 } 87 switch (nl.sara.webdav.Ie.getLocalName(child)) { 88 case 'href': 89 case 'status': 90 case 'error': 91 case 'responsedescription': 92 // always CDATA, so just take the text 93 this[nl.sara.webdav.Ie.getLocalName(child)] = child.childNodes.item(0).nodeValue; 94 break; 95 case 'location': 96 this[nl.sara.webdav.Ie.getLocalName(child)] = child.childNodes.item(0).childNodes.item(0).nodeValue; 97 break; 98 case 'propstat': // propstat node should be parsed further 99 var propstatChilds = child.childNodes; 100 // First find status, error, responsedescription and props (as Node objects, not yet as Property objects) 101 var status = null; 102 var errors = []; 103 var responsedescription = null; 104 var props = []; 105 for (var j = 0; j < propstatChilds.length; j++) { // Parse the child nodes of the propstat element 106 var propstatChild = propstatChilds.item(j); 107 if ((propstatChild.nodeType !== 1) || (propstatChild.namespaceURI !== 'DAV:')) { 108 continue; 109 } 110 switch (nl.sara.webdav.Ie.getLocalName(propstatChild)) { 111 case 'prop': 112 for (var k = 0; k < propstatChild.childNodes.length; k++) { 113 props.push(propstatChild.childNodes.item(k)); 114 } 115 break; 116 case 'error': 117 for (k = 0; k < propstatChild.childNodes.length; k++) { 118 errors.push(propstatChild.childNodes.item(k)); 119 } 120 break; 121 break; 122 case 'status': // always CDATA, so just take the text 123 status = propstatChild.childNodes.item(0).nodeValue; 124 status = parseInt(status.substr(status.indexOf(' ') + 1, 3)); 125 break; 126 case 'responsedescription': // always CDATA, so just take the text 127 responsedescription = propstatChild.childNodes.item(0).nodeValue; 128 break; 129 } 130 } 131 132 // Then create and add a new property for each element found in DAV:prop 133 for (j = 0; j < props.length; j++) { 134 if (props[j].nodeType === 1) { 135 var property = new nl.sara.webdav.Property(props[j], status, responsedescription, errors); 136 this.addProperty(property); 137 } 138 } 139 break; 140 } 141 } 142 } 143 }; 144 145 //########################## DEFINE PUBLIC METHODS ############################# 146 /** 147 * Adds a WebDAV property 148 * 149 * @param {nl.sara.webdav.Property} property The property 150 * @returns {nl.sara.webdav.Response} The response itself for chaining methods 151 */ 152 nl.sara.webdav.Response.prototype.addProperty = function(property) { 153 if (!nl.sara.webdav.Ie.isIE && !(property instanceof nl.sara.webdav.Property)) { 154 throw new nl.sara.webdav.Exception('Response property should be instance of Property', nl.sara.webdav.Exception.WRONG_TYPE); 155 } 156 var namespace = property.namespace; 157 if (typeof namespace !== 'string') { 158 namespace = ''; 159 } 160 if (this._namespaces[namespace] === undefined) { 161 this._namespaces[namespace] = {}; 162 } 163 164 this._namespaces[namespace][property.tagname] = property; 165 return this; 166 }; 167 168 /** 169 * Gets a WebDAV property 170 * 171 * @param {String} namespace The namespace of the WebDAV property 172 * @param {String} prop The WebDAV property to get 173 * @returns {nl.sara.webdav.Property} The value of the WebDAV property or undefined if the WebDAV property doesn't exist 174 */ 175 nl.sara.webdav.Response.prototype.getProperty = function(namespace, prop) { 176 if ((this._namespaces[namespace] === undefined) || (this._namespaces[namespace][prop] === undefined)) { 177 return undefined; 178 } 179 return this._namespaces[namespace][prop]; 180 }; 181 182 /** 183 * Gets the namespace names 184 * 185 * @returns {String[]} The names of the different namespaces 186 */ 187 nl.sara.webdav.Response.prototype.getNamespaceNames = function() { 188 return Object.keys(this._namespaces); 189 }; 190 191 /** 192 * Gets the property names of a namespace 193 * 194 * @param {String} namespace The namespace of the WebDAV property 195 * @returns {String[]} The names of the different properties of a namespace 196 */ 197 nl.sara.webdav.Response.prototype.getPropertyNames = function(namespace) { 198 if (this._namespaces[namespace] === undefined) { 199 return new Array(); 200 } 201 return Object.keys(this._namespaces[namespace]); 202 }; 203 204 // End of library 205