PageRenderTime 63ms CodeModel.GetById 57ms app.highlight 2ms RepoModel.GetById 0ms app.codeStats 1ms

/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
 23@import "CPArray.j"
 24@import "CPDictionary.j"
 25@import "CPObject.j"
 26@import "CPString.j"
 27@import "CPURL.j"
 28@import "CPURLConnection.j"
 29@import "CPURLRequest.j"
 30
 31var setURLResourceValuesForKeysFromProperties = function(aURL, keys, properties)
 32{
 33    var resourceType = [properties objectForKey:@"resourcetype"];
 34
 35    if (resourceType === CPWebDAVManagerCollectionResourceType)
 36    {
 37        [aURL setResourceValue:YES forKey:CPURLIsDirectoryKey];
 38        [aURL setResourceValue:NO forKey:CPURLIsRegularFileKey];
 39    }
 40    else if (resourceType === CPWebDAVManagerNonCollectionResourceType)
 41    {
 42        [aURL setResourceValue:NO forKey:CPURLIsDirectoryKey];
 43        [aURL setResourceValue:YES forKey:CPURLIsRegularFileKey];
 44    }
 45
 46    var displayName = [properties objectForKey:@"displayname"];
 47
 48    if (displayName !== nil)
 49    {
 50        [aURL setResourceValue:displayName forKey:CPURLNameKey];
 51        [aURL setResourceValue:displayName forKey:CPURLLocalizedNameKey];
 52    }
 53};
 54
 55CPWebDAVManagerCollectionResourceType       = 1;
 56CPWebDAVManagerNonCollectionResourceType    = 0;
 57
 58@implementation CPWebDAVManager : CPObject
 59{
 60    CPDictionary _blocksForConnections;
 61}
 62
 63- (id)init
 64{
 65    self = [super init];
 66
 67    if (self)
 68        _blocksForConnections = @{};
 69
 70    return self;
 71}
 72
 73- (CPArray)contentsOfDirectoryAtURL:(CPURL)aURL includingPropertiesForKeys:(CPArray)keys options:(CPDirectoryEnumerationOptions)aMask block:(Function)aBlock
 74{
 75    var properties = [],
 76        count = [keys count];
 77
 78    while (count--)
 79        properties.push(WebDAVPropertiesForURLKeys[keys[count]]);
 80
 81    var makeContents = function(aURL, response)
 82    {
 83        var contents = [],
 84            URLString = nil,
 85            URLStrings = [response keyEnumerator];
 86
 87        while ((URLString = [URLStrings nextObject]) !== nil)
 88        {
 89            var URL = [CPURL URLWithString:URLString],
 90                properties = [response objectForKey:URLString];
 91
 92            // FIXME: We need better way of comparing URLs.
 93            if (![[URL absoluteString] isEqual:[aURL absoluteString]])
 94            {
 95                contents.push(URL);
 96
 97                setURLResourceValuesForKeysFromProperties(URL, keys, properties);
 98            }
 99        }
100
101        return contents;
102    };
103
104    if (!aBlock)
105        return makeContents(aURL, [self PROPFIND:aURL properties:properties depth:1 block:nil]);
106
107    [self PROPFIND:aURL properties:properties depth:1 block:function(aURL, response)
108    {
109        aBlock(aURL, makeContents(aURL, response));
110    }];
111}
112
113- (CPDictionary)PROPFIND:(CPURL)aURL properties:(CPDictionary)properties depth:(CPString)aDepth block:(Function)aBlock
114{
115    var request = [CPURLRequest requestWithURL:aURL];
116
117    [request setHTTPMethod:@"PROPFIND"];
118    [request setValue:aDepth forHTTPHeaderField:@"Depth"];
119
120    var HTTPBody = ["<?xml version=\"1.0\"?><a:propfind xmlns:a=\"DAV:\">"],
121        index = 0,
122        count = properties.length;
123
124    for (; index < count; ++index)
125        HTTPBody.push("<a:prop><a:", properties[index], "/></a:prop>");
126
127    HTTPBody.push("</a:propfind>");
128
129    [request setHTTPBody:HTTPBody.join("")];
130
131    if (!aBlock)
132        return parsePROPFINDResponse([[CPURLConnection sendSynchronousRequest:request returningResponse:nil] rawString]);
133
134    else
135    {
136        var connection = [CPURLConnection connectionWithRequest:request delegate:self];
137
138        [_blocksForConnections setObject:aBlock forKey:[connection UID]];
139    }
140}
141
142- (void)connection:(CPURLConnection)aURLConnection didReceiveData:(CPString)aString
143{
144    var block = [_blocksForConnections objectForKey:[aURLConnection UID]];
145
146    // FIXME: get the request...
147    block([aURLConnection._request URL], parsePROPFINDResponse(aString));
148}
149
150@end
151
152var WebDAVPropertiesForURLKeys = { };
153
154WebDAVPropertiesForURLKeys[CPURLNameKey]            = @"displayname";
155WebDAVPropertiesForURLKeys[CPURLLocalizedNameKey]   = @"displayname";
156WebDAVPropertiesForURLKeys[CPURLIsRegularFileKey]   = @"resourcetype";
157WebDAVPropertiesForURLKeys[CPURLIsDirectoryKey]     = @"resourcetype";
158//CPURLIsSymbolicLinkKey              = @"CPURLIsSymbolicLinkKey";
159//CPURLIsVolumeKey                    = @"CPURLIsVolumeKey";
160//CPURLIsPackageKey                   = @"CPURLIsPackageKey";
161//CPURLIsSystemImmutableKey           = @"CPURLIsSystemImmutableKey";
162//CPURLIsUserImmutableKey             = @"CPURLIsUserImmutableKey";
163//CPURLIsHiddenKey                    = @"CPURLIsHiddenKey";
164//CPURLHasHiddenExtensionKey          = @"CPURLHasHiddenExtensionKey";
165//CPURLCreationDateKey                = @"CPURLCreationDateKey";
166//CPURLContentAccessDateKey           = @"CPURLContentAccessDateKey";
167//CPURLContentModificationDateKey     = @"CPURLContentModificationDateKey";
168//CPURLAttributeModificationDateKey   = @"CPURLAttributeModificationDateKey";
169//CPURLLinkCountKey                   = @"CPURLLinkCountKey";
170//CPURLParentDirectoryURLKey          = @"CPURLParentDirectoryURLKey";
171//CPURLVolumeURLKey                   = @"CPURLVolumeURLKey";
172//CPURLTypeIdentifierKey              = @"CPURLTypeIdentifierKey";
173//CPURLLocalizedTypeDescriptionKey    = @"CPURLLocalizedTypeDescriptionKey";
174//CPURLLabelNumberKey                 = @"CPURLLabelNumberKey";
175//CPURLLabelColorKey                  = @"CPURLLabelColorKey";
176//CPURLLocalizedLabelKey              = @"CPURLLocalizedLabelKey";
177//CPURLEffectiveIconKey               = @"CPURLEffectiveIconKey";
178//CPURLCustomIconKey                  = @"CPURLCustomIconKey";
179
180var XMLDocumentFromString = function(anXMLString)
181{
182    if (typeof window["ActiveXObject"] !== "undefined")
183    {
184        var XMLDocument = new ActiveXObject("Microsoft.XMLDOM");
185
186        XMLDocument.async = false;
187        XMLDocument.loadXML(anXMLString);
188
189        return XMLDocument;
190    }
191
192    return new DOMParser().parseFromString(anXMLString,"text/xml");
193};
194
195var parsePROPFINDResponse = function(anXMLString)
196{
197    var XMLDocument = XMLDocumentFromString(anXMLString),
198        responses = XMLDocument.getElementsByTagNameNS("*", "response"),
199        responseIndex = 0,
200        responseCount = responses.length,
201        propertiesForURLs = @{};
202
203    for (; responseIndex < responseCount; ++responseIndex)
204    {
205        var response = responses[responseIndex],
206            elements = response.getElementsByTagNameNS("*", "prop").item(0).childNodes,
207            index = 0,
208            count = elements.length,
209            properties = @{};
210
211        for (; index < count; ++index)
212        {
213            var element = elements[index];
214
215            if (element.nodeType === 8 || element.nodeType === 3)
216                continue;
217
218            var nodeName = element.nodeName,
219                colonIndex = nodeName.lastIndexOf(':');
220
221            if (colonIndex > -1)
222                nodeName = nodeName.substr(colonIndex + 1);
223
224            if (nodeName === @"resourcetype")
225                [properties setObject:element.firstChild ? CPWebDAVManagerCollectionResourceType : CPWebDAVManagerNonCollectionResourceType forKey:nodeName];
226            else
227                [properties setObject:element.firstChild.nodeValue forKey:nodeName];
228        }
229
230        var href = response.getElementsByTagNameNS("*", "href").item(0);
231
232        [propertiesForURLs setObject:properties forKey:href.firstChild.nodeValue];
233    }
234
235    return propertiesForURLs;
236};
237
238var mapURLsAndProperties = function(/*CPDictionary*/ properties, /*CPURL*/ ignoredURL)
239{
240
241};