]> err.no Git - scalable-opengroupware.org/blobdiff - SoObjects/Contacts/SOGoContactLDAPFolder.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1257 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SoObjects / Contacts / SOGoContactLDAPFolder.m
index 75c198947765ad87e30cab1968d2dbbf013c0179..7345c9c5a34ba18fe2b2547a5a5ce8b1412596a5 100644 (file)
 #import <Foundation/NSString.h>
 
 #import <NGObjWeb/NSException+HTTP.h>
-#import <NGObjWeb/SoObject.h>
 #import <NGObjWeb/WOApplication.h>
 #import <NGObjWeb/WOContext.h>
 #import <NGObjWeb/WOContext+SoObjects.h>
+#import <NGObjWeb/WOResponse.h>
+#import <NGObjWeb/SoObject.h>
 #import <NGObjWeb/SoUser.h>
 #import <EOControl/EOSortOrdering.h>
+#import <SaxObjC/XMLNamespaces.h>
 
 #import <SoObjects/SOGo/LDAPSource.h>
+#import <SoObjects/SOGo/NSString+Utilities.h>
 #import "SOGoContactLDIFEntry.h"
 #import "SOGoContactLDAPFolder.h"
-
-#define folderListingFields [NSArray arrayWithObjects: @"c_name", @"cn", \
-                                     @"displayName",                     \
-                                     @"streetAddress",                   \
-                                     @"o", \
-                                     @"sn", @"givenname", @"l",          \
-                                     @"mail", @"telephonenumber",        \
-                                     @"mailNickname",                    \
-                                     @"sAMAccountName",                  \
-                                     @"uid",                  \
-                                     nil]
+#import <NGExtensions/NSString+misc.h>
+#import <NGObjWeb/WORequest.h>
+#import <NGObjWeb/SoSelectorInvocation.h>
 
 @class WOContext;
 
 @implementation SOGoContactLDAPFolder
 
-+ (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
-                                  andDisplayName: (NSString *) aDisplayName
-                                     inContainer: (SOGoObject *) aContainer
+#warning this should be unified within SOGoFolder
+- (void) appendObject: (NSDictionary *) object
+          withBaseURL: (NSString *) baseURL
+     toREPORTResponse: (WOResponse *) r
 {
-  SOGoContactLDAPFolder *folder;
+  SOGoContactLDIFEntry *component;
+  NSString *name, *etagLine, *contactString;
+
+  name = [object objectForKey: @"c_name"];
+  component = [self lookupName: name inContext: context acquire: NO];
+
+  [r appendContentString: @"  <D:response>\r\n"];
+  [r appendContentString: @"    <D:href>"];
+  [r appendContentString: baseURL];
+  if (![baseURL hasSuffix: @"/"])
+    [r appendContentString: @"/"];
+  [r appendContentString: name];
+  [r appendContentString: @"</D:href>\r\n"];
+
+  [r appendContentString: @"    <D:propstat>\r\n"];
+  [r appendContentString: @"      <D:prop>\r\n"];
+  etagLine = [NSString stringWithFormat: @"        <D:getetag>%@</D:getetag>\r\n",
+                       [component davEntityTag]];
+  [r appendContentString: etagLine];
+  [r appendContentString: @"      </D:prop>\r\n"];
+  [r appendContentString: @"      <D:status>HTTP/1.1 200 OK</D:status>\r\n"];
+  [r appendContentString: @"    </D:propstat>\r\n"];
+  [r appendContentString: @"    <C:addressbook-data>"];
+  contactString = [[component contentAsString] stringByEscapingXMLString];
+  [r appendContentString: contactString];
+  [r appendContentString: @"</C:addressbook-data>\r\n"];
+  [r appendContentString: @"  </D:response>\r\n"];
+}
+
++ (id) folderWithName: (NSString *) aName
+       andDisplayName: (NSString *) aDisplayName
+         inContainer: (id) aContainer
+{
+  id folder;
 
   folder = [[self alloc] initWithName: aName
                          andDisplayName: aDisplayName
@@ -69,9 +98,7 @@
 {
   if ((self = [super init]))
     {
-      name = nil;
       displayName = nil;
-      container = nil;
       entries = nil;
       ldapSource = nil;
     }
   return self;
 }
 
-- (id <SOGoContactFolder>) initWithName: (NSString *) newName
-                         andDisplayName: (NSString *) newDisplayName
-                            inContainer: (SOGoObject *) newContainer
+- (id) initWithName: (NSString *) newName
+     andDisplayName: (NSString *) newDisplayName
+       inContainer: (id) newContainer
 {
-  self = [self init];
-
-  ASSIGN (name, newName);
-  ASSIGN (displayName, newDisplayName);
-  ASSIGN (container, newContainer);
+  if ((self = [self initWithName: newName
+                   inContainer: newContainer]))
+    {
+      ASSIGN (displayName, newDisplayName);
+    }
 
   return self;
 }
 
 - (void) dealloc
 {
-  [name release];
   [displayName release];
-  [container release];
   [entries release];
   [ldapSource release];
   [super dealloc];
   return displayName;
 }
 
-- (NSString *) nameInContainer
+- (NSArray *) davNamespaces
 {
-  return name;
+  return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:carddav"];
 }
 
 - (id) lookupName: (NSString *) objectName
   id obj;
   NSDictionary *ldifEntry;
 
-//   NSLog (@"looking up name '%@'...", name);
+  //NSLog (@"looking up name '%@'...", objectName);
 
   /* first check attributes directly bound to the application */
   obj = [super lookupName: objectName inContext: lookupContext acquire: NO];
+
   if (!obj)
     {
       ldifEntry = [ldapSource lookupContactEntry: objectName];
       obj = ((ldifEntry)
-            ? [SOGoContactLDIFEntry contactEntryWithName: name
+            ? [SOGoContactLDIFEntry contactEntryWithName: objectName
                                     withLDIFEntry: ldifEntry
                                     inContainer: self]
             : [NSException exceptionWithHTTPStatus: 404]);
   return [ldapSource allEntryIDs];
 }
 
+- (NSArray *) _flattenedRecords: (NSArray *) records
+{
+  NSMutableArray *newRecords;
+  NSEnumerator *oldRecords;
+  NSDictionary *oldRecord;
+  NSMutableDictionary *newRecord;
+  NSString *data;
+  
+  newRecords = [[NSMutableArray alloc] initWithCapacity: [records count]];
+  [newRecords autorelease];
+
+  oldRecords = [records objectEnumerator];
+  oldRecord = [oldRecords nextObject];
+  while (oldRecord)
+    {
+      newRecord = [NSMutableDictionary new];
+      [newRecord autorelease];
+
+      [newRecord setObject: [oldRecord objectForKey: @"c_uid"]
+                forKey: @"c_uid"];
+      [newRecord setObject: [oldRecord objectForKey: @"c_name"]
+                forKey: @"c_name"];
+
+      data = [oldRecord objectForKey: @"displayName"];
+      if (!data)
+       data = [oldRecord objectForKey: @"c_cn"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data forKey: @"displayName"];
+
+      data = [oldRecord objectForKey: @"mail"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data forKey: @"mail"];
+
+      data = [oldRecord objectForKey: @"nsAIMid"];
+      if (![data length])
+       data = [oldRecord objectForKey: @"nscpaimscreenname"];
+      if (![data length])
+       data = @"";
+      [newRecord setObject: data forKey: @"screenName"];
+
+      data = [oldRecord objectForKey: @"o"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data forKey: @"org"];
+
+      data = [oldRecord objectForKey: @"telephoneNumber"];
+      if (![data length])
+       data = [oldRecord objectForKey: @"cellphone"];
+      if (![data length])
+       data = [oldRecord objectForKey: @"homePhone"];
+      if (![data length])
+       data = @"";
+      [newRecord setObject: data forKey: @"phone"];
+
+      [newRecords addObject: newRecord];
+      oldRecord = [oldRecords nextObject];
+    }
+
+  return newRecords;
+}
+
 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
                                 sortBy: (NSString *) sortKey
                               ordering: (NSComparisonResult) sortOrdering
 
   if (filter && [filter length] > 0)
     {
-      records = [ldapSource fetchContactsMatching: filter];
+      records = [self _flattenedRecords:
+                       [ldapSource fetchContactsMatching: filter]];
       ordering
         = [EOSortOrdering sortOrderingWithKey: sortKey
                           selector: ((sortOrdering == NSOrderedDescending)
                      [NSArray arrayWithObject: ordering]];
     }
 
-  //[self debugWithFormat:@"fetched %i records.", [records count]];
   return result;
 }
 
-- (NSString *) groupDavResourceType
+- (NSArray *) davResourceType
+{
+  NSArray *rType, *groupDavCollection;
+
+  groupDavCollection = [NSArray arrayWithObjects: @"vcard-collection",
+                               XMLNS_GROUPDAV, nil];
+  rType = [NSArray arrayWithObjects: @"collection", groupDavCollection, nil];
+
+  return rType;
+}
+
+- (NSString *) davContentType
 {
-  return @"vcard-collection";
+  return @"httpd/unix-directory";
+}
+
+- (BOOL) davIsCollection
+{
+  return YES;
+}
+
+- (NSString *) davDisplayName
+{
+  return displayName;
+}
+
+- (BOOL) isFolderish
+{
+  return YES;
+}
+
+/* sorting */
+- (NSComparisonResult) compare: (id) otherFolder
+{
+  NSComparisonResult comparison;
+
+  if ([NSStringFromClass([otherFolder class])
+                       isEqualToString: @"SOGoContactGCSFolder"])
+    comparison = NSOrderedDescending;
+  else
+    comparison
+      = [[self displayName]
+         localizedCaseInsensitiveCompare: [otherFolder displayName]];
+
+  return comparison;
 }
 
 /* acls */
+- (NSString *) ownerInContext: (WOContext *) noContext
+{
+  return @"nobody";
+}
+
 /* TODO: this might change one day when we support LDAP acls */
 - (NSArray *) aclsForUser: (NSString *) uid
 {