/Foundation/CPWebDAVManager.j

http://github.com/cacaodev/cappuccino · Unknown · 241 lines · 192 code · 49 blank · 0 comment · 0 complexity · 79fca2c40f2950f0452a39cfa93d7049 MD5 · raw file

  1. /*
  2. * CPWebDAVManager.j
  3. * Foundation
  4. *
  5. * Created by Francisco Tolmasky.
  6. * Copyright 2008, 280 North, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. @import "CPArray.j"
  23. @import "CPDictionary.j"
  24. @import "CPObject.j"
  25. @import "CPString.j"
  26. @import "CPURL.j"
  27. @import "CPURLConnection.j"
  28. @import "CPURLRequest.j"
  29. var setURLResourceValuesForKeysFromProperties = function(aURL, keys, properties)
  30. {
  31. var resourceType = [properties objectForKey:@"resourcetype"];
  32. if (resourceType === CPWebDAVManagerCollectionResourceType)
  33. {
  34. [aURL setResourceValue:YES forKey:CPURLIsDirectoryKey];
  35. [aURL setResourceValue:NO forKey:CPURLIsRegularFileKey];
  36. }
  37. else if (resourceType === CPWebDAVManagerNonCollectionResourceType)
  38. {
  39. [aURL setResourceValue:NO forKey:CPURLIsDirectoryKey];
  40. [aURL setResourceValue:YES forKey:CPURLIsRegularFileKey];
  41. }
  42. var displayName = [properties objectForKey:@"displayname"];
  43. if (displayName !== nil)
  44. {
  45. [aURL setResourceValue:displayName forKey:CPURLNameKey];
  46. [aURL setResourceValue:displayName forKey:CPURLLocalizedNameKey];
  47. }
  48. };
  49. CPWebDAVManagerCollectionResourceType = 1;
  50. CPWebDAVManagerNonCollectionResourceType = 0;
  51. @implementation CPWebDAVManager : CPObject
  52. {
  53. CPDictionary _blocksForConnections;
  54. }
  55. - (id)init
  56. {
  57. self = [super init];
  58. if (self)
  59. _blocksForConnections = @{};
  60. return self;
  61. }
  62. - (CPArray)contentsOfDirectoryAtURL:(CPURL)aURL includingPropertiesForKeys:(CPArray)keys options:(CPDirectoryEnumerationOptions)aMask block:(Function)aBlock
  63. {
  64. var properties = [],
  65. count = [keys count];
  66. while (count--)
  67. properties.push(WebDAVPropertiesForURLKeys[keys[count]]);
  68. var makeContents = function(aURL, response)
  69. {
  70. var contents = [],
  71. URLString = nil,
  72. URLStrings = [response keyEnumerator];
  73. while ((URLString = [URLStrings nextObject]) !== nil)
  74. {
  75. var URL = [CPURL URLWithString:URLString],
  76. properties = [response objectForKey:URLString];
  77. // FIXME: We need better way of comparing URLs.
  78. if (![[URL absoluteString] isEqual:[aURL absoluteString]])
  79. {
  80. contents.push(URL);
  81. setURLResourceValuesForKeysFromProperties(URL, keys, properties);
  82. }
  83. }
  84. return contents;
  85. };
  86. if (!aBlock)
  87. return makeContents(aURL, [self PROPFIND:aURL properties:properties depth:1 block:nil]);
  88. [self PROPFIND:aURL properties:properties depth:1 block:function(aURL, response)
  89. {
  90. aBlock(aURL, makeContents(aURL, response));
  91. }];
  92. }
  93. - (CPDictionary)PROPFIND:(CPURL)aURL properties:(CPDictionary)properties depth:(CPString)aDepth block:(Function)aBlock
  94. {
  95. var request = [CPURLRequest requestWithURL:aURL];
  96. [request setHTTPMethod:@"PROPFIND"];
  97. [request setValue:aDepth forHTTPHeaderField:@"Depth"];
  98. var HTTPBody = ["<?xml version=\"1.0\"?><a:propfind xmlns:a=\"DAV:\">"],
  99. index = 0,
  100. count = properties.length;
  101. for (; index < count; ++index)
  102. HTTPBody.push("<a:prop><a:", properties[index], "/></a:prop>");
  103. HTTPBody.push("</a:propfind>");
  104. [request setHTTPBody:HTTPBody.join("")];
  105. if (!aBlock)
  106. return parsePROPFINDResponse([[CPURLConnection sendSynchronousRequest:request returningResponse:nil] rawString]);
  107. else
  108. {
  109. var connection = [CPURLConnection connectionWithRequest:request delegate:self];
  110. [_blocksForConnections setObject:aBlock forKey:[connection UID]];
  111. }
  112. }
  113. - (void)connection:(CPURLConnection)aURLConnection didReceiveData:(CPString)aString
  114. {
  115. var block = [_blocksForConnections objectForKey:[aURLConnection UID]];
  116. // FIXME: get the request...
  117. block([aURLConnection._request URL], parsePROPFINDResponse(aString));
  118. }
  119. @end
  120. var WebDAVPropertiesForURLKeys = { };
  121. WebDAVPropertiesForURLKeys[CPURLNameKey] = @"displayname";
  122. WebDAVPropertiesForURLKeys[CPURLLocalizedNameKey] = @"displayname";
  123. WebDAVPropertiesForURLKeys[CPURLIsRegularFileKey] = @"resourcetype";
  124. WebDAVPropertiesForURLKeys[CPURLIsDirectoryKey] = @"resourcetype";
  125. //CPURLIsSymbolicLinkKey = @"CPURLIsSymbolicLinkKey";
  126. //CPURLIsVolumeKey = @"CPURLIsVolumeKey";
  127. //CPURLIsPackageKey = @"CPURLIsPackageKey";
  128. //CPURLIsSystemImmutableKey = @"CPURLIsSystemImmutableKey";
  129. //CPURLIsUserImmutableKey = @"CPURLIsUserImmutableKey";
  130. //CPURLIsHiddenKey = @"CPURLIsHiddenKey";
  131. //CPURLHasHiddenExtensionKey = @"CPURLHasHiddenExtensionKey";
  132. //CPURLCreationDateKey = @"CPURLCreationDateKey";
  133. //CPURLContentAccessDateKey = @"CPURLContentAccessDateKey";
  134. //CPURLContentModificationDateKey = @"CPURLContentModificationDateKey";
  135. //CPURLAttributeModificationDateKey = @"CPURLAttributeModificationDateKey";
  136. //CPURLLinkCountKey = @"CPURLLinkCountKey";
  137. //CPURLParentDirectoryURLKey = @"CPURLParentDirectoryURLKey";
  138. //CPURLVolumeURLKey = @"CPURLVolumeURLKey";
  139. //CPURLTypeIdentifierKey = @"CPURLTypeIdentifierKey";
  140. //CPURLLocalizedTypeDescriptionKey = @"CPURLLocalizedTypeDescriptionKey";
  141. //CPURLLabelNumberKey = @"CPURLLabelNumberKey";
  142. //CPURLLabelColorKey = @"CPURLLabelColorKey";
  143. //CPURLLocalizedLabelKey = @"CPURLLocalizedLabelKey";
  144. //CPURLEffectiveIconKey = @"CPURLEffectiveIconKey";
  145. //CPURLCustomIconKey = @"CPURLCustomIconKey";
  146. var XMLDocumentFromString = function(anXMLString)
  147. {
  148. if (typeof window["ActiveXObject"] !== "undefined")
  149. {
  150. var XMLDocument = new ActiveXObject("Microsoft.XMLDOM");
  151. XMLDocument.async = false;
  152. XMLDocument.loadXML(anXMLString);
  153. return XMLDocument;
  154. }
  155. return new DOMParser().parseFromString(anXMLString,"text/xml");
  156. };
  157. var parsePROPFINDResponse = function(anXMLString)
  158. {
  159. var XMLDocument = XMLDocumentFromString(anXMLString),
  160. responses = XMLDocument.getElementsByTagNameNS("*", "response"),
  161. responseIndex = 0,
  162. responseCount = responses.length,
  163. propertiesForURLs = @{};
  164. for (; responseIndex < responseCount; ++responseIndex)
  165. {
  166. var response = responses[responseIndex],
  167. elements = response.getElementsByTagNameNS("*", "prop").item(0).childNodes,
  168. index = 0,
  169. count = elements.length,
  170. properties = @{};
  171. for (; index < count; ++index)
  172. {
  173. var element = elements[index];
  174. if (element.nodeType === 8 || element.nodeType === 3)
  175. continue;
  176. var nodeName = element.nodeName,
  177. colonIndex = nodeName.lastIndexOf(':');
  178. if (colonIndex > -1)
  179. nodeName = nodeName.substr(colonIndex + 1);
  180. if (nodeName === @"resourcetype")
  181. [properties setObject:element.firstChild ? CPWebDAVManagerCollectionResourceType : CPWebDAVManagerNonCollectionResourceType forKey:nodeName];
  182. else
  183. [properties setObject:element.firstChild.nodeValue forKey:nodeName];
  184. }
  185. var href = response.getElementsByTagNameNS("*", "href").item(0);
  186. [propertiesForURLs setObject:properties forKey:href.firstChild.nodeValue];
  187. }
  188. return propertiesForURLs;
  189. };
  190. var mapURLsAndProperties = function(/*CPDictionary*/ properties, /*CPURL*/ ignoredURL)
  191. {
  192. };