1*ac937ea6SAndrew Rist/************************************************************** 2cdf0e10cSrcweir * 3*ac937ea6SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*ac937ea6SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*ac937ea6SAndrew Rist * distributed with this work for additional information 6*ac937ea6SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*ac937ea6SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*ac937ea6SAndrew Rist * "License"); you may not use this file except in compliance 9*ac937ea6SAndrew Rist * with the License. You may obtain a copy of the License at 10*ac937ea6SAndrew Rist * 11*ac937ea6SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*ac937ea6SAndrew Rist * 13*ac937ea6SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*ac937ea6SAndrew Rist * software distributed under the License is distributed on an 15*ac937ea6SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*ac937ea6SAndrew Rist * KIND, either express or implied. See the License for the 17*ac937ea6SAndrew Rist * specific language governing permissions and limitations 18*ac937ea6SAndrew Rist * under the License. 19*ac937ea6SAndrew Rist * 20*ac937ea6SAndrew Rist *************************************************************/ 21*ac937ea6SAndrew Rist 22*ac937ea6SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir#import "OOoMetaDataParser.h" 25cdf0e10cSrcweir 26cdf0e10cSrcweirstatic NSSet *singleValueXMLElements; 27cdf0e10cSrcweirstatic NSSet *multiValueXMLElements; 28cdf0e10cSrcweirstatic NSDictionary *metaXML2MDIKeys; 29cdf0e10cSrcweir 30cdf0e10cSrcweir@implementation OOoMetaDataParser 31cdf0e10cSrcweir 32cdf0e10cSrcweir+ (void)initialize 33cdf0e10cSrcweir{ 34cdf0e10cSrcweir static BOOL isInitialized = NO; 35cdf0e10cSrcweir 36cdf0e10cSrcweir if (isInitialized == NO) { 37cdf0e10cSrcweir //set up the meta elements with only one value 38cdf0e10cSrcweir NSMutableSet *temp = [NSMutableSet new]; 39cdf0e10cSrcweir [temp addObject:@"dc:title"]; 40cdf0e10cSrcweir [temp addObject:@"dc:description"]; 41cdf0e10cSrcweir [temp addObject:@"meta:user-defined"]; 42cdf0e10cSrcweir singleValueXMLElements = [[NSSet setWithSet:temp] retain]; 43cdf0e10cSrcweir 44cdf0e10cSrcweir //set up the meta elements that can have more than one value 45cdf0e10cSrcweir [temp removeAllObjects]; 46cdf0e10cSrcweir [temp addObject:@"dc:subject"]; 47cdf0e10cSrcweir [temp addObject:@"meta:keyword"]; 48cdf0e10cSrcweir [temp addObject:@"meta:initial-creator"]; 49cdf0e10cSrcweir [temp addObject:@"dc:creator"]; 50cdf0e10cSrcweir multiValueXMLElements = [[NSSet setWithSet:temp] retain]; 51cdf0e10cSrcweir [temp release]; 52cdf0e10cSrcweir 53cdf0e10cSrcweir //set up the map to store the values with the correct MDI keys 54cdf0e10cSrcweir NSMutableDictionary *tempDict = [NSMutableDictionary new]; 55cdf0e10cSrcweir [tempDict setObject:(NSString*)kMDItemTitle forKey:@"dc:title"]; 56cdf0e10cSrcweir [tempDict setObject:(NSString*)kMDItemDescription forKey:@"dc:description"]; 57cdf0e10cSrcweir [tempDict setObject:(NSString*)kMDItemKeywords forKey:@"dc:subject"]; 58cdf0e10cSrcweir [tempDict setObject:(NSString*)kMDItemAuthors forKey:@"meta:initial-creator"]; 59cdf0e10cSrcweir [tempDict setObject:(NSString*)kMDItemAuthors forKey:@"dc:creator"]; 60cdf0e10cSrcweir [tempDict setObject:(NSString*)kMDItemKeywords forKey:@"meta:keyword"]; 61cdf0e10cSrcweir [tempDict setObject:@"org_openoffice_opendocument_custominfo1" forKey:@"Info 1"]; 62cdf0e10cSrcweir [tempDict setObject:@"org_openoffice_opendocument_custominfo2" forKey:@"Info 2"]; 63cdf0e10cSrcweir [tempDict setObject:@"org_openoffice_opendocument_custominfo3" forKey:@"Info 3"]; 64cdf0e10cSrcweir [tempDict setObject:@"org_openoffice_opendocument_custominfo4" forKey:@"Info 4"]; 65cdf0e10cSrcweir metaXML2MDIKeys = [[NSDictionary dictionaryWithDictionary:tempDict] retain]; 66cdf0e10cSrcweir [tempDict release]; 67cdf0e10cSrcweir 68cdf0e10cSrcweir isInitialized = YES; 69cdf0e10cSrcweir } 70cdf0e10cSrcweir} 71cdf0e10cSrcweir 72cdf0e10cSrcweir- (id)init 73cdf0e10cSrcweir{ 74cdf0e10cSrcweir if ((self = [super init]) != nil) { 75cdf0e10cSrcweir shouldReadCharacters = NO; 76cdf0e10cSrcweir// currentElement = nil; 77cdf0e10cSrcweir textCurrentElement = nil; 78cdf0e10cSrcweir 79cdf0e10cSrcweir return self; 80cdf0e10cSrcweir } 81cdf0e10cSrcweir 82cdf0e10cSrcweir return nil; 83cdf0e10cSrcweir} 84cdf0e10cSrcweir 85cdf0e10cSrcweir- (void)parseXML:(NSData*)data intoDictionary:(NSMutableDictionary*)dict 86cdf0e10cSrcweir{ 87cdf0e10cSrcweir metaValues = dict; 88cdf0e10cSrcweir 89cdf0e10cSrcweir //NSLog(@"data: %@ %d", data, [data length]); 90cdf0e10cSrcweir 91cdf0e10cSrcweir //init parser settings 92cdf0e10cSrcweir shouldReadCharacters = NO; 93cdf0e10cSrcweir 94cdf0e10cSrcweir NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; 95cdf0e10cSrcweir 96cdf0e10cSrcweir [parser setDelegate:self]; 97cdf0e10cSrcweir [parser setShouldResolveExternalEntities:NO]; 98cdf0e10cSrcweir [parser parse]; 99cdf0e10cSrcweir 100cdf0e10cSrcweir [parser release]; 101cdf0e10cSrcweir 102cdf0e10cSrcweir //NSLog(@"finished parsing meta"); 103cdf0e10cSrcweir} 104cdf0e10cSrcweir 105cdf0e10cSrcweir- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict 106cdf0e10cSrcweir{ 107cdf0e10cSrcweir// NSLog(@"<%@>", elementName); 108cdf0e10cSrcweir if ([singleValueXMLElements containsObject:elementName] == YES) { 109cdf0e10cSrcweir shouldReadCharacters = YES; 110cdf0e10cSrcweir } else if ([multiValueXMLElements containsObject:elementName] == YES) { 111cdf0e10cSrcweir shouldReadCharacters = YES; 112cdf0e10cSrcweir } else { 113cdf0e10cSrcweir //we are not interested in this element 114cdf0e10cSrcweir shouldReadCharacters = NO; 115cdf0e10cSrcweir return; 116cdf0e10cSrcweir } 117cdf0e10cSrcweir 118cdf0e10cSrcweir if (shouldReadCharacters == YES) { 119cdf0e10cSrcweir textCurrentElement = [NSMutableString new]; 120cdf0e10cSrcweir isCustom = [elementName isEqualToString:@"meta:user-defined"]; 121cdf0e10cSrcweir if (isCustom == YES) { 122cdf0e10cSrcweir customAttribute = [[attributeDict objectForKey:@"meta:name"] retain]; 123cdf0e10cSrcweir //NSLog(customAttribute); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir //NSLog(@"start element %@", elementName); 128cdf0e10cSrcweir} 129cdf0e10cSrcweir 130cdf0e10cSrcweir- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 131cdf0e10cSrcweir{ 132cdf0e10cSrcweir// NSLog(@"</%@>", elementName); 133cdf0e10cSrcweir if (shouldReadCharacters == YES) { 134cdf0e10cSrcweir NSString *mdiName = nil; 135cdf0e10cSrcweir if (isCustom == YES) { 136cdf0e10cSrcweir mdiName = (NSString*)[metaXML2MDIKeys objectForKey:customAttribute]; 137cdf0e10cSrcweir } else { 138cdf0e10cSrcweir mdiName = (NSString*)[metaXML2MDIKeys objectForKey:elementName]; 139cdf0e10cSrcweir } 140cdf0e10cSrcweir //NSLog(@"mdiName: %@", mdiName); 141cdf0e10cSrcweir 142cdf0e10cSrcweir if (mdiName == nil) { 143cdf0e10cSrcweir return; 144cdf0e10cSrcweir } 145cdf0e10cSrcweir 146cdf0e10cSrcweir if ([singleValueXMLElements containsObject:elementName] == YES) { 147cdf0e10cSrcweir [metaValues setObject:textCurrentElement forKey:mdiName]; 148cdf0e10cSrcweir } else { 149cdf0e10cSrcweir // must be multi-value 150cdf0e10cSrcweir NSMutableArray *arr = [metaValues objectForKey:mdiName]; 151cdf0e10cSrcweir if (arr == nil) { 152cdf0e10cSrcweir // we have no array yet, create it 153cdf0e10cSrcweir arr = [[NSMutableArray new] autorelease]; 154cdf0e10cSrcweir // and store it 155cdf0e10cSrcweir [metaValues setObject:arr forKey:mdiName]; 156cdf0e10cSrcweir } 157cdf0e10cSrcweir // only store an element once, no need for duplicates 158cdf0e10cSrcweir if ([arr containsObject:textCurrentElement] == NO) { 159cdf0e10cSrcweir [arr addObject:textCurrentElement]; 160cdf0e10cSrcweir } 161cdf0e10cSrcweir } 162cdf0e10cSrcweir // cleanup part 1 163cdf0e10cSrcweir [textCurrentElement release]; 164cdf0e10cSrcweir if (customAttribute != nil) { 165cdf0e10cSrcweir [customAttribute release]; 166cdf0e10cSrcweir } 167cdf0e10cSrcweir } 168cdf0e10cSrcweir 169cdf0e10cSrcweir //cleanup part 2 170cdf0e10cSrcweir shouldReadCharacters = NO; 171cdf0e10cSrcweir isCustom = NO; 172cdf0e10cSrcweir} 173cdf0e10cSrcweir 174cdf0e10cSrcweir- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 175cdf0e10cSrcweir{ 176cdf0e10cSrcweir// NSLog(@"%@", string); 177cdf0e10cSrcweir if (shouldReadCharacters == NO) { 178cdf0e10cSrcweir return; 179cdf0e10cSrcweir } 180cdf0e10cSrcweir 181cdf0e10cSrcweir // this delegate method might be called several times for a single element, 182cdf0e10cSrcweir // so we have to collect the received data 183cdf0e10cSrcweir [textCurrentElement appendString:string]; 184cdf0e10cSrcweir 185cdf0e10cSrcweir //NSLog(@"chars read: %@", string); 186cdf0e10cSrcweir} 187cdf0e10cSrcweir 188cdf0e10cSrcweir- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError 189cdf0e10cSrcweir{ 190cdf0e10cSrcweir //NSLog(@"parsing finished with error"); 191cdf0e10cSrcweir NSLog([NSString stringWithFormat:@"Error %i, Description: %@, Line: %i, Column: %i", [parseError code], 192cdf0e10cSrcweir [[parser parserError] localizedDescription], [parser lineNumber], 193cdf0e10cSrcweir [parser columnNumber]]); 194cdf0e10cSrcweir} 195cdf0e10cSrcweir 196cdf0e10cSrcweir@end 197