merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / macosx / spotlight / OOoMetaDataParser.m
blobcddbbd1309e12a5e2a97ce7d84a34555595764ef
1 /*************************************************************************
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  * 
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26 *************************************************************************/
28 #import "OOoMetaDataParser.h"
30 static NSSet *singleValueXMLElements;
31 static NSSet *multiValueXMLElements;
32 static NSDictionary *metaXML2MDIKeys;
34 @implementation OOoMetaDataParser
36 + (void)initialize
38     static BOOL isInitialized = NO;
39     
40     if (isInitialized == NO) {
41         //set up the meta elements with only one value
42         NSMutableSet *temp = [NSMutableSet new];
43         [temp addObject:@"dc:title"];
44         [temp addObject:@"dc:description"];
45         [temp addObject:@"meta:user-defined"];
46         singleValueXMLElements = [[NSSet setWithSet:temp] retain];
47         
48         //set up the meta elements that can have more than one value
49         [temp removeAllObjects];
50         [temp addObject:@"dc:subject"];
51         [temp addObject:@"meta:keyword"];
52         [temp addObject:@"meta:initial-creator"];
53         [temp addObject:@"dc:creator"];
54         multiValueXMLElements = [[NSSet setWithSet:temp] retain];
55         [temp release];
56         
57         //set up the map to store the values with the correct MDI keys
58         NSMutableDictionary *tempDict = [NSMutableDictionary new];
59         [tempDict setObject:(NSString*)kMDItemTitle forKey:@"dc:title"];
60         [tempDict setObject:(NSString*)kMDItemDescription forKey:@"dc:description"];
61         [tempDict setObject:(NSString*)kMDItemKeywords forKey:@"dc:subject"];
62         [tempDict setObject:(NSString*)kMDItemAuthors forKey:@"meta:initial-creator"];
63         [tempDict setObject:(NSString*)kMDItemAuthors forKey:@"dc:creator"];
64         [tempDict setObject:(NSString*)kMDItemKeywords forKey:@"meta:keyword"];
65         [tempDict setObject:@"org_openoffice_opendocument_custominfo1" forKey:@"Info 1"];
66         [tempDict setObject:@"org_openoffice_opendocument_custominfo2" forKey:@"Info 2"];
67         [tempDict setObject:@"org_openoffice_opendocument_custominfo3" forKey:@"Info 3"];
68         [tempDict setObject:@"org_openoffice_opendocument_custominfo4" forKey:@"Info 4"];
69         metaXML2MDIKeys = [[NSDictionary dictionaryWithDictionary:tempDict] retain];
70         [tempDict release];
71         
72         isInitialized = YES;
73     }
76 - (id)init
78     if ((self = [super init]) != nil) {
79         shouldReadCharacters = NO;
80 //        currentElement = nil;
81         textCurrentElement = nil;
82         
83         return self;
84     }
85     
86     return nil;
89 - (void)parseXML:(NSData*)data intoDictionary:(NSMutableDictionary*)dict
91     metaValues = dict;
92     
93     //NSLog(@"data: %@ %d", data, [data length]);
94         
95     //init parser settings
96     shouldReadCharacters = NO;
97     
98     NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
99     
100     [parser setDelegate:self];
101     [parser setShouldResolveExternalEntities:NO];
102     [parser parse];
103     
104     [parser release];
105     
106     //NSLog(@"finished parsing meta");
109 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
111 //    NSLog(@"<%@>", elementName);
112     if ([singleValueXMLElements containsObject:elementName] == YES) {
113         shouldReadCharacters = YES;
114     } else if ([multiValueXMLElements containsObject:elementName] == YES) {
115         shouldReadCharacters = YES;
116     } else {
117         //we are not interested in this element
118         shouldReadCharacters = NO;
119         return;
120     }
121     
122     if (shouldReadCharacters == YES) {
123         textCurrentElement = [NSMutableString new];
124         isCustom = [elementName isEqualToString:@"meta:user-defined"];
125         if (isCustom == YES) {
126             customAttribute = [[attributeDict objectForKey:@"meta:name"] retain];
127             //NSLog(customAttribute);
128         }
129     }
131     //NSLog(@"start element %@", elementName);
134 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
136 //    NSLog(@"</%@>", elementName);
137     if (shouldReadCharacters == YES) {
138         NSString *mdiName = nil;
139         if (isCustom == YES) {
140             mdiName = (NSString*)[metaXML2MDIKeys objectForKey:customAttribute];
141         } else {
142             mdiName = (NSString*)[metaXML2MDIKeys objectForKey:elementName];
143         }
144         //NSLog(@"mdiName: %@", mdiName);
145         
146         if (mdiName == nil) {
147             return;
148         }
149         
150         if ([singleValueXMLElements containsObject:elementName] == YES) {
151             [metaValues setObject:textCurrentElement forKey:mdiName];
152         } else {
153             // must be multi-value
154             NSMutableArray *arr = [metaValues objectForKey:mdiName];
155             if (arr == nil) {
156                 // we have no array yet, create it
157                 arr = [[NSMutableArray new] autorelease];
158                 // and store it
159                 [metaValues setObject:arr forKey:mdiName];
160             }
161             // only store an element once, no need for duplicates
162             if ([arr containsObject:textCurrentElement] == NO) {
163                 [arr addObject:textCurrentElement];
164             }
165         }
166         // cleanup part 1
167         [textCurrentElement release];
168         if (customAttribute != nil) {
169             [customAttribute release];
170         }
171     }
172     
173     //cleanup part 2
174     shouldReadCharacters = NO;
175     isCustom = NO;
178 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
180 //    NSLog(@"%@", string);
181     if (shouldReadCharacters == NO) {
182         return;
183     }
184     
185     // this delegate method might be called several times for a single element, 
186     // so we have to collect the received data
187     [textCurrentElement appendString:string];
188     
189     //NSLog(@"chars read: %@", string);
192 - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
194     //NSLog(@"parsing finished with error");
195     NSLog([NSString stringWithFormat:@"Error %i, Description: %@, Line: %i, Column: %i", [parseError code], 
196         [[parser parserError] localizedDescription], [parser lineNumber],
197         [parser columnNumber]]);
200 @end