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: OOoSpotlightImporter.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 "OOoSpotlightImporter.h"
32 #import "OOoMetaDataParser.h"
33 #import "OOoContentDataParser.h"
35 #define CASESENSITIVITY (0)
36 #define BUFFER_SIZE (4096)
38 /* a dictionary to hold the UTIs */
39 static NSDictionary *uti2kind;
41 @implementation OOoSpotlightImporter
43 /* initialize is only called once the first time this class is loaded */
46 static BOOL isInitialized = NO;
47 if (isInitialized == NO) {
48 NSMutableDictionary *temp = [NSMutableDictionary new];
49 [temp setObject:@"OpenOffice.org 1.0 Text" forKey:@"org.openoffice.text"];
50 [temp setObject:@"OpenDocument Text" forKey:@"org.oasis.opendocument.text"];
51 [temp setObject:@"OpenOffice.org 1.0 Spreadsheet" forKey:@"org.openoffice.spreadsheet"];
52 [temp setObject:@"OpenDocument Spreadsheet" forKey:@"org.oasis.opendocument.spreadsheet"];
53 [temp setObject:@"OpenOffice.org 1.0 Presentation" forKey:@"org.openoffice.presentation"];
54 [temp setObject:@"OpenDocument Presentation" forKey:@"org.oasis.opendocument.presentation"];
55 [temp setObject:@"OpenOffice.org 1.0 Drawing" forKey:@"org.openoffice.graphics"];
56 [temp setObject:@"OpenDocument Drawing" forKey:@"org.oasis.opendocument.graphics"];
57 [temp setObject:@"OpenOffice.org 1.0 Master" forKey:@"org.openoffice.text-master"];
58 [temp setObject:@"OpenDocument Master" forKey:@"org.oasis.opendocument.text-master"];
59 [temp setObject:@"OpenOffice.org 1.0 Formula" forKey:@"org.openoffice.formula"];
60 [temp setObject:@"OpenDocument Formula" forKey:@"org.oasis.opendocument.formula"];
61 [temp setObject:@"OpenOffice.org 1.0 Text Template" forKey:@"org.openoffice.text-template"];
62 [temp setObject:@"OpenDocument Text Template" forKey:@"org.oasis.opendocument.text-template"];
63 [temp setObject:@"OpenOffice.org 1.0 Spreadsheet Template" forKey:@"org.openoffice.spreadsheet-template"];
64 [temp setObject:@"OpenDocument Spreadsheet Template" forKey:@"org.oasis.opendocument.spreadsheet-template"];
65 [temp setObject:@"OpenOffice.org 1.0 Presentation Template" forKey:@"org.openoffice.presentation-template"];
66 [temp setObject:@"OpenDocument Presentation Template" forKey:@"org.oasis.opendocument.presentation-template"];
67 [temp setObject:@"OpenOffice.org 1.0 Drawing Template" forKey:@"org.openoffice.graphics-template"];
68 [temp setObject:@"OpenDocument Drawing Template" forKey:@"org.oasis.opendocument.graphics-template"];
69 [temp setObject:@"OpenOffice.org 1.0 Database" forKey:@"org.openoffice.database"];
70 [temp setObject:@"OpenDocument Chart" forKey:@"org.oasis.opendocument.chart"];
72 uti2kind = [[NSDictionary dictionaryWithDictionary:temp] retain];
79 /* importDocument is the real starting point for our plugin */
80 - (BOOL)importDocument:(NSString*)pathToFile contentType:(NSString*)contentTypeUTI attributes:(NSMutableDictionary*)attributes
82 //NSLog(contentTypeUTI);
85 NSString *itemKind = [uti2kind objectForKey:contentTypeUTI];
86 if (itemKind != nil) {
87 [attributes setObject:itemKind forKey:(NSString*)kMDItemKind];
90 //first check to see if this is a valid zipped file that contains a file "meta.xml"
91 unzFile unzipFile = [self openZipFileAtPath:pathToFile];
94 if (unzipFile == nil) {
95 //NSLog(@"zip file not open");
99 //first get the metadata
100 NSData *metaData = [self metaDataFileFromZip:unzipFile];
101 if (metaData == nil) {
108 OOoMetaDataParser *parser = [OOoMetaDataParser new];
110 //parse and extract the data
111 [parser parseXML:metaData intoDictionary:attributes];
117 //and now get the content
118 NSData *contentData = [self contentDataFileFromZip:unzipFile];
119 if (contentData == nil) {
124 [contentData retain];
126 OOoContentDataParser *parser2 = [OOoContentDataParser new];
127 if (parser2 != nil) {
128 //parse and extract the data
129 [parser2 parseXML:contentData intoDictionary:attributes];
132 [contentData release];
140 /* openZipFileAtPath returns the file as a valid data structure or nil otherwise*/
141 - (unzFile)openZipFileAtPath:(NSString*)pathToFile
143 unzFile unzipFile = nil;
145 const char *zipfilename = [pathToFile UTF8String];
147 if (zipfilename != nil)
149 unzipFile = unzOpen(zipfilename);
152 if (unzipFile == nil)
154 //NSLog(@"Cannot open %s",zipfilename);
158 //NSLog(@"%s opened",zipfilename);
163 /* metaDataFileFromZip extracts the file meta.xml from the zip file and returns it as an NSData* structure
164 or nil if the metadata is not present */
165 - (NSData*) metaDataFileFromZip:(unzFile)unzipFile
167 //search and set the cursor to meta.xml
168 if (unzLocateFile(unzipFile, "meta.xml", CASESENSITIVITY) != UNZ_OK) {
169 //we hit an error, do cleanup
170 unzCloseCurrentFile(unzipFile);
174 //open the current file
175 if (unzOpenCurrentFile(unzipFile) != UNZ_OK) {
176 //we hit an error, do cleanup
177 unzCloseCurrentFile(unzipFile);
182 NSMutableData *data = [NSMutableData new];
184 unsigned buffer[BUFFER_SIZE];
186 while ((bytesRead = unzReadCurrentFile(unzipFile, buffer, sizeof(buffer))) > 0) {
187 //append the data until we are finished
188 [data appendData:[NSData dataWithBytes:(const void *)buffer length:bytesRead]];
191 //we no longer need the file, so close it
192 unzCloseCurrentFile(unzipFile);
194 NSData *returnValue = [NSData dataWithData:data];
200 /* contentDataFileFromZip extracts the file content.xml from the zip file and returns it as an NSData* structure
201 or nil if the metadata is not present */
202 - (NSData*) contentDataFileFromZip:(unzFile)unzipFile
204 //search and set the cursor to content.xml
205 if (unzLocateFile(unzipFile, "content.xml", CASESENSITIVITY) != UNZ_OK) {
206 //we hit an error, do cleanup
207 unzCloseCurrentFile(unzipFile);
211 //open the current file
212 if (unzOpenCurrentFile(unzipFile) != UNZ_OK) {
213 //we hit an error, do cleanup
214 unzCloseCurrentFile(unzipFile);
219 NSMutableData *data = [NSMutableData new];
221 unsigned buffer[BUFFER_SIZE];
223 while ((bytesRead = unzReadCurrentFile(unzipFile, buffer, sizeof(buffer))) > 0) {
225 [data appendData:[NSData dataWithBytes:(const void *)buffer length:bytesRead]];
228 //we no longer need the file, so close it
229 unzCloseCurrentFile(unzipFile);
231 NSData *returnValue = [NSData dataWithData:data];