1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: OOoMetaDataParser.m,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 *************************************************************************/
31 #import "OOoMetaDataParser.h"
33 static NSSet *singleValueXMLElements;
34 static NSSet *multiValueXMLElements;
35 static NSDictionary *metaXML2MDIKeys;
37 @implementation OOoMetaDataParser
41 static BOOL isInitialized = NO;
43 if (isInitialized == NO) {
44 //set up the meta elements with only one value
45 NSMutableSet *temp = [NSMutableSet new];
46 [temp addObject:@"dc:title"];
47 [temp addObject:@"dc:description"];
48 [temp addObject:@"meta:user-defined"];
49 singleValueXMLElements = [[NSSet setWithSet:temp] retain];
51 //set up the meta elements that can have more than one value
52 [temp removeAllObjects];
53 [temp addObject:@"dc:subject"];
54 [temp addObject:@"meta:keyword"];
55 [temp addObject:@"meta:initial-creator"];
56 [temp addObject:@"dc:creator"];
57 multiValueXMLElements = [[NSSet setWithSet:temp] retain];
60 //set up the map to store the values with the correct MDI keys
61 NSMutableDictionary *tempDict = [NSMutableDictionary new];
62 [tempDict setObject:(NSString*)kMDItemTitle forKey:@"dc:title"];
63 [tempDict setObject:(NSString*)kMDItemDescription forKey:@"dc:description"];
64 [tempDict setObject:(NSString*)kMDItemKeywords forKey:@"dc:subject"];
65 [tempDict setObject:(NSString*)kMDItemAuthors forKey:@"meta:initial-creator"];
66 [tempDict setObject:(NSString*)kMDItemAuthors forKey:@"dc:creator"];
67 [tempDict setObject:(NSString*)kMDItemKeywords forKey:@"meta:keyword"];
68 [tempDict setObject:@"org_openoffice_opendocument_custominfo1" forKey:@"Info 1"];
69 [tempDict setObject:@"org_openoffice_opendocument_custominfo2" forKey:@"Info 2"];
70 [tempDict setObject:@"org_openoffice_opendocument_custominfo3" forKey:@"Info 3"];
71 [tempDict setObject:@"org_openoffice_opendocument_custominfo4" forKey:@"Info 4"];
72 metaXML2MDIKeys = [[NSDictionary dictionaryWithDictionary:tempDict] retain];
81 if ((self = [super init]) != nil) {
82 shouldReadCharacters = NO;
83 // currentElement = nil;
84 textCurrentElement = nil;
92 - (void)parseXML:(NSData*)data intoDictionary:(NSMutableDictionary*)dict
96 //NSLog(@"data: %@ %d", data, [data length]);
98 //init parser settings
99 shouldReadCharacters = NO;
101 NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
103 [parser setDelegate:self];
104 [parser setShouldResolveExternalEntities:NO];
109 //NSLog(@"finished parsing meta");
112 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
114 // NSLog(@"<%@>", elementName);
115 if ([singleValueXMLElements containsObject:elementName] == YES) {
116 shouldReadCharacters = YES;
117 } else if ([multiValueXMLElements containsObject:elementName] == YES) {
118 shouldReadCharacters = YES;
120 //we are not interested in this element
121 shouldReadCharacters = NO;
125 if (shouldReadCharacters == YES) {
126 textCurrentElement = [NSMutableString new];
127 isCustom = [elementName isEqualToString:@"meta:user-defined"];
128 if (isCustom == YES) {
129 customAttribute = [[attributeDict objectForKey:@"meta:name"] retain];
130 //NSLog(customAttribute);
134 //NSLog(@"start element %@", elementName);
137 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
139 // NSLog(@"</%@>", elementName);
140 if (shouldReadCharacters == YES) {
141 NSString *mdiName = nil;
142 if (isCustom == YES) {
143 mdiName = (NSString*)[metaXML2MDIKeys objectForKey:customAttribute];
145 mdiName = (NSString*)[metaXML2MDIKeys objectForKey:elementName];
147 //NSLog(@"mdiName: %@", mdiName);
149 if (mdiName == nil) {
153 if ([singleValueXMLElements containsObject:elementName] == YES) {
154 [metaValues setObject:textCurrentElement forKey:mdiName];
156 // must be multi-value
157 NSMutableArray *arr = [metaValues objectForKey:mdiName];
159 // we have no array yet, create it
160 arr = [[NSMutableArray new] autorelease];
162 [metaValues setObject:arr forKey:mdiName];
164 // only store an element once, no need for duplicates
165 if ([arr containsObject:textCurrentElement] == NO) {
166 [arr addObject:textCurrentElement];
170 [textCurrentElement release];
171 if (customAttribute != nil) {
172 [customAttribute release];
177 shouldReadCharacters = NO;
181 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
183 // NSLog(@"%@", string);
184 if (shouldReadCharacters == NO) {
188 // this delegate method might be called several times for a single element,
189 // so we have to collect the received data
190 [textCurrentElement appendString:string];
192 //NSLog(@"chars read: %@", string);
195 - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
197 //NSLog(@"parsing finished with error");
198 NSLog([NSString stringWithFormat:@"Error %i, Description: %@, Line: %i, Column: %i", [parseError code],
199 [[parser parserError] localizedDescription], [parser lineNumber],
200 [parser columnNumber]]);