diff --git a/ChangeLog b/ChangeLog index 19f563e20..82c31a3ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2011-02-24 Wolfgang Sourdeau + * OpenChange/MAPIStoreTable.m: refactored class to be used as an + accessor on MAPIStoreFolder or other MAPIStoreObject derivatives + based on a defined set of methods. Now strictly handle the sorting + and filtering of folder entries, the getting of properties having + been moved to the MAPIStoreMessage classes. + * OpenChange/SOGoMAPIFSMessage.m (-appendProperties:): new name for "setMAPIProperties:" (-save): new name for "MAPISave", since those were methods diff --git a/OpenChange/MAPIStoreFAIMessageTable.h b/OpenChange/MAPIStoreAttachmentTable.h similarity index 72% rename from OpenChange/MAPIStoreFAIMessageTable.h rename to OpenChange/MAPIStoreAttachmentTable.h index f9044d05a..94f57e551 100644 --- a/OpenChange/MAPIStoreFAIMessageTable.h +++ b/OpenChange/MAPIStoreAttachmentTable.h @@ -1,6 +1,6 @@ -/* MAPIStoreFAIMessageTable.h - this file is part of SOGo +/* MAPIStoreAttachmentTable.h - this file is part of SOGo * - * Copyright (C) 2010 Inverse inc + * Copyright (C) 2011 Inverse inc * * Author: Wolfgang Sourdeau * @@ -20,13 +20,12 @@ * Boston, MA 02111-1307, USA. */ -#ifndef MAPISTOREFAIMESSAGETABLE_H -#define MAPISTOREFAIMESSAGETABLE_H +#ifndef MAPISTOREATTACHMENTTABLE_H +#define MAPISTOREATTACHMENTTABLE_H -#import "MAPIStoreFSMessageTable.h" - -@interface MAPIStoreFAIMessageTable : MAPIStoreFSMessageTable +#import "MAPIStoreTable.h" +@interface MAPIStoreAttachmentTable : MAPIStoreTable @end -#endif /* MAPISTOREFAIMESSAGETABLE_H */ +#endif /* MAPISTOREATTACHMENTTABLE_H */ diff --git a/OpenChange/MAPIStoreFAIMessageTable.m b/OpenChange/MAPIStoreAttachmentTable.m similarity index 75% rename from OpenChange/MAPIStoreFAIMessageTable.m rename to OpenChange/MAPIStoreAttachmentTable.m index b989a98aa..5cef83f89 100644 --- a/OpenChange/MAPIStoreFAIMessageTable.m +++ b/OpenChange/MAPIStoreAttachmentTable.m @@ -1,12 +1,12 @@ -/* MAPIStoreFAIMessageTable.m - this file is part of SOGo +/* MAPIStoreAttachmentTable.m - this file is part of SOGo * - * Copyright (C) 2010 Inverse inc + * Copyright (C) 2011 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 3, or (at your option) + * 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, @@ -20,8 +20,8 @@ * Boston, MA 02111-1307, USA. */ -#import "MAPIStoreFAIMessageTable.h" +#import "MAPIStoreAttachmentTable.h" -@implementation MAPIStoreFAIMessageTable +@implementation MAPIStoreAttachmentTable @end diff --git a/OpenChange/MAPIStoreCalendarMessageTable.m b/OpenChange/MAPIStoreCalendarMessageTable.m index ad1bf6f8a..d7b5490f8 100644 --- a/OpenChange/MAPIStoreCalendarMessageTable.m +++ b/OpenChange/MAPIStoreCalendarMessageTable.m @@ -25,8 +25,6 @@ #import -#import - #import #import "MAPIStoreTypes.h" @@ -39,125 +37,6 @@ @implementation MAPIStoreCalendarMessageTable -- (EOQualifier *) componentQualifier -{ - static EOQualifier *componentQualifier = nil; - - if (!componentQualifier) - componentQualifier - = [[EOKeyValueQualifier alloc] initWithKey: @"c_component" - operatorSelector: EOQualifierOperatorEqual - value: @"vevent"]; - - return componentQualifier; -} - -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) propTag -{ - NSTimeInterval timeValue; - id event; - int rc; - - rc = MAPI_E_SUCCESS; - switch (propTag) - { - case PR_ICON_INDEX: // TODO - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */ - // *longValue = 0x00000401 for recurring event - // *longValue = 0x00000402 for meeting - // *longValue = 0x00000403 for recurring meeting - // *longValue = 0x00000404 for invitation - *data = MAPILongValue (memCtx, 0x00000400); - break; - case PR_MESSAGE_CLASS_UNICODE: - *data = talloc_strdup(memCtx, "IPM.Appointment"); - break; - case PidLidAppointmentStartWhole: // DTSTART - event = [[self lookupChild: childKey] component: NO secure: NO]; - *data = [[event startDate] asFileTimeInMemCtx: memCtx]; - break; - case PidLidAppointmentEndWhole: // DTEND - event = [[self lookupChild: childKey] component: NO secure: NO]; - *data = [[event endDate] asFileTimeInMemCtx: memCtx]; - break; - case PidLidAppointmentDuration: - event = [[self lookupChild: childKey] component: NO secure: NO]; - timeValue = [[event endDate] timeIntervalSinceDate: [event startDate]]; - *data = MAPILongValue (memCtx, (uint32_t) (timeValue / 60)); - break; - case PidLidAppointmentSubType: - event = [[self lookupChild: childKey] component: NO secure: NO]; - *data = MAPIBoolValue (memCtx, [event isAllDay]); - break; - case PidLidBusyStatus: // TODO - *data = MAPILongValue (memCtx, 0x02); - break; - case PidLidRecurring: // TODO - *data = MAPIBoolValue (memCtx, NO); - break; - - // case 0x82410003: // TODO - // *data = MAPILongValue (memCtx, 0); - // break; - case PR_SUBJECT_UNICODE: // SUMMARY - event = [[self lookupChild: childKey] component: NO secure: NO]; - *data = [[event summary] asUnicodeInMemCtx: memCtx]; - break; - case PidLidLocation: // LOCATION - event = [[self lookupChild: childKey] component: NO secure: NO]; - *data = [[event location] asUnicodeInMemCtx: memCtx]; - break; - case PidLidPrivate: // private (bool), should depend on CLASS and permissions - *data = MAPIBoolValue (memCtx, NO); - break; - case PR_SENSITIVITY: // not implemented, depends on CLASS - // normal = 0, personal?? = 1, private = 2, confidential = 3 - *data = MAPILongValue (memCtx, 0); - break; - case PR_CREATION_TIME: - event = [[self lookupChild: childKey] component: NO secure: NO]; - *data = [[event created] asFileTimeInMemCtx: memCtx]; - break; - - case PR_IMPORTANCE: - { - unsigned int v; - - event = [[self lookupChild: childKey] component: NO secure: NO]; - - if ([[event priority] isEqualToString: @"9"]) - v = 0x0; - else if ([[event priority] isEqualToString: @"1"]) - v = 0x2; - else - v = 0x1; - - *data = MAPILongValue (memCtx, v); - } - break; - - // case PidLidTimeZoneStruct: - // case PR_VD_NAME_UNICODE: - // *data = talloc_strdup(memCtx, "PR_VD_NAME_UNICODE"); - // break; - // case PR_EMS_AB_DXA_REMOTE_CLIENT_UNICODE: "Home:" ??? - // *data = talloc_strdup(memCtx, "PR_EMS..."); - // break; - default: - rc = [super getChildProperty: data - forKey: childKey - withTag: propTag]; - } - - // #define PR_REPLY_TIME PROP_TAG(PT_SYSTIME , 0x0030) /* 0x00300040 */ - // #define PR_INTERNET_MESSAGE_ID_UNICODE PROP_TAG(PT_UNICODE , 0x1035) /* 0x1035001f */ - // #define PR_FLAG_STATUS PROP_TAG(PT_LONG , 0x1090) /* 0x10900003 */ - - return rc; -} - - (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res intoQualifier: (EOQualifier **) qualifier { diff --git a/OpenChange/MAPIStoreContactsMessageTable.m b/OpenChange/MAPIStoreContactsMessageTable.m index 5fc7205c4..549b8cb05 100644 --- a/OpenChange/MAPIStoreContactsMessageTable.m +++ b/OpenChange/MAPIStoreContactsMessageTable.m @@ -42,515 +42,6 @@ @implementation MAPIStoreContactsMessageTable -- (EOQualifier *) componentQualifier -{ - static EOQualifier *componentQualifier = nil; - - /* TODO: we need to support vlist as well */ - if (!componentQualifier) - componentQualifier - = [[EOKeyValueQualifier alloc] initWithKey: @"c_component" - operatorSelector: EOQualifierOperatorEqual - value: @"vcard"]; - - return componentQualifier; -} - -- (CardElement *) _element: (NSString *) elementTag - ofType: (NSString *) aType - excluding: (NSString *) aTypeToExclude - inCard: (NGVCard *) card -{ - NSArray *elements; - CardElement *ce, *found; - NSUInteger count, max; - - found = nil; - - elements = [[card childrenWithTag: elementTag] - cardElementsWithAttribute: @"type" - havingValue: aType]; - max = [elements count]; - for (count = 0; !found && count < max; count++) - { - ce = [elements objectAtIndex: count]; - if (!aTypeToExclude - || ![ce hasAttribute: @"type" havingValue: aTypeToExclude]) - found = ce; - } - - return found; -} - -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) proptag -{ - NSString *stringValue, *stringValue2; - SOGoContactGCSEntry *child; - CardElement *element; - uint32_t longValue; - NGVCard *vCard; - enum MAPISTATUS rc; - - rc = MAPI_E_SUCCESS; - switch (proptag) - { - case PR_ICON_INDEX: // TODO - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */ - *data = MAPILongValue (memCtx, 0x00000200); - break; - case PR_MESSAGE_CLASS_UNICODE: - *data = talloc_strdup (memCtx, "IPM.Contact"); - break; - // case PR_VD_NAME_UNICODE: - // *data = talloc_strdup (memCtx, "PR_VD_NAME_UNICODE"); - // break; - // case PR_EMS_AB_DXA_REMOTE_CLIENT_UNICODE: "Home:" ??? - // *data = talloc_strdup (memCtx, "PR_EMS..."); - // break; - case PR_OAB_NAME_UNICODE: - *data = talloc_strdup (memCtx, "PR_OAB_NAME_UNICODE"); - break; - case PR_OAB_LANGID: - /* see http://msdn.microsoft.com/en-us/goglobal/bb895996.asxp */ - /* English US */ - *data = MAPILongValue (memCtx, 0x0409); - break; - - case PR_TITLE_UNICODE: - child = [self lookupChild: childKey]; - stringValue = [[child vCard] title]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - case PR_COMPANY_NAME_UNICODE: - case PR_DEPARTMENT_NAME_UNICODE: - { - NSArray *values; - - child = [self lookupChild: childKey]; - values = [[child vCard] org]; - stringValue = nil; - - if (proptag == PR_COMPANY_NAME_UNICODE && [values count] > 0) - stringValue = [values objectAtIndex: 0]; - else if (proptag == PR_DEPARTMENT_NAME_UNICODE && [values count] > 1) - stringValue = [values objectAtIndex: 1]; - - if (!stringValue) - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - } - break; - - case PR_SEND_INTERNET_ENCODING: - *data = MAPILongValue (memCtx, 0x00065001); - break; - - case PR_SUBJECT_UNICODE: - case PR_DISPLAY_NAME_UNICODE: // Full Name - case PidLidFileUnder: // contact block title name - rc = [super getChildProperty: data - forKey: childKey - withTag: PR_DISPLAY_NAME_UNICODE]; - break; - case PidLidFileUnderId: - *data = MAPILongValue (memCtx, 0xffffffff); - break; - - case PidLidEmail1OriginalDisplayName: - case PidLidEmail1DisplayName: - child = [self lookupChild: childKey]; - vCard = [child vCard]; - stringValue = [vCard fn]; - stringValue2 = [vCard preferredEMail]; - *data = [[NSString stringWithFormat: @"%@ <%@>", - stringValue, stringValue2] - asUnicodeInMemCtx: memCtx]; - break; - - case PidLidEmail1EmailAddress: - case PR_ACCOUNT_UNICODE: - child = [self lookupChild: childKey]; - stringValue = [[child vCard] preferredEMail]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - case PR_CONTACT_EMAIL_ADDRESSES_UNICODE: - child = [self lookupChild: childKey]; - stringValue = [[child vCard] preferredEMail]; - *data = [[NSArray arrayWithObject: stringValue] - asArrayOfUnicodeStringsInCtx: memCtx]; - break; - - case PR_EMS_AB_TARGET_ADDRESS_UNICODE: - child = [self lookupChild: childKey]; - stringValue = [[child vCard] preferredEMail]; - *data = [[NSString stringWithFormat: @"SMTP:%@", stringValue] - asUnicodeInMemCtx: memCtx]; - break; - - case PR_SEARCH_KEY: // TODO - child = [self lookupChild: childKey]; - stringValue = [[child vCard] preferredEMail]; - *data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding] - asBinaryInMemCtx: memCtx]; - break; - - case PR_MAIL_PERMISSION: - *data = MAPIBoolValue (memCtx, YES); - break; - - // - // TODO - same logic as -secondaryEmail in UI/Contacts/UIxContactView.m - // We should eventually merge that in order to not duplicate the code. - // We should also eventually handle PidLidEmail3OriginalDisplayName in - // SOGo, Thunderbird, etc. - // - case PidLidEmail2EmailAddress: - case PidLidEmail2OriginalDisplayName: // Other email - { - NSMutableArray *emails; - NSString *email; - NGVCard *card; - - emails = [NSMutableArray array]; - stringValue = nil; - - card = [[self lookupChild: childKey] vCard]; - [emails addObjectsFromArray: [card childrenWithTag: @"email"]]; - [emails removeObjectsInArray: [card childrenWithTag: @"email" - andAttribute: @"type" - havingValue: @"pref"]]; - - if ([emails count] > 0) - { - int i; - - for (i = 0; i < [emails count]; i++) - { - email = [[emails objectAtIndex: i] value: 0]; - - if ([email caseInsensitiveCompare: [card preferredEMail]] != NSOrderedSame) - { - stringValue = email; - break; - } - } - } - - if (!stringValue) - stringValue = @""; - - *data = [stringValue asUnicodeInMemCtx: memCtx]; - } - break; - - // FIXME: this property does NOT work - case PR_BODY_UNICODE: - child = [self lookupChild: childKey]; - stringValue = [[child vCard] note]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - case PR_OFFICE_TELEPHONE_NUMBER_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"tel" ofType: @"work" - excluding: @"fax" - inCard: [child vCard]]; - if (element) - stringValue = [element value: 0]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_HOME_TELEPHONE_NUMBER_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"tel" ofType: @"home" - excluding: @"fax" - inCard: [child vCard]]; - if (element) - stringValue = [element value: 0]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_MOBILE_TELEPHONE_NUMBER_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"tel" ofType: @"cell" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 0]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_PRIMARY_TELEPHONE_NUMBER_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"tel" ofType: @"pref" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 0]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - case PR_BUSINESS_HOME_PAGE_UNICODE: - case PR_PERSONAL_HOME_PAGE_UNICODE: - { - NSString *type; - - type = (proptag == PR_BUSINESS_HOME_PAGE_UNICODE ? @"work" : @"home"); - - child = [self lookupChild: childKey]; - - element = [self _element: @"url" ofType: type - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 0]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - } - break; - - case PidLidEmail1AddressType: - case PidLidEmail2AddressType: - case PidLidEmail3AddressType: - *data = [@"SMTP" asUnicodeInMemCtx: memCtx]; - break; - - case PidLidInstantMessagingAddress: - child = [self lookupChild: childKey]; - stringValue = [[[child vCard] uniqueChildWithTag: @"x-aim"] value: 0]; - - if (!stringValue) - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - // - // We don't handle 0x00000003 - The Other Address is the mailing address. - // See: http://msdn.microsoft.com/en-us/library/cc815430.aspx - // - case PidLidPostalAddressId: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"pref" - excluding: nil - inCard: [child vCard]]; - if ([element hasAttribute: @"type" - havingValue: @"home"]) - longValue = 1; // The Home Address is the mailing address. - else if ([element hasAttribute: @"type" - havingValue: @"work"]) - longValue = 2; // The Work Address is the mailing address. - else - longValue = 0; // No address is selected as the mailing address. - *data = MAPILongValue (memCtx, longValue); - break; - - /* preferred address */ - case PR_POSTAL_ADDRESS_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"label" ofType: @"pref" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 0]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_POST_OFFICE_BOX_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"pref" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 0]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_STREET_ADDRESS_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"pref" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 2]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_LOCALITY_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"pref" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 3]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_STATE_OR_PROVINCE_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"pref" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 4]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_POSTAL_CODE_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"pref" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 5]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_COUNTRY_UNICODE: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"pref" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 6]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - // case PidLidAddressCountryCode: - - case PidLidWorkAddress: - child = [self lookupChild: childKey]; - element = [self _element: @"label" ofType: @"work" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 0]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - case PidLidWorkAddressPostOfficeBox: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"work" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 0]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PidLidWorkAddressStreet: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"work" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 2]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PidLidWorkAddressCity: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"work" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 3]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PidLidWorkAddressState: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"work" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 4]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PidLidWorkAddressPostalCode: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"work" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 5]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PidLidWorkAddressCountry: - child = [self lookupChild: childKey]; - element = [self _element: @"adr" ofType: @"work" - excluding: nil - inCard: [child vCard]]; - if (element) - stringValue = [element value: 6]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - // PidTagNickname - case PR_NICKNAME_UNICODE: - child = [self lookupChild: childKey]; - stringValue = [[child vCard] nickname]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - case PR_BIRTHDAY: - { - NSCalendarDate *dateValue; - - child = [self lookupChild: childKey]; - - stringValue = [[child vCard] bday]; - - if (stringValue) - { - dateValue = [NSCalendarDate dateWithString: stringValue - calendarFormat: @"%Y-%m-%d"]; - // FIXME: We add a day, otherwise Outlook 2003 will display at day earlier - dateValue = [dateValue addYear: 0 month: 0 day: 1 hour: 0 minute: 0 second: 0]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - } - else - rc = MAPI_E_NOT_FOUND; - } - break; - - default: - rc = [super getChildProperty: data - forKey: childKey - withTag: proptag]; - } - - return rc; -} - - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property { static NSMutableDictionary *knownProperties = nil; diff --git a/OpenChange/MAPIStoreFSMessageTable.m b/OpenChange/MAPIStoreFSMessageTable.m index 453e403ce..60f5baf8e 100644 --- a/OpenChange/MAPIStoreFSMessageTable.m +++ b/OpenChange/MAPIStoreFSMessageTable.m @@ -27,6 +27,7 @@ #import "EOQualifier+MAPIFS.h" #import "MAPIStoreTypes.h" +#import "MAPIStoreFSMessage.h" #import "NSObject+MAPIStore.h" #import "SOGoMAPIFSFolder.h" #import "SOGoMAPIFSMessage.h" @@ -38,69 +39,9 @@ @implementation MAPIStoreFSMessageTable -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) propTag -{ - NSDictionary *properties; - SOGoMAPIFSMessage *child; - id value; - enum MAPISTATUS rc; - - child = [self lookupChild: childKey]; - properties = [child properties]; - value = [properties objectForKey: MAPIPropertyKey (propTag)]; - if (value) - rc = [value getMAPIValue: data forTag: propTag inMemCtx: memCtx]; - else - rc = [super getChildProperty: data forKey: childKey withTag: propTag]; - - return rc; -} - - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property { return [NSString stringWithFormat: @"%@", MAPIPropertyKey (property)]; } -- (NSArray *) childKeys -{ - return [folder toOneRelationshipKeys]; -} - -- (NSArray *) restrictedChildKeys -{ - NSMutableArray *keys; - NSArray *allKeys; - NSUInteger count, max; - NSString *messageKey; - - allKeys = [self cachedChildKeys]; - if (restrictionState == MAPIRestrictionStateAlwaysTrue) - keys = (NSMutableArray *) allKeys; - else if (restrictionState == MAPIRestrictionStateAlwaysFalse) - keys = (NSMutableArray *) [NSArray array]; - else - { - [self logWithFormat: @"%s: getting restricted keys", __PRETTY_FUNCTION__]; - max = [allKeys count]; - keys = [NSMutableArray arrayWithCapacity: max]; - if (restrictionState == MAPIRestrictionStateNeedsEval) - { - for (count = 0; count < max; count++) - { - messageKey = [allKeys objectAtIndex: count]; - if ([restriction evaluateMAPIFSMessage: - [folder lookupName: messageKey - inContext: nil - acquire: NO]]) - [keys addObject: messageKey]; - } - } - [self logWithFormat: @" resulting keys: $$$%@$$$", keys]; - } - - return keys; -} - @end diff --git a/OpenChange/MAPIStoreFolderTable.m b/OpenChange/MAPIStoreFolderTable.m index 5bcac4e8c..8beeada1b 100644 --- a/OpenChange/MAPIStoreFolderTable.m +++ b/OpenChange/MAPIStoreFolderTable.m @@ -20,12 +20,9 @@ * Boston, MA 02111-1307, USA. */ -#import - #import -#import - +#import "MAPIStoreFolder.h" #import "MAPIStoreMapping.h" #import "MAPIStoreTypes.h" @@ -47,83 +44,13 @@ static MAPIStoreMapping *mapping; - (NSArray *) childKeys { - return [NSArray array]; - // return [folder toManyRelationshipKeys]; + return [(MAPIStoreFolder *) container folderKeys]; } - (NSArray *) restrictedChildKeys { - [self errorWithFormat: @"restrictions are ignored on mail folder tables"]; - return [folder toManyRelationshipKeys]; -} - -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) propTag -{ - SOGoFolder *child; - // id child; - // struct Binary_r *binaryValue; - NSString *childURL; - uint32_t contextId; - uint64_t mappingId; - int rc; - - rc = MAPI_E_SUCCESS; - switch (propTag) - { - case PR_FID: - childURL = [NSString stringWithFormat: @"%@%@", folderURL, childKey]; - mappingId = [mapping idFromURL: childURL]; - if (mappingId == NSNotFound) - { - openchangedb_get_new_folderID (ldbCtx, &mappingId); - [mapping registerURL: childURL withID: mappingId]; - contextId = 0; - mapistore_search_context_by_uri (memCtx, [folderURL UTF8String] + 7, - &contextId); - mapistore_indexing_record_add_mid (memCtx, contextId, mappingId); - } - *data = MAPILongLongValue (memCtx, mappingId); - break; - case PR_ACCESS: // TODO - *data = MAPILongValue (memCtx, 0x63); - break; - case PR_ACCESS_LEVEL: // TODO - *data = MAPILongValue (memCtx, 0x01); - break; - case PR_PARENT_FID: - *data = MAPILongLongValue (memCtx, fid); - break; - case PR_ATTR_HIDDEN: - case PR_ATTR_SYSTEM: - case PR_ATTR_READONLY: - *data = MAPIBoolValue (memCtx, NO); - break; - case PR_SUBFOLDERS: - child = [self lookupChild: childKey]; - *data = MAPIBoolValue (memCtx, 0); - // [[child toManyRelationshipKeys] count] > 0); - // *data = MAPIBoolValue (memCtx, - // [[child toManyRelationshipKeys] count] > 0); - break; - case PR_CONTENT_COUNT: - child = [self lookupChild: childKey]; - *data = MAPILongValue (memCtx, - [[child toOneRelationshipKeys] count]); - break; - // case PR_EXTENDED_FOLDER_FLAGS: // TODO: DOUBT: how to indicate the - // // number of subresponses ? - // binaryValue = talloc_zero(memCtx, struct Binary_r); - // *data = binaryValue; - // break; - default: - rc = [super getChildProperty: data - forKey: childKey - withTag: propTag]; - } - - return rc; + [self errorWithFormat: @"restrictions are ignored on folder tables"]; + return [self childKeys]; } - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property diff --git a/OpenChange/MAPIStoreGCSMessageTable.h b/OpenChange/MAPIStoreGCSMessageTable.h index e26a41252..8c1a941ed 100644 --- a/OpenChange/MAPIStoreGCSMessageTable.h +++ b/OpenChange/MAPIStoreGCSMessageTable.h @@ -28,9 +28,6 @@ @class EOQualifier; @interface MAPIStoreGCSMessageTable : MAPIStoreMessageTable -{ - NSMutableArray *sortOrderings; -} - (EOQualifier *) componentQualifier; - (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property; diff --git a/OpenChange/MAPIStoreGCSMessageTable.m b/OpenChange/MAPIStoreGCSMessageTable.m index cb86f387a..13d44264c 100644 --- a/OpenChange/MAPIStoreGCSMessageTable.m +++ b/OpenChange/MAPIStoreGCSMessageTable.m @@ -37,6 +37,7 @@ #import "MAPIStoreTypes.h" #import "NSAutoreleasePool+MAPIStore.h" +#import "MAPIStoreFolder.h" #import "MAPIStoreGCSMessageTable.h" @@ -61,66 +62,6 @@ [super dealloc]; } -- (NSArray *) _childKeysUsingRestrictions: (BOOL) useRestrictions -{ - static NSArray *fields = nil; - NSArray *records; - EOQualifier *componentQualifier, *fetchQualifier; - GCSFolder *ocsFolder; - EOFetchSpecification *fs; - NSArray *keys; - - if (!fields) - fields = [[NSArray alloc] - initWithObjects: @"c_name", @"c_version", nil]; - - componentQualifier = [self componentQualifier]; - - if (useRestrictions - && restrictionState != MAPIRestrictionStateAlwaysTrue) - { - if (restrictionState == MAPIRestrictionStateNeedsEval) - { - fetchQualifier = [[EOAndQualifier alloc] - initWithQualifiers: - componentQualifier, - restriction, - nil]; - [fetchQualifier autorelease]; - } - else - fetchQualifier = nil; - } - else - fetchQualifier = componentQualifier; - - if (fetchQualifier) - { - ocsFolder = [folder ocsFolder]; - fs = [EOFetchSpecification - fetchSpecificationWithEntityName: [ocsFolder folderName] - qualifier: fetchQualifier - sortOrderings: sortOrderings]; - records = [ocsFolder fetchFields: fields fetchSpecification: fs]; - keys = [records objectsForKey: @"c_name" - notFoundMarker: nil]; - } - else - keys = [NSArray array]; - - return keys; -} - -- (NSArray *) childKeys -{ - return [self _childKeysUsingRestrictions: NO]; -} - -- (NSArray *) restrictedChildKeys -{ - return [self _childKeysUsingRestrictions: YES]; -} - - (struct mapi_SPropertyRestriction *) _fixedDatePropertyRestriction: (struct mapi_SPropertyRestriction *) res { struct mapi_SPropertyRestriction *translatedRes; @@ -204,13 +145,6 @@ /* sorting */ -- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - - (EOSortOrdering *) _sortOrderingFromSortOrder: (struct SSortOrder *) sortOrder { EOSortOrdering *newSortOrdering; @@ -295,4 +229,12 @@ [self logWithFormat: @"new sort orderings: %@", sortOrderings]; } +/* subclasses */ +- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property +{ + [self subclassResponsibility: _cmd]; + + return nil; +} + @end diff --git a/OpenChange/MAPIStoreMailFolderTable.m b/OpenChange/MAPIStoreMailFolderTable.m index 3d7e85886..98b78ebe5 100644 --- a/OpenChange/MAPIStoreMailFolderTable.m +++ b/OpenChange/MAPIStoreMailFolderTable.m @@ -36,38 +36,4 @@ @implementation MAPIStoreMailFolderTable -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) propTag -{ - enum MAPISTATUS rc; - SOGoMailFolder *child; - EOQualifier *searchQualifier; - uint32_t intValue; - - rc = MAPI_E_SUCCESS; - switch (propTag) - { - case PR_CONTENT_UNREAD: - child = [self lookupChild: childKey]; - searchQualifier - = [EOQualifier qualifierWithQualifierFormat: @"flags = %@ AND not flags = %@", - @"unseen", @"deleted"]; - intValue = [[child fetchUIDsMatchingQualifier: searchQualifier - sortOrdering: nil] count]; - [self logWithFormat: @"unread count for %@: %u\n", childKey, intValue]; - *data = MAPILongValue (memCtx, intValue); - break; - case PR_CONTAINER_CLASS_UNICODE: - *data = [@"IPF.Note" asUnicodeInMemCtx: memCtx]; - break; - default: - rc = [super getChildProperty: data - forKey: childKey - withTag: propTag]; - } - - return rc; -} - @end diff --git a/OpenChange/MAPIStoreMailMessageTable.h b/OpenChange/MAPIStoreMailMessageTable.h index cdc70afc5..0b7eee2df 100644 --- a/OpenChange/MAPIStoreMailMessageTable.h +++ b/OpenChange/MAPIStoreMailMessageTable.h @@ -26,9 +26,6 @@ #import "MAPIStoreMessageTable.h" @interface MAPIStoreMailMessageTable : MAPIStoreMessageTable -{ - NSString *sortOrdering; -} @end diff --git a/OpenChange/MAPIStoreMailMessageTable.m b/OpenChange/MAPIStoreMailMessageTable.m index e2f69ce6e..8e807cfec 100644 --- a/OpenChange/MAPIStoreMailMessageTable.m +++ b/OpenChange/MAPIStoreMailMessageTable.m @@ -25,11 +25,8 @@ #import #import #import - #import - #import - #import #import @@ -37,6 +34,7 @@ #import #import "MAPIStoreContext.h" +#import "MAPIStoreMailFolder.h" #import "MAPIStoreTypes.h" #import "NSData+MAPIStore.h" #import "NSCalendarDate+MAPIStore.h" @@ -48,33 +46,6 @@ #include #include -@interface NSString (MAPIStoreMIME) - -- (NSString *) _strippedBodyKey; - -@end - -@implementation NSString (MAPIStoreMIME) - -- (NSString *) _strippedBodyKey -{ - NSRange bodyRange; - NSString *strippedKey; - - bodyRange = [self rangeOfString: @"body["]; - if (bodyRange.length > 0) - { - strippedKey = [self substringFromIndex: NSMaxRange (bodyRange)]; - strippedKey = [strippedKey substringToIndex: [strippedKey length] - 1]; - } - else - strippedKey = nil; - - return strippedKey; -} - -@end - @implementation MAPIStoreMailMessageTable static Class NSDataK, NSStringK; @@ -89,503 +60,12 @@ static Class NSDataK, NSStringK; { if ((self = [super init])) { - sortOrdering = @"ARRIVAL"; + ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]); } return self; } -- (void) dealloc -{ - [sortOrdering release]; - [super dealloc]; -} - -- (NSArray *) childKeys -{ - return [[folder fetchUIDsMatchingQualifier: nil - sortOrdering: sortOrdering] - stringsWithFormat: @"%@.eml"]; -} - -- (NSArray *) restrictedChildKeys -{ - NSArray *keys; - - if (restrictionState == MAPIRestrictionStateAlwaysTrue) - keys = [self cachedChildKeys]; - else if (restrictionState == MAPIRestrictionStateAlwaysFalse) - keys = [NSArray array]; - else - { - keys = [[folder fetchUIDsMatchingQualifier: restriction - sortOrdering: sortOrdering] - stringsWithFormat: @"%@.eml"]; - [self logWithFormat: @" restricted keys: %@", keys]; - } - - return keys; -} - -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) propTag -{ - SOGoMailObject *child; - NSString *subject, *stringValue; - NSInteger colIdx; - uint32_t intValue; - enum MAPISTATUS rc; - - rc = MAPI_E_SUCCESS; - switch (propTag) - { - case PR_ICON_INDEX: - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */ - child = [self lookupChild: childKey]; - if ([child isNewMail]) - intValue = 0xffffffff; - else if ([child replied]) - intValue = 0x105; - else if ([child forwarded]) - intValue = 0x106; - else if ([child read]) - intValue = 0x100; - else - intValue = 0x101; - *data = MAPILongValue (memCtx, intValue); - break; - case PidLidImapDeleted: - child = [self lookupChild: childKey]; - if ([child deleted]) - intValue = 1; - else - intValue = 0; - *data = MAPILongValue (memCtx, intValue); - break; - case PR_SUBJECT_UNICODE: - child = [self lookupChild: childKey]; - stringValue = [child decodedSubject]; - if (!stringValue) - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_SUBJECT_PREFIX_UNICODE: - child = [self lookupChild: childKey]; - subject = [child decodedSubject]; - colIdx = [subject rangeOfString: @":"].location; - if (colIdx != NSNotFound && colIdx < 4) - stringValue = [NSString stringWithFormat: @"%@: ", - [subject substringToIndex: colIdx]]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_NORMALIZED_SUBJECT_UNICODE: - child = [self lookupChild: childKey]; - subject = [child decodedSubject]; - colIdx = [subject rangeOfString: @":"].location; - if (colIdx != NSNotFound && colIdx < 4) - stringValue = [[subject substringFromIndex: colIdx + 1] - stringByTrimmingLeadSpaces]; - else - stringValue = subject; - if (!stringValue) - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - case PR_MESSAGE_CLASS_UNICODE: - case PR_ORIG_MESSAGE_CLASS_UNICODE: - *data = talloc_strdup (memCtx, "IPM.Note"); - break; - case PidLidRemoteAttachment: // TODO - case PR_HASATTACH: // TODO - case PR_REPLY_REQUESTED: // TODO - case PR_RESPONSE_REQUESTED: // TODO - *data = MAPIBoolValue (memCtx, NO); - break; - // case PidLidHeaderItem: - // *data = MAPILongValue (memCtx, 0x00000001); - // break; - // case PidLidRemoteTransferSize: - // rc = [self getChildProperty: data - // forKey: childKey - // withTag: PR_MESSAGE_SIZE]; - // break; - case PR_CREATION_TIME: // DOUBT - case PR_LAST_MODIFICATION_TIME: // DOUBT - case PR_LATEST_DELIVERY_TIME: // DOUBT - case PR_ORIGINAL_SUBMIT_TIME: - case PR_CLIENT_SUBMIT_TIME: - case PR_MESSAGE_DELIVERY_TIME: - child = [self lookupChild: childKey]; - // offsetDate = [[child date] addYear: -1 month: 0 day: 0 - // hour: 0 minute: 0 second: 0]; - // *data = [offsetDate asFileTimeInMemCtx: memCtx]; - *data = [[child date] asFileTimeInMemCtx: memCtx]; - break; - case PR_MESSAGE_FLAGS: // TODO - { - NSDictionary *coreInfos; - NSArray *flags; - unsigned int v; - - child = [self lookupChild: childKey]; - coreInfos = [child fetchCoreInfos]; - - flags = [coreInfos objectForKey: @"flags"]; - v = MSGFLAG_FROMME; - - if ([flags containsObject: @"seen"]) - v |= MSGFLAG_READ; - - *data = MAPILongValue (memCtx, v); - } - break; - - case PR_FLAG_STATUS: - { - NSDictionary *coreInfos; - NSArray *flags; - unsigned int v; - - child = [self lookupChild: childKey]; - coreInfos = [child fetchCoreInfos]; - - flags = [coreInfos objectForKey: @"flags"]; - if ([flags containsObject: @"flagged"]) - v = 2; - else - v = 0; - - *data = MAPILongValue (memCtx, v); - } - break; - - case PR_FOLLOWUP_ICON: - { - NSDictionary *coreInfos; - NSArray *flags; - unsigned int v; - - child = [self lookupChild: childKey]; - coreInfos = [child fetchCoreInfos]; - - flags = [coreInfos objectForKey: @"flags"]; - if ([flags containsObject: @"flagged"]) - v = 6; - else - v = 0; - - *data = MAPILongValue (memCtx, v); - } - break; - - case PR_SENSITIVITY: // TODO - case PR_ORIGINAL_SENSITIVITY: // TODO - *data = MAPILongValue (memCtx, 0); - break; - - case PR_EXPIRY_TIME: // TODO - case PR_REPLY_TIME: - *data = [[NSCalendarDate date] asFileTimeInMemCtx: memCtx]; - break; - - case PR_SENT_REPRESENTING_ADDRTYPE_UNICODE: - case PR_RCVD_REPRESENTING_ADDRTYPE_UNICODE: - case PR_RECEIVED_BY_ADDRTYPE_UNICODE: - case PR_SENDER_ADDRTYPE_UNICODE: - *data = [@"SMTP" asUnicodeInMemCtx: memCtx]; - break; - case PR_ORIGINAL_AUTHOR_NAME_UNICODE: - case PR_SENDER_NAME_UNICODE: - case PR_SENDER_EMAIL_ADDRESS_UNICODE: - case PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE: - case PR_SENT_REPRESENTING_NAME_UNICODE: - child = [self lookupChild: childKey]; - *data = [[child from] asUnicodeInMemCtx: memCtx]; - break; - - /* TODO: some of the following are supposed to be display names, separated by a semicolumn */ - case PR_RECEIVED_BY_NAME_UNICODE: - case PR_RECEIVED_BY_EMAIL_ADDRESS_UNICODE: - case PR_RCVD_REPRESENTING_NAME_UNICODE: - case PR_RCVD_REPRESENTING_EMAIL_ADDRESS_UNICODE: - case PR_DISPLAY_TO_UNICODE: - case PR_ORIGINAL_DISPLAY_TO_UNICODE: - child = [self lookupChild: childKey]; - stringValue = [child to]; - if (!stringValue) - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_DISPLAY_CC_UNICODE: - case PR_ORIGINAL_DISPLAY_CC_UNICODE: - child = [self lookupChild: childKey]; - stringValue = [child cc]; - if (!stringValue) - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - case PR_DISPLAY_BCC_UNICODE: - case PR_ORIGINAL_DISPLAY_BCC_UNICODE: - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - break; - - case PidNameContentType: - *data = [@"message/rfc822" asUnicodeInMemCtx: memCtx]; - break; - - - // - // TODO: Merge with the code in UI/MailerUI/UIxMailListActions.m: -messagePriority - // to avoid the duplication of the logic - // - case PR_IMPORTANCE: - { - unsigned int v; - NSString *s; - - child = [self lookupChild: childKey]; - s = [[child mailHeaders] objectForKey: @"x-priority"]; - v = 0x1; - - - if ([s hasPrefix: @"1"]) v = 0x2; - else if ([s hasPrefix: @"2"]) v = 0x2; - else if ([s hasPrefix: @"4"]) v = 0x0; - else if ([s hasPrefix: @"5"]) v = 0x0; - - *data = MAPILongValue (memCtx, v); - } - break; - - case PR_BODY_UNICODE: - { - NSMutableArray *keys; - - child = [self lookupChild: childKey]; - - keys = [NSMutableArray array]; - [child addRequiredKeysOfStructure: [child bodyStructure] - path: @"" toArray: keys - acceptedTypes: [NSArray arrayWithObject: - @"text/html"]]; - if ([keys count] > 0) - { - *data = NULL; - rc = MAPI_E_NOT_FOUND; - } - else - { - [keys removeAllObjects]; - [child addRequiredKeysOfStructure: [child bodyStructure] - path: @"" toArray: keys - acceptedTypes: [NSArray arrayWithObject: - @"text/plain"]]; - if ([keys count] > 0) - { - id result; - NSData *content; - NSDictionary *partHeaderData; - NSString *key, *encoding, *charset; - - result = [child fetchParts: [keys objectsForKey: @"key" - notFoundMarker: nil]]; - result = [[result valueForKey: @"RawResponse"] objectForKey: @"fetch"]; - key = [[keys objectAtIndex: 0] objectForKey: @"key"]; - content = [[result objectForKey: key] objectForKey: @"data"]; - - partHeaderData - = [child lookupInfoForBodyPart: [key _strippedBodyKey]]; - encoding = [partHeaderData objectForKey: @"encoding"]; - charset = [[partHeaderData objectForKey: @"parameterList"] - objectForKey: @"charset"]; - stringValue = [[content bodyDataFromEncoding: encoding] - bodyStringFromCharset: charset]; - - *data = [stringValue asUnicodeInMemCtx: memCtx]; - if (strlen (*data) > 16384) - { - [context registerValue: stringValue - asProperty: propTag - forURL: [NSString stringWithFormat: @"%@%@", folderURL, childKey]]; - *data = NULL; - rc = MAPI_E_NOT_ENOUGH_MEMORY; - [self logWithFormat: @"PR_BODY data too wide"]; - } - } - else - rc = MAPI_E_NOT_FOUND; - } - } - break; - - case PR_INTERNET_CPID: - /* ref: - http://msdn.microsoft.com/en-us/library/dd317756%28v=vs.85%29.aspx - - minimal list that should be handled: - us-ascii: 20127 - iso-8859-1: 28591 - iso-8859-15: 28605 - utf-8: 65001 */ - *data = MAPILongValue(memCtx, 65001); - break; - - case PR_HTML: - { - NSMutableArray *keys; - NSArray *acceptedTypes; - - child = [self lookupChild: childKey]; - - acceptedTypes = [NSArray arrayWithObject: @"text/html"]; - keys = [NSMutableArray array]; - [child addRequiredKeysOfStructure: [child bodyStructure] - path: @"" toArray: keys acceptedTypes: acceptedTypes]; - if ([keys count] > 0) - { - id result; - NSData *content; - NSDictionary *partHeaderData; - NSString *key, *encoding; - - result = [child fetchParts: [keys objectsForKey: @"key" - notFoundMarker: nil]]; - result = [[result valueForKey: @"RawResponse"] objectForKey: - @"fetch"]; - key = [[keys objectAtIndex: 0] objectForKey: @"key"]; - content = [[result objectForKey: key] objectForKey: @"data"]; - - partHeaderData - = [child lookupInfoForBodyPart: [key _strippedBodyKey]]; - encoding = [partHeaderData objectForKey: @"encoding"]; - content = [content bodyDataFromEncoding: encoding]; - - if ([content length] > 16384) - { - [context registerValue: content - asProperty: propTag - forURL: [NSString stringWithFormat: @"%@%@", folderURL, childKey]]; - *data = NULL; - rc = MAPI_E_NOT_ENOUGH_MEMORY; - [self logWithFormat: @"PR_HTML data too wide"]; - } - else - *data = [content asBinaryInMemCtx: memCtx]; - } - else - { - *data = NULL; - rc = MAPI_E_NOT_FOUND; - } - } - break; - - /* We don't handle any RTF content. */ - case PR_RTF_COMPRESSED: - *data = NULL; - rc = MAPI_E_NOT_FOUND; - break; - case PR_RTF_IN_SYNC: - *data = MAPIBoolValue (memCtx, NO); - break; - case PR_INTERNET_MESSAGE_ID_UNICODE: - child = [self lookupChild: childKey]; - *data = [[child messageId] asUnicodeInMemCtx: memCtx]; - break; - case PR_READ_RECEIPT_REQUESTED: // TODO - case PR_DELETE_AFTER_SUBMIT: // TODO - *data = MAPIBoolValue (memCtx, NO); - break; - case PidLidPrivate: - *data = MAPIBoolValue (memCtx, NO); - break; - - case PR_MSG_EDITOR_FORMAT: - { - NSMutableArray *keys; - NSArray *acceptedTypes; - uint32_t format; - - child = [self lookupChild: childKey]; - - format = 0; /* EDITOR_FORMAT_DONTKNOW */ - - acceptedTypes = [NSArray arrayWithObject: @"text/plain"]; - keys = [NSMutableArray array]; - [child addRequiredKeysOfStructure: [child bodyStructure] - path: @"" toArray: keys - acceptedTypes: acceptedTypes]; - if ([keys count] == 1) - format = EDITOR_FORMAT_PLAINTEXT; - - acceptedTypes = [NSArray arrayWithObject: @"text/html"]; - [keys removeAllObjects]; - [child addRequiredKeysOfStructure: [child bodyStructure] - path: @"" toArray: keys - acceptedTypes: acceptedTypes]; - if ([keys count] == 1) - format = EDITOR_FORMAT_HTML; - - *data = MAPILongValue (memCtx, format); - } - break; - - case PidLidReminderSet: // TODO - case PidLidUseTnef: // TODO - *data = MAPIBoolValue (memCtx, NO); - break; - case PidLidRemoteStatus: // TODO - *data = MAPILongValue (memCtx, 0); - break; - case PidLidSmartNoAttach: // TODO - case PidLidAgingDontAgeMe: // TODO - *data = MAPIBoolValue (memCtx, YES); - break; - -// PidLidFlagRequest -// PidLidBillingInformation -// PidLidMileage -// PidLidCommonEnd -// PidLidCommonStart -// PidLidNonSendableBcc -// PidLidNonSendableCc -// PidLidNonSendtableTo -// PidLidNonSendBccTrackStatus -// PidLidNonSendCcTrackStatus -// PidLidNonSendToTrackStatus -// PidLidReminderDelta -// PidLidReminderFileParameter -// PidLidReminderSignalTime -// PidLidReminderOverride -// PidLidReminderPlaySound -// PidLidReminderTime -// PidLidReminderType -// PidLidSmartNoAttach -// PidLidTaskGlobalId -// PidLidTaskMode -// PidLidVerbResponse -// PidLidVerbStream -// PidLidInternetAccountName -// PidLidInternetAccountStamp -// PidLidContactLinkName -// PidLidContactLinkEntry -// PidLidContactLinkSearchKey -// PidLidSpamOriginalFolder - - default: - rc = [super getChildProperty: data - forKey: childKey - withTag: propTag]; - } - - return rc; -} - - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property { static NSMutableDictionary *knownProperties = nil; @@ -606,11 +86,6 @@ static Class NSDataK, NSStringK; /* restrictions */ -- (void) setRestrictions: (const struct mapi_SRestriction *) res -{ - [super setRestrictions: res]; -} - - (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res intoQualifier: (EOQualifier **) qualifier { @@ -760,6 +235,7 @@ static Class NSDataK, NSStringK; - (void) setSortOrder: (const struct SSortOrderSet *) set { + NSMutableArray *newSortOrderings; NSMutableString *newSortOrdering; struct SSortOrder *sortOrder; NSString *sortIdentifier; @@ -772,7 +248,7 @@ static Class NSDataK, NSStringK; if (set->cCategories > 0) [self errorWithFormat: @"we don't handle sort categories yet"]; - newSortOrdering = [NSMutableString string]; + newSortOrderings = [NSMutableArray array]; for (count = 0; count < set->cSorts; count++) { @@ -781,11 +257,13 @@ static Class NSDataK, NSStringK; = [self _sortIdentifierForProperty: sortOrder->ulPropTag]; if (sortIdentifier) { + newSortOrdering = [NSMutableString string]; if (sortOrder->ulOrder == TABLE_SORT_DESCEND) [newSortOrdering appendString: @" REVERSE"]; else if (sortOrder->ulOrder == TABLE_SORT_MAXIMUM_CATEGORY) [self errorWithFormat: @"TABLE_SORT_MAXIMUM_CATEGORY is not handled"]; [newSortOrdering appendFormat: @" %@", sortIdentifier]; + [newSortOrderings addObject: [newSortOrdering substringFromIndex: 1]]; } else { @@ -797,15 +275,16 @@ static Class NSDataK, NSStringK; propName, sortOrder->ulPropTag]; } } - if ([newSortOrdering length] > 0) - ASSIGN (sortOrdering, [newSortOrdering substringFromIndex: 1]); + if ([newSortOrderings count] > 0) + ASSIGN (sortOrderings, newSortOrderings); else - ASSIGN (sortOrdering, @"ARRIVAL"); - [self cleanupCaches]; - [self logWithFormat: @"new sort ordering: '%@'", sortOrdering]; + ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]); + [self logWithFormat: @"new sort orderings: '%@'", sortOrderings]; } else - ASSIGN (sortOrdering, @"ARRIVAL"); + ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]); + + [self cleanupCaches]; } @end diff --git a/OpenChange/MAPIStoreMessageTable.m b/OpenChange/MAPIStoreMessageTable.m index f9e99386f..057010768 100644 --- a/OpenChange/MAPIStoreMessageTable.m +++ b/OpenChange/MAPIStoreMessageTable.m @@ -25,6 +25,7 @@ #import #import +#import "MAPIStoreFolder.h" #import "MAPIStoreMapping.h" #import "MAPIStoreTypes.h" #import "NSData+MAPIStore.h" @@ -32,21 +33,6 @@ #import "MAPIStoreMessageTable.h" -#undef DEBUG -#include -#include -#include -#include -#include -#include - -@interface SOGoObject (MAPIStoreProtocol) - -- (NSString *) davEntityTag; -- (NSString *) davContentLength; - -@end - @implementation MAPIStoreMessageTable static MAPIStoreMapping *mapping; @@ -56,169 +42,6 @@ static MAPIStoreMapping *mapping; mapping = [MAPIStoreMapping sharedMapping]; } -- (NSArray *) childKeys -{ - return [folder toOneRelationshipKeys]; -} - -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) propTag -{ - int rc; - uint32_t contextId; - uint64_t mappingId; - NSString *stringValue, *childURL; - NSUInteger length; - id child; - - rc = MAPI_E_SUCCESS; - switch (propTag) - { - case PR_INST_ID: // TODO: DOUBT - /* we return a unique id based on the key */ - *data = MAPILongLongValue (memCtx, [childKey hash]); - break; - case PR_INSTANCE_NUM: // TODO: DOUBT - *data = MAPILongValue (memCtx, 0); - break; - case PR_ROW_TYPE: // TODO: DOUBT - *data = MAPILongValue (memCtx, TBL_LEAF_ROW); - break; - case PR_DEPTH: // TODO: DOUBT - *data = MAPILongLongValue (memCtx, 0); - break; - case PR_ACCESS: // TODO - *data = MAPILongValue (memCtx, 0x03); - break; - case PR_ACCESS_LEVEL: // TODO - *data = MAPILongValue (memCtx, 0x01); - break; - case PR_VIEW_STYLE: - case PR_VIEW_MAJORVERSION: - *data = MAPILongValue (memCtx, 0); - break; - case PidLidSideEffects: // TODO - *data = MAPILongValue (memCtx, 0x00000000); - break; - case PidLidCurrentVersion: - *data = MAPILongValue (memCtx, 115608); // Outlook 11.5608 - break; - case PidLidCurrentVersionName: - *data = [@"11.0" asUnicodeInMemCtx: memCtx]; - break; - case PidLidAutoProcessState: - *data = MAPILongValue (memCtx, 0x00000000); - break; - case PidNameContentClass: - *data = [@"Sharing" asUnicodeInMemCtx: memCtx]; - break; - - // case PR_VD_NAME_UNICODE: - // *data = [@"PR_VD_NAME_UNICODE fake value" asUnicodeInMemCtx: memCtx]; - // break; - // case PR_VD_VERSION: - // /* mandatory value... wtf? */g - // *data = MAPILongValue (memCtx, 8); - // break; - case PR_FID: - *data = MAPILongLongValue (memCtx, fid); - break; - case PR_MID: - childURL = [NSString stringWithFormat: @"%@%@", folderURL, childKey]; - mappingId = [mapping idFromURL: childURL]; - if (mappingId == NSNotFound) - { - openchangedb_get_new_folderID (ldbCtx, &mappingId); - [mapping registerURL: childURL withID: mappingId]; - contextId = 0; - mapistore_search_context_by_uri (memCtx, [folderURL UTF8String] + 7, - &contextId); - mapistore_indexing_record_add_mid (memCtx, contextId, mappingId); - } - *data = MAPILongLongValue (memCtx, mappingId); - break; - case PR_MESSAGE_LOCALE_ID: - *data = MAPILongValue (memCtx, 0x0409); - break; - case PR_MESSAGE_FLAGS: // TODO - *data = MAPILongValue (memCtx, MSGFLAG_FROMME | MSGFLAG_READ | MSGFLAG_UNMODIFIED); - break; - case PR_MESSAGE_SIZE: // TODO - child = [self lookupChild: childKey]; - /* TODO: choose another name in SOGo for that method */ - *data = MAPILongValue (memCtx, [[child davContentLength] intValue]); - break; - case PR_MSG_STATUS: // TODO - *data = MAPILongValue (memCtx, 0); - break; - case PR_IMPORTANCE: // TODO -> subclass? - *data = MAPILongValue (memCtx, 1); - break; - case PR_PRIORITY: // TODO -> subclass? - *data = MAPILongValue (memCtx, 0); - break; - case PR_SENSITIVITY: // TODO -> subclass in calendar - *data = MAPILongValue (memCtx, 0); - break; - case PR_CHANGE_KEY: - child = [self lookupChild: childKey]; - stringValue = [child davEntityTag]; - length = [stringValue length]; - if (length < 6) /* guid = 16 bytes */ - { - length += 6; - stringValue = [NSString stringWithFormat: @"000000%@", - stringValue]; - } - if (length > 6) - stringValue = [stringValue substringFromIndex: length - 7]; - stringValue = [NSString stringWithFormat: @"SOGo%@%@%@", - stringValue, stringValue, stringValue]; - *data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding] - asShortBinaryInMemCtx: memCtx]; - break; - - case PR_ORIGINAL_SUBJECT_UNICODE: - case PR_CONVERSATION_TOPIC_UNICODE: - rc = [self getChildProperty: data forKey: childKey - withTag: PR_NORMALIZED_SUBJECT_UNICODE]; - break; - - case PR_SUBJECT_PREFIX_UNICODE: - *data = [@"" asUnicodeInMemCtx: memCtx]; - break; - case PR_NORMALIZED_SUBJECT_UNICODE: - rc = [self getChildProperty: data forKey: childKey - withTag: PR_SUBJECT_UNICODE]; - break; - - case PR_DISPLAY_TO_UNICODE: - case PR_DISPLAY_CC_UNICODE: - case PR_DISPLAY_BCC_UNICODE: - case PR_ORIGINAL_DISPLAY_TO_UNICODE: - case PR_ORIGINAL_DISPLAY_CC_UNICODE: - case PR_ORIGINAL_DISPLAY_BCC_UNICODE: - *data = [@"" asUnicodeInMemCtx: memCtx]; - break; - case PR_LAST_MODIFIER_NAME_UNICODE: - *data = [@"openchange" asUnicodeInMemCtx: memCtx]; - break; - - case PR_ORIG_MESSAGE_CLASS_UNICODE: - rc = [self getChildProperty: data forKey: childKey - withTag: PR_MESSAGE_CLASS_UNICODE]; - break; - - default: - rc = [super getChildProperty: data - forKey: childKey - withTag: propTag]; - } - - return rc; -} - - (void) setSortOrder: (const struct SSortOrderSet *) set { [self logWithFormat: @"unimplemented method: %@", NSStringFromSelector (_cmd)]; diff --git a/OpenChange/MAPIStoreNotesMessageTable.h b/OpenChange/MAPIStoreNotesMessageTable.h deleted file mode 100644 index c577759cb..000000000 --- a/OpenChange/MAPIStoreNotesMessageTable.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreNotesMessageTable.h - this file is part of SOGo - * - * Copyright (C) 2011 Inverse inc - * - * Author: Ludovic Marcotte - * - * 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 3, 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 MAPISTORENOTESMESSAGETABLE_H -#define MAPISTORENOTESMESSAGETABLE_H - -#import "MAPIStoreFSMessageTable.h" - -@interface MAPIStoreNotesMessageTable : MAPIStoreFSMessageTable -@end - -#endif /* MAPISTORENOTESMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreNotesMessageTable.m b/OpenChange/MAPIStoreNotesMessageTable.m deleted file mode 100644 index 87cdc1080..000000000 --- a/OpenChange/MAPIStoreNotesMessageTable.m +++ /dev/null @@ -1,77 +0,0 @@ -/* MAPIStoreNotesMessageTable.m - this file is part of SOGo - * - * Copyright (C) 2010 Inverse inc - * - * Author: Ludovic Marcotte - * - * 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 3, 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 - -#import "MAPIStoreMapping.h" -#import "MAPIStoreTypes.h" -#import "NSData+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreNotesMessageTable.h" - -#undef DEBUG -#include -#include -#include -#include -#include -#include - - -@implementation MAPIStoreNotesMessageTable - -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) propTag -{ - int rc; - - rc = MAPI_E_SUCCESS; - switch (propTag) - { - case PR_ICON_INDEX: // TODO - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */ - // *longValue = 0x00000300 for blue - // *longValue = 0x00000301 for green - // *longValue = 0x00000302 for pink - // *longValue = 0x00000303 for yellow - // *longValue = 0x00000304 for white - *data = MAPILongValue (memCtx, 0x00000303); - break; - - case PR_SUBJECT_UNICODE: - rc = [self getChildProperty: data - forKey: childKey - withTag: PR_NORMALIZED_SUBJECT_UNICODE]; - break; - default: - rc = [super getChildProperty: data - forKey: childKey - withTag: propTag]; - } - - return rc; -} - -@end diff --git a/OpenChange/MAPIStoreTable.h b/OpenChange/MAPIStoreTable.h index 2e4bb8de4..4e01df33c 100644 --- a/OpenChange/MAPIStoreTable.h +++ b/OpenChange/MAPIStoreTable.h @@ -30,11 +30,6 @@ #define SENSITIVITY_PRIVATE 2 #define SENSITIVITY_COMPANY_CONFIDENTIAL 3 -#define TBL_LEAF_ROW 0x00000001 -#define TBL_EMPTY_CATEGORY 0x00000002 -#define TBL_EXPANDED_CATEGORY 0x00000003 -#define TBL_COLLAPSED_CATEGORY 0x00000004 - typedef enum { MAPIRestrictionStateAlwaysFalse = NO, MAPIRestrictionStateAlwaysTrue = YES, @@ -43,48 +38,49 @@ typedef enum { } MAPIRestrictionState; @class NSArray; +@class NSMutableArray; @class NSString; @class EOQualifier; +@class MAPIStoreObject; + @interface MAPIStoreTable : NSObject { - id context; - struct mapistore_context *memCtx; - void *ldbCtx; + MAPIStoreObject *container; - id folder; - NSString *folderURL; - uint64_t fid; + NSArray *childKeys; + NSArray *restrictedChildKeys; - id lastChild; - NSString *lastChildKey; - - NSArray *cachedKeys; - NSArray *cachedRestrictedKeys; EOQualifier *restriction; /* should probably be a dictionary too */ MAPIRestrictionState restrictionState; + NSMutableArray *sortOrderings; + + uint32_t currentRow; + MAPIStoreObject *currentChild; + + /* proof of concept */ + uint16_t columnsCount; + enum MAPITAGS *columns; } -- (id) folder; ++ (id) tableForContainer: (MAPIStoreObject *) newContainer; -- (void) setContext: (id) newContext - withMemCtx: (struct mapistore_context *) newMemCtx; -- (void) setFolder: (id) newFolder - withURL: (NSString *) newFolderURL - andFID: (uint64_t) newFid; +- (id) initForContainer: (MAPIStoreObject *) newContainer; -- (void) setRestrictions: (const struct mapi_SRestriction *) res; +- (NSArray *) childKeys; +- (NSArray *) restrictedChildKeys; -- (NSArray *) cachedChildKeys; -- (NSArray *) cachedRestrictedChildKeys; - -- (id) lookupChild: (NSString *) childKey; +- (id) childAtRowID: (uint32_t) rowId + forQueryType: (enum table_query_type) queryType; - (void) cleanupCaches; -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) proptag; +- (void) setRestrictions: (const struct mapi_SRestriction *) res; +- (int) setColumns: (enum MAPITAGS *) newColumns + withCount: (uint16_t) newColumCount; +- (int) getRow: (struct mapistore_property_data *) data + withRowID: (uint32_t) rowId + andQueryType: (enum table_query_type) queryType; /* helpers */ @@ -92,9 +88,7 @@ typedef enum { inFunction: (const char *) function; /* subclasses */ - -- (NSArray *) childKeys; -- (NSArray *) restrictedChildKeys; +- (void) setSortOrder: (const struct SSortOrderSet *) set; - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property; - (MAPIRestrictionState) evaluateContentRestriction: (const struct mapi_SContentRestriction *) res diff --git a/OpenChange/MAPIStoreTable.m b/OpenChange/MAPIStoreTable.m index c1a50730a..d1225131a 100644 --- a/OpenChange/MAPIStoreTable.m +++ b/OpenChange/MAPIStoreTable.m @@ -25,13 +25,13 @@ #import #import -#import - #import "EOBitmaskQualifier.h" #import "MAPIStoreTypes.h" #import "NSData+MAPIStore.h" #import "NSString+MAPIStore.h" +#import "MAPIStoreObject.h" + #import "MAPIStoreTable.h" #undef DEBUG @@ -249,23 +249,41 @@ static Class NSDataK, NSStringK; NSStringK = [NSString class]; } ++ (id) tableForContainer: (MAPIStoreObject *) newContainer +{ + MAPIStoreTable *newTable; + + newTable = [[self alloc] initForContainer: newContainer]; + [newTable autorelease]; + + return newTable; +} + - (id) init { if ((self = [super init])) { - context = nil; - memCtx = NULL; + container = nil; - folder = nil; - folderURL = nil; + childKeys = nil; + restrictedChildKeys = nil; - lastChild = nil; - lastChildKey = nil; + currentRow = (uint32_t) -1; + currentChild = nil; - cachedKeys = nil; - cachedRestrictedKeys = nil; restriction = nil; restrictionState = MAPIRestrictionStateAlwaysTrue; + sortOrderings = nil; + } + + return self; +} + +- (id) initForContainer: (MAPIStoreObject *) newContainer +{ + if ((self = [self init])) + { + container = newContainer; } return self; @@ -273,95 +291,57 @@ static Class NSDataK, NSStringK; - (void) dealloc { - [folder release]; - [folderURL release]; - [lastChildKey release]; - [lastChild release]; - [cachedKeys release]; - [cachedRestrictedKeys release]; + [currentChild release]; + [childKeys release]; + [restrictedChildKeys release]; [restriction release]; [super dealloc]; } -- (void) setContext: (id) newContext - withMemCtx: (struct mapistore_context *) newMemCtx +- (NSArray *) childKeys { - struct loadparm_context *lpCtx; - - context = newContext; - - memCtx = newMemCtx; - lpCtx = loadparm_init (newMemCtx); - ldbCtx = mapiproxy_server_openchange_ldb_init (lpCtx); -} - -- (void) setFolder: (id) newFolder - withURL: (NSString *) newFolderURL - andFID: (uint64_t) newFid -{ - ASSIGN (folder, newFolder); - ASSIGN (folderURL, newFolderURL); - fid = newFid; -} - -- (id) folder -{ - if (!folder) - [self warnWithFormat: @"returning nil folder"]; - return folder; -} - -- (NSArray *) cachedChildKeys -{ - if (!cachedKeys) + if (!childKeys) { - cachedKeys = [self childKeys]; - [cachedKeys retain]; + childKeys = [container childKeysMatchingQualifier: nil + andSortOrderings: sortOrderings]; + [childKeys retain]; } - return cachedKeys; + return childKeys; } -- (NSArray *) cachedRestrictedChildKeys +- (NSArray *) restrictedChildKeys { - if (!cachedRestrictedKeys) + NSArray *keys; + + if (!restrictedChildKeys) { - cachedRestrictedKeys = [self restrictedChildKeys]; - [cachedRestrictedKeys retain]; + if (restrictionState != MAPIRestrictionStateAlwaysTrue) + { + if (restrictionState == MAPIRestrictionStateNeedsEval) + keys = [container childKeysMatchingQualifier: restriction + andSortOrderings: sortOrderings]; + else + keys = [NSArray array]; + } + else + keys = [self childKeys]; + + ASSIGN (restrictedChildKeys, keys); } - return cachedRestrictedKeys; + return restrictedChildKeys; } - (void) cleanupCaches { - [cachedRestrictedKeys release]; - cachedRestrictedKeys = nil; - [cachedKeys release]; - cachedKeys = nil; - [lastChildKey release]; - lastChildKey = nil; - [lastChild release]; - lastChild = nil; -} - -- (id) lookupChild: (NSString *) childKey -{ - id newChild; - - if ([lastChildKey isEqualToString: childKey]) - newChild = lastChild; - else - { - [self logWithFormat: @"child key is now '%@'", childKey]; - newChild = [folder lookupName: childKey - inContext: nil - acquire: NO]; - ASSIGN (lastChildKey, childKey); - ASSIGN (lastChild, newChild); - } - - return newChild; + [restrictedChildKeys release]; + restrictedChildKeys = nil; + [childKeys release]; + childKeys = nil; + [currentChild release]; + currentChild = nil; + currentRow = (uint32_t) -1; } - (void) setRestrictions: (const struct mapi_SRestriction *) res @@ -385,8 +365,7 @@ static Class NSDataK, NSStringK; restriction = nil; // FIXME: we should not flush the caches if the restrictions matches - [cachedRestrictedKeys release]; - cachedRestrictedKeys = nil; + [self cleanupCaches]; if (restriction) [self logWithFormat: @"restriction set to EOQualifier: %@", @@ -395,59 +374,6 @@ static Class NSDataK, NSStringK; [self logWithFormat: @"restriction unset (was %@)", oldRestriction]; } -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) propTag -{ - NSString *stringValue; - id child; - // uint64_t *llongValue; - // uint32_t *longValue; - int rc; - const char *propName; - - rc = MAPI_E_SUCCESS; - switch (propTag) - { - case PR_DISPLAY_NAME_UNICODE: - child = [self lookupChild: childKey]; - *data = [[child displayName] asUnicodeInMemCtx: memCtx]; - break; - case PR_SEARCH_KEY: // TODO - child = [self lookupChild: childKey]; - stringValue = [child nameInContainer]; - *data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding] - asBinaryInMemCtx: memCtx]; - break; - case PR_GENERATE_EXCHANGE_VIEWS: // TODO - *data = MAPIBoolValue (memCtx, NO); - break; - - default: - propName = get_proptag_name (propTag); - if (!propName) - propName = ""; - [self warnWithFormat: - @"unhandled or NULL value: %s (0x%.8x), childKey: %@", - propName, propTag, childKey]; - // if ((propTag & 0x001F) == 0x001F) - // { - // stringValue = [NSString stringWithFormat: @"fake %s (0x.8x) value", - // propName, propTag]; - // *data = [stringValue asUnicodeInMemCtx: memCtx]; - // rc = MAPI_E_SUCCESS; - // } - // else - // { - *data = NULL; - rc = MAPI_E_NOT_FOUND; - // } - break; - } - - return rc; -} - - (MAPIRestrictionState) evaluateNotRestriction: (struct mapi_SNotRestriction *) res intoQualifier: (EOQualifier **) qualifierPtr { @@ -555,13 +481,6 @@ static Class NSDataK, NSStringK; return state; } -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - - (void) warnUnhandledProperty: (enum MAPITAGS) property inFunction: (const char *) function { @@ -781,18 +700,97 @@ static Class NSDataK, NSStringK; return state; } -- (NSArray *) childKeys +/* proof of concept */ +- (int) setColumns: (enum MAPITAGS *) newColumns + withCount: (uint16_t) newColumnsCount +{ + NSUInteger count; + + if (columns) + NSZoneFree (NULL, columns); + columns = NSZoneMalloc (NULL, newColumnsCount * sizeof (enum MAPITAGS)); + for (count = 0; count < newColumnsCount; count++) + columns[count] = newColumns[count]; + columnsCount = newColumnsCount; + + return MAPISTORE_SUCCESS; +} + +- (id) childAtRowID: (uint32_t) rowId + forQueryType: (enum table_query_type) queryType +{ + id child; + NSArray *children, *restrictedChildren; + NSString *childKey; + + if (rowId == currentRow) + child = currentChild; + else + { + child = nil; + + if (queryType == MAPISTORE_PREFILTERED_QUERY) + { + children = [self restrictedChildKeys]; + restrictedChildren = nil; + } + else + { + children = [self childKeys]; + restrictedChildren = [self restrictedChildKeys]; + } + + if ([children count] > rowId) + { + childKey = [children objectAtIndex: rowId]; + + if (queryType == MAPISTORE_PREFILTERED_QUERY + || [restrictedChildren containsObject: childKey]) + child = [container lookupChild: childKey]; + } + + currentChild = child; + [currentChild retain]; + currentRow = rowId; + } + + return child; +} + +- (int) getRow: (struct mapistore_property_data *) data + withRowID: (uint32_t) rowId + andQueryType: (enum table_query_type) queryType +{ + NSUInteger count; + MAPIStoreObject *child; + enum MAPISTATUS rc; + + child = [self childAtRowID: rowId + forQueryType: queryType]; + if (child) + { + rc = MAPI_E_SUCCESS; + for (count = 0; count < columnsCount; count++) + data[count].error = [child getProperty: &data[count].data + withTag: columns[count]]; + } + else + rc = MAPI_E_INVALID_OBJECT; + + return rc; +} + +/* subclasses */ +- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property { [self subclassResponsibility: _cmd]; return nil; } -- (NSArray *) restrictedChildKeys +- (void) setSortOrder: (const struct SSortOrderSet *) set { [self subclassResponsibility: _cmd]; - - return nil; } @end diff --git a/OpenChange/MAPIStoreTasksMessageTable.m b/OpenChange/MAPIStoreTasksMessageTable.m index 1abaa7d72..83ab5a35e 100644 --- a/OpenChange/MAPIStoreTasksMessageTable.m +++ b/OpenChange/MAPIStoreTasksMessageTable.m @@ -39,239 +39,6 @@ @implementation MAPIStoreTasksMessageTable -- (enum MAPISTATUS) getChildProperty: (void **) data - forKey: (NSString *) childKey - withTag: (enum MAPITAGS) propTag -{ - NSString *status; - // id child; - iCalToDo *task; - int32_t statusValue; - NSCalendarDate *dateValue; - int rc; - double doubleValue; - - rc = MAPI_E_SUCCESS; - switch (propTag) - { - case PR_ICON_INDEX: // TODO - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */ - // Unassigned recurring task 0x00000501 - // Assignee's task 0x00000502 - // Assigner's task 0x00000503 - // Task request 0x00000504 - // Task acceptance 0x00000505 - // Task rejection 0x00000506 - *data = MAPILongValue (memCtx, 0x00000500); - break; - case PR_MESSAGE_CLASS_UNICODE: - *data = talloc_strdup(memCtx, "IPM.Task"); - break; - case PR_SUBJECT_UNICODE: // SUMMARY - task = [[self lookupChild: childKey] component: NO secure: NO]; - *data = [[task summary] asUnicodeInMemCtx: memCtx]; - break; - - // - // Not to be confused with PR_PRIORITY - // - // IMPORTANCE_LOW = 0x0, IMPORTANCE_NORMAL = 0x1 and IMPORTANCE_HIGH = 0x2 - // - case PR_IMPORTANCE: - { - unsigned int v; - - task = [[self lookupChild: childKey] component: NO secure: NO]; - - if ([[task priority] isEqualToString: @"9"]) - v = 0x0; - else if ([[task priority] isEqualToString: @"1"]) - v = 0x2; - else - v = 0x1; - - *data = MAPILongValue (memCtx, v); - } - break; - case PidLidTaskComplete: - task = [[self lookupChild: childKey] component: NO secure: NO]; - *data = MAPIBoolValue (memCtx, - [[task status] isEqualToString: @"COMPLETED"]); - break; - case PidLidPercentComplete: - task = [[self lookupChild: childKey] component: NO secure: NO]; - doubleValue = ((double) [[task percentComplete] intValue] / 100); - *data = MAPIDoubleValue (memCtx, doubleValue); - break; - case PidLidTaskDateCompleted: - task = [[self lookupChild: childKey] component: NO secure: NO]; - dateValue = [task completed]; - if (dateValue) - *data = [dateValue asFileTimeInMemCtx: memCtx]; - else - rc = MAPI_E_NOT_FOUND; - break; - // http://msdn.microsoft.com/en-us/library/cc765590.aspx - // It's important to have a proper value for PidLidTaskState - // as it'll affect the UI options of Outlook - making the - // task non-editable in some cases. - case PidLidTaskState: - *data = MAPILongValue (memCtx, 0x1); // not assigned - break; - case PidLidTaskMode: // TODO - *data = MAPILongValue (memCtx, 0x0); - break; - case PidLidTaskFRecurring: - case PidLidTaskAccepted: // TODO - *data = MAPIBoolValue (memCtx, NO); - break; - case PidLidTaskActualEffort: // TODO - case PidLidTaskEstimatedEffort: // TODO - *data = MAPILongValue (memCtx, 0); - break; - case PR_HASATTACH: - *data = MAPIBoolValue (memCtx, NO); - break; - - case PidLidTaskDueDate: - task = [[self lookupChild: childKey] component: NO secure: NO]; - dateValue = [task due]; - if (dateValue) - *data = [dateValue asFileTimeInMemCtx: memCtx]; - else - rc = MAPI_E_NOT_FOUND; - break; - - case PR_CREATION_TIME: - task = [[self lookupChild: childKey] component: NO secure: NO]; - *data = [[task created] asFileTimeInMemCtx: memCtx]; - break; - case PR_MESSAGE_DELIVERY_TIME: - case PR_CLIENT_SUBMIT_TIME: - case PR_LOCAL_COMMIT_TIME: - case PR_LAST_MODIFICATION_TIME: - task = [[self lookupChild: childKey] component: NO secure: NO]; - *data = [[task lastModified] asFileTimeInMemCtx: memCtx]; - break; - case PidLidTaskStatus: // status - task = [[self lookupChild: childKey] component: NO secure: NO]; - status = [task status]; - if (![status length] - || [status isEqualToString: @"NEEDS-ACTION"]) - statusValue = 0; - else if ([status isEqualToString: @"IN-PROCESS"]) - statusValue = 1; - else if ([status isEqualToString: @"COMPLETED"]) - statusValue = 2; - else - statusValue = 0xff; - *data = MAPILongValue (memCtx, statusValue); - break; - /* Completed */ - // - 0x81380003 = -2000 - // + 0x81380003 = -4000 - - // 68330048 - // 68420102 - case 0x68340003: - case 0x683a0003: - case 0x68410003: - *data = MAPILongValue (memCtx, 0); - break; - - // FIXME - use the current user - case PidLidTaskOwner: - *data = [@"openchange@example.com" asUnicodeInMemCtx: memCtx]; - break; - - // See http://msdn.microsoft.com/en-us/library/cc842113.aspx - case PidLidTaskOwnership: - *data = MAPILongValue (memCtx, 0x0); // not assigned - break; - -// #define PidLidFlagRequest 0x9027001f -// #define PidNameContentType 0x905a001f -// #define PidLidBillingInformation 0x908b001f -// #define PidLidTaskStartDate 0x911e0040 -// #define PidLidTaskOwner 0x9122001f -// #define PidLidTaskDeadOccurrence 0x9127000b -// #define PidLidTaskMultipleRecipients 0x912a0003 -// #define PidLidTaskHistory 0x912b0003 -// #define PidLidAcceptanceState 0x912c0003 -// #define PidLidTaskLastUser 0x912d001f -// #define PidLidTaskLastUpdate 0x912e0040 -// #define PidLidTaskOwnership 0x912f0003 -// #define PidLidTaskNoCompute 0x9130000b -// #define PidLidTaskFFixOffline 0x9131000b -// #define PidLidTaskRole 0x9132001f -// #define PidLidTaskVersion 0x91330003 -// #define PidLidTaskAssigner 0x9134001f -// #define PidLidTeamTask 0x9135000b -// #define PidLidTaskRecurrence 0x91360102 -// #define PidLidTaskResetReminder 0x9137000b -// #define PidLidTaskOrdinal 0x91380003 -// #define PidLidMileage 0x914a001f -// #define PidLidAgingDontAgeMe 0x9185000b -// #define PidLidCommonEnd 0x91980040 -// #define PidLidCommonStart 0x91990040 -// #define PidLidNonSendableBcc 0x91d7001f -// #define PidLidNonSendableCc 0x91d8001f -// #define PidLidNonSendtableTo 0x91d9001f -// #define PidLidNonSendBccTrackStatus 0x91da1003 -// #define PidLidNonSendCcTrackStatus 0x91db1003 -// #define PidLidNonSendToTrackStatus 0x91dc1003 -// #define PidLidReminderDelta 0x91e90003 -// #define PidLidReminderFileParameter 0x91ea001f -// #define PidLidReminderSignalTime 0x91eb0040 -// #define PidLidReminderOverride 0x91ec000b -// #define PidLidReminderPlaySound 0x91ed000b -// #define PidLidReminderSet 0x91ee000b -// #define PidLidReminderTime 0x91ef0040 -// #define PidLidReminderType 0x91f20003 -// #define PidLidRemoteStatus 0x91f30003 -// #define PidLidSmartNoAttach 0x91fa000b -// #define PidLidTaskGlobalId 0x91fe0102 -// #define PidLidVerbResponse 0x9203001f -// #define PidLidVerbStream 0x92040102 -// #define PidLidPrivate 0x9224000b -// #define PidLidInternetAccountName 0x9225001f -// #define PidLidInternetAccountStamp 0x9226001f -// #define PidLidUseTnef 0x9227000b -// #define PidLidContactLinkName 0x9229001f -// #define PidLidContactLinkEntry 0x922a0102 -// #define PidLidContactLinkSearchKey 0x922b0102 -// #define PidLidSpamOriginalFolder 0x92370102 -// #define PidLidTaskUpdates 0x9345000b -// #define PidLidTaskStatusOnComplete 0x9346000b -// #define PidLidTaskLastDelegate 0x9347001f -// #define PidLidTaskAssigners 0x934a0102 -// #define PidLidTaskFCreator 0x934c000b -// #define PidLidImapDeleted 0x94e50003 -// #define PidLidHeaderItem 0x94e60003 - - default: - rc = [super getChildProperty: data - forKey: childKey - withTag: propTag]; - } - - return rc; -} - -- (EOQualifier *) componentQualifier -{ - static EOQualifier *componentQualifier = nil; - - /* TODO: we need to support vlist as well */ - if (!componentQualifier) - componentQualifier - = [[EOKeyValueQualifier alloc] initWithKey: @"c_component" - operatorSelector: EOQualifierOperatorEqual - value: @"vtodo"]; - - return componentQualifier; -} - - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property { static NSMutableDictionary *knownProperties = nil;