]> err.no Git - scalable-opengroupware.org/blob - SoObjects/Contacts/SOGoFolder+CardDAV.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1246 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SoObjects / Contacts / SOGoFolder+CardDAV.m
1 /* NSObject+CardDAV.m - this file is part of SOGo
2  *
3  * Copyright (C) 2007 Inverse groupe conseil
4  *
5  * Author: Ludovic Marcotte <ludovic@inverse.ca>
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #import <Foundation/NSArray.h>
24
25 #import <NGObjWeb/WOContext.h>
26 #import <NGObjWeb/WORequest.h>
27 #import <NGObjWeb/WOResponse.h>
28 #import <NGExtensions/NSString+misc.h>
29 #import <DOM/DOMProtocols.h>
30 #import <SaxObjC/SaxObjC.h>
31 #import <SaxObjC/XMLNamespaces.h>
32
33 #import "SOGoContactFolder.h"
34 #import "SOGoContactGCSEntry.h"
35
36 @implementation SOGoFolder (CardDAV)
37
38 - (void) _appendComponentsMatchingFilters: (NSArray *) filters
39                                toResponse: (WOResponse *) response
40                                   context: (id) localContext
41 {
42   unsigned int count, max;
43   NSDictionary *currentFilter, *contact;
44   NSEnumerator *contacts;
45   NSString *baseURL;
46   SOGoObject <SOGoContactFolder> *o;
47
48   o = (id<SOGoContactFolder>)self;
49   baseURL = [o baseURLInContext: localContext];
50   
51   max = [filters count];
52   for (count = 0; count < max; count++)
53     {
54       currentFilter = [filters objectAtIndex: count];
55       contacts = [[o lookupContactsWithFilter: [[currentFilter allValues] lastObject]
56                      sortBy: @"c_givenname"
57                      ordering: NSOrderedDescending]
58                    objectEnumerator];
59       
60       while ((contact = [contacts nextObject]))
61       {
62         [o appendObject: contact
63            withBaseURL: baseURL
64            toREPORTResponse: response];
65         }
66     }
67 }
68
69 - (BOOL) _isValidFilter: (NSString *) theString
70 {
71   if ([theString caseInsensitiveCompare: @"sn"] == NSOrderedSame)
72     return YES;
73
74   if ([theString caseInsensitiveCompare: @"givenname"] == NSOrderedSame)
75     return YES;
76
77   if ([theString caseInsensitiveCompare: @"mail"] == NSOrderedSame)
78     return YES;
79
80   if ([theString caseInsensitiveCompare: @"telephonenumber"] == NSOrderedSame)
81     return YES;
82
83   return NO;
84 }
85
86 - (NSDictionary *) _parseContactFilter: (id <DOMElement>) filterElement
87 {
88   NSMutableDictionary *filterData;
89   id <DOMNode> parentNode;
90   id <DOMNodeList> ranges;
91
92   parentNode = [filterElement parentNode];
93
94   if ([[parentNode tagName] isEqualToString: @"filter"] &&
95       [self _isValidFilter: [filterElement attribute: @"name"]])
96     {
97       ranges = [filterElement getElementsByTagName: @"text-match"];
98      
99       if ([(NSArray *)ranges count] && [(NSArray *)[[ranges objectAtIndex: 0] childNodes] count])
100         {
101           filterData = [NSMutableDictionary new];
102           [filterData autorelease];
103           [filterData setObject: [[(NSArray *)[[ranges objectAtIndex: 0] childNodes] lastObject] data]
104                       forKey: [filterElement attribute: @"name"]];
105         }
106     }
107   else
108     filterData = nil;
109
110   return filterData;
111 }
112
113 - (NSArray *) _parseContactFilters: (id <DOMElement>) parentNode
114 {
115   NSEnumerator *children;
116   id<DOMElement> node;
117   NSMutableArray *filters;
118   NSDictionary *filter;
119
120   filters = [[NSMutableArray new] autorelease];
121
122   children = [[parentNode getElementsByTagName: @"prop-filter"]
123                objectEnumerator];
124
125   node = [children nextObject];
126
127   while (node)
128     {
129       filter = [self _parseContactFilter: node];
130       if (filter)
131         [filters addObject: filter];
132       node = [children nextObject];
133     }
134
135   return filters;
136 }
137
138 - (id) davAddressbookQuery: (id) queryContext
139 {
140   WOResponse *r;
141   NSArray *filters;
142   id <DOMDocument> document;
143
144   r = [queryContext response];
145   [r setStatus: 207];
146   [r setContentEncoding: NSUTF8StringEncoding];
147   [r setHeader: @"text/xml; charset=\"utf-8\"" forKey: @"content-type"];
148   [r setHeader: @"no-cache" forKey: @"pragma"];
149   [r setHeader: @"no-cache" forKey: @"cache-control"];
150   [r appendContentString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"];
151   [r appendContentString: @"<D:multistatus xmlns:D=\"DAV:\""
152      @" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\r\n"];
153
154   document = [[queryContext request] contentAsDOMDocument];
155   filters = [self _parseContactFilters: [document documentElement]];
156
157   [self _appendComponentsMatchingFilters: filters
158         toResponse: r
159         context: queryContext];
160   [r appendContentString:@"</D:multistatus>\r\n"];
161
162   return r;
163 }
164
165 @end