![]() |
API 0.9.5
|
00001 /* 00002 * CPWebDAVManager.j 00003 * Foundation 00004 * 00005 * Created by Francisco Tolmasky. 00006 * Copyright 2008, 280 North, Inc. 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 00024 var setURLResourceValuesForKeysFromProperties = function(aURL, keys, properties) 00025 { 00026 var resourceType = [properties objectForKey:@"resourcetype"]; 00027 00028 if (resourceType === CPWebDAVManagerCollectionResourceType) 00029 { 00030 [aURL setResourceValue:YES forKey:CPURLIsDirectoryKey]; 00031 [aURL setResourceValue:NO forKey:CPURLIsRegularFileKey]; 00032 } 00033 else if (resourceType === CPWebDAVManagerNonCollectionResourceType) 00034 { 00035 [aURL setResourceValue:NO forKey:CPURLIsDirectoryKey]; 00036 [aURL setResourceValue:YES forKey:CPURLIsRegularFileKey]; 00037 } 00038 00039 var displayName = [properties objectForKey:@"displayname"]; 00040 00041 if (displayName !== nil) 00042 { 00043 [aURL setResourceValue:displayName forKey:CPURLNameKey]; 00044 [aURL setResourceValue:displayName forKey:CPURLLocalizedNameKey]; 00045 } 00046 } 00047 00048 CPWebDAVManagerCollectionResourceType = 1; 00049 CPWebDAVManagerNonCollectionResourceType = 0; 00050 00051 @implementation CPWebDAVManager : CPObject 00052 { 00053 CPDictionary _blocksForConnections; 00054 } 00055 00056 - (id)init 00057 { 00058 self = [super init]; 00059 00060 if (self) 00061 _blocksForConnections = [CPDictionary dictionary]; 00062 00063 return self; 00064 } 00065 00066 - (CPArray)contentsOfDirectoryAtURL:(CPURL)aURL includingPropertiesForKeys:(CPArray)keys options:(CPDirectoryEnumerationOptions)aMask block:(Function)aBlock 00067 { 00068 var properties = [], 00069 count = [keys count]; 00070 00071 while (count--) 00072 properties.push(WebDAVPropertiesForURLKeys[keys[count]]); 00073 00074 var makeContents = function(aURL, response) 00075 { 00076 var contents = [], 00077 URLString = nil, 00078 URLStrings = [response keyEnumerator]; 00079 00080 while (URLString = [URLStrings nextObject]) 00081 { 00082 var URL = [CPURL URLWithString:URLString], 00083 properties = [response objectForKey:URLString]; 00084 00085 // FIXME: We need better way of comparing URLs. 00086 if (![[URL absoluteString] isEqual:[aURL absoluteString]]) 00087 { 00088 contents.push(URL); 00089 00090 setURLResourceValuesForKeysFromProperties(URL, keys, properties); 00091 } 00092 } 00093 00094 return contents; 00095 } 00096 00097 if (!aBlock) 00098 return makeContents(aURL, [self PROPFIND:aURL properties:properties depth:1 block:nil]); 00099 00100 [self PROPFIND:aURL properties:properties depth:1 block:function(aURL, response) 00101 { 00102 aBlock(aURL, makeContents(aURL, response)); 00103 }]; 00104 } 00105 00106 - (CPDictionary)PROPFIND:(CPURL)aURL properties:(CPDictionary)properties depth:(CPString)aDepth block:(Function)aBlock 00107 { 00108 var request = [CPURLRequest requestWithURL:aURL]; 00109 00110 [request setHTTPMethod:@"PROPFIND"]; 00111 [request setValue:aDepth forHTTPHeaderField:@"Depth"]; 00112 00113 var HTTPBody = ["<?xml version=\"1.0\"?><a:propfind xmlns:a=\"DAV:\">"], 00114 index = 0, 00115 count = properties.length; 00116 00117 for (; index < count; ++index) 00118 HTTPBody.push("<a:prop><a:", properties[index], "/></a:prop>"); 00119 00120 HTTPBody.push("</a:propfind>"); 00121 00122 [request setHTTPBody:HTTPBody.join("")]; 00123 00124 if (!aBlock) 00125 return parsePROPFINDResponse([[CPURLConnection sendSynchronousRequest:request returningResponse:nil] rawString]); 00126 00127 else 00128 { 00129 var connection = [CPURLConnection connectionWithRequest:request delegate:self]; 00130 00131 [_blocksForConnections setObject:aBlock forKey:[connection UID]]; 00132 } 00133 } 00134 00135 - (void)connection:(CPURLConnection)aURLConnection didReceiveData:(CPString)aString 00136 { 00137 var block = [_blocksForConnections objectForKey:[aURLConnection UID]]; 00138 00139 // FIXME: get the request... 00140 block([aURLConnection._request URL], parsePROPFINDResponse(aString)); 00141 } 00142 00143 @end 00144 00145 var WebDAVPropertiesForURLKeys = { }; 00146 00147 WebDAVPropertiesForURLKeys[CPURLNameKey] = @"displayname"; 00148 WebDAVPropertiesForURLKeys[CPURLLocalizedNameKey] = @"displayname"; 00149 WebDAVPropertiesForURLKeys[CPURLIsRegularFileKey] = @"resourcetype"; 00150 WebDAVPropertiesForURLKeys[CPURLIsDirectoryKey] = @"resourcetype"; 00151 //CPURLIsSymbolicLinkKey = @"CPURLIsSymbolicLinkKey"; 00152 //CPURLIsVolumeKey = @"CPURLIsVolumeKey"; 00153 //CPURLIsPackageKey = @"CPURLIsPackageKey"; 00154 //CPURLIsSystemImmutableKey = @"CPURLIsSystemImmutableKey"; 00155 //CPURLIsUserImmutableKey = @"CPURLIsUserImmutableKey"; 00156 //CPURLIsHiddenKey = @"CPURLIsHiddenKey"; 00157 //CPURLHasHiddenExtensionKey = @"CPURLHasHiddenExtensionKey"; 00158 //CPURLCreationDateKey = @"CPURLCreationDateKey"; 00159 //CPURLContentAccessDateKey = @"CPURLContentAccessDateKey"; 00160 //CPURLContentModificationDateKey = @"CPURLContentModificationDateKey"; 00161 //CPURLAttributeModificationDateKey = @"CPURLAttributeModificationDateKey"; 00162 //CPURLLinkCountKey = @"CPURLLinkCountKey"; 00163 //CPURLParentDirectoryURLKey = @"CPURLParentDirectoryURLKey"; 00164 //CPURLVolumeURLKey = @"CPURLVolumeURLKey"; 00165 //CPURLTypeIdentifierKey = @"CPURLTypeIdentifierKey"; 00166 //CPURLLocalizedTypeDescriptionKey = @"CPURLLocalizedTypeDescriptionKey"; 00167 //CPURLLabelNumberKey = @"CPURLLabelNumberKey"; 00168 //CPURLLabelColorKey = @"CPURLLabelColorKey"; 00169 //CPURLLocalizedLabelKey = @"CPURLLocalizedLabelKey"; 00170 //CPURLEffectiveIconKey = @"CPURLEffectiveIconKey"; 00171 //CPURLCustomIconKey = @"CPURLCustomIconKey"; 00172 00173 var XMLDocumentFromString = function(anXMLString) 00174 { 00175 if (typeof window["ActiveXObject"] !== "undefined") 00176 { 00177 var XMLDocument = new ActiveXObject("Microsoft.XMLDOM"); 00178 00179 XMLDocument.async = false; 00180 XMLDocument.loadXML(anXMLString); 00181 00182 return XMLDocument; 00183 } 00184 00185 return new DOMParser().parseFromString(anXMLString,"text/xml"); 00186 } 00187 00188 var parsePROPFINDResponse = function(anXMLString) 00189 { 00190 var XMLDocument = XMLDocumentFromString(anXMLString), 00191 responses = XMLDocument.getElementsByTagNameNS("*", "response"), 00192 responseIndex = 0, 00193 responseCount = responses.length, 00194 propertiesForURLs = [CPDictionary dictionary]; 00195 00196 for (; responseIndex < responseCount; ++responseIndex) 00197 { 00198 var response = responses[responseIndex], 00199 elements = response.getElementsByTagNameNS("*", "prop").item(0).childNodes, 00200 index = 0, 00201 count = elements.length, 00202 properties = [CPDictionary dictionary]; 00203 00204 for (; index < count; ++index) 00205 { 00206 var element = elements[index]; 00207 00208 if (element.nodeType === 8 || element.nodeType === 3) 00209 continue; 00210 00211 var nodeName = element.nodeName, 00212 colonIndex = nodeName.lastIndexOf(':'); 00213 00214 if (colonIndex > -1) 00215 nodeName = nodeName.substr(colonIndex + 1); 00216 00217 if (nodeName === @"resourcetype") 00218 [properties setObject:element.firstChild ? CPWebDAVManagerCollectionResourceType : CPWebDAVManagerNonCollectionResourceType forKey:nodeName]; 00219 else 00220 [properties setObject:element.firstChild.nodeValue forKey:nodeName]; 00221 } 00222 00223 var href = response.getElementsByTagNameNS("*", "href").item(0); 00224 00225 [propertiesForURLs setObject:properties forKey:href.firstChild.nodeValue]; 00226 } 00227 00228 return propertiesForURLs; 00229 } 00230 00231 var mapURLsAndProperties = function(/*CPDictionary*/ properties, /*CPURL*/ ignoredURL) 00232 { 00233 00234 }