Monotone-Parent: a1865313ff7142cbf139f7645dcbb299dd1acb92

Monotone-Revision: 06779f0bbfe40e7611b69790cf2eff4809382438

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2011-06-07T00:17:46
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2011-06-07 00:17:46 +00:00
parent b11f1c25df
commit 2974a91c5e
23 changed files with 923 additions and 331 deletions
+11
View File
@@ -1,5 +1,16 @@
2011-06-06 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/*:
- (context) cached last requested folder and table
- (context) open folders are now cached in an nsdictionary
- getPrLastModificationTime and getPrCreationTime are now
centralized in MAPIStoreObject and rely on mandator lastModificationTime
and creationTime methods on individual subclasses.
- openMessage now takes a "struct mapistore_message **" argument.
- MAPIStoreFSFolder can now create subfolders
- converted MAPIStoreFolder to the new property API, by
implementing one method per property.
* OpenChange/MAPIStoreMailMessage.m: (-getPrExpiryTime:) removed
method as we don't want the message to appear as "expired".
(-getPrOriginalSensitivity:): uppercased the "o" in "getPrOriginal..."
-5
View File
@@ -25,12 +25,7 @@
#import "MAPIStoreGCSMessage.h"
@class iCalEvent;
@interface MAPIStoreCalendarMessage : MAPIStoreGCSMessage
{
iCalEvent *event;
}
@end
+77 -63
View File
@@ -73,36 +73,17 @@ static NSTimeZone *utcTZ;
[utcTZ retain];
}
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
if ((self = [super initWithSOGoObject: newSOGoObject
inContainer: newContainer]))
{
ASSIGN (event, [newSOGoObject component: NO secure: NO]);
}
return self;
}
- (id) init
{
if ((self = [super init]))
{
attachmentKeys = [NSMutableArray new];
attachmentParts = [NSMutableDictionary new];
event = nil;
}
return self;
}
- (void) dealloc
{
[event release];
[super dealloc];
}
- (NSTimeZone *) ownerTimeZone
{
NSString *owner;
@@ -124,6 +105,9 @@ static NSTimeZone *utcTZ;
struct Binary_r *blob;
struct AppointmentRecurrencePattern *pattern;
NSMutableArray *otherEvents;
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
/* cleanup */
otherEvents = [[calendar events] mutableCopy];
@@ -169,7 +153,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
struct SBinary_short *sBin;
NSCalendarDate *firstStartDate;
iCalRecurrenceRule *rule;
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
rule = [[event recurrenceRules] objectAtIndex: 0];
firstStartDate = [event firstRecurrenceStartDate];
@@ -204,6 +190,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPrIconIndex: (void **) data // TODO
{
uint32_t longValue;
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
// *longValue = 0x00000401 for recurring event
@@ -232,6 +221,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPrStartDate: (void **) data
{
NSCalendarDate *dateValue;
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
if ([event isRecurrent])
dateValue = [event firstRecurrenceStartDate];
@@ -256,6 +248,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPrEndDate: (void **) data
{
NSCalendarDate *dateValue;
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
if ([event isRecurrent])
dateValue = [event firstRecurrenceStartDate];
@@ -285,6 +280,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPidLidAppointmentDuration: (void **) data
{
NSTimeInterval timeValue;
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
timeValue = [[event endDate] timeIntervalSinceDate: [event startDate]];
*data = MAPILongValue (memCtx, (uint32_t) (timeValue / 60));
@@ -294,6 +292,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPidLidAppointmentSubType: (void **) data
{
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
*data = MAPIBoolValue (memCtx, [event isAllDay]);
return MAPISTORE_SUCCESS;
@@ -308,6 +309,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPrSubject: (void **) data // SUMMARY
{
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
*data = [[event summary] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
@@ -315,6 +319,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPidLidLocation: (void **) data // LOCATION
{
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
*data = [[event location] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
@@ -331,17 +338,12 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
return [self getLongZero: data];
}
- (int) getPrCreationTime: (void **) data
{
*data = [[event created] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrImportance: (void **) data
{
uint32_t v;
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
if ([[event priority] isEqualToString: @"9"])
v = 0x0;
else if ([[event priority] isEqualToString: @"1"])
@@ -356,6 +358,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPidLidIsRecurring: (void **) data
{
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
*data = MAPIBoolValue (memCtx, [event isRecurrent]);
return MAPISTORE_SUCCESS;
@@ -363,6 +368,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPidLidRecurring: (void **) data
{
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
*data = MAPIBoolValue (memCtx, [event isRecurrent]);
return MAPISTORE_SUCCESS;
@@ -371,6 +379,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (int) getPidLidAppointmentRecur: (void **) data
{
int rc = MAPISTORE_SUCCESS;
iCalEvent *event;
event = [sogoObject component: NO secure: NO];
if ([event isRecurrent])
*data = [self _computeAppointmentRecur];
@@ -382,50 +393,57 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
- (void) openMessage: (struct mapistore_message *) msg
{
NSString *name, *email;
NSString *text;
NSArray *attendees;
iCalPerson *person;
struct SRowSet *recipients;
int count, max;
iCalEvent *event;
[super openMessage: msg];
event = [sogoObject component: NO secure: NO];
attendees = [event attendees];
max = [attendees count];
recipients = msg->recipients;
recipients = talloc_zero (memCtx, struct SRowSet);
recipients->cRows = max;
recipients->aRow = talloc_array (recipients, struct SRow, max);
for (count = 0; count < max; count++)
{
recipients->aRow[count].ulAdrEntryPad = 0;
recipients->aRow[count].cValues = 3;
recipients->aRow[count].lpProps = talloc_array (recipients->aRow,
struct SPropValue,
3);
4);
// TODO (0x01 = primary recipient)
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[0]),
set_SPropValue_proptag (recipients->aRow[count].lpProps,
PR_RECIPIENT_TYPE,
MAPILongValue (memCtx, 0x01));
MAPILongValue (recipients->aRow[count].lpProps, 0x01));
set_SPropValue_proptag (recipients->aRow[count].lpProps + 1,
PR_ADDRTYPE_UNICODE,
[@"SMTP" asUnicodeInMemCtx: recipients->aRow]);
person = [attendees objectAtIndex: count];
name = [person cn];
if (!name)
name = @"";
email = [person email];
if (!email)
email = @"";
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[1]),
PR_DISPLAY_NAME,
[name asUnicodeInMemCtx: recipients->aRow[count].lpProps]);
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[2]),
PR_EMAIL_ADDRESS,
[email asUnicodeInMemCtx: recipients->aRow[count].lpProps]);
text = [person rfc822Email];
if (!text)
text = @"";
set_SPropValue_proptag (recipients->aRow[count].lpProps + 2,
PR_EMAIL_ADDRESS_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
text = [person cn];
if ([text length] > 0)
{
recipients->aRow[count].cValues++;
set_SPropValue_proptag (recipients->aRow[count].lpProps + 3,
PR_DISPLAY_NAME_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
}
}
msg->recipients = recipients;
}
- (void) save
@@ -446,28 +464,24 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
if (![content length])
{
newEvent = [sogoObject component: YES secure: NO];
if (newEvent != event)
ASSIGN (event, newEvent);
vCalendar = [event parent];
vCalendar = [newEvent parent];
[vCalendar setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"];
content = [vCalendar versitString];
}
vCalendar = [iCalCalendar parseSingleFromSource: content];
newEvent = [[vCalendar events] objectAtIndex: 0];
if (newEvent != event)
ASSIGN (event, newEvent);
// summary
value = [newProperties
objectForKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)];
if (value)
[event setSummary: value];
[newEvent setSummary: value];
// Location
value = [newProperties objectForKey: MAPIPropertyKey (PidLidLocation)];
if (value)
[event setLocation: value];
[newEvent setLocation: value];
tzName = [[self ownerTimeZone] name];
tz = [iCalTimeZone timeZoneForName: tzName];
@@ -479,7 +493,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
value = [newProperties objectForKey: MAPIPropertyKey (PidLidAppointmentStartWhole)];
if (value)
{
start = (iCalDateTime *) [event uniqueChildWithTag: @"dtstart"];
start = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtstart"];
[start setTimeZone: tz];
[start setDateTime: value];
}
@@ -490,7 +504,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
value = [newProperties objectForKey: MAPIPropertyKey (PidLidAppointmentEndWhole)];
if (value)
{
end = (iCalDateTime *) [event uniqueChildWithTag: @"dtend"];
end = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtend"];
[end setTimeZone: tz];
[end setDateTime: value];
}
@@ -498,9 +512,9 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
now = [NSCalendarDate date];
if ([sogoObject isNew])
{
[event setCreated: now];
[newEvent setCreated: now];
}
[event setTimeStampAsDate: now];
[newEvent setTimeStampAsDate: now];
// Organizer and attendees
value = [newProperties objectForKey: @"recipients"];
@@ -517,7 +531,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
person = [iCalPerson new];
[person setCn: [dict objectForKey: @"fullName"]];
[person setEmail: [dict objectForKey: @"email"]];
[event setOrganizer: person];
[newEvent setOrganizer: person];
[person release];
recipients = [value objectForKey: @"to"];
@@ -534,8 +548,8 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
[person setRole: @"REQ-PARTICIPANT"];
// FIXME: We must NOT always rely on this
if (![event isAttendee: [person rfc822Email]])
[event addToAttendees: person];
if (![newEvent isAttendee: [person rfc822Email]])
[newEvent addToAttendees: person];
[person release];
}
@@ -549,7 +563,7 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
fromData: value];
// [sogoObject saveContentString: [vCalendar versitString]];
[sogoObject saveComponent: event];
[sogoObject saveComponent: newEvent];
}
/* TODO: those are stubs meant to prevent OpenChange from crashing when a
+9
View File
@@ -62,6 +62,15 @@
/* for active messages (NSDictionary instances) */
NSMutableDictionary *messages;
/* for active folders (NSDictionary instances) */
NSMutableDictionary *folders;
/* hackish table cache */
MAPIStoreTable *cachedTable;
MAPIStoreFolder *cachedFolder;
uint64_t cachedTableFID;
uint8_t cachedTableType;
}
+ (id) contextFromURI: (const char *) newUri
+137 -55
View File
@@ -136,6 +136,8 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
[context setupRequest];
[context setupBaseFolder: url];
[context->folders setObject: context->baseFolder
forKey: [NSNumber numberWithUnsignedLongLong: fid]];
[context tearDownRequest];
return context;
@@ -192,14 +194,15 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
if ((self = [super init]))
{
messages = [NSMutableDictionary new];
folders = [NSMutableDictionary new];
woContext = [WOContext contextWithRequest: nil];
[woContext retain];
baseFolder = nil;
contextUrl = nil;
cachedTable = nil;
cachedFolder = nil;
}
[self logWithFormat: @"-init"];
return self;
}
@@ -244,9 +247,10 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
- (void) dealloc
{
[self logWithFormat: @"-dealloc"];
[messages release];
[folders release];
[cachedTable release];
[cachedFolder release];
[baseFolder release];
[woContext release];
@@ -305,10 +309,78 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
[MAPIApp setMAPIStoreContext: nil];
}
- (MAPIStoreFolder *) lookupFolder: (NSString *) folderURL
- (MAPIStoreObject *) _lookupObjectWithParts: (NSArray *) parts
{
NSUInteger count, max;
NSString *currentPart;
MAPIStoreObject *currentObject;
currentObject = baseFolder;
max = [parts count];
for (count = 0; count < max; count++)
{
currentPart = [parts objectAtIndex: count];
if ([currentPart length] > 0)
currentObject = [currentObject lookupChild: currentPart];
}
return currentObject;
}
- (id) lookupObject: (NSString *) childURL
{
NSString *baseURL, *subURL;
MAPIStoreObject *foundObject;
NSArray *parts;
baseURL = [contextUrl absoluteString];
if (![baseURL hasSuffix: @"/"])
baseURL = [NSString stringWithFormat: @"%@/", baseURL];
if (![childURL hasSuffix: @"/"])
childURL = [NSString stringWithFormat: @"%@/", childURL];
if ([childURL isEqualToString: baseURL])
foundObject = baseFolder;
else if ([childURL hasPrefix: baseURL])
{
subURL = [childURL substringFromIndex: [baseURL length]];
parts = [subURL componentsSeparatedByString: @"/"];
foundObject = [self _lookupObjectWithParts: parts];
[self logWithFormat: @"returning object '%@'", childURL];
}
else
{
[self errorWithFormat: @"url '%@' is not a child of this context (%@)",
childURL, baseURL];
foundObject = nil;
}
/* TODO hierarchy */
return baseFolder;
return foundObject;
}
- (id) lookupFolderWithFID: (uint64_t) fid
{
MAPIStoreFolder *folder;
NSNumber *fidKey;
NSString *folderURL;
fidKey = [NSNumber numberWithUnsignedLongLong: fid];
folder = [folders objectForKey: fidKey];
if (!folder)
{
/* TODO: should handle folder hierarchies */
folderURL = [mapping urlFromID: fid];
if (folderURL)
{
folder = [self lookupObject: folderURL];
if (folder)
[folders setObject: folder forKey: fidKey];
}
else
[self errorWithFormat: @"folder with url '%@' not found", folderURL];
}
return folder;
}
/**
@@ -323,8 +395,8 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
withFID: (uint64_t) fid
inParentFID: (uint64_t) parentFID
{
NSString *folderURL, *folderKey, *parentFolderURL;
MAPIStoreFolder *parentFolder;
NSString *folderURL, *folderKey;
MAPIStoreFolder *parentFolder, *newFolder;
int rc;
[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
@@ -334,16 +406,22 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
rc = MAPISTORE_ERR_EXIST;
else
{
parentFolderURL = [mapping urlFromID: parentFID];
if (parentFolderURL)
parentFolder = [self lookupFolderWithFID: parentFID];
if (parentFolder)
{
parentFolder = [self lookupFolder: parentFolderURL];
folderKey = [parentFolder createFolder: aRow];
folderKey = [parentFolder createFolder: aRow withFID: fid];
if (folderKey)
{
folderURL = [NSString stringWithFormat: @"%@%@/",
parentFolderURL, folderKey];
[parentFolder cleanupCaches];
folderURL = [NSString stringWithFormat: @"%@%@",
[parentFolder url], folderKey];
[mapping registerURL: folderURL withID: fid];
newFolder = [parentFolder lookupChild: folderKey];
if (newFolder)
[newFolder setProperties: aRow];
else
[NSException raise: @"MAPIStoreIOException"
format: @"unable to fetch created folder"];
rc = MAPISTORE_SUCCESS;
}
else
@@ -413,13 +491,19 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
{
MAPIStoreFolder *folder;
MAPIStoreTable *table;
NSString *folderURL;
/* TODO: should handle folder hierarchies */
folderURL = [mapping urlFromID: fid];
if (folderURL)
if (fid == cachedTableFID && tableType == cachedTableType)
table = cachedTable;
else
{
folder = [self lookupFolder: folderURL];
[cachedTable release];
cachedTable = nil;
[cachedFolder release];
cachedFolder = nil;
cachedTableFID = 0;
cachedTableType = 0;
folder = [self lookupFolderWithFID: fid];
if (folder)
{
if (tableType == MAPISTORE_MESSAGE_TABLE)
@@ -432,21 +516,24 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
{
table = nil;
[NSException raise: @"MAPIStoreIOException"
format: @"unsupported table type: %d", tableType];
format: @"unsupported table type: %d", tableType];
}
if (table)
{
cachedTableFID = fid;
cachedTableType = tableType;
ASSIGN (cachedTable, table);
ASSIGN (cachedFolder, folder);
}
}
else
{
table = nil;
[self errorWithFormat: @"folder with url '%@' not found", folderURL];
[self errorWithFormat: @"folder with fid %Lu not found",
(unsigned long long) fid];
}
}
else
{
table = nil;
[self errorWithFormat: @"folder with fid %Lu not found",
(unsigned long long) fid];
}
return table;
}
@@ -475,7 +562,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
url = [mapping urlFromID: fid];
if (url)
{
folder = [self lookupFolder: url];
folder = [self lookupFolderWithFID: fid];
if (folder)
{
if (tableType == MAPISTORE_MESSAGE_TABLE)
@@ -559,16 +646,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
const char *propName;
int rc;
[self errorWithFormat: @"%s: obsolete method", __FUNCTION__];
// [self logWithFormat: @"METHOD '%s' (%d) -- proptag: %s (0x%.8x), pos: %.8x,"
// @" tableType: %d, queryType: %d, fid: %.16x",
// __FUNCTION__, __LINE__, propName, proptag, pos, tableType, queryType, fid];
// [self logWithFormat: @"context restriction state is: %@",
// MAPIStringForRestrictionState (restrictionState)];
// if (restriction)
// [self logWithFormat: @" active qualifier: %@", restriction];
// [self errorWithFormat: @"%s: obsolete method", __FUNCTION__];
folderURL = [mapping urlFromID: fid];
if (folderURL)
@@ -642,7 +720,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
withMID: (uint64_t) mid
inFID: (uint64_t) fid
{
NSString *messageKey, *folderURL, *messageURL;
NSString *messageKey, *messageURL;
MAPIStoreMessage *message;
MAPIStoreFolder *folder;
NSNumber *midKey;
@@ -659,9 +737,9 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
messageURL = [mapping urlFromID: mid];
if (messageURL)
{
folder = [self lookupFolderWithFID: fid];
messageKey = [self extractChildNameFromURL: messageURL
andFolderURLAt: &folderURL];
folder = [self lookupFolder: folderURL];
andFolderURLAt: NULL];
message = [folder lookupChild: messageKey];
if (message)
{
@@ -681,7 +759,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
isAssociated: (BOOL) isAssociated
{
NSNumber *midKey;
NSString *folderURL, *childURL;
NSString *childURL;
MAPIStoreMessage *message;
MAPIStoreFolder *folder;
int rc;
@@ -695,17 +773,16 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
rc = MAPISTORE_ERR_EXIST;
else
{
folderURL = [mapping urlFromID: fid];
if (folderURL)
folder = [self lookupFolderWithFID: fid];
if (folder)
{
folder = [self lookupFolder: folderURL];
message = [folder createMessage: isAssociated];
if (message)
{
[messages setObject: message forKey: midKey];
[message setMAPIRetainCount: [message mapiRetainCount] + 1];
childURL = [NSString stringWithFormat: @"%@%@",
folderURL, [message nameInContainer]];
[folder url], [message nameInContainer]];
[mapping registerURL: childURL withID: mid];
rc = MAPISTORE_SUCCESS;
}
@@ -749,6 +826,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
{
rc = MAPISTORE_SUCCESS;
folder = (MAPIStoreFolder *) [message container];
[self logWithFormat: @"folder for message is: %p", folder];
if (isSave)
{
/* notifications */
@@ -985,6 +1063,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
inRow: (struct SRow *) aRow
{
MAPIStoreMessage *message;
MAPIStoreFolder *folder;
NSMutableDictionary *properties;
NSNumber *midKey;
struct SPropValue *cValue;
@@ -1023,9 +1102,11 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
}
break;
case MAPISTORE_FOLDER:
[self logWithFormat: @"%s: ignored setting of props on folders",
__FUNCTION__];
rc = MAPISTORE_SUCCESS;
folder = [self lookupFolderWithFID: fmid];
if (folder)
rc = [folder setProperties: aRow];
else
rc = MAPISTORE_ERR_NOT_FOUND;
break;
default:
[self errorWithFormat: @"%s: value of tableType not handled: %d",
@@ -1152,7 +1233,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
inFID: (uint64_t) fid
withFlags: (uint8_t) flags
{
NSString *childURL, *folderURL, *childKey;
NSString *childURL, *childKey;
MAPIStoreFolder *folder;
MAPIStoreMessage *message;
NSArray *activeTables;
@@ -1167,9 +1248,10 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
{
[self logWithFormat: @"-deleteMessageWithMID: url (%@) found for object", childURL];
folder = [self lookupFolderWithFID: fid];
childKey = [self extractChildNameFromURL: childURL
andFolderURLAt: &folderURL];
folder = [self lookupFolder: folderURL];
andFolderURLAt: NULL];
message = [folder lookupChild: childKey];
if (message)
{
@@ -1233,7 +1315,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
[[activeTables objectAtIndex: count]
notifyChangesForChild: message];
}
[self logWithFormat: @"sucessfully deleted object at URL: %@", childURL];
[self logWithFormat: @"successfully deleted object at URL: %@", childURL];
[mapping unregisterURLWithID: mid];
[folder cleanupCaches];
rc = MAPISTORE_SUCCESS;
@@ -1431,10 +1513,10 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
*count = [[message childKeysMatchingQualifier: nil
andSortOrderings: nil] count];
attTable = [message attachmentTable];
*tablePtr = attTable;
if (attTable)
{
[attTable retain];
*tablePtr = attTable;
rc = MAPISTORE_SUCCESS;
}
}
@@ -1463,10 +1545,10 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
if (aid < [keys count])
{
attachment = [message lookupChild: [keys objectAtIndex: aid]];
*attachmentPtr = attachment;
if (attachment)
{
[attachment retain];
*attachmentPtr = attachment;
rc = MAPISTORE_SUCCESS;
}
}
+24
View File
@@ -37,6 +37,7 @@
#include <stdbool.h>
#include <gen_ndr/exchange.h>
#include <mapistore/mapistore_errors.h>
@implementation MAPIStoreDraftsMessage
@@ -51,6 +52,19 @@
return self;
}
- (int) getPrMessageFlags: (void **) data
{
unsigned int v = MSGFLAG_FROMME;
if ([[self childKeysMatchingQualifier: nil
andSortOrderings: nil] count] > 0)
v |= MSGFLAG_HASATTACH;
*data = MAPILongValue (memCtx, v);
return MAPISTORE_SUCCESS;
}
- (void) _saveAttachment: (NSString *) attachmentKey
{
NSDictionary *properties, *metadata;
@@ -233,4 +247,14 @@ e)
[self logWithFormat: @"ignored scheduling message"];
}
- (NSCalendarDate *) creationTime
{
return [newProperties objectForKey: MAPIPropertyKey (PR_CREATION_TIME)];
}
- (NSCalendarDate *) lastModificationTime
{
return [newProperties objectForKey: MAPIPropertyKey (PR_LAST_MODIFICATION_TIME)];
}
@end
+5
View File
@@ -24,4 +24,9 @@
@implementation MAPIStoreFAIMessage
- (int) getPrAssociated: (void **) data
{
return [self getYes: data];
}
@end
+7
View File
@@ -20,6 +20,8 @@
* Boston, MA 02111-1307, USA.
*/
#import "MAPIStoreFolder.h"
#import "MAPIStoreFAIMessageTable.h"
#undef DEBUG
@@ -37,4 +39,9 @@
return self;
}
- (NSArray *) childKeys
{
return [(MAPIStoreFolder *) container faiMessageKeys];
}
@end
+78
View File
@@ -22,11 +22,14 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <NGExtensions/NSObject+Logs.h>
#import "EOQualifier+MAPIFS.h"
#import "MAPIStoreFSMessage.h"
#import "MAPIStoreFSMessageTable.h"
#import "MAPIStoreFolderTable.h"
#import "MAPIStoreTypes.h"
#import "SOGoMAPIFSFolder.h"
#import "SOGoMAPIFSMessage.h"
@@ -71,6 +74,22 @@ static Class MAPIStoreFSMessageK;
return MAPIStoreFSMessageK;
}
- (NSString *) createFolder: (struct SRow *) aRow
withFID: (uint64_t) newFID
{
NSString *newKey, *urlString;
SOGoMAPIFSFolder *childFolder;
newKey = [NSString stringWithFormat: @"0x%.16"PRIx64, (unsigned long long) newFID];
urlString = [NSString stringWithFormat: @"%@/%@", [self url], newKey];
childFolder = [SOGoMAPIFSFolder folderWithURL: [NSURL URLWithString: urlString]
andTableType: MAPISTORE_MESSAGE_TABLE];
[childFolder ensureDirectory];
return newKey;
}
- (MAPIStoreMessage *) createMessage
{
MAPIStoreMessage *newMessage;
@@ -122,4 +141,63 @@ static Class MAPIStoreFSMessageK;
return keys;
}
- (NSArray *) folderKeys
{
if (!folderKeys)
ASSIGN (folderKeys, [sogoObject toManyRelationshipKeys]);
return folderKeys;
}
- (id) lookupChild: (NSString *) childKey
{
id childObject;
SOGoMAPIFSFolder *childFolder;
[self folderKeys];
if ([folderKeys containsObject: childKey])
{
childFolder = [sogoObject lookupName: childKey inContext: nil
acquire: NO];
childObject = [MAPIStoreFSFolder mapiStoreObjectWithSOGoObject: childFolder
inContainer: self];
}
else
childObject = [super lookupChild: childKey];
return childObject;
}
- (MAPIStoreFAIMessageTable *) folderTable
{
return [MAPIStoreFolderTable tableForContainer: self];
}
- (NSDate *) lastMessageModificationTime
{
NSUInteger count, max;
NSDate *date, *fileDate;
MAPIStoreFSMessage *msg;
[self messageKeys];
date = [NSCalendarDate date];
[self logWithFormat: @"current date: %@", date];
max = [messageKeys count];
for (count = 0; count < max; count++)
{
msg = [self lookupChild: [messageKeys objectAtIndex: count]];
fileDate = [msg lastModificationTime];
if ([date laterDate: fileDate] == fileDate)
{
[self logWithFormat: @"current date: %@", date];
date = fileDate;
}
}
return date;
}
@end
+93
View File
@@ -20,16 +20,49 @@
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import "MAPIStorePropertySelectors.h"
#import "MAPIStoreTypes.h"
#import "NSObject+MAPIStore.h"
#import "NSString+MAPIStore.h"
#import "SOGoMAPIFSMessage.h"
#import "MAPIStoreFSMessage.h"
#undef DEBUG
#include <mapistore/mapistore_errors.h>
@implementation MAPIStoreFSMessage
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
{
struct SPropTagArray *properties;
NSUInteger count;
enum MAPITAGS faiProperties[] = { 0x68350102, 0x683c0102, 0x683e0102,
0x683f0102, 0x68410003, 0x68420102,
0x68450102, 0x68460003 };
properties = talloc_zero (NULL, struct SPropTagArray);
properties->cValues = MAPIStoreSupportedPropertiesCount + 8;
properties->aulPropTag = talloc_array (NULL, enum MAPITAGS,
MAPIStoreSupportedPropertiesCount + 8);
for (count = 0; count < MAPIStoreSupportedPropertiesCount; count++)
properties->aulPropTag[count] = MAPIStoreSupportedProperties[count];
/* FIXME (hack): append a few undocumented properties that can be added to
FAI messages */
for (count = 0; count < 8; count++)
properties->aulPropTag[MAPIStoreSupportedPropertiesCount+count] = faiProperties[count];
*propertiesP = properties;
return MAPISTORE_SUCCESS;
}
- (enum MAPISTATUS) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
{
@@ -45,10 +78,70 @@
return rc;
}
- (int) getPrSubject: (void **) data
{
/* if we get here, it means that the properties file didn't contain a
relevant value */
return [self getEmptyString: data];
}
- (int) getPrMessageClass: (void **) data
{
/* if we get here, it means that the properties file didn't contain a
relevant value */
*data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
{
NSArray *keys;
NSUInteger count, max;
struct SPropTagArray *properties;
keys = [[sogoObject properties] allKeys];
max = [keys count];
properties = talloc_zero (NULL, struct SPropTagArray);
properties->cValues = max;
properties->aulPropTag = talloc_array (properties, enum MAPITAGS, max);
for (count = 0; count < max; count++)
{
// #if (GS_SIZEOF_LONG == 4)
// return [NSNumber numberWithUnsignedLong: propTag];
// #elif (GS_SIZEOF_INT == 4)
// return [NSNumber numberWithUnsignedInt: propTag];
// #else
#if (GS_SIZEOF_LONG == 4)
properties->aulPropTag[count] = [[keys objectAtIndex: count] unsignedLongValue];
#elif (GS_SIZEOF_INT == 4)
properties->aulPropTag[count] = [[keys objectAtIndex: count] unsignedIntValue];
#endif
}
*propertiesP = properties;
return MAPISTORE_SUCCESS;
}
- (void) save
{
[sogoObject appendProperties: newProperties];
[sogoObject save];
[self resetNewProperties];
}
- (NSDate *) creationTime
{
return [sogoObject creationTime];
}
- (NSDate *) lastModificationTime
{
return [sogoObject lastModificationTime];
}
@end
+9 -4
View File
@@ -38,6 +38,7 @@
@class MAPIStoreFolderTable;
@class MAPIStoreMessageTable;
@class SOGoMAPIFSFolder;
@class SOGoMAPIFSMessage;
#import "MAPIStoreObject.h"
@@ -49,10 +50,11 @@
NSArray *faiMessageKeys;
NSMutableArray *folderKeys;
SOGoMAPIFSFolder *faiFolder;
NSDictionary *properties;
NSMutableArray *activeMessageTables;
NSMutableArray *activeFAIMessageTables;
SOGoMAPIFSFolder *faiFolder;
SOGoMAPIFSFolder *propsFolder;
SOGoMAPIFSMessage *propsMessage;
}
+ (id) baseFolderWithURL: (NSURL *) newURL
@@ -73,7 +75,8 @@
- (NSArray *) folderKeys;
- (MAPIStoreMessage *) createMessage: (BOOL) isAssociated;
- (NSString *) createFolder: (struct SRow *) aRow;
- (NSString *) createFolder: (struct SRow *) aRow
withFID: (uint64_t) newFID;
/* helpers */
- (uint64_t) idForObjectWithKey: (NSString *) childKey;
@@ -82,6 +85,8 @@
- (Class) messageClass;
- (MAPIStoreMessage *) createMessage;
- (NSCalendarDate *) lastMessageModificationTime;
@end
#endif /* MAPISTOREFOLDER_H */
+189 -44
View File
@@ -23,6 +23,7 @@
/* TODO: main key arrays must be initialized */
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
@@ -36,7 +37,9 @@
#import "MAPIStoreFolder.h"
#import "MAPIStoreMessage.h"
#import "MAPIStoreTypes.h"
#import "NSDate+MAPIStore.h"
#import "NSString+MAPIStore.h"
#import "NSObject+MAPIStore.h"
#import "SOGoMAPIFSFolder.h"
#import "SOGoMAPIFSMessage.h"
@@ -45,7 +48,7 @@
#undef DEBUG
#include <mapistore/mapistore.h>
#include <mapistore/mapistore_nameid.h>
// #include <mapistore/mapistore_errors.h>
#include <mapistore/mapistore_errors.h>
Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStoreFolderTableK;
@@ -81,11 +84,14 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
folderURL = nil;
context = nil;
propsFolder = nil;
propsMessage = nil;
}
return self;
}
/* from context */
- (id) initWithURL: (NSURL *) newURL
inContext: (MAPIStoreContext *) newContext
{
@@ -96,13 +102,71 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
ASSIGN (faiFolder,
[SOGoMAPIFSFolder folderWithURL: newURL
andTableType: MAPISTORE_FAI_TABLE]);
ASSIGN (propsFolder,
[SOGoMAPIFSFolder folderWithURL: newURL
andTableType: MAPISTORE_FOLDER_TABLE]);
ASSIGN (propsMessage,
[SOGoMAPIFSMessage objectWithName: @"properties.plist"
inContainer: propsFolder]);
}
return self;
}
/* from parent folder */
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
NSURL *propsURL;
if ((self = [super initWithSOGoObject: newSOGoObject inContainer: newContainer]))
{
propsURL = [NSURL URLWithString: [self url]];
ASSIGN (propsFolder,
[SOGoMAPIFSFolder folderWithURL: propsURL
andTableType: MAPISTORE_FOLDER_TABLE]);
ASSIGN (propsMessage,
[SOGoMAPIFSMessage objectWithName: @"properties.plist"
inContainer: propsFolder]);
}
return self;
}
- (int) setProperties: (struct SRow *) aRow
{
static enum MAPITAGS bannedProps[] = { PR_MID, PR_FID, PR_PARENT_FID,
PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY,
PR_CHANGE_NUM, PR_CHANGE_KEY,
0x00000000 };
enum MAPITAGS *currentProp;
int rc;
rc = [super setProperties: aRow];
/* TODO: this should no longer be required once mapistore v2 API is in
place, when we can then do this from -dealloc below */
if ([newProperties count] > 0)
{
currentProp = bannedProps;
while (*currentProp)
{
[newProperties removeObjectForKey: MAPIPropertyKey (*currentProp)];
currentProp++;
}
[propsMessage appendProperties: newProperties];
[propsMessage save];
[self resetNewProperties];
}
return rc;
}
- (void) dealloc
{
[propsMessage release];
[propsFolder release];
[folderURL release];
[messageKeys release];
[faiMessageKeys release];
@@ -209,8 +273,8 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
if ([faiMessageKeys containsObject: childKey])
{
msgObject = [faiFolder lookupName: childKey
inContext: nil
acquire: NO];
inContext: nil
acquire: NO];
newChild
= [MAPIStoreFAIMessage mapiStoreObjectWithSOGoObject: msgObject
inContainer: self];
@@ -218,8 +282,8 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
else
{
msgObject = [sogoObject lookupName: childKey
inContext: nil
acquire: NO];
inContext: nil
acquire: NO];
if ([msgObject isKindOfClass: NSExceptionK])
msgObject = nil;
@@ -237,48 +301,111 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
return newChild;
}
- (enum MAPISTATUS) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
- (int) getPrParentFid: (void **) data
{
*data = MAPILongLongValue (memCtx, [container objectId]);
return MAPISTORE_SUCCESS;
}
- (int) getPrFid: (void **) data
{
*data = MAPILongLongValue (memCtx, [self objectId]);
return MAPISTORE_SUCCESS;
}
- (int) getPrAccess: (void **) data
{
*data = MAPILongValue (memCtx, 0x63);
return MAPISTORE_SUCCESS;
}
- (int) getPrAccessLevel: (void **) data
{
*data = MAPILongValue (memCtx, 0x01);
return MAPISTORE_SUCCESS;
}
- (int) getPrAttrHidden: (void **) data
{
return [self getNo: data];
}
- (int) getPrAttrSystem: (void **) data
{
return [self getNo: data];
}
- (int) getPrAttrReadOnly: (void **) data
{
return [self getNo: data];
}
- (int) getPrSubfolders: (void **) data
{
*data = MAPIBoolValue (memCtx, [folderKeys count] > 0);
return MAPISTORE_SUCCESS;
}
- (int) getPrFolderChildCount: (void **) data;
{
*data = MAPILongValue (memCtx, [[self folderKeys] count]);
return MAPISTORE_SUCCESS;
}
- (int) getPrContentCount: (void **) data
{
*data = MAPILongValue (memCtx, [[self messageKeys] count]);
return MAPISTORE_SUCCESS;
}
- (int) getPrContentUnread: (void **) data
{
*data = MAPILongValue (memCtx, 0);
return MAPISTORE_SUCCESS;
}
- (int) getPrAssocContentCount: (void **) data
{
*data = MAPILongValue (memCtx, [[self faiMessageKeys] count]);
return MAPISTORE_SUCCESS;
}
- (int) getPrDeletedCountTotal: (void **) data
{
/* TODO */
*data = MAPILongValue (memCtx, 0);
return MAPISTORE_SUCCESS;
}
- (int) getPrLocalCommitTimeMax: (void **) data
{
*data = [[self lastMessageModificationTime] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
{
int rc;
id value;
rc = MAPI_E_SUCCESS;
switch (propTag)
{
case PR_FID:
/* TODO: incomplete */
*data = MAPILongValue (memCtx, [self objectId]);
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, [container objectId]);
break;
case PR_ATTR_HIDDEN:
case PR_ATTR_SYSTEM:
case PR_ATTR_READONLY:
*data = MAPIBoolValue (memCtx, NO);
break;
case PR_SUBFOLDERS:
*data = MAPIBoolValue (memCtx, [folderKeys count]);
// [[child toManyRelationshipKeys] count] > 0);
break;
case PR_CONTENT_COUNT:
*data = MAPILongValue (memCtx, [messageKeys 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 getProperty: data
withTag: propTag];
}
value = [[propsMessage properties]
objectForKey: MAPIPropertyKey (propTag)];
if (value)
rc = [value getMAPIValue: data forTag: propTag inMemCtx: memCtx];
else
rc = [super getProperty: data withTag: propTag];
return rc;
}
@@ -313,6 +440,7 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
}
- (NSString *) createFolder: (struct SRow *) aRow
withFID: (uint64_t) newFID
{
[self errorWithFormat: @"new folders cannot be created in this context"];
@@ -351,6 +479,16 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
inFolderURL: [self url]];
}
- (NSCalendarDate *) creationTime
{
return [propsMessage creationTime];
}
- (NSCalendarDate *) lastModificationTime
{
return [propsMessage lastModificationTime];
}
/* subclasses */
- (MAPIStoreMessageTable *) messageTable
@@ -371,4 +509,11 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore
return nil;
}
- (NSCalendarDate *) lastMessageModificationTime
{
[self subclassResponsibility: _cmd];
return nil;
}
@end
+10 -1
View File
@@ -31,6 +31,10 @@
#import "NSDate+MAPIStore.h"
#import "MAPIStoreGCSFolder.h"
#import "MAPIStoreTypes.h"
#undef DEBUG
#include <mapistore/mapistore.h>
@implementation MAPIStoreGCSFolder
@@ -60,7 +64,7 @@
}
else
fetchQualifier = componentQualifier;
ocsFolder = [sogoObject ocsFolder];
fs = [EOFetchSpecification
fetchSpecificationWithEntityName: [ocsFolder folderName]
@@ -73,6 +77,11 @@
return keys;
}
- (NSDate *) lastMessageModificationTime
{
return [[sogoObject ocsFolder] lastModificationDate];
}
/* subclasses */
- (EOQualifier *) componentQualifier
+17
View File
@@ -20,8 +20,25 @@
* Boston, MA 02111-1307, USA.
*/
#import <SOGo/SOGoContentObject.h>
#import "MAPIStoreTypes.h"
#import "MAPIStoreGCSMessage.h"
#undef DEBUG
#include <mapistore/mapistore.h>
@implementation MAPIStoreGCSMessage
- (NSCalendarDate *) creationTime
{
return [sogoObject creationDate];
}
- (NSCalendarDate *) lastModificationTime
{
return [sogoObject lastModified];
}
@end
+5
View File
@@ -30,7 +30,12 @@
@class SOGoMailAccount;
@class SOGoMailFolder;
@class MAPIStoreMailMessageTable;
@interface MAPIStoreMailFolder : MAPIStoreFolder
{
MAPIStoreMailMessageTable *messageTable;
}
/* subclasses */
- (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) account
+47 -32
View File
@@ -53,6 +53,7 @@ static Class SOGoMailFolderK;
#undef DEBUG
#include <libmapi/libmapi.h>
#include <mapistore/mapistore.h>
@implementation MAPIStoreMailFolder
@@ -108,6 +109,12 @@ static Class SOGoMailFolderK;
return self;
}
- (void) dealloc
{
[messageTable release];
[super dealloc];
}
- (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) accountFolder
inContext: (WOContext *) woContext
{
@@ -118,7 +125,13 @@ static Class SOGoMailFolderK;
- (MAPIStoreMessageTable *) messageTable
{
return [MAPIStoreMailMessageTable tableForContainer: self];
if (!messageTable)
{
ASSIGN (messageTable, [MAPIStoreMailMessageTable tableForContainer: self]);
[self logWithFormat: @"new message table"];
}
return messageTable;
}
- (Class) messageClass
@@ -127,6 +140,7 @@ static Class SOGoMailFolderK;
}
- (NSString *) createFolder: (struct SRow *) aRow
withFID: (uint64_t) newFID
{
NSString *folderName, *nameInContainer;
SOGoMailFolder *newFolder;
@@ -156,42 +170,33 @@ static Class SOGoMailFolderK;
return nameInContainer;
}
- (enum MAPISTATUS) getProperty: (void **) data
withTag: (enum MAPITAGS) propTag
- (int) getPrContentUnread: (void **) data
{
enum MAPISTATUS rc;
EOQualifier *searchQualifier;
uint32_t intValue;
uint32_t longValue;
searchQualifier
= [EOQualifier qualifierWithQualifierFormat: @"flags = %@", @"unseen"];
longValue = [[sogoObject fetchUIDsMatchingQualifier: searchQualifier
sortOrdering: nil]
count];
*data = MAPILongValue (memCtx, longValue);
rc = MAPI_E_SUCCESS;
switch (propTag)
{
case PR_CONTENT_UNREAD:
searchQualifier
= [EOQualifier qualifierWithQualifierFormat: @"flags = %@", @"unseen"];
intValue = [[sogoObject fetchUIDsMatchingQualifier: searchQualifier
sortOrdering: nil] count];
*data = MAPILongValue (memCtx, intValue);
break;
case PR_CONTAINER_CLASS_UNICODE:
*data = [@"IPF.Note" asUnicodeInMemCtx: memCtx];
break;
default:
{
const char *propName;
return MAPISTORE_SUCCESS;
}
propName = get_proptag_name (propTag);
if (!propName)
propName = "<unknown>";
[self warnWithFormat: @"get folder tag: %s (0x%.8x)", propName,
propTag];
}
rc = [super getProperty: data withTag: propTag];
}
- (int) getPrContainerClass: (void **) data
{
*data = [@"IPF.Note" asUnicodeInMemCtx: memCtx];
return rc;
return MAPISTORE_SUCCESS;
}
- (int) getPrMessageClass: (void **) data
{
*data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (NSArray *) childKeysMatchingQualifier: (EOQualifier *) qualifier
@@ -263,6 +268,16 @@ static Class SOGoMailFolderK;
return childObject;
}
- (NSCalendarDate *) creationTime
{
return [NSCalendarDate dateWithTimeIntervalSince1970: 0x4dbb2dbe]; /* oc_version_time */
}
- (NSCalendarDate *) lastModificationTime
{
return [NSCalendarDate date];
}
@end
@implementation MAPIStoreInboxFolder : MAPIStoreMailFolder
+36 -20
View File
@@ -85,6 +85,11 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
MAPIStoreDraftsFolderK = [MAPIStoreDraftsFolder class];
}
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
{
return [super getAvailableProperties: propertiesP];
}
- (int) getPrIconIndex: (void **) data
{
uint32_t longValue;
@@ -187,16 +192,14 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
return MAPISTORE_SUCCESS;
}
- (int) getPrCreationTime: (void **) data // DOUBT
- (NSCalendarDate *) creationTime
{
*data = [[sogoObject date] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
return [sogoObject date];
}
- (int) getPrLastModificationTime: (void **) data // DOUBT
- (NSCalendarDate *) lastModificationTime
{
return [self getPrCreationTime: data];
return [sogoObject date];
}
- (int) getPrLatestDeliveryTime: (void **) data // DOUBT
@@ -651,7 +654,7 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
NSArray *to;
NSInteger count, max;
NGImap4EnvelopeAddress *currentAddress;
NSString *name;
NSString *text;
[super openMessage: msg];
/* Retrieve recipients from the message */
@@ -663,25 +666,38 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
for (count = 0; count < max; count++)
{
recipients->aRow[count].ulAdrEntryPad = 0;
recipients->aRow[count].cValues = 2;
recipients->aRow[count].cValues = 3;
recipients->aRow[count].lpProps = talloc_array (recipients->aRow,
struct SPropValue,
2);
4);
// TODO (0x01 = primary recipient)
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[0]),
set_SPropValue_proptag (recipients->aRow[count].lpProps + 0,
PR_RECIPIENT_TYPE,
MAPILongValue (memCtx, 0x01));
MAPILongValue (recipients->aRow, 0x01));
set_SPropValue_proptag (recipients->aRow[count].lpProps + 1,
PR_ADDRTYPE_UNICODE,
[@"SMTP" asUnicodeInMemCtx: recipients->aRow]);
currentAddress = [to objectAtIndex: count];
// name = [currentAddress personalName];
// if (![name length])
name = [currentAddress baseEMail];
if (!name)
name = @"";
set_SPropValue_proptag (&(recipients->aRow[count].lpProps[1]),
PR_DISPLAY_NAME,
[name asUnicodeInMemCtx: recipients->aRow[count].lpProps]);
// text = [currentAddress personalName];
// if (![text length])
text = [currentAddress baseEMail];
if (!text)
text = @"";
set_SPropValue_proptag (recipients->aRow[count].lpProps + 2,
PR_EMAIL_ADDRESS_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
text = [currentAddress personalName];
if ([text length] > 0)
{
recipients->aRow[count].cValues++;
set_SPropValue_proptag (recipients->aRow[count].lpProps + 3,
PR_DISPLAY_NAME_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
}
}
msg->recipients = recipients;
}
+25 -49
View File
@@ -180,15 +180,15 @@
return MAPISTORE_SUCCESS;
}
- (int) getPrViewStyle: (void **) data
{
return [self getLongZero: data];
}
// - (int) getPrViewStyle: (void **) data
// {
// return [self getLongZero: data];
// }
- (int) getPrViewMajorversion: (void **) data
{
return [self getLongZero: data];
}
// - (int) getPrViewMajorversion: (void **) data
// {
// return [self getLongZero: data];
// }
- (int) getPidLidSideEffects: (void **) data // TODO
{
@@ -281,35 +281,6 @@
return [self getLongZero: data];
}
// TODO: PR_CHANGE_KEY is a GID based on the ReplGUID
- (int) getPrChangeKey: (void **) data
{
int rc = MAPISTORE_SUCCESS;
NSString *stringValue;
NSUInteger length;
stringValue = [sogoObject davEntityTag];
if (stringValue)
{
stringValue = @"-1";
length = [stringValue length];
if (length < 6) /* guid = 16 bytes */
length += 6;
stringValue = [NSString stringWithFormat: @"000000%@",
stringValue];
if (length > 6)
stringValue = [stringValue substringFromIndex: length - 6];
stringValue = [NSString stringWithFormat: @"SOGo%@%@%@",
stringValue, stringValue, stringValue];
*data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding]
asBinaryInMemCtx: memCtx];
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (int) getPrSubject: (void **) data
{
[self subclassResponsibility: _cmd];
@@ -352,20 +323,20 @@
return [self getEmptyString: data];
}
- (int) getPrOriginalDisplayTo: (void **) data
{
return [self getPrDisplayTo: data];
}
// - (int) getPrOriginalDisplayTo: (void **) data
// {
// return [self getPrDisplayTo: data];
// }
- (int) getPrOriginalDisplayCc: (void **) data
{
return [self getPrDisplayCc: data];
}
// - (int) getPrOriginalDisplayCc: (void **) data
// {
// return [self getPrDisplayCc: data];
// }
- (int) getPrOriginalDisplayBcc: (void **) data
{
return [self getPrDisplayBcc: data];
}
// - (int) getPrOriginalDisplayBcc: (void **) data
// {
// return [self getPrDisplayBcc: data];
// }
- (int) getPrLastModifierName: (void **) data
{
@@ -398,6 +369,11 @@
return MAPISTORE_SUCCESS;
}
- (int) getPrAssociated: (void **) data
{
return [self getNo: data];
}
- (void) save
{
[self subclassResponsibility: _cmd];
+17 -3
View File
@@ -49,7 +49,7 @@
+ (id) mapiStoreObjectWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer;
+ (int) getAvailableProperties: (struct SPropTagArray **) properties;
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP;
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newFolder;
@@ -69,7 +69,6 @@
- (uint64_t) objectId;
- (NSString *) url;
/* properties */
- (void) addNewProperties: (NSDictionary *) newNewProperties;
@@ -77,7 +76,7 @@
- (void) resetNewProperties;
/* ops */
- (int) getAvailableProperties: (struct SPropTagArray **) properties;
- (int) getAvailableProperties: (struct SPropTagArray **) propertiesP;
- (int) getProperties: (struct mapistore_property_data *) data
withTags: (enum MAPITAGS *) tags
andCount: (uint16_t) columnCount;
@@ -92,8 +91,23 @@
- (int) getLongZero: (void **) data;
- (int) getYes: (void **) data;
- (int) getNo: (void **) data;
- (int) getReplicaKey: (void **) data
fromGlobCnt: (uint64_t) objectCnt;
/* implemented getters */
- (int) getPrDisplayName: (void **) data;
- (int) getPrSearchKey: (void **) data;
- (int) getPrGenerateExchangeViews: (void **) data;
- (int) getPrParentSourceKey: (void **) data;
- (int) getPrSourceKey: (void **) data;
- (int) getPrChangeKey: (void **) data;
- (int) getPrCreationTime: (void **) data;
- (int) getPrLastModificationTime: (void **) data;
/* subclasses */
- (NSDate *) creationTime;
- (NSDate *) lastModificationTime;
- (id) lookupChild: (NSString *) childKey;
- (NSArray *) childKeysMatchingQualifier: (EOQualifier *) qualifier
andSortOrderings: (NSArray *) sortOrderings;
+98 -10
View File
@@ -24,9 +24,11 @@
#import <NGExtensions/NSObject+Logs.h>
#import <SOGo/SOGoObject.h>
#import "MAPIStoreContext.h"
#import "MAPIStoreFolder.h"
#import "MAPIStorePropertySelectors.h"
#import "MAPIStoreTypes.h"
#import "NSDate+MAPIStore.h"
#import "NSData+MAPIStore.h"
#import "NSString+MAPIStore.h"
@@ -119,10 +121,10 @@ static Class NSExceptionK, MAPIStoreFolderK;
- (void) dealloc
{
[sogoObject release];
[newProperties release];
[parentContainersBag release];
[container release];
[sogoObject release];
[newProperties dealloc];
talloc_free (memCtx);
[super dealloc];
}
@@ -192,8 +194,6 @@ static Class NSExceptionK, MAPIStoreFolderK;
containerURL, [self nameInContainer]];
}
- (void) addNewProperties: (NSDictionary *) newNewProperties
{
[newProperties addEntriesFromDictionary: newNewProperties];
@@ -233,12 +233,12 @@ static Class NSExceptionK, MAPIStoreFolderK;
propName = get_proptag_name (propTag);
if (!propName)
propName = "<unknown>";
[self warnWithFormat:
@"unimplemented selector (%@) for %s (0x%.8x)",
NSStringFromSelector (methodSel), propName, propTag];
// [self warnWithFormat:
// @"unimplemented selector (%@) for %s (0x%.8x)",
// NSStringFromSelector (methodSel), propName, propTag];
}
else
[self warnWithFormat: @"unsupported property tag: 0x%.8x", propTag];
// else
// [self warnWithFormat: @"unsupported property tag: 0x%.8x", propTag];
}
return rc;
@@ -273,8 +273,34 @@ static Class NSExceptionK, MAPIStoreFolderK;
return MAPISTORE_SUCCESS;
}
- (int) getReplicaKey: (void **) data
fromGlobCnt: (uint64_t) objectCnt
{
struct mapistore_connection_info *connInfo;
NSMutableData *replicaKey;
char buffer[6];
NSUInteger count;
connInfo = [[self context] connectionInfo];
for (count = 0; count < 6; count++)
{
buffer[count] = objectCnt & 0xff;
objectCnt >>= 8;
}
replicaKey = [NSMutableData dataWithCapacity: 22];
[replicaKey appendBytes: &connInfo->replica_guid
length: sizeof (struct GUID)];
[replicaKey appendBytes: buffer
length: 6];
*data = [replicaKey asBinaryInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
/* getters */
- (int) getPrDisplayName: (void **) data
- (int) getPrDisplayName: (void **) data
{
*data = [[sogoObject displayName] asUnicodeInMemCtx: memCtx];
@@ -297,6 +323,54 @@ static Class NSExceptionK, MAPIStoreFolderK;
return [self getNo: data];
}
- (int) getPrParentSourceKey: (void **) data
{
return [self getReplicaKey: data fromGlobCnt: [container objectId] >> 16];
}
- (int) getPrSourceKey: (void **) data
{
return [self getReplicaKey: data fromGlobCnt: [self objectId] >> 16];
}
- (uint64_t) objectVersion
{
uint32_t lmTime;
lmTime = (uint32_t) [[self lastModificationTime] timeIntervalSince1970];
if (lmTime < 0x4dbb2dbe) /* oc_version_time */
lmTime = 0x4dbb2dbe;
return ((([self objectId] & 0xffff000000000000LL) >> 16)
| (exchange_globcnt((uint64_t) lmTime - 0x4dbb2dbe) >> 16));
}
- (int) getPrChangeKey: (void **) data
{
return [self getReplicaKey: data fromGlobCnt: [self objectVersion]];
}
- (int) getPrChangeNum: (void **) data
{
*data = MAPILongLongValue (memCtx, ([self objectVersion] << 16) | 0x0001);
return MAPISTORE_SUCCESS;
}
- (int) getPrCreationTime: (void **) data
{
*data = [[self creationTime] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrLastModificationTime: (void **) data
{
*data = [[self lastModificationTime] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
{
return [isa getAvailableProperties: propertiesP];
@@ -332,6 +406,20 @@ static Class NSExceptionK, MAPIStoreFolderK;
}
/* subclasses */
- (NSDate *) creationTime
{
[self subclassResponsibility: _cmd];
return nil;
}
- (NSDate *) lastModificationTime
{
[self subclassResponsibility: _cmd];
return nil;
}
- (id) lookupChild: (NSString *) childKey
{
[self subclassResponsibility: _cmd];
+4 -1
View File
@@ -718,6 +718,9 @@ static Class NSDataK, NSStringK;
case 6: state = [self evaluateBitmaskRestriction: &res->res.resBitmask
intoQualifier: qualifier];
break;
case 7: state = MAPIRestrictionStateAlwaysTrue; /* let's cheat a little */
break;
case 8: state = [self evaluateExistRestriction: &res->res.resExist
intoQualifier: qualifier];
break;
@@ -727,7 +730,7 @@ static Class NSDataK, NSStringK;
// case 10: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;
default:
[NSException raise: @"MAPIStoreRestrictionException"
format: @"unhandled restriction type"];
format: @"unhandled restriction type: %.2x", res->rt];
state = MAPIRestrictionStateAlwaysTrue;
}
-5
View File
@@ -25,12 +25,7 @@
#import "MAPIStoreGCSMessage.h"
@class iCalToDo;
@interface MAPIStoreTasksMessage : MAPIStoreGCSMessage
{
iCalToDo *task;
}
@end
+25 -39
View File
@@ -49,24 +49,6 @@
@implementation MAPIStoreTasksMessage
- (id) initWithSOGoObject: (id) newSOGoObject
inContainer: (MAPIStoreObject *) newContainer
{
if ((self = [super initWithSOGoObject: newSOGoObject
inContainer: newContainer]))
{
ASSIGN (task, [newSOGoObject component: NO secure: NO]);
}
return self;
}
- (void) dealloc
{
[task release];
[super dealloc];
}
- (int) getPrIconIndex: (void **) data // TODO
{
/* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
@@ -90,6 +72,9 @@
- (int) getPrSubject: (void **) data // SUMMARY
{
iCalToDo *task;
task = [sogoObject component: NO secure: NO];
*data = [[task summary] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
@@ -98,7 +83,9 @@
- (int) getPrImportance: (void **) data
{
uint32_t v;
iCalToDo *task;
task = [sogoObject component: NO secure: NO];
if ([[task priority] isEqualToString: @"9"])
v = 0x0;
else if ([[task priority] isEqualToString: @"1"])
@@ -113,6 +100,9 @@
- (int) getPidLidTaskComplete: (void **) data
{
iCalToDo *task;
task = [sogoObject component: NO secure: NO];
*data = MAPIBoolValue (memCtx,
[[task status] isEqualToString: @"COMPLETED"]);
@@ -122,6 +112,9 @@
- (int) getPidLidPercentComplete: (void **) data
{
double doubleValue;
iCalToDo *task;
task = [sogoObject component: NO secure: NO];
doubleValue = ((double) [[task percentComplete] intValue] / 100);
*data = MAPIDoubleValue (memCtx, doubleValue);
@@ -131,8 +124,11 @@
- (int) getPidLidTaskDateCompleted: (void **) data
{
NSCalendarDate *dateValue;
int rc = MAPISTORE_SUCCESS;
NSCalendarDate *dateValue;
iCalToDo *task;
task = [sogoObject component: NO secure: NO];
dateValue = [task completed];
if (dateValue)
@@ -182,52 +178,42 @@
- (int) getPidLidTaskDueDate: (void **) data
{
NSCalendarDate *dateValue;
int rc = MAPISTORE_SUCCESS;
NSCalendarDate *dateValue;
iCalToDo *task;
task = [sogoObject component: NO secure: NO];
dateValue = [task due];
if (dateValue)
*data = [dateValue asFileTimeInMemCtx: memCtx];
else
rc = MAPISTORE_ERR_NOT_FOUND;
return MAPISTORE_SUCCESS;
}
- (int) getPrCreationTime: (void **) data
{
*data = [[task created] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
return rc;
}
- (int) getPrMessageDeliveryTime: (void **) data
{
*data = [[task lastModified] asFileTimeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
return [self getPrLastModificationTime: data];
}
- (int) getClientSubmitTime: (void **) data
{
return [self getPrMessageDeliveryTime: data];
return [self getPrLastModificationTime: data];
}
- (int) getLocalCommitTime: (void **) data
{
return [self getPrMessageDeliveryTime: data];
}
- (int) getLastModificationTime: (void **) data
{
return [self getPrMessageDeliveryTime: data];
return [self getPrLastModificationTime: data];
}
- (int) getPidLidTaskStatus: (void **) data // status
{
NSString *status;
uint32_t longValue;
iCalToDo *task;
task = [sogoObject component: NO secure: NO];
status = [task status];
if (![status length]
|| [status isEqualToString: @"NEEDS-ACTION"])