diff --git a/ChangeLog b/ChangeLog index 673042b63..d7449179e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,11 +9,6 @@ 2010-10-13 Wolfgang Sourdeau - * OpenChange/MAPIStoreContext.m - (-getMessageTableChildproperty:atURL:withTag:inFolder:withFID:): - added missing "break" statement, leading PR_FID to get the value - of PR_MID. - * OpenChange/MAPIStoreMapping.m (-registerURL:): commented method out. (-_setupFixedMapping): new method that registers well-known ids with well-known urls. @@ -21,6 +16,22 @@ * OpenChange/MAPIStoreContext.m (+contextFromURI:): no longer register the URI mapping since the basic ones are always registered. + (-setURI:andMemCtx:): new method, + replacing setMemCtx, which also stores the context uri in the new + "uri" ivar. + (-getMessageTableChildproperty:atURL:withTag:inFolder:withFID:) + added assertions for context id searches. Make the context id + search without the "sogo://" prefix. + Added missing "break" statement, leading PR_FID to get the value + of PR_MID. + (-parentFID): simply returns fid... + (-getPath:ofFMID:withTableType:): implemented. + (-getFoldersList:withFMID:): new temporary store method, + implemented. + + * OpenChange/NSArray+MAPIStore.m: new category module. + (-asFoldersListInCtx:): new method returning a properly populated + "struct struct indexing_folders_list *" from an array of fids. 2010-10-13 Francis Lachapelle diff --git a/OpenChange/GNUmakefile b/OpenChange/GNUmakefile index 8119b5b94..e88ed8fb6 100644 --- a/OpenChange/GNUmakefile +++ b/OpenChange/GNUmakefile @@ -39,6 +39,7 @@ $(MAPISTORESOGO)_OBJC_FILES += \ \ SOGoGCSFolder+MAPIStore.m \ \ + NSArray+MAPIStore.m \ NSCalendarDate+MAPIStore.m \ NSString+MAPIStore.m diff --git a/OpenChange/MAPIStoreContext.h b/OpenChange/MAPIStoreContext.h index 545c21389..be024353d 100644 --- a/OpenChange/MAPIStoreContext.h +++ b/OpenChange/MAPIStoreContext.h @@ -55,22 +55,26 @@ extern uint64_t *MAPILongLongValue (void *, uint64_t); struct mapistore_context *memCtx; void *ldbCtx; + BOOL baseContextSet; + + NSString *uri; + NSMutableDictionary *objectCache; MAPIStoreAuthenticator *authenticator; WOContext *woContext; NSMutableDictionary *messageCache; NSMutableDictionary *subfolderCache; SOGoFolder *moduleFolder; - NSString *lastObjectURL; - id lastObject; } -+ (id) contextFromURI: (const char *) newUri; ++ (id) contextFromURI: (const char *) newUri + inMemCtx: (struct mapistore_context *) newMemCtx; + +- (void) setURI: (NSString *) newUri + andMemCtx: (struct mapistore_context *) newMemCtx; - (void) setupModuleFolder; -- (void) setMemCtx: (struct mapistore_context *) newMemCtx; - - (void) setAuthenticator: (MAPIStoreAuthenticator *) newAuthenticator; - (MAPIStoreAuthenticator *) authenticator; @@ -80,6 +84,10 @@ extern uint64_t *MAPILongLongValue (void *, uint64_t); - (id) lookupObject: (NSString *) objectURLString; /* backend methods */ +- (int) getPath: (char **) path + ofFMID: (uint64_t) fmid + withTableType: (uint8_t) tableType; + - (int) getFID: (uint64_t *) fid byName: (const char *) foldername inParentFID: (uint64_t) parent_fid; @@ -142,6 +150,9 @@ extern uint64_t *MAPILongLongValue (void *, uint64_t); inFolder: (SOGoFolder *) folder withFID: (uint64_t) fid; +- (int) getFoldersList: (struct indexing_folders_list **) folders_list + withFMID: (uint64_t) fmid; + @end #endif /* MAPISTORECONTEXT_H */ diff --git a/OpenChange/MAPIStoreContext.m b/OpenChange/MAPIStoreContext.m index 2eb0ad615..dce81b95a 100644 --- a/OpenChange/MAPIStoreContext.m +++ b/OpenChange/MAPIStoreContext.m @@ -40,6 +40,8 @@ #import #import +#import "NSArray+MAPIStore.h" + #import "MAPIApplication.h" #import "MAPIStoreAuthenticator.h" #import "MAPIStoreMapping.h" @@ -124,6 +126,7 @@ static MAPIStoreMapping *mapping = nil; } + (id) contextFromURI: (const char *) newUri + inMemCtx: (struct mapistore_context *) newMemCtx { MAPIStoreContext *context; MAPIStoreAuthenticator *authenticator; @@ -161,6 +164,7 @@ static MAPIStoreMapping *mapping = nil; if (contextClass) { context = [NSClassFromString (contextClass) new]; + [context setURI: completeURLString andMemCtx: newMemCtx]; [context autorelease]; authenticator = [MAPIStoreAuthenticator new]; @@ -193,6 +197,8 @@ static MAPIStoreMapping *mapping = nil; woContext = [WOContext contextWithRequest: nil]; [woContext retain]; moduleFolder = nil; + uri = nil; + baseContextSet = NO; } [self logWithFormat: @"-init"]; @@ -211,9 +217,23 @@ static MAPIStoreMapping *mapping = nil; [woContext release]; [authenticator release]; + [uri release]; + [super dealloc]; } +- (void) setURI: (NSString *) newUri + andMemCtx: (struct mapistore_context *) newMemCtx +{ + struct loadparm_context *lpCtx; + + ASSIGN (uri, newUri); + memCtx = newMemCtx; + + lpCtx = loadparm_init (newMemCtx); + ldbCtx = mapiproxy_server_openchange_ldb_init (lpCtx); +} + - (void) setAuthenticator: (MAPIStoreAuthenticator *) newAuthenticator { ASSIGN (authenticator, newAuthenticator); @@ -224,15 +244,6 @@ static MAPIStoreMapping *mapping = nil; return authenticator; } -- (void) setMemCtx: (struct mapistore_context *) newMemCtx -{ - struct loadparm_context *lpCtx; - memCtx = newMemCtx; - - lpCtx = loadparm_init (newMemCtx); - ldbCtx = mapiproxy_server_openchange_ldb_init (lpCtx); -} - - (void) setupRequest { NSMutableDictionary *info; @@ -403,17 +414,19 @@ static MAPIStoreMapping *mapping = nil; parentFolderURL = [mapping urlFromID: parentFID]; if (!parentFolderURL) [self errorWithFormat: @"No url found for FID: %lld", parentFID]; - if (parentFolderURL) { - folderURL = [self _createFolder: aRow inParentURL: parentFolderURL]; - if (folderURL) { - [mapping registerURL: folderURL withID: fid]; - // if ([sogoFolder isKindOfClass: SOGoMailAccountK]) - // [sogoFolder subscribe]; - rc = MAPISTORE_SUCCESS; + if (parentFolderURL) + { + folderURL = [self _createFolder: aRow inParentURL: parentFolderURL]; + if (folderURL) + { + [mapping registerURL: folderURL withID: fid]; + // if ([sogoFolder isKindOfClass: SOGoMailAccountK]) + // [sogoFolder subscribe]; + rc = MAPISTORE_SUCCESS; + } + else + rc = MAPISTORE_ERR_NOT_FOUND; } - else - rc = MAPISTORE_ERR_NOT_FOUND; - } else rc = MAPISTORE_ERR_NO_DIRECTORY; } @@ -617,6 +630,7 @@ static MAPIStoreMapping *mapping = nil; int rc; uint32_t contextId; uint64_t mappingId; + NSString *folderURL; id child; rc = MAPI_E_SUCCESS; @@ -648,9 +662,13 @@ static MAPIStoreMapping *mapping = nil; { openchangedb_get_new_folderID (ldbCtx, &mappingId); [mapping registerURL: childURL withID: mappingId]; - mapistore_search_context_by_uri (memCtx, - [[mapping urlFromID: fid] UTF8String], + folderURL = [mapping urlFromID: fid]; + NSAssert (folderURL != nil, + @"folder URL is expected to be known here"); + contextId = 0; + mapistore_search_context_by_uri (memCtx, [uri UTF8String] + 7, &contextId); + NSAssert (contextId > 0, @"no matching context found"); mapistore_indexing_record_add_mid (memCtx, contextId, mappingId); } *data = MAPILongLongValue (memCtx, mappingId); @@ -735,7 +753,7 @@ static MAPIStoreMapping *mapping = nil; uint32_t contextId; uint64_t mappingId; int rc; - NSString *parentURL; + NSString *folderURL; rc = MAPI_E_SUCCESS; switch (proptag) @@ -746,9 +764,13 @@ static MAPIStoreMapping *mapping = nil; { openchangedb_get_new_folderID (ldbCtx, &mappingId); [mapping registerURL: childURL withID: mappingId]; - mapistore_search_context_by_uri (memCtx, - [[mapping urlFromID: fid] UTF8String], + folderURL = [mapping urlFromID: fid]; + NSAssert (folderURL != nil, + @"folder URL is expected to be known here"); + contextId = 0; + mapistore_search_context_by_uri (memCtx, [uri UTF8String] + 7, &contextId); + NSAssert (contextId > 0, @"no matching context found"); mapistore_indexing_record_add_fid (memCtx, contextId, mappingId); } // mappingId = [mapping idFromURL: childURL]; @@ -756,30 +778,7 @@ static MAPIStoreMapping *mapping = nil; *data = MAPILongLongValue (memCtx, mappingId); break; case PR_PARENT_FID: - parentURL = [self _parentURLFromURL: childURL]; - if (parentURL) - { - mappingId = [mapping idFromURL: parentURL]; - NSAssert (mappingId != NSNotFound, - @"parent folder should be known at this stage"); - // if (mappingId == NSNotFound) - // { - // [NSException raise: @"MAPIStoreSOGoException" - // format: @"This should never happen" - // // openchangedb_get_new_folderID (ldbCtx, &mappingId); - // // [mapping registerURL: childURL withID: mappingId]; - // // mapistore_search_context_by_uri (memCtx, [childURL UTF8String], &contextId); - // // mapistore_indexing_record_add_fid (memCtx, contextId, mappingId); - // // [mapping registerURL: parentURL]; - // // mappingId = [mapping idFromURL: parentURL]; - // } - *data = MAPILongLongValue (memCtx, mappingId); - } - else - { - *data = NULL; - rc = MAPISTORE_ERR_NOT_FOUND; - } + *data = MAPILongLongValue (memCtx, fid); break; case PR_ATTR_HIDDEN: case PR_ATTR_SYSTEM: @@ -896,7 +895,6 @@ static MAPIStoreMapping *mapping = nil; return rc; } - - (int) openMessage: (struct mapistore_message *) msg withMID: (uint64_t) mid inFID: (uint64_t) fid @@ -949,6 +947,25 @@ static MAPIStoreMapping *mapping = nil; return MAPI_E_SUCCESS; } +- (int) getPath: (char **) path + ofFMID: (uint64_t) fmid + withTableType: (uint8_t) tableType +{ + int rc; + NSString *objectURL; + + objectURL = [mapping urlFromID: fmid]; + if (objectURL) + { + *path = [[objectURL substringFromIndex: 7] asUnicodeInMemCtx: memCtx]; + rc = MAPISTORE_SUCCESS; + } + else + rc = MAPI_E_NOT_FOUND; + + return rc; +} + - (int) getFID: (uint64_t *) fid byName: (const char *) foldername inParentFID: (uint64_t) parent_fid @@ -984,4 +1001,47 @@ static MAPIStoreMapping *mapping = nil; return MAPI_E_SUCCESS; } +- (int) getFoldersList: (struct indexing_folders_list **) folders_list + withFMID: (uint64_t) fmid +{ + int rc; + NSString *currentURL; + NSMutableArray *nsFolderList; + uint64_t fid; + + rc = MAPI_E_SUCCESS; + + currentURL = [mapping urlFromID: fmid]; + if (currentURL && ![currentURL isEqualToString: uri]) + { + nsFolderList = [NSMutableArray arrayWithCapacity: 32]; + currentURL = [self _parentURLFromURL: currentURL]; + while (currentURL && rc == MAPI_E_SUCCESS + && ![currentURL isEqualToString: uri]) + { + fid = [mapping idFromURL: currentURL]; + if (fid == NSNotFound) + rc = MAPI_E_NOT_FOUND; + else + { + [nsFolderList insertObject: [NSNumber numberWithUnsignedLongLong: fid] + atIndex: 0]; + currentURL = [self _parentURLFromURL: currentURL]; + } + } + + if (rc != MAPI_E_NOT_FOUND) + { + fid = [mapping idFromURL: uri]; + [nsFolderList insertObject: [NSNumber numberWithUnsignedLongLong: fid] + atIndex: 0]; + *folders_list = [nsFolderList asFoldersListInCtx: memCtx]; + } + } + else + rc = MAPI_E_NOT_FOUND; + + return rc; +} + @end diff --git a/OpenChange/MAPIStoreMapping.m b/OpenChange/MAPIStoreMapping.m index 90e43dfd3..10830842a 100644 --- a/OpenChange/MAPIStoreMapping.m +++ b/OpenChange/MAPIStoreMapping.m @@ -50,7 +50,7 @@ reverseMapping = [NSMutableDictionary new]; [self _setupFixedMapping]; } - + return self; } diff --git a/OpenChange/MAPIStoreSOGo.m b/OpenChange/MAPIStoreSOGo.m index e7fb9614a..81156b086 100644 --- a/OpenChange/MAPIStoreSOGo.m +++ b/OpenChange/MAPIStoreSOGo.m @@ -65,12 +65,13 @@ static int sogo_create_context(TALLOC_CTX *mem_ctx, const char *uri, void **priv DEBUG(0, ("[%s:%d]\n", __FUNCTION__, __LINE__)); - context = [MAPIStoreContext contextFromURI: uri]; - [context setMemCtx: mem_ctx]; + context = [MAPIStoreContext contextFromURI: uri + inMemCtx: mem_ctx]; [context retain]; cContext = talloc_zero(mem_ctx, sogo_context); cContext->objcContext = context; + *private_data = cContext; [pool release]; @@ -148,21 +149,23 @@ static int sogo_get_path(void *private_data, uint64_t fmid, uint8_t type, char **path) { NSAutoreleasePool *pool; + sogo_context *cContext; + MAPIStoreContext *context; + int rc; pool = [NSAutoreleasePool new]; - DEBUG(5, ("[%s:%d]\n", __FUNCTION__, __LINE__)); + cContext = private_data; + context = cContext->objcContext; + [context setupRequest]; - switch (type) { - case MAPISTORE_FOLDER: - break; - case MAPISTORE_MESSAGE: - break; - } + rc = [context getPath: path ofFMID: fmid withTableType: type]; + + [context tearDownRequest]; [pool release]; - return MAPISTORE_SUCCESS; + return rc; } static int sogo_op_get_fid_by_name(void *private_data, uint64_t parent_fid, const char* foldername, uint64_t *fid) @@ -535,6 +538,29 @@ static int sogo_op_deletemessage(void *private_data, return rc; } +static int sogo_op_get_folders_list(void *private_data, + uint64_t fmid, + struct indexing_folders_list **folders_list) +{ + NSAutoreleasePool *pool; + sogo_context *cContext; + MAPIStoreContext *context; + int rc; + + pool = [NSAutoreleasePool new]; + + cContext = private_data; + context = cContext->objcContext; + [context setupRequest]; + + rc = [context getFoldersList: folders_list withFMID: fmid]; + + [context tearDownRequest]; + [pool release]; + + return rc; +} + /** \details Entry point for mapistore SOGO backend @@ -580,6 +606,7 @@ int mapistore_init_backend(void) backend.op_get_fid_by_name = sogo_op_get_fid_by_name; backend.op_setprops = sogo_op_setprops; backend.op_deletemessage = sogo_op_deletemessage; + backend.op_get_folders_list = sogo_op_get_folders_list; /* Register ourselves with the MAPISTORE subsystem */ ret = mapistore_backend_register(&backend); diff --git a/OpenChange/NSArray+MAPIStore.h b/OpenChange/NSArray+MAPIStore.h new file mode 100644 index 000000000..57d219d95 --- /dev/null +++ b/OpenChange/NSArray+MAPIStore.h @@ -0,0 +1,34 @@ +/* NSArray+MAPIStore.h - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef NSARRAY_MAPISTORE_H +#define NSARRAY_MAPISTORE_H + +#import + +@interface NSArray (MAPIStoreFolders) + +- (struct indexing_folders_list *) asFoldersListInCtx: (void *) memCtx; + +@end + +#endif /* NSARRAY+MAPISTORE_H */ diff --git a/OpenChange/NSArray+MAPIStore.m b/OpenChange/NSArray+MAPIStore.m new file mode 100644 index 000000000..581904253 --- /dev/null +++ b/OpenChange/NSArray+MAPIStore.m @@ -0,0 +1,50 @@ +/* NSArray+MAPIStore.m - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import + +#import "NSArray+MAPIStore.h" + +#undef DEBUG +#include +#include + +@implementation NSArray (MAPIStoreFolders) + +- (struct indexing_folders_list *) asFoldersListInCtx: (void *) memCtx +{ + struct indexing_folders_list *flist; + NSInteger count, max; + + max = [self count]; + + flist = talloc_zero(memCtx, struct indexing_folders_list); + flist->folderID = talloc_array(flist, uint64_t, max); + flist->count = max; + + for (count = 0; count < max; count++) + *(flist->folderID + count) = [[self objectAtIndex: count] unsignedLongLongValue]; + + return flist; +} + +@end