Changeset 3247

Show
Ignore:
Timestamp:
06/04/06 13:15:41 (2 years ago)
Author:
timothy
Message:

One step closer to allowing SQL only transcripts.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Models/JVChatEvent.h

    r3236 r3247  
    44        @protected 
    55        /* xmlNode */ void *_node; 
     6        /* xmlDoc */ void *_doc; 
    67        NSString *_eventIdentifier; 
    78        NSScriptObjectSpecifier *_objectSpecifier; 
     
    3031@end 
    3132 
    32 @interface JVMutableChatEvent : JVChatEvent { 
    33         @protected 
    34         /* xmlDoc */ void *_doc; 
    35 
     33@interface JVMutableChatEvent : JVChatEvent 
    3634+ (id) chatEventWithName:(NSString *) name andMessage:(id) message; 
    3735- (id) initWithName:(NSString *) name andMessage:(id) message; 
  • trunk/Models/JVChatEvent.m

    r3236 r3247  
    2020        _transcript = nil; // weak reference 
    2121        _node = NULL; 
     22 
     23        if( _doc ) xmlFreeDoc( _doc ); 
     24        _doc = NULL; 
    2225 
    2326        [super dealloc]; 
     
    105108 
    106109        _loadedAttributes = YES; 
    107 } 
    108  
    109 #pragma mark - 
    110  
    111 - (void *) node { 
    112         return _node; 
    113 } 
    114  
    115 - (void) _setNode:(xmlNode *) node { 
    116         _node = node; 
    117 } 
    118  
    119 #pragma mark - 
    120  
    121 - (JVChatTranscript *) transcript { 
    122         return _transcript; 
    123 } 
    124  
    125 - (NSString *) eventIdentifier { 
    126         return _eventIdentifier; 
    127 } 
    128  
    129 #pragma mark - 
    130  
    131 - (NSDate *) date { 
    132         [self loadSmall]; 
    133         return _date; 
    134 } 
    135  
    136 #pragma mark - 
    137  
    138 - (NSString *) name { 
    139         [self loadSmall]; 
    140         return _name; 
    141 } 
    142  
    143 #pragma mark - 
    144  
    145 - (NSTextStorage *) message { 
    146         [self loadMessage]; 
    147         return _message; 
    148 } 
    149  
    150 - (NSString *) messageAsPlainText { 
    151         return [[self message] string]; 
    152 } 
    153  
    154 - (NSString *) messageAsHTML { 
    155         NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"IgnoreFonts", [NSNumber numberWithBool:YES], @"IgnoreFontSizes", nil]; 
    156         return [[self message] HTMLFormatWithOptions:options]; 
    157 } 
    158  
    159 #pragma mark - 
    160  
    161 - (NSDictionary *) attributes { 
    162         [self loadAttributes]; 
    163         return _attributes; 
    164 } 
    165 @end 
    166  
    167 #pragma mark - 
    168  
    169 @implementation JVMutableChatEvent 
    170 + (id) chatEventWithName:(NSString *) name andMessage:(id) message { 
    171         return [[[self alloc] initWithName:name andMessage:message] autorelease]; 
    172 } 
    173  
    174 #pragma mark - 
    175  
    176 - (id) init { 
    177         if( ( self = [super init] ) ) _doc = NULL; 
    178         return self; 
    179 } 
    180  
    181 - (id) initWithName:(NSString *) name andMessage:(id) message { 
    182         if( ( self = [self init] ) ) { 
    183                 _loadedMessage = YES; 
    184                 _loadedAttributes = YES; 
    185                 _loadedSmall = YES; 
    186                 [self setDate:[NSDate date]]; 
    187                 [self setName:name]; 
    188                 [self setMessage:message]; 
    189                 [self setEventIdentifier:[NSString locallyUniqueString]]; 
    190         } 
    191  
    192         return self; 
    193 } 
    194  
    195 - (void) dealloc { 
    196         if( _doc ) xmlFreeDoc( _doc ); 
    197         _doc = NULL; 
    198  
    199         [super dealloc]; 
    200110} 
    201111 
     
    271181} 
    272182 
    273 - (void) setNode:(xmlNode *) node { 
     183- (void) _setNode:(xmlNode *) node { 
    274184        if( _doc ) { 
    275185                xmlFreeDoc( _doc ); 
     
    282192#pragma mark - 
    283193 
     194- (JVChatTranscript *) transcript { 
     195        return _transcript; 
     196} 
     197 
     198- (NSString *) eventIdentifier { 
     199        return _eventIdentifier; 
     200} 
     201 
     202#pragma mark - 
     203 
     204- (NSDate *) date { 
     205        [self loadSmall]; 
     206        return _date; 
     207} 
     208 
     209- (NSString *) name { 
     210        [self loadSmall]; 
     211        return _name; 
     212} 
     213 
     214#pragma mark - 
     215 
     216- (NSTextStorage *) message { 
     217        [self loadMessage]; 
     218        return _message; 
     219} 
     220 
     221- (NSString *) messageAsPlainText { 
     222        return [[self message] string]; 
     223} 
     224 
     225- (NSString *) messageAsHTML { 
     226        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"IgnoreFonts", [NSNumber numberWithBool:YES], @"IgnoreFontSizes", nil]; 
     227        return [[self message] HTMLFormatWithOptions:options]; 
     228} 
     229 
     230#pragma mark - 
     231 
     232- (NSDictionary *) attributes { 
     233        [self loadAttributes]; 
     234        return _attributes; 
     235} 
     236@end 
     237 
     238#pragma mark - 
     239 
     240@implementation JVMutableChatEvent 
     241+ (id) chatEventWithName:(NSString *) name andMessage:(id) message { 
     242        return [[[self alloc] initWithName:name andMessage:message] autorelease]; 
     243} 
     244 
     245#pragma mark - 
     246 
     247- (id) init { 
     248        if( ( self = [super init] ) ) _doc = NULL; 
     249        return self; 
     250} 
     251 
     252- (id) initWithName:(NSString *) name andMessage:(id) message { 
     253        if( ( self = [self init] ) ) { 
     254                _loadedMessage = YES; 
     255                _loadedAttributes = YES; 
     256                _loadedSmall = YES; 
     257                [self setDate:[NSDate date]]; 
     258                [self setName:name]; 
     259                [self setMessage:message]; 
     260                [self setEventIdentifier:[NSString locallyUniqueString]]; 
     261        } 
     262 
     263        return self; 
     264} 
     265 
     266#pragma mark - 
     267 
    284268- (void) setDate:(NSDate *) date { 
    285         [self setNode:NULL]; 
     269        [self _setNode:NULL]; 
    286270        [_date autorelease]; 
    287271        _date = [date copyWithZone:[self zone]]; 
     
    289273 
    290274- (void) setName:(NSString *) name { 
    291         [self setNode:NULL]; 
     275        [self _setNode:NULL]; 
    292276        [_name autorelease]; 
    293277        _name = [name copyWithZone:[self zone]]; 
     
    297281 
    298282- (void) setMessage:(id) message { 
    299         [self setNode:NULL]; 
     283        [self _setNode:NULL]; 
    300284        if( ! _message ) { 
    301285                if( [message isKindOfClass:[NSTextStorage class]] ) _message = [message retain]; 
     
    321305 
    322306- (void) setAttributes:(NSDictionary *) attributes { 
    323         [self setNode:NULL]; 
     307        [self _setNode:NULL]; 
    324308        [_attributes autorelease]; 
    325309        _attributes = [attributes copyWithZone:[self zone]]; 
     
    329313 
    330314- (void) setEventIdentifier:(NSString *) identifier { 
    331         [self setNode:NULL]; 
     315        [self _setNode:NULL]; 
    332316        [_eventIdentifier autorelease]; 
    333317        _eventIdentifier = [identifier copyWithZone:[self zone]]; 
  • trunk/Models/JVChatMessage.h

    r3236 r3247  
    1010        @public 
    1111        /* xmlNode */ void *_node; 
     12        /* xmlDoc */ void *_doc; 
    1213        NSString *_messageIdentifier; 
    1314        NSScriptObjectSpecifier *_objectSpecifier; 
     
    2627        JVIgnoreMatchResult _ignoreStatus; 
    2728        JVChatMessageType _type; 
     29        unsigned _consecutiveOffset; 
    2830        BOOL _senderIsLocalUser; 
    2931        BOOL _action; 
     
    3638 
    3739- (NSDate *) date; 
     40 
     41- (unsigned) consecutiveOffset; 
    3842 
    3943- (NSString *) senderName; 
     
    6569        @protected 
    6670        id _sender; 
    67         /* xmlDoc */ void *_doc; 
    6871} 
    6972+ (id) messageWithText:(id) body sender:(id) sender; 
  • trunk/Models/JVChatMessage.m

    r3236 r3247  
    131131        _senderBuddyIdentifier = nil; 
    132132 
    133         [super dealloc]; 
    134 } 
    135  
    136 #pragma mark - 
    137  
    138 - (void *) node { 
    139         return _node; 
    140 } 
    141  
    142 - (void) _setNode:(xmlNode *) node { 
    143         _node = node; 
    144 } 
    145  
    146 #pragma mark - 
    147  
    148 - (NSDate *) date { 
    149         [self load]; 
    150         return _date; 
    151 } 
    152  
    153 #pragma mark - 
    154  
    155 - (NSString *) senderName { 
    156         [self loadSender]; 
    157         return _senderName; 
    158 } 
    159  
    160 - (NSString *) senderIdentifier { 
    161         [self loadSender]; 
    162         return _senderIdentifier; 
    163 } 
    164  
    165 - (NSString *) senderNickname { 
    166         [self loadSender]; 
    167         return _senderNickname; 
    168 } 
    169  
    170 - (NSString *) senderHostmask { 
    171         [self loadSender]; 
    172         return _senderHostmask; 
    173 } 
    174  
    175 - (NSString *) senderClass { 
    176         [self loadSender]; 
    177         return _senderClass; 
    178 } 
    179  
    180 - (NSString *) senderBuddyIdentifier { 
    181         [self loadSender]; 
    182         return _senderBuddyIdentifier; 
    183 } 
    184  
    185 - (BOOL) senderIsLocalUser { 
    186         [self loadSender]; 
    187         return _senderIsLocalUser; 
    188 } 
    189  
    190 #pragma mark - 
    191  
    192 - (NSTextStorage *) body { 
    193         [self loadBody]; 
    194         return _attributedMessage; 
    195 } 
    196  
    197 - (NSString *) bodyAsPlainText { 
    198         return [[self body] string]; 
    199 } 
    200  
    201 - (NSString *) bodyAsHTML { 
    202         NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"IgnoreFonts", [NSNumber numberWithBool:YES], @"IgnoreFontSizes", nil]; 
    203         return [[self body] HTMLFormatWithOptions:options]; 
    204 } 
    205  
    206 #pragma mark - 
    207  
    208 - (BOOL) isAction { 
    209         [self load]; 
    210         return _action; 
    211 } 
    212  
    213 - (BOOL) isHighlighted { 
    214         [self load]; 
    215         return _highlighted; 
    216 } 
    217  
    218 - (JVIgnoreMatchResult) ignoreStatus { 
    219         [self load]; 
    220         return _ignoreStatus; 
    221 } 
    222  
    223 - (JVChatMessageType) type { 
    224         [self load]; 
    225         return _type; 
    226 } 
    227  
    228 #pragma mark - 
    229  
    230 - (NSURL *) source { 
    231         [self load]; 
    232         return _source; 
    233 } 
    234  
    235 - (JVChatTranscript *) transcript { 
    236         return _transcript; 
    237 } 
    238  
    239 - (NSString *) messageIdentifier { 
    240         return _messageIdentifier; 
    241 } 
    242  
    243 #pragma mark - 
    244  
    245 - (NSScriptObjectSpecifier *) objectSpecifier { 
    246         return _objectSpecifier; 
    247 } 
    248  
    249 - (void) setObjectSpecifier:(NSScriptObjectSpecifier *) objectSpecifier { 
    250         id old = _objectSpecifier; 
    251         _objectSpecifier = [objectSpecifier retain]; 
    252         [old release]; 
    253 } 
    254  
    255 #pragma mark - 
    256  
    257 - (NSString *) description { 
    258         return [self bodyAsPlainText]; 
    259 } 
    260  
    261 - (NSString *) debugDescription { 
    262         return [NSString stringWithFormat:@"<%@ 0x%x [%@]: (%@) %@>", NSStringFromClass( [self class] ), (unsigned long) self, _messageIdentifier, [self senderNickname], [self body]]; 
    263 } 
    264  
    265 #pragma mark - 
    266  
    267 - (id) valueForUndefinedKey:(NSString *) key { 
    268         if( [NSScriptCommand currentCommand] ) { 
    269                 [[NSScriptCommand currentCommand] setScriptErrorNumber:1000]; 
    270                 [[NSScriptCommand currentCommand] setScriptErrorString:[NSString stringWithFormat:@"The message id %@ doesn't have the \"%@\" property.", [self messageIdentifier], key]]; 
    271                 return nil; 
    272         } 
    273  
    274         return [super valueForUndefinedKey:key]; 
    275 } 
    276  
    277 - (void) setValue:(id) value forUndefinedKey:(NSString *) key { 
    278         if( [NSScriptCommand currentCommand] ) { 
    279                 // this is a non-mutable message, give AppleScript a good error if this is a script command call 
    280                 [[NSScriptCommand currentCommand] setScriptErrorNumber:1000]; 
    281                 [[NSScriptCommand currentCommand] setScriptErrorString:[NSString stringWithFormat:@"The properties of message id %@ are read only.", key, [self messageIdentifier]]]; 
    282                 return; 
    283         } 
    284  
    285         [super setValue:value forUndefinedKey:key]; 
    286 } 
    287 @end 
    288  
    289 #pragma mark - 
    290  
    291 @implementation JVMutableChatMessage 
    292 + (void) initialize { 
    293         [super initialize]; 
    294         static BOOL tooLate = NO; 
    295         if( ! tooLate ) { 
    296                 [[NSScriptCoercionHandler sharedCoercionHandler] registerCoercer:[self class] selector:@selector( coerceMessage:toString: ) toConvertFromClass:[JVMutableChatMessage class] toClass:[NSString class]]; 
    297                 [[NSScriptCoercionHandler sharedCoercionHandler] registerCoercer:[self class] selector:@selector( coerceString:toMessage: ) toConvertFromClass:[NSString class] toClass:[JVMutableChatMessage class]]; 
    298                 [[NSScriptCoercionHandler sharedCoercionHandler] registerCoercer:[self class] selector:@selector( coerceMessage:toTextStorage: ) toConvertFromClass:[JVMutableChatMessage class] toClass:[NSTextStorage class]]; 
    299                 [[NSScriptCoercionHandler sharedCoercionHandler] registerCoercer:[self class] selector:@selector( coerceTextStorage:toMessage: ) toConvertFromClass:[NSTextStorage class] toClass:[JVMutableChatMessage class]]; 
    300                 tooLate = YES; 
    301         } 
    302 } 
    303  
    304 + (id) messageWithText:(id) body sender:(id) sender { 
    305         return [[[self allocWithZone:nil] initWithText:body sender:sender] autorelease]; 
    306 } 
    307  
    308 #pragma mark - 
    309  
    310 - (id) initWithText:(id) body sender:(id) sender { 
    311         if( ( self = [self init] ) ) { 
    312                 _loaded = YES; 
    313                 _bodyLoaded = YES; 
    314                 _senderLoaded = YES; 
    315                 [self setDate:[NSDate date]]; 
    316                 [self setBody:body]; 
    317                 [self setSender:sender]; 
    318                 [self setMessageIdentifier:[NSString locallyUniqueString]]; 
    319         } 
    320  
    321         return self; 
    322 } 
    323  
    324 - (void) dealloc { 
    325133        if( _doc ) xmlFreeDoc( _doc ); 
    326134        _doc = NULL; 
    327  
    328         [_sender release]; 
    329         _sender = nil; 
    330135 
    331136        [super dealloc]; 
     
    345150                if( _source ) xmlSetProp( root, (xmlChar *) "source", (xmlChar *) [[[self source] absoluteString] UTF8String] ); 
    346151 
    347                 if( [self sender] && [[self sender] respondsToSelector:@selector( xmlDescriptionWithTagName: )] ) { 
    348                         const char *sendDesc = [(NSString *)[[self sender] performSelector:@selector( xmlDescriptionWithTagName: ) withObject:@"sender"] UTF8String]; 
     152                id sender = nil; 
     153                if( [self respondsToSelector:@selector( sender )] ) 
     154                        sender = [self performSelector:@selector( sender )]; 
     155 
     156                if( sender && [sender respondsToSelector:@selector( xmlDescriptionWithTagName: )] ) { 
     157                        const char *sendDesc = [(NSString *)[sender performSelector:@selector( xmlDescriptionWithTagName: ) withObject:@"sender"] UTF8String]; 
    349158 
    350159                        if( sendDesc ) { 
     
    356165                                xmlFreeDoc( tempDoc ); 
    357166                        } 
    358                 } else if( [self senderName] )
    359                         child = xmlNewTextChild( root, NULL, (xmlChar *) "sender", (xmlChar *) [[self senderName] UTF8String] ); 
     167                } else
     168                        child = xmlNewTextChild( root, NULL, (xmlChar *) "sender", ( [self senderName] ? (xmlChar *) [[self senderName] UTF8String] : @"" ) ); 
    360169                        if( [self senderIsLocalUser] ) xmlSetProp( child, (xmlChar *) "self", (xmlChar *) "yes" ); 
    361170                        if( [self senderNickname] && ! [[self senderName] isEqualToString:[self senderNickname]] ) 
     
    369178                        if( [self senderBuddyIdentifier] && ! [self senderIsLocalUser] ) 
    370179                                xmlSetProp( child, (xmlChar *) "buddy", (xmlChar *) [[self senderBuddyIdentifier] UTF8String] ); 
    371                 } else return NULL; 
     180                } 
    372181 
    373182                NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"IgnoreFonts", [NSNumber numberWithBool:YES], @"IgnoreFontSizes", nil]; 
     
    400209 
    401210        _node = node; 
     211} 
     212 
     213#pragma mark - 
     214 
     215- (NSDate *) date { 
     216        [self load]; 
     217        return _date; 
     218} 
     219 
     220#pragma mark - 
     221 
     222- (unsigned) consecutiveOffset { 
     223        [self load]; 
     224        return _consecutiveOffset; 
     225} 
     226 
     227#pragma mark - 
     228 
     229- (NSString *) senderName { 
     230        [self loadSender]; 
     231        return _senderName; 
     232} 
     233 
     234- (NSString *) senderIdentifier { 
     235        [self loadSender]; 
     236        return _senderIdentifier; 
     237} 
     238 
     239- (NSString *) senderNickname { 
     240        [self loadSender]; 
     241        return _senderNickname; 
     242} 
     243 
     244- (NSString *) senderHostmask { 
     245        [self loadSender]; 
     246        return _senderHostmask; 
     247} 
     248 
     249- (NSString *) senderClass { 
     250        [self loadSender]; 
     251        return _senderClass; 
     252} 
     253 
     254- (NSString *) senderBuddyIdentifier { 
     255        [self loadSender]; 
     256        return _senderBuddyIdentifier; 
     257} 
     258 
     259- (BOOL) senderIsLocalUser { 
     260        [self loadSender]; 
     261        return _senderIsLocalUser; 
     262} 
     263 
     264#pragma mark - 
     265 
     266- (NSTextStorage *) body { 
     267        [self loadBody]; 
     268        return _attributedMessage; 
     269} 
     270 
     271- (NSString *) bodyAsPlainText { 
     272        return [[self body] string]; 
     273} 
     274 
     275- (NSString *) bodyAsHTML { 
     276        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"IgnoreFonts", [NSNumber numberWithBool:YES], @"IgnoreFontSizes", nil]; 
     277        return [[self body] HTMLFormatWithOptions:options]; 
     278} 
     279 
     280#pragma mark - 
     281 
     282- (BOOL) isAction { 
     283        [self load]; 
     284        return _action; 
     285} 
     286 
     287- (BOOL) isHighlighted { 
     288        [self load]; 
     289        return _highlighted; 
     290} 
     291 
     292- (JVIgnoreMatchResult) ignoreStatus { 
     293        [self load]; 
     294        return _ignoreStatus; 
     295} 
     296 
     297- (JVChatMessageType) type { 
     298        [self load]; 
     299        return _type; 
     300} 
     301 
     302#pragma mark - 
     303 
     304- (NSURL *) source { 
     305        [self load]; 
     306        return _source; 
     307} 
     308 
     309- (JVChatTranscript *) transcript { 
     310        return _transcript; 
     311} 
     312 
     313- (NSString *) messageIdentifier { 
     314        return _messageIdentifier; 
     315} 
     316 
     317#pragma mark - 
     318 
     319- (NSScriptObjectSpecifier *) objectSpecifier { 
     320        return _objectSpecifier; 
     321} 
     322 
     323- (void) setObjectSpecifier:(NSScriptObjectSpecifier *) objectSpecifier { 
     324        id old = _objectSpecifier; 
     325        _objectSpecifier = [objectSpecifier retain]; 
     326        [old release]; 
     327} 
     328 
     329#pragma mark - 
     330 
     331- (NSString *) description { 
     332        return [self bodyAsPlainText]; 
     333} 
     334 
     335- (NSString *) debugDescription { 
     336        return [NSString stringWithFormat:@"<%@ 0x%x [%@]: (%@) %@>", NSStringFromClass( [self class] ), (unsigned long) self, _messageIdentifier, [self senderNickname], [self body]]; 
     337} 
     338 
     339#pragma mark - 
     340 
     341- (id) valueForUndefinedKey:(NSString *) key { 
     342        if( [NSScriptCommand currentCommand] ) { 
     343                [[NSScriptCommand currentCommand] setScriptErrorNumber:1000]; 
     344                [[NSScriptCommand currentCommand] setScriptErrorString:[NSString stringWithFormat:@"The message id %@ doesn't have the \"%@\" property.", [self messageIdentifier], key]]; 
     345                return nil; 
     346        } 
     347 
     348        return [super valueForUndefinedKey:key]; 
     349} 
     350 
     351- (void) setValue:(id) value forUndefinedKey:(NSString *) key { 
     352        if( [NSScriptCommand currentCommand] ) { 
     353                // this is a non-mutable message, give AppleScript a good error if this is a script command call 
     354                [[NSScriptCommand currentCommand] setScriptErrorNumber:1000]; 
     355                [[NSScriptCommand currentCommand] setScriptErrorString:[NSString stringWithFormat:@"The properties of message id %@ are read only.", key, [self messageIdentifier]]]; 
     356                return; 
     357        } 
     358 
     359        [super setValue:value forUndefinedKey:key]; 
     360} 
     361@end 
     362 
     363#pragma mark - 
     364 
     365@implementation JVMutableChatMessage 
     366+ (void) initialize { 
     367        [super initialize]; 
     368        static BOOL tooLate = NO; 
     369        if( ! tooLate ) { 
     370                [[NSScriptCoercionHandler sharedCoercionHandler] registerCoercer:[self class] selector:@selector( coerceMessage:toString: ) toConvertFromClass:[JVMutableChatMessage class] toClass:[NSString class]]; 
     371                [[NSScriptCoercionHandler sharedCoercionHandler] registerCoercer:[self class] selector:@selector( coerceString:toMessage: ) toConvertFromClass:[NSString class] toClass:[JVMutableChatMessage class]]; 
     372                [[NSScriptCoercionHandler sharedCoercionHandler] registerCoercer:[self class] selector:@selector( coerceMessage:toTextStorage: ) toConvertFromClass:[JVMutableChatMessage class] toClass:[NSTextStorage class]]; 
     373                [[NSScriptCoercionHandler sharedCoercionHandler] registerCoercer:[self class] selector:@selector( coerceTextStorage:toMessage: ) toConvertFromClass:[NSTextStorage class] toClass:[JVMutableChatMessage class]]; 
     374                tooLate = YES; 
     375        } 
     376} 
     377 
     378+ (id) messageWithText:(id) body sender:(id) sender { 
     379        return [[[self allocWithZone:nil] initWithText:body sender:sender] autorelease]; 
     380} 
     381 
     382#pragma mark - 
     383 
     384- (id) initWithText:(id) body sender:(id) sender { 
     385        if( ( self = [self init] ) ) { 
     386                _loaded = YES; 
     387                _bodyLoaded = YES; 
     388                _senderLoaded = YES; 
     389                [self setDate:[NSDate date]]; 
     390                [self setBody:body]; 
     391                [self setSender:sender]; 
     392                [self setMessageIdentifier:[NSString locallyUniqueString]]; 
     393        } 
     394 
     395        return self; 
     396} 
     397 
     398- (void) dealloc { 
     399        [_sender release]; 
     400        _sender = nil; 
     401 
     402        [super dealloc]; 
    402403} 
    403404 
  • trunk/Models/JVChatSession.m

    r3236 r3247  
    33 
    44@implementation JVChatSession 
    5 - (id) initWithNode:(xmlNode *) node andTranscript:(JVChatTranscript *) transcript { 
    6         if( ( self = [self init] ) ) { 
    7                 _node = node; 
    8                 _transcript = transcript; // weak reference 
    9  
    10                 if( ! _node || node -> type != XML_ELEMENT_NODE ) { 
    11                         [self release]; 
    12                         return nil; 
    13                 } 
    14  
    15                 @synchronized( _transcript ) { 
    16                         xmlChar *startedStr = xmlGetProp( (xmlNode *) _node, (xmlChar *) "started" ); 
    17                         _startDate = ( startedStr ? [[NSDate allocWithZone:[self zone]] initWithString:[NSString stringWithUTF8String:(char *) startedStr]] : nil ); 
    18                         xmlFree( startedStr ); 
    19                 } 
    20         } 
    21  
    22         return self; 
    23 } 
    24  
    25 + (id) sessionWithNode:(xmlNode *) node andTranscript:(JVChatTranscript *) transcript { 
    26         return [[[self alloc] initWithNode:node andTranscript:transcript] autorelease]; 
    27 } 
    28  
    295- (void) dealloc { 
    306        [_startDate release]; 
  • trunk/Models/JVChatTranscript.h

    r3236 r3247  
    5757- (JVChatMessage *) messageAtIndex:(unsigned long) index; 
    5858- (JVChatMessage *) messageWithIdentifier:(NSString *) identifier; 
    59 - (NSArray *) messagesInEnvelopeWithMessage:(JVChatMessage *) message; 
    6059- (JVChatMessage *) lastMessage; 
    6160 
     
    7372 
    7473- (JVChatSession *) startNewSession; 
    75 - (JVChatSession *) appendSessionWithStartDate:(NSDate *) startDate
     74- (JVChatSession *) appendSession:(JVChatSession *) session
    7675 
    7776- (NSArray *) events; 
  • trunk/Models/JVChatTranscript.m

    r3236 r3247  
    3232 
    3333@interface JVChatSession (JVChatSessionPrivate) 
    34 + (id) sessionWithNode:(xmlNode *) node andTranscript:(JVChatTranscript *) transcript; 
    35 - (id) initWithNode:(xmlNode *) node andTranscript:(JVChatTranscript *) transcript; 
    36 - (void) setNode:(xmlNode *) node; 
     34- (id) _initWithNode:(xmlNode *) node andTranscript:(JVChatTranscript *) transcript; 
     35- (void) _setNode:(xmlNode *) node; 
    3736@end 
    3837 
     
    306305                        } else if( node && node -> type == XML_ELEMENT_NODE && ! strncmp( "session", (char *) node -> name, 7 ) ) { 
    307306                                if( NSLocationInRange( i, range ) ) { 
    308                                         JVChatSession *session = [JVChatSession sessionWithNode:node andTranscript:self]; 
     307                                        JVChatSession *session = [[JVChatSession allocWithZone:nil] _initWithNode:node andTranscript:self]; 
    309308                                        if( session ) [ret addObject:session]; 
     309                                        [session release]; 
    310310                                } 
    311311 
     
    342342                                } while( subNode && ( subNode = subNode -> prev ) ); 
    343343                        } else if( node && node -> type == XML_ELEMENT_NODE && ! strncmp( "session", (char *) node -> name, 7 ) ) { 
    344                                 return [JVChatSession sessionWithNode:node andTranscript:self]; 
     344                                return [[[JVChatSession allocWithZone:nil] _initWithNode:node andTranscript:self] autorelease]; 
    345345                        } else if( node && node -> type == XML_ELEMENT_NODE && ! strncmp( "event", (char *) node -> name, 5 ) ) { 
    346346                                return [[[JVChatEvent allocWithZone:nil] _initWithNode:node andTranscript:self] autorelease]; 
     
    365365                        if( [element isKindOfClass:[JVChatMessage class]] ) newElement = [self appendMessage:element]; 
    366366                        else if( [element isKindOfClass:[JVChatEvent class]] ) newElement = [self appendEvent:element]; 
    367                         else if( [element isKindOfClass:[JVChatSession class]] ) newElement = [self appendSessionWithStartDate:[element startDate]]; 
     367                        else if( [element isKindOfClass:[JVChatSession class]] ) newElement = [self appendSession:element]; 
    368368                        if( newElement ) [ret addObject:newElement]; 
    369369                } 
     
    478478} 
    479479 
    480 - (NSArray *) messagesInEnvelopeWithMessage:(JVChatMessage *) message { 
    481         NSParameterAssert( message != nil ); 
    482         NSParameterAssert( [message node] != NULL ); 
    483  
    484         @synchronized( self ) { 
    485                 xmlNode *envelope = ((xmlNode *)[message node]) -> parent; 
    486                 xmlNode *node = envelope -> children; 
    487                 NSMutableArray *results = [NSMutableArray allocWithZone:nil]; 
    488  
    489                 do { 
    490                         if( node && node -> type == XML_ELEMENT_NODE && ! strncmp( "message", (char *) node -> name, 7 ) ) { 
    491                                 JVChatMessage *msg = [[JVChatMessage allocWithZone:nil] _initWithNode:node andTranscript:self]; 
    492                                 if( msg ) [results addObject:msg]; 
    493                                 [msg release]; 
    494                         } 
    495                 } while( node && ( node = node -> next ) ); 
    496  
    497                 return [results autorelease]; 
    498         } 
    499  
    500         return nil; 
    501 } 
    502  
    503480- (JVChatMessage *) lastMessage { 
    504481        @synchronized( self ) { 
     
    687664                        if( node && node -> type == XML_ELEMENT_NODE && ! strncmp( "session", (char *) node -> name, 7 ) ) { 
    688665                                if( NSLocationInRange( i, range ) ) { 
    689                                         JVChatSession *session = [JVChatSession sessionWithNode:node andTranscript:self]; 
     666                                        JVChatSession *session = [[JVChatSession allocWithZone:nil] _initWithNode:node andTranscript:self]; 
    690667                                        if( session ) [ret addObject:session]; 
     668                                        [session release]; 
    691669                                } 
    692670 
     
    709687                do { 
    710688                        if( node && node -> type == XML_ELEMENT_NODE && ! strncmp( "session", (char *) node -> name, 7 ) ) 
    711                                 return [JVChatSession sessionWithNode:node andTranscript:self]; 
     689                                return [[[JVChatSession allocWithZone:nil] _initWithNode:node andTranscript:self] autorelease]; 
    712690                } while( node && ( node = node -> prev ) ); 
    713691        } 
     
    719697 
    720698- (JVChatSession *) startNewSession { 
    721         return [self appendSessionWithStartDate:[NSDate date]]; 
    722 
    723  
    724 - (JVChatSession *) appendSessionWithStartDate:(NSDate *) startDate { 
     699        return nil; 
     700//      return [self appendSession:[NSDate date]]; 
     701
     702 
     703- (JVChatSession *) appendSession:(JVChatSession *) session { 
    725704        xmlNodePtr sessionNode = xmlNewNode( NULL, (xmlChar *) "session" ); 
    726         xmlSetProp( sessionNode, (xmlChar *) "started", (xmlChar *) [[startDate description] UTF8String] ); 
     705        xmlSetProp( sessionNode, (xmlChar *) "started", (xmlChar *) [[[session startDate] description] UTF8String] ); 
    727706        xmlAddChild( xmlDocGetRootElement( _xmlLog ), sessionNode ); 
     707 
    728708        [self _enforceElementLimit]; 
    729709        [self _incrementalWriteToLog:sessionNode continuation:NO]; 
    730         return [JVChatSession sessionWithNode:sessionNode andTranscript:self]; 
     710 
     711        return [[[JVChatSession allocWithZone:nil] _initWithNode:sessionNode andTranscript:self] autorelease]; 
    731712} 
    732713 
     
    12741255#pragma mark - 
    12751256 
     1257@implementation JVChatSession (JVChatSessionChatTranscriptPrivate) 
     1258- (id) _initWithNode:(xmlNode *) node andTranscript:(JVChatTranscript *) transcript { 
     1259        if( ( self = [self init] ) ) { 
     1260                _node = node; 
     1261                _transcript = transcript; // weak reference 
     1262 
     1263                if( ! _node || node -> type != XML_ELEMENT_NODE ) { 
     1264                        [self release]; 
     1265                        return nil; 
     1266                } 
     1267 
     1268                @synchronized( _transcript ) { 
     1269                        xmlChar *startedStr = xmlGetProp( (xmlNode *) _node, (xmlChar *) "started" ); 
     1270                        _startDate = ( startedStr ? [[NSDate allocWithZone:[self zone]] initWithString:[NSString stringWithUTF8String:(char *) startedStr]] : nil ); 
     1271                        xmlFree( startedStr ); 
     1272                } 
     1273        } 
     1274 
     1275        return self; 
     1276} 
     1277@end 
     1278 
     1279#pragma mark - 
     1280 
    12761281@implementation JVChatMessage (JVChatMessageChatTranscriptPrivate) 
    12771282- (id) _initWithNode:(xmlNode *) node andTranscript:(JVChatTranscript *) transcript { 
     
    13201325                xmlFree( prop ); 
    13211326 
    1322                 prop = xmlGetProp( ((xmlNode *) _node) -> parent, (xmlChar *) "ignored" ); 
     1327                xmlNode *envelope = ((xmlNode *) _node) -> parent; 
     1328 
     1329                prop = xmlGetProp( envelope, (xmlChar *) "ignored" ); 
    13231330                _ignoreStatus = ( ( prop && ! strcmp( (char *) prop, "yes" ) ) ? JVUserIgnored : _ignoreStatus ); 
    13241331                xmlFree( prop ); 
    13251332 
    1326                 prop = xmlGetProp( ((xmlNode *) _node) -> parent, (xmlChar *) "source" ); 
     1333                prop = xmlGetProp( envelope, (xmlChar *) "source" ); 
    13271334                [_source autorelease]; 
    13281335                _source = ( prop ? [[NSURL allocWithZone:[self zone]] initWithString:[NSString stringWithUTF8String:(char *) prop]] : nil ); 
    13291336                xmlFree( prop ); 
     1337 
     1338                xmlNode *node = envelope -> children; 
     1339 
     1340                do { 
     1341                        if( node && node -> type == XML_ELEMENT_NODE && ! strncmp( "message", (char *) node -> name, 7 ) ) { 
     1342                                if( node == _node ) break; 
     1343                                _consecutiveOffset++; 
     1344                        } 
     1345                } while( node && ( node = node -> next ) ); 
    13301346        } 
    13311347 
     
    13421358                        if( subNode -> type == XML_ELEMENT_NODE && ! strncmp( "sender", (char *) subNode -> name, 6 ) ) { 
    13431359                                xmlChar *prop = xmlNodeGetContent( subNode ); 
    1344                                 [_senderName autorelease]
     1360                                id old = _senderName
    13451361                                if( prop ) _senderName = [[NSString allocWithZone:[self zone]] initWithUTF8String:(char *) prop]; 
    13461362                                else _senderName = nil; 
     1363                                [old release]; 
    13471364                                xmlFree( prop ); 
    13481365 
    13491366                                prop = xmlGetProp( subNode, (xmlChar *) "nickname" ); 
    1350                                 [_senderNickname autorelease]
     1367                                old = _senderNickname
    13511368                                if( prop ) _senderNickname = [[NSString allocWithZone:[self zone]] initWithUTF8String:(char *) prop]; 
    13521369                                else _senderNickname = nil; 
     1370                                [old release]; 
    13531371                                xmlFree( prop ); 
    13541372 
    13551373                                prop = xmlGetProp( subNode, (xmlChar *) "identifier" ); 
    1356                                 [_senderIdentifier autorelease]
    &