Adium

Changeset 23850

Show
Ignore:
Timestamp:
06/08/2008 02:43:46 PM (6 months ago)
Author:
evands
Message:

Decode messages separately, and filter them on their own, rather than decoding and filtering the entire displayed chat log. This lets us not emoticonify and otherwise modify timestamps, sender names, and statuses. Fixes #9989

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Adium.xcodeproj/project.pbxproj

    r23835 r23850  
    571571                34A1A8ED0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = 34A1A8EB0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.h */; }; 
    572572                34A1A8EE0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A1A8EC0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.m */; }; 
     573                34A1AB6C0DFC531000AC78CF /* AIXMLChatlogConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A1AB6B0DFC531000AC78CF /* AIXMLChatlogConverter.m */; }; 
    573574                34A1EDAF0DD3AF220090667A /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C103FAE057127A500F3C158 /* WebKit.framework */; }; 
    574575                34A1EE990DD3BFB00090667A /* AIFacebookBuddyListManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A1EE980DD3BFB00090667A /* AIFacebookBuddyListManager.m */; }; 
     
    13211322                F551B1000B8F5130007D3A3C /* FireLogImporter.nib in Resources */ = {isa = PBXBuildFile; fileRef = F56E0DAF0A4CDF9C008D1EB5 /* FireLogImporter.nib */; }; 
    13221323                F58904F20A7828B9001F0ADC /* OTR.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 341BDBBA0968BC9A00CF83F5 /* OTR.framework */; }; 
    1323                 F5DA8A740A546AC5004A41D0 /* GBChatlogHTMLConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = F5DA8A720A546AC4004A41D0 /* GBChatlogHTMLConverter.m */; }; 
    13241324                F5F8CA4D0A1A9C9400154550 /* GBQuestionHandlerPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = F5F8CA4B0A1A9C9400154550 /* GBQuestionHandlerPlugin.m */; }; 
    13251325/* End PBXBuildFile section */ 
     
    30453045                34A1A8EB0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AICustomSocialNetworkingStatusWindowController.h; path = "Frameworks/Adium Framework/Source/AICustomSocialNetworkingStatusWindowController.h"; sourceTree = "<group>"; }; 
    30463046                34A1A8EC0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AICustomSocialNetworkingStatusWindowController.m; path = "Frameworks/Adium Framework/Source/AICustomSocialNetworkingStatusWindowController.m"; sourceTree = "<group>"; }; 
     3047                34A1AB6A0DFC531000AC78CF /* AIXMLChatlogConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIXMLChatlogConverter.h; path = Source/AIXMLChatlogConverter.h; sourceTree = "<group>"; }; 
     3048                34A1AB6B0DFC531000AC78CF /* AIXMLChatlogConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIXMLChatlogConverter.m; path = Source/AIXMLChatlogConverter.m; sourceTree = "<group>"; }; 
    30473049                34A1EE970DD3BFB00090667A /* AIFacebookBuddyListManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIFacebookBuddyListManager.h; path = "Plugins/Facebook Service/AIFacebookBuddyListManager.h"; sourceTree = "<group>"; }; 
    30483050                34A1EE980DD3BFB00090667A /* AIFacebookBuddyListManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIFacebookBuddyListManager.m; path = "Plugins/Facebook Service/AIFacebookBuddyListManager.m"; sourceTree = "<group>"; }; 
     
    42704272                F59DB3E7033EB4B601A8010A /* Adium.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Adium.h; path = "Frameworks/Adium Framework/Source/Adium.h"; sourceTree = "<group>"; }; 
    42714273                F59DB6AD033EB74801A8010A /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Source/main.m; sourceTree = SOURCE_ROOT; }; 
    4272                 F5DA8A710A546AC4004A41D0 /* GBChatlogHTMLConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GBChatlogHTMLConverter.h; path = Source/GBChatlogHTMLConverter.h; sourceTree = "<group>"; }; 
    4273                 F5DA8A720A546AC4004A41D0 /* GBChatlogHTMLConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GBChatlogHTMLConverter.m; path = Source/GBChatlogHTMLConverter.m; sourceTree = "<group>"; }; 
    42744274                F5F0FE9C04B12CAC01A80106 /* AIEmoticonPreferences.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AIEmoticonPreferences.h; path = Plugins/Emoticons/AIEmoticonPreferences.h; sourceTree = "<group>"; }; 
    42754275                F5F0FE9D04B12CAC01A80106 /* AIEmoticonPreferences.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = AIEmoticonPreferences.m; path = Plugins/Emoticons/AIEmoticonPreferences.m; sourceTree = "<group>"; }; 
     
    74357435                                9ECB03E409F2A9D800996F44 /* AIXMLAppender.h */, 
    74367436                                9ECB03E509F2A9D800996F44 /* AIXMLAppender.m */, 
    7437                                 F5DA8A710A546AC4004A41D0 /* GBChatlogHTMLConverter.h */, 
    7438                                 F5DA8A720A546AC4004A41D0 /* GBChatlogHTMLConverter.m */, 
     7437                                34A1AB6A0DFC531000AC78CF /* AIXMLChatlogConverter.h */, 
     7438                                34A1AB6B0DFC531000AC78CF /* AIXMLChatlogConverter.m */, 
    74397439                        ); 
    74407440                        name = "XML Logging"; 
     
    96319631                                34382CEA0A50386C004BF6A2 /* DCMessageContextDisplayPlugin.m in Sources */, 
    96329632                                348B250D0A50A1C900B2B972 /* ESSourceListBackgroundView.m in Sources */, 
    9633                                 F5DA8A740A546AC5004A41D0 /* GBChatlogHTMLConverter.m in Sources */, 
    96349633                                340670A90A55A4B4004E22AC /* ESGlassSplitView.m in Sources */, 
    96359634                                345AFAEE0A5D9A5F00D7DA6F /* AINoisyTableColumn.m in Sources */, 
     
    97399738                                EFB1C3140DDBDA3100B3973D /* AITwitterIMPlugin.m in Sources */, 
    97409739                                11077B6F0DE647C100A4DD25 /* AIStatusItemView.m in Sources */, 
     9740                                34A1AB6C0DFC531000AC78CF /* AIXMLChatlogConverter.m in Sources */, 
    97419741                        ); 
    97429742                        runOnlyForDeploymentPostprocessing = 0; 
  • trunk/Source/AIAbstractLogViewerWindowController.m

    r23817 r23850  
    1212#import "AILoggerPlugin.h" 
    1313#import "ESRankingCell.h"  
    14 #import "GBChatlogHTMLConverter.h" 
     14#import "AIXMLChatlogConverter.h" 
    1515#import "AILogDateFormatter.h" 
    1616 
     
    720720                if ([[theLog path] hasSuffix:@".AdiumHTMLLog"] || [[theLog path] hasSuffix:@".html"] || [[theLog path] hasSuffix:@".html.bak"]) { 
    721721                        //HTML log 
    722                         NSString *logFileText = [NSString stringWithContentsOfFile:[logBasePath stringByAppendingPathComponent:[theLog path]]]; 
    723                          
     722                        NSString                   *logFileText = [NSString stringWithContentsOfFile:[logBasePath stringByAppendingPathComponent:[theLog path]]]; 
     723                        NSAttributedString *attributedLogFileText = [AIHTMLDecoder decodeHTML:logFileText]; 
     724 
     725                        if (showEmoticons) { 
     726                                attributedLogFileText = [[adium contentController] filterAttributedString:attributedLogFileText 
     727                                                                                                                                                  usingFilterType:AIFilterMessageDisplay 
     728                                                                                                                                                                direction:AIFilterOutgoing 
     729                                                                                                                                                                  context:nil];                                          
     730                        }                        
     731 
    724732                        if (displayText) { 
    725                                 [displayText appendAttributedString:[AIHTMLDecoder decodeHTML:logFileText]]; 
     733                                [displayText appendAttributedString:attributedLogFileText]; 
    726734                        } else { 
    727                                 displayText = [[AIHTMLDecoder decodeHTML:logFileText] mutableCopy]; 
     735                                displayText = [attributedLogFileText mutableCopy]; 
    728736                        } 
    729737 
     
    738746                                                                                 [[[logFullPath lastPathComponent] stringByDeletingPathExtension] stringByAppendingPathExtension:@"xml"]]; 
    739747                        } 
    740                          
    741                         //If this log begins with a malformed UTF-8 BOM (which was written out by Adium for a brief time between 1.0b7 and 1.0b8), fix it before trying to read it in. 
    742                         enum { 
    743                                 failedUtf8BomLength = 6 
    744                         }; 
    745                         NSData *data = [NSData dataWithContentsOfMappedFile:logFullPath]; 
    746                         const unsigned char *ptr = [data bytes]; 
    747                         unsigned len = [data length]; 
    748                         if ((len >= failedUtf8BomLength) 
    749                                 &&  (ptr[0] == 0xC3) 
    750                                 &&  (ptr[1] == 0x94) 
    751                                 &&  (ptr[2] == 0xC2) 
    752                                 &&  (ptr[3] == 0xAA) 
    753                                 &&  (ptr[4] == 0xC3) 
    754                                 &&  (ptr[5] == 0xB8) 
    755                                 ) { 
    756                                 //Yup. Back up the old file, then strip it off. 
    757                                 NSLog(@"Transcript file at %@ has unwanted bytes at the front of it. (This is a bug in a previous version of Adium, not this version.) Attempting recovery.", logFullPath); 
    758                                 NSString *backupPath = [logFullPath stringByAppendingPathExtension:@"bak"]; 
    759                                 if(![[NSFileManager defaultManager] movePath:logFullPath toPath:backupPath handler:nil]) 
    760                                         NSLog(@"Could not back up file; recovery failed. This transcript will probably appear blank in the transcript viewer."); 
    761                                 else { 
    762                                         NSRange range = { failedUtf8BomLength, len - failedUtf8BomLength }; 
    763                                         NSData *theRestOfIt = [data subdataWithRange:range]; 
    764                                         if([theRestOfIt writeToFile:logFullPath atomically:YES]) 
    765                                                 NSLog(@"Wrote fixed version to same file. The corrupted version was renamed to %@; you may remove this file at your leisure after you are satisfied that the recovery succeeded. You can test this by viewing the transcript (%@) in the transcript viewer.", backupPath, [logFullPath lastPathComponent]); 
    766                                         else 
    767                                                 NSLog(@"Could not write fix!"); 
    768                                 } 
    769                         } 
    770                          
    771                         NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:showTimestamps] 
    772                                                                                                                                 forKey:@"showTimestamps"]; 
    773                         NSString *logFileText = [GBChatlogHTMLConverter readFile:logFullPath withOptions:options]; 
    774                         if (logFileText) { 
     748 
     749                        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
     750                                                                         [NSNumber numberWithBool:showTimestamps], @"showTimestamps", 
     751                                                                         [NSNumber numberWithBool:showEmoticons], @"showEmoticons",  
     752                                                                         nil]; 
     753                        NSAttributedString *attributedLogFileText = [AIXMLChatlogConverter readFile:logFullPath withOptions:options]; 
     754                        if (attributedLogFileText) { 
    775755                                if (displayText) 
    776                                         [displayText appendAttributedString:[AIHTMLDecoder decodeHTML:logFileText]]; 
     756                                        [displayText appendAttributedString:attributedLogFileText]; 
    777757                                else 
    778                                         displayText = [[AIHTMLDecoder decodeHTML:logFileText] mutableCopy]; 
     758                                        displayText = [attributedLogFileText mutableCopy]; 
    779759                        } 
    780760 
     
    784764                        if (logFileText) { 
    785765                                AITextAttributes *textAttributes = [AITextAttributes textAttributesWithFontFamily:@"Helvetica" traits:0 size:12]; 
     766                                NSAttributedString *attributedLogFileText = [[[NSAttributedString alloc] initWithString:logFileText  
     767                                                                                                                                                                                         attributes:[textAttributes dictionary]] autorelease]; 
     768                                if (showEmoticons) { 
     769                                        attributedLogFileText = [[adium contentController] filterAttributedString:attributedLogFileText 
     770                                                                                                                                                          usingFilterType:AIFilterMessageDisplay 
     771                                                                                                                                                                        direction:AIFilterOutgoing 
     772                                                                                                                                                                          context:nil];                                          
     773                                } 
    786774                                 
    787775                                if (displayText) { 
    788                                         [displayText appendAttributedString:[[[NSAttributedString alloc] initWithString:logFileText  
    789                                                                                                                                                                                  attributes:[textAttributes dictionary]] autorelease]]; 
     776                                        [displayText appendAttributedString:attributedLogFileText]; 
    790777                                } else { 
    791                                         displayText = [[NSMutableAttributedString alloc] initWithString:logFileText attributes:[textAttributes dictionary]]; 
     778                                        displayText = [attributedLogFileText mutableCopy]; 
    792779                                } 
    793780                        } 
     
    885872                } 
    886873                 
    887                 //Filter emoticons 
    888                 if (showEmoticons) { 
    889                         finalDisplayText = [[adium contentController] filterAttributedString:displayText 
    890                                                                                                                                  usingFilterType:AIFilterMessageDisplay 
    891                                                                                                                                            direction:AIFilterOutgoing 
    892                                                                                                                                                  context:nil]; 
    893                 } else { 
    894                         finalDisplayText = displayText; 
    895                 } 
     874                finalDisplayText = displayText; 
    896875        } 
    897876 
  • trunk/Source/AIXMLChatlogConverter.h

    r23660 r23850  
    3737} AINameFormat; 
    3838 
    39 @interface GBChatlogHTMLConverter : AIObject { 
     39@class AIHTMLDecoder; 
     40 
     41@interface AIXMLChatlogConverter : AIObject { 
    4042        CFXMLParserRef  parser; 
    4143        NSString                *inputFileString; 
     
    5254        BOOL                    autoResponse; 
    5355        BOOL                    showTimestamps; 
     56        BOOL                    showEmoticons; 
    5457        NSString                *status; 
    5558         
    56         NSMutableString *output; 
     59        NSMutableAttributedString *output; 
     60        NSAttributedString *newlineAttributedString; 
    5761        NSDictionary    *statusLookup; 
    58          
     62        AIHTMLDecoder   *htmlDecoder; 
     63 
    5964        AINameFormat    nameFormat; 
    6065} 
    6166 
    62 + (NSString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options; 
    63 - (NSString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options; 
     67+ (NSAttributedString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options; 
     68- (NSAttributedString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options; 
    6469 
    6570@end 
  • trunk/Source/AIXMLChatlogConverter.m

    r23660 r23850  
    1515 */ 
    1616 
    17 #import "GBChatlogHTMLConverter.h" 
     17#import "AIXMLChatlogConverter.h" 
    1818#import "AIStandardListWindowController.h" 
     19#import <Adium/AIHTMLDecoder.h> 
    1920#import <Adium/AIListContact.h> 
    2021#import <Adium/AIAccountControllerProtocol.h> 
    2122#import <Adium/AIContactControllerProtocol.h> 
     23#import <Adium/AIContentControllerProtocol.h> 
    2224#import <Adium/AIPreferenceControllerProtocol.h> 
    2325#import <Adium/AIStatusControllerProtocol.h> 
     
    2628#import <AIUtilities/AIStringAdditions.h> 
    2729 
    28  
    2930#define PREF_GROUP_WEBKIT_MESSAGE_DISPLAY               @"WebKit Message Display" 
    3031#define KEY_WEBKIT_USE_NAME_FORMAT                              @"Use Custom Name Format" 
     
    3536static void endStructure(CFXMLParserRef parser, void *xmlType, void *context); 
    3637 
    37 @implementation GBChatlogHTMLConverter 
    38  
    39 + (NSString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options 
    40 { 
    41         GBChatlogHTMLConverter *converter = [[GBChatlogHTMLConverter alloc] init]; 
    42         NSString *ret = [[converter readFile:filePath withOptions:options] retain]; 
     38@implementation AIXMLChatlogConverter 
     39 
     40+ (NSAttributedString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options 
     41{ 
     42        AIXMLChatlogConverter *converter = [[AIXMLChatlogConverter alloc] init]; 
     43        NSAttributedString *ret = [[converter readFile:filePath withOptions:options] retain]; 
    4344        [converter release]; 
    4445        return [ret autorelease]; 
     
    6162        status = nil; 
    6263         
     64        newlineAttributedString = [[NSAttributedString alloc] initWithString:@"\n" attributes:nil]; 
     65 
    6366        statusLookup = [[NSDictionary alloc] initWithObjectsAndKeys: 
    6467                AILocalizedString(@"Online", nil), @"online", 
     
    9396- (void)dealloc 
    9497{ 
     98        [newlineAttributedString release]; 
    9599        [inputFileString release]; 
    96100        [eventTranslate release]; 
     
    104108        [output release]; 
    105109        [statusLookup release]; 
     110        [htmlDecoder release]; 
    106111        [super dealloc]; 
    107112} 
    108113 
    109 - (NSString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options 
     114- (NSAttributedString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options 
    110115{ 
    111116        NSData *inputData = [NSData dataWithContentsOfFile:filePath]; 
    112117        inputFileString = [[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding]; 
    113118        NSURL *url = [[NSURL alloc] initFileURLWithPath:filePath]; 
    114         output = [[NSMutableString alloc] init]; 
    115         [output appendFormat:@"<head><base href=\"%@\" /></head>", [filePath stringByDeletingLastPathComponent]]; 
     119        output = [[NSMutableAttributedString alloc] init]; 
     120         
     121        htmlDecoder = [[AIHTMLDecoder alloc] init]; 
     122        [htmlDecoder setBaseURL:[filePath stringByDeletingLastPathComponent]]; 
    116123         
    117124        showTimestamps = [[options objectForKey:@"showTimestamps"] boolValue]; 
     125        showEmoticons = [[options objectForKey:@"showEmoticons"] boolValue]; 
     126 
    118127        CFXMLParserCallBacks callbacks = { 
    119128                0, 
     
    298307                                                                                                                                        timeZone:nil 
    299308                                                                                                                                          locale:nil]; 
    300                                 [output appendFormat:@"<div class=\"%@\">%@<span class=\"sender\">%@%@:</span> <pre class=\"message\">%@</pre></div>\n", 
    301                                  ([mySN isEqualToString:sender] ? @"send" : @"receive"), 
    302                                  (showTimestamps ? [NSString stringWithFormat:@"<span class=\"timestamp\">%@</span> ", timestampStr] : @""), 
    303                                  shownSender, (autoResponse ? AILocalizedString(@" (Autoreply)", nil) : @""), 
    304                                  message]; 
     309                                BOOL sentMessage = [mySN isEqualToString:sender]; 
     310                                [output appendAttributedString:[htmlDecoder decodeHTML:[NSString stringWithFormat: 
     311                                                                                 @"<div class=\"%@\">%@<span class=\"sender\">%@%@:</span></div> ", 
     312                                                                                 (sentMessage ? @"send" : @"receive"), 
     313                                                                                 (showTimestamps ? [NSString stringWithFormat:@"<span class=\"timestamp\">%@</span> ", timestampStr] : @""), 
     314                                                                                 shownSender, (autoResponse ? AILocalizedString(@" (Autoreply)", nil) : @"")]]]; 
     315                                 
     316                                NSAttributedString *attributedMessage = [htmlDecoder decodeHTML:message]; 
     317                                if (showEmoticons) { 
     318                                        attributedMessage = [[adium contentController] filterAttributedString:attributedMessage 
     319                                                                                                                                                  usingFilterType:AIFilterMessageDisplay 
     320                                                                                                                                                                direction:(sentMessage ? AIFilterOutgoing : AIFilterIncoming) 
     321                                                                                                                                                                  context:nil];                          
     322                                } 
     323                                [output appendAttributedString:attributedMessage]; 
     324                                [output appendAttributedString:newlineAttributedString]; 
     325 
    305326                                state = XML_STATE_CHAT; 
    306327                        } 
     
    327348 
    328349                                if([displayMessage length]) 
    329                                         [output appendFormat:@"<div class=\"status\">%@ (%@)</div>\n", 
    330                                                 displayMessage, 
    331                                                 [date descriptionWithCalendarFormat:[NSDateFormatter localizedDateFormatStringShowingSeconds:YES 
    332                                                                                                                                                                                                            showingAMorPM:YES] 
    333                                                                                                    timeZone:nil 
    334                                                                                                         locale:nil]]; 
     350                                        [output appendAttributedString:[htmlDecoder decodeHTML:[NSString stringWithFormat:@"<div class=\"status\">%@ (%@)</div>\n", 
     351                                                                                                                                                       displayMessage, 
     352                                                                                                                                                       [date descriptionWithCalendarFormat:[NSDateFormatter localizedDateFormatStringShowingSeconds:YES 
     353                                                                                                                                                                                                                                                                                                                  showingAMorPM:YES] 
     354                                                                                                                                                                                                          timeZone:nil 
     355                                                                                                                                                                                                                locale:nil]]]]; 
    335356                                state = XML_STATE_CHAT; 
    336357                        }                        
     
    361382                        NSString *name = [NSString stringWithString:(NSString *)CFXMLNodeGetString(node)]; 
    362383                        const CFXMLElementInfo *info = CFXMLNodeGetInfoPtr(node); 
    363                         [(GBChatlogHTMLConverter *)context startedElement:name info:info]; 
     384                        [(AIXMLChatlogConverter *)context startedElement:name info:info]; 
    364385                        ret = (element *)malloc(sizeof(element)); 
    365386                        ret->name = [name retain]; 
     
    396417                empty = ((element *)xmlType)->empty; 
    397418        } 
    398         [(GBChatlogHTMLConverter *)context endedElement:name empty:empty]; 
     419        [(AIXMLChatlogConverter *)context endedElement:name empty:empty]; 
    399420        if(xmlType != NULL) 
    400421        {