]> err.no Git - sope/blob - sope-ldap/NGLdap/NGLdapDataSource.m
some code cleanups
[sope] / sope-ldap / NGLdap / NGLdapDataSource.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21
22 #include "NGLdapDataSource.h"
23 #include "NGLdapEntry.h"
24 #include "NGLdapAttribute.h"
25 #include "NGLdapConnection.h"
26 #import <NGExtensions/NGFileFolderInfoDataSource.h>
27 #import <EOControl/EOControl.h>
28 #include "common.h"
29
30 @implementation NGLdapDataSource
31
32 - (id)initWithLdapConnection:(NGLdapConnection *)_con searchBase:(NSString *)_dn{
33   if (_con == nil) {
34     [self release];
35     return nil;
36   }
37   if ((self = [super init])) {
38     self->ldap       = [_con retain];
39     self->searchBase = [_dn copy];
40   }
41   return self;
42 }
43
44 - (void)dealloc {
45   [self->searchBase release];
46   [self->fspec      release];
47   [self->ldap       release];
48   [super dealloc];
49 }
50
51 - (void)setFetchSpecification:(EOFetchSpecification *)_fspec {
52   /* should invalidate ds chain */
53   ASSIGN(self->fspec, _fspec);
54 }
55 - (EOFetchSpecification *)fetchSpecification {
56   return self->fspec;
57 }
58
59 /* transformation */
60
61 - (NSDictionary *)_recordFromEntry:(NGLdapEntry *)_entry {
62   NSMutableDictionary *md;
63   NSEnumerator        *keys;
64   NSString            *key;
65   id tmp;
66   
67   if (_entry == nil)
68     return nil;
69   
70   md = [NSMutableDictionary dictionaryWithCapacity:[_entry count]];
71   
72   if ((tmp = [_entry dn])) {
73     [md setObject:tmp forKey:@"NSFileIdentifier"];
74     [md setObject:tmp forKey:NSFilePath];
75   }
76   if ((tmp = [_entry rdn]))
77     [md setObject:tmp forKey:NSFileName];
78   
79   keys = [[_entry attributeNames] objectEnumerator];
80   
81   while ((key = [keys nextObject])) {
82     NGLdapAttribute *attribute;
83     unsigned count;
84     id value;
85     
86     attribute = [_entry attributeWithName:key];
87     count     = [attribute count];
88     
89     if (count == 0)
90       value = [EONull null];
91     else if (count == 1)
92       value = [attribute stringValueAtIndex:0];
93     else
94       value = [attribute allStringValues];
95
96     [md setObject:value forKey:key];
97   }
98
99   return [[md copy] autorelease];
100 }
101
102 /* operations */
103
104 - (NSArray *)fetchObjects { // TODO: use the new fetch-enumerator
105   NSAutoreleasePool *pool;
106   NSString       *scope;
107   EOQualifier    *qualifier;
108   NSArray        *sortOrderings;
109   NSEnumerator   *e;
110   NSString       *baseDN;
111   NSMutableArray *results;
112   NGLdapEntry    *entry;
113   NSArray        *array;
114   NSArray        *attrs;
115
116   pool = [NSAutoreleasePool new];
117   
118   scope         = nil;
119   qualifier     = nil;
120   sortOrderings = nil;
121   baseDN        = nil;
122   attrs         = nil;
123   
124   if (self->fspec) {
125     NSString *entityName;
126     
127     qualifier     = [self->fspec qualifier];
128     sortOrderings = [self->fspec sortOrderings];
129     scope         = [[self->fspec hints] objectForKey:@"NSFetchScope"];
130     attrs         = [[self->fspec hints] objectForKey:@"NSFetchKeys"];
131
132     if ((entityName = [self->fspec entityName])) {
133       EOQualifier *oq;
134
135       oq = [[EOKeyValueQualifier alloc]
136                                  initWithKey:@"objectclass"
137                                  operatorSelector:EOQualifierOperatorEqual
138                                  value:entityName];
139       if (qualifier) {
140         NSArray *qa;
141         
142         qa = [NSArray arrayWithObjects:oq, qualifier, nil];
143         qualifier = [[EOAndQualifier alloc] initWithQualifierArray:qa];
144         qualifier = [qualifier autorelease];
145         [oq release]; oq = nil;
146       }
147       else {
148         qualifier = [oq autorelease];
149         oq = nil;
150       }
151     }
152   }
153   else {
154     static NSArray *so = nil;
155     if (so == nil) {
156       EOSortOrdering *o;
157       o = [EOSortOrdering sortOrderingWithKey:@"NSFileIdentifier"
158                           selector:EOCompareAscending];
159       so = [[NSArray alloc] initWithObjects:&o count:1];
160     }
161     sortOrderings = so;
162   }
163   
164   if (scope == nil)
165     scope = @"NSFetchScopeOneLevel";
166   if (baseDN == nil)
167     baseDN = self->searchBase;
168
169   if ([scope isEqualToString:@"NSFetchScopeOneLevel"]) {
170     e = [self->ldap flatSearchAtBaseDN:baseDN
171                     qualifier:qualifier
172                     attributes:attrs];
173   }
174   else if ([scope isEqualToString:@"NSFetchScopeSubTree"]) {
175     e = [self->ldap deepSearchAtBaseDN:baseDN
176                     qualifier:qualifier
177                     attributes:attrs];
178   }
179   else {
180     [NSException raise:@"NGLdapDataSourceException"
181                  format:@"unsupported fetch-scope: '%@' !", scope];
182     e = nil;
183   }
184   
185   if (e == nil) {
186     /* no results */
187     [pool release];
188     return nil;
189   }
190
191   /* transform results into records */
192   
193   results = [NSMutableArray arrayWithCapacity:64];
194   while ((entry = [e nextObject])) {
195     NSDictionary *record;
196
197     if ((record = [self _recordFromEntry:entry]) == nil) {
198       NSLog(@"WARNING: couldn't transform entry %@ into record !", entry);
199       continue;
200     }
201     
202     [results addObject:record];
203   }
204   array = [[results copy] autorelease];
205   
206   /* apply sort-orderings in-memory */
207   if (sortOrderings)
208     array = [array sortedArrayUsingKeyOrderArray:sortOrderings];
209
210   array = [array retain];
211   [pool release];
212   
213   return [array autorelease];
214 }
215
216 - (NSString *)searchBase {
217   return self->searchBase;
218 }
219
220
221 @end /* NGLdapDataSource */