]> err.no Git - sope/blob - sope-ldap/NGLdap/NGLdapDataSource.m
more directory hierarchy reorganisations,
[sope] / sope-ldap / NGLdap / NGLdapDataSource.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo 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   OGo 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 OGo; 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 // $Id$
22
23 #include "NGLdapDataSource.h"
24 #include "NGLdapEntry.h"
25 #include "NGLdapAttribute.h"
26 #include "NGLdapConnection.h"
27 #import <NGExtensions/NGFileFolderInfoDataSource.h>
28 #import <EOControl/EOControl.h>
29 #include "common.h"
30
31 @implementation NGLdapDataSource
32
33 - (id)initWithLdapConnection:(NGLdapConnection *)_con searchBase:(NSString *)_dn{
34   if (_con == nil) {
35     [self release];
36     return nil;
37   }
38   if ((self = [super init])) {
39     self->ldap       = [_con retain];
40     self->searchBase = [_dn copy];
41   }
42   return self;
43 }
44
45 - (void)dealloc {
46   [self->searchBase release];
47   [self->fspec      release];
48   [self->ldap       release];
49   [super dealloc];
50 }
51
52 - (void)setFetchSpecification:(EOFetchSpecification *)_fspec {
53   /* should invalidate ds chain */
54   ASSIGN(self->fspec, _fspec);
55 }
56 - (EOFetchSpecification *)fetchSpecification {
57   return self->fspec;
58 }
59
60 /* transformation */
61
62 - (NSDictionary *)_recordFromEntry:(NGLdapEntry *)_entry {
63   NSMutableDictionary *md;
64   NSEnumerator        *keys;
65   NSString            *key;
66   id tmp;
67   
68   if (_entry == nil)
69     return nil;
70   
71   md = [NSMutableDictionary dictionaryWithCapacity:[_entry count]];
72   
73   if ((tmp = [_entry dn])) {
74     [md setObject:tmp forKey:@"NSFileIdentifier"];
75     [md setObject:tmp forKey:NSFilePath];
76   }
77   if ((tmp = [_entry rdn]))
78     [md setObject:tmp forKey:NSFileName];
79   
80   keys = [[_entry attributeNames] objectEnumerator];
81   
82   while ((key = [keys nextObject])) {
83     NGLdapAttribute *attribute;
84     unsigned count;
85     id value;
86     
87     attribute = [_entry attributeWithName:key];
88     count     = [attribute count];
89     
90     if (count == 0)
91       value = [EONull null];
92     else if (count == 1)
93       value = [attribute stringValueAtIndex:0];
94     else
95       value = [attribute allStringValues];
96
97     [md setObject:value forKey:key];
98   }
99
100   return [[md copy] autorelease];
101 }
102
103 /* operations */
104
105 - (NSArray *)fetchObjects { // TODO: use the new fetch-enumerator
106   NSAutoreleasePool *pool;
107   NSString       *scope;
108   EOQualifier    *qualifier;
109   NSArray        *sortOrderings;
110   NSEnumerator   *e;
111   NSString       *baseDN;
112   NSMutableArray *results;
113   NGLdapEntry    *entry;
114   NSArray        *array;
115   NSArray        *attrs;
116
117   pool = [NSAutoreleasePool new];
118   
119   scope         = nil;
120   qualifier     = nil;
121   sortOrderings = nil;
122   baseDN        = nil;
123   attrs         = nil;
124   
125   if (self->fspec) {
126     NSString *entityName;
127     
128     qualifier     = [self->fspec qualifier];
129     sortOrderings = [self->fspec sortOrderings];
130     scope         = [[self->fspec hints] objectForKey:@"NSFetchScope"];
131     attrs         = [[self->fspec hints] objectForKey:@"NSFetchKeys"];
132
133     if ((entityName = [self->fspec entityName])) {
134       EOQualifier *oq;
135
136       oq = [[EOKeyValueQualifier alloc]
137                                  initWithKey:@"objectclass"
138                                  operatorSelector:EOQualifierOperatorEqual
139                                  value:entityName];
140       if (qualifier) {
141         NSArray *qa;
142         
143         qa = [NSArray arrayWithObjects:oq, qualifier, nil];
144         qualifier = [[EOAndQualifier alloc] initWithQualifierArray:qa];
145         qualifier = [qualifier autorelease];
146         [oq release]; oq = nil;
147       }
148       else {
149         qualifier = [oq autorelease];
150         oq = nil;
151       }
152     }
153   }
154   else {
155     static NSArray *so = nil;
156     if (so == nil) {
157       EOSortOrdering *o;
158       o = [EOSortOrdering sortOrderingWithKey:@"NSFileIdentifier"
159                           selector:EOCompareAscending];
160       so = [[NSArray alloc] initWithObjects:&o count:1];
161     }
162     sortOrderings = so;
163   }
164   
165   if (scope == nil)
166     scope = @"NSFetchScopeOneLevel";
167   if (baseDN == nil)
168     baseDN = self->searchBase;
169
170   if ([scope isEqualToString:@"NSFetchScopeOneLevel"]) {
171     e = [self->ldap flatSearchAtBaseDN:baseDN
172                     qualifier:qualifier
173                     attributes:attrs];
174   }
175   else if ([scope isEqualToString:@"NSFetchScopeSubTree"]) {
176     e = [self->ldap deepSearchAtBaseDN:baseDN
177                     qualifier:qualifier
178                     attributes:attrs];
179   }
180   else {
181     [NSException raise:@"NGLdapDataSourceException"
182                  format:@"unsupported fetch-scope: '%@' !", scope];
183     e = nil;
184   }
185   
186   if (e == nil) {
187     /* no results */
188     [pool release];
189     return nil;
190   }
191
192   /* transform results into records */
193   
194   results = [NSMutableArray arrayWithCapacity:64];
195   while ((entry = [e nextObject])) {
196     NSDictionary *record;
197
198     if ((record = [self _recordFromEntry:entry]) == nil) {
199       NSLog(@"WARNING: couldn't transform entry %@ into record !", entry);
200       continue;
201     }
202     
203     [results addObject:record];
204   }
205   array = [[results copy] autorelease];
206   
207   /* apply sort-orderings in-memory */
208   if (sortOrderings)
209     array = [array sortedArrayUsingKeyOrderArray:sortOrderings];
210
211   array = [array retain];
212   [pool release];
213   
214   return [array autorelease];
215 }
216
217 - (NSString *)searchBase {
218   return self->searchBase;
219 }
220
221
222 @end /* NGLdapDataSource */