diff --git a/ChangeLog b/ChangeLog index 65a677992..6961311ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-08-02 Wolfgang Sourdeau + + * OpenChange/MAPIStoreContactsMessageTable.m + (-evaluateContentRestriction:intoQualifier:): overriden method in + order to evaluate PR_MESSAGE_CLASS_UNICODE. + (-evaluatePropertyRestriction:intoQualifier:): added stub support for + PidLidAddressBookProviderArrayType, + PidLidAddressBookProviderEmailList and real support for + PidLidEmail[123]OriginalDisplayName. + + * OpenChange/MAPIStoreTable.m (-operatorFromRestrictionOperator): + code split from -evaluatePropertyRestriction:intoQualifier: and + exposed for external use. + 2011-08-02 Francis Lachapelle * UI/WebServerResources/MailerUI.js (_onMenuLabelFlagX): fixed a diff --git a/OpenChange/MAPIStoreContactsMessageTable.m b/OpenChange/MAPIStoreContactsMessageTable.m index 95c9fd023..60e95a968 100644 --- a/OpenChange/MAPIStoreContactsMessageTable.m +++ b/OpenChange/MAPIStoreContactsMessageTable.m @@ -20,11 +20,14 @@ * Boston, MA 02111-1307, USA. */ +#import #import +#import #import #import - +#import +#import #import #import @@ -41,13 +44,16 @@ #include -static Class MAPIStoreContactsMessageK; +static Class MAPIStoreContactsMessageK, NGMailAddressK, NSDataK, NSStringK; @implementation MAPIStoreContactsMessageTable + (void) initialize { MAPIStoreContactsMessageK = [MAPIStoreContactsMessage class]; + NSDataK = [NSData class]; + NSStringK = [NSString class]; + NGMailAddressK = [NGMailAddress class]; } + (Class) childObjectClass @@ -83,7 +89,11 @@ static Class MAPIStoreContactsMessageK; intoQualifier: (EOQualifier **) qualifier { MAPIRestrictionState rc; - id value; + EOAndQualifier *andQualifier; + EOKeyValueQualifier *fullNameQualifier, *emailQualifier; + NSString *fullName, *email; + SEL operator; + id value, ngAddress; value = NSObjectFromMAPISPropValue (&res->lpProp); switch ((uint32_t) res->ulPropTag) @@ -94,6 +104,51 @@ static Class MAPIStoreContactsMessageK; else rc = MAPIRestrictionStateAlwaysFalse; break; + + case PidLidAddressBookProviderArrayType: + case PidLidAddressBookProviderEmailList: + /* FIXME: this is a hack. We should return a real qualifier here */ + rc = MAPIRestrictionStateAlwaysTrue; + break; + + case PidLidEmail1OriginalDisplayName: + case PidLidEmail2OriginalDisplayName: + case PidLidEmail3OriginalDisplayName: + rc = MAPIRestrictionStateAlwaysFalse; + value = NSObjectFromMAPISPropValue (&res->lpProp); + if (value && [value isKindOfClass: NSStringK]) + { + rc = MAPIRestrictionStateNeedsEval; + ngAddress = [[NGMailAddressParser mailAddressParserWithString: value] + parse]; + if ([ngAddress isKindOfClass: NGMailAddressK]) + { + operator = [self operatorFromRestrictionOperator: res->relop]; + fullName = [ngAddress displayName]; + email = [ngAddress address]; + emailQualifier = [[EOKeyValueQualifier alloc] + initWithKey: @"c_mail" + operatorSelector: operator + value: email]; + if ([fullName length] > 0) + { + fullNameQualifier = [[EOKeyValueQualifier alloc] + initWithKey: @"c_cn" + operatorSelector: operator + value: fullName]; + andQualifier = [[EOAndQualifier alloc] + initWithQualifiers: + emailQualifier, fullNameQualifier, nil]; + [fullNameQualifier release]; + [emailQualifier release]; + *qualifier = andQualifier; + } + else + *qualifier = emailQualifier; + [*qualifier autorelease]; + } + } + break; case PidLidEmail1AddressType: case PidLidEmail2AddressType: case PidLidEmail3AddressType: @@ -110,6 +165,39 @@ static Class MAPIStoreContactsMessageK; return rc; } +- (MAPIRestrictionState) evaluateContentRestriction: (struct mapi_SContentRestriction *) res + intoQualifier: (EOQualifier **) qualifier +{ + MAPIRestrictionState rc; + id value; + + value = NSObjectFromMAPISPropValue (&res->lpProp); + if ([value isKindOfClass: NSDataK]) + { + value = [[NSString alloc] initWithData: value + encoding: NSUTF8StringEncoding]; + [value autorelease]; + } + else if (![value isKindOfClass: NSStringK]) + [NSException raise: @"MAPIStoreTypeConversionException" + format: @"unhandled content restriction for class '%@'", + NSStringFromClass ([value class])]; + + switch (res->ulPropTag) + { + case PR_MESSAGE_CLASS_UNICODE: /* FIXME: should make use of c_component here */ + if ([value isEqualToString: @"IPM.Contact"]) + rc = MAPIRestrictionStateAlwaysTrue; + else + rc = MAPIRestrictionStateAlwaysFalse; + break; + default: + rc = [super evaluateContentRestriction: res intoQualifier: qualifier]; + } + + return rc; +} + /* sorting */ - (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property diff --git a/OpenChange/MAPIStoreTable.h b/OpenChange/MAPIStoreTable.h index ae2f60d8d..941d835af 100644 --- a/OpenChange/MAPIStoreTable.h +++ b/OpenChange/MAPIStoreTable.h @@ -79,12 +79,8 @@ typedef enum { - (void) setHandleId: (uint32_t) newHandleId; -- (NSArray *) childKeys; -- (NSArray *) restrictedChildKeys; - - (id) childAtRowID: (uint32_t) rowId forQueryType: (enum table_query_type) queryType; -- (id) lookupChild: (NSString *) childKey; - (void) cleanupCaches; @@ -104,10 +100,16 @@ typedef enum { /* helpers */ +- (SEL) operatorFromRestrictionOperator: (uint32_t) resOp; - (void) warnUnhandledProperty: (enum MAPITAGS) property inFunction: (const char *) function; /* subclasses */ +- (NSArray *) childKeys; +- (NSArray *) restrictedChildKeys; + +- (id) lookupChild: (NSString *) childKey; + - (void) setSortOrder: (const struct SSortOrderSet *) set; - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property; diff --git a/OpenChange/MAPIStoreTable.m b/OpenChange/MAPIStoreTable.m index 861279473..ed4f73a69 100644 --- a/OpenChange/MAPIStoreTable.m +++ b/OpenChange/MAPIStoreTable.m @@ -580,8 +580,7 @@ static Class NSDataK, NSStringK; return rc; } -- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier +- (SEL) operatorFromRestrictionOperator: (uint32_t) resOp { static SEL operators[] = { EOQualifierOperatorLessThan, EOQualifierOperatorLessThanOrEqualTo, @@ -591,6 +590,23 @@ static Class NSDataK, NSStringK; EOQualifierOperatorNotEqual, EOQualifierOperatorContains }; SEL operator; + + if (resOp < 7) + operator = operators[resOp]; + else + { + operator = NULL; + [NSException raise: @"MAPIStoreRestrictionException" + format: @"unhandled operator type number %d", resOp]; + } + + return operator; +} + +- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res + intoQualifier: (EOQualifier **) qualifier +{ + SEL operator; id value; NSString *property; MAPIRestrictionState rc; @@ -598,17 +614,8 @@ static Class NSDataK, NSStringK; property = [self backendIdentifierForProperty: res->ulPropTag]; if (property) { - if (res->relop >= 0 && res->relop < 7) - operator = operators[res->relop]; - else - { - operator = NULL; - [NSException raise: @"MAPIStoreRestrictionException" - format: @"unhandled operator type number %d", res->relop]; - } - + operator = [self operatorFromRestrictionOperator: res->relop]; value = NSObjectFromMAPISPropValue (&res->lpProp); - *qualifier = [[EOKeyValueQualifier alloc] initWithKey: property operatorSelector: operator value: value]; @@ -686,32 +693,41 @@ static Class NSDataK, NSStringK; switch (res->rt) { /* basic operators */ - case 0: state = [self evaluateAndRestriction: &res->res.resAnd - intoQualifier: qualifier]; + case RES_AND: state = [self evaluateAndRestriction: &res->res.resAnd + intoQualifier: qualifier]; break; - case 1: state = [self evaluateOrRestriction: &res->res.resOr - intoQualifier: qualifier]; + case RES_OR: state = [self evaluateOrRestriction: &res->res.resOr + intoQualifier: qualifier]; break; - case 2: state = [self evaluateNotRestriction: &res->res.resNot - intoQualifier: qualifier]; + case RES_NOT: state = [self evaluateNotRestriction: &res->res.resNot + intoQualifier: qualifier]; break; /* content restrictions */ - case 3: state = [self evaluateContentRestriction: &res->res.resContent - intoQualifier: qualifier]; + case RES_CONTENT: state = [self evaluateContentRestriction: &res->res.resContent + intoQualifier: qualifier]; break; - case 4: state = [self evaluatePropertyRestriction: &res->res.resProperty - intoQualifier: qualifier]; + case RES_PROPERTY: state = [self evaluatePropertyRestriction: &res->res.resProperty + intoQualifier: qualifier]; break; - case 6: state = [self evaluateBitmaskRestriction: &res->res.resBitmask - intoQualifier: qualifier]; + case RES_BITMASK: state = [self evaluateBitmaskRestriction: &res->res.resBitmask + intoQualifier: qualifier]; break; - case 7: state = MAPIRestrictionStateAlwaysTrue; /* let's cheat a little */ + case RES_SIZE: state = MAPIRestrictionStateAlwaysTrue; /* let's cheat a little */ break; - case 8: state = [self evaluateExistRestriction: &res->res.resExist - intoQualifier: qualifier]; + case RES_EXIST: state = [self evaluateExistRestriction: &res->res.resExist + intoQualifier: qualifier]; break; + + case RES_COMMENT: + if (res->res.resComment.RestrictionPresent) + state = [self evaluateRestriction: (struct mapi_SRestriction *) res->res.resComment.Restriction.res + intoQualifier: qualifier]; + else + state = MAPIRestrictionStateAlwaysTrue; + break; + // case 5: MAPIStringForComparePropsRestriction(&resPtr->res.resCompareProps); break; // case 7: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break; // case 9: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;