1/************************************************************************* 2* 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*************************************************************************/ 27 28#import "OOoSpotlightImporter.h" 29#import "OOoMetaDataParser.h" 30#import "OOoContentDataParser.h" 31 32#define CASESENSITIVITY (0) 33#define BUFFER_SIZE (4096) 34 35/* a dictionary to hold the UTIs */ 36static NSDictionary *uti2kind; 37 38@implementation OOoSpotlightImporter 39 40/* initialize is only called once the first time this class is loaded */ 41+ (void)initialize 42{ 43 static BOOL isInitialized = NO; 44 if (isInitialized == NO) { 45 NSMutableDictionary *temp = [NSMutableDictionary new]; 46 [temp setObject:@"OpenOffice.org 1.0 Text" forKey:@"org.openoffice.text"]; 47 [temp setObject:@"OpenDocument Text" forKey:@"org.oasis.opendocument.text"]; 48 [temp setObject:@"OpenOffice.org 1.0 Spreadsheet" forKey:@"org.openoffice.spreadsheet"]; 49 [temp setObject:@"OpenDocument Spreadsheet" forKey:@"org.oasis.opendocument.spreadsheet"]; 50 [temp setObject:@"OpenOffice.org 1.0 Presentation" forKey:@"org.openoffice.presentation"]; 51 [temp setObject:@"OpenDocument Presentation" forKey:@"org.oasis.opendocument.presentation"]; 52 [temp setObject:@"OpenOffice.org 1.0 Drawing" forKey:@"org.openoffice.graphics"]; 53 [temp setObject:@"OpenDocument Drawing" forKey:@"org.oasis.opendocument.graphics"]; 54 [temp setObject:@"OpenOffice.org 1.0 Master" forKey:@"org.openoffice.text-master"]; 55 [temp setObject:@"OpenDocument Master" forKey:@"org.oasis.opendocument.text-master"]; 56 [temp setObject:@"OpenOffice.org 1.0 Formula" forKey:@"org.openoffice.formula"]; 57 [temp setObject:@"OpenDocument Formula" forKey:@"org.oasis.opendocument.formula"]; 58 [temp setObject:@"OpenOffice.org 1.0 Text Template" forKey:@"org.openoffice.text-template"]; 59 [temp setObject:@"OpenDocument Text Template" forKey:@"org.oasis.opendocument.text-template"]; 60 [temp setObject:@"OpenOffice.org 1.0 Spreadsheet Template" forKey:@"org.openoffice.spreadsheet-template"]; 61 [temp setObject:@"OpenDocument Spreadsheet Template" forKey:@"org.oasis.opendocument.spreadsheet-template"]; 62 [temp setObject:@"OpenOffice.org 1.0 Presentation Template" forKey:@"org.openoffice.presentation-template"]; 63 [temp setObject:@"OpenDocument Presentation Template" forKey:@"org.oasis.opendocument.presentation-template"]; 64 [temp setObject:@"OpenOffice.org 1.0 Drawing Template" forKey:@"org.openoffice.graphics-template"]; 65 [temp setObject:@"OpenDocument Drawing Template" forKey:@"org.oasis.opendocument.graphics-template"]; 66 [temp setObject:@"OpenOffice.org 1.0 Database" forKey:@"org.openoffice.database"]; 67 [temp setObject:@"OpenDocument Chart" forKey:@"org.oasis.opendocument.chart"]; 68 69 uti2kind = [[NSDictionary dictionaryWithDictionary:temp] retain]; 70 [temp release]; 71 72 isInitialized = YES; 73 } 74} 75 76/* importDocument is the real starting point for our plugin */ 77- (BOOL)importDocument:(NSString*)pathToFile contentType:(NSString*)contentTypeUTI attributes:(NSMutableDictionary*)attributes 78{ 79 //NSLog(contentTypeUTI); 80 //NSLog(pathToFile); 81 82 NSString *itemKind = [uti2kind objectForKey:contentTypeUTI]; 83 if (itemKind != nil) { 84 [attributes setObject:itemKind forKey:(NSString*)kMDItemKind]; 85 } 86 87 //first check to see if this is a valid zipped file that contains a file "meta.xml" 88 unzFile unzipFile = [self openZipFileAtPath:pathToFile]; 89 90 // 91 if (unzipFile == nil) { 92 //NSLog(@"zip file not open"); 93 return YES; 94 } 95 96 //first get the metadata 97 NSData *metaData = [self metaDataFileFromZip:unzipFile]; 98 if (metaData == nil) { 99 unzClose(unzipFile); 100 return YES; 101 } 102 103 [metaData retain]; 104 105 OOoMetaDataParser *parser = [OOoMetaDataParser new]; 106 if (parser != nil) { 107 //parse and extract the data 108 [parser parseXML:metaData intoDictionary:attributes]; 109 } 110 111 [metaData release]; 112 [parser release]; 113 114 //and now get the content 115 NSData *contentData = [self contentDataFileFromZip:unzipFile]; 116 if (contentData == nil) { 117 unzClose(unzipFile); 118 return YES; 119 } 120 121 [contentData retain]; 122 123 OOoContentDataParser *parser2 = [OOoContentDataParser new]; 124 if (parser2 != nil) { 125 //parse and extract the data 126 [parser2 parseXML:contentData intoDictionary:attributes]; 127 } 128 129 [contentData release]; 130 [parser2 release]; 131 132 unzClose(unzipFile); 133 134 return YES; 135} 136 137/* openZipFileAtPath returns the file as a valid data structure or nil otherwise*/ 138- (unzFile)openZipFileAtPath:(NSString*)pathToFile 139{ 140 unzFile unzipFile = nil; 141 142 const char *zipfilename = [pathToFile UTF8String]; 143 144 if (zipfilename != nil) 145 { 146 unzipFile = unzOpen(zipfilename); 147 } 148 149 if (unzipFile == nil) 150 { 151 //NSLog(@"Cannot open %s",zipfilename); 152 return nil; 153 } 154 155 //NSLog(@"%s opened",zipfilename); 156 157 return unzipFile; 158} 159 160/* metaDataFileFromZip extracts the file meta.xml from the zip file and returns it as an NSData* structure 161 or nil if the metadata is not present */ 162- (NSData*) metaDataFileFromZip:(unzFile)unzipFile 163{ 164 //search and set the cursor to meta.xml 165 if (unzLocateFile(unzipFile, "meta.xml", CASESENSITIVITY) != UNZ_OK) { 166 //we hit an error, do cleanup 167 unzCloseCurrentFile(unzipFile); 168 return nil; 169 } 170 171 //open the current file 172 if (unzOpenCurrentFile(unzipFile) != UNZ_OK) { 173 //we hit an error, do cleanup 174 unzCloseCurrentFile(unzipFile); 175 unzClose(unzipFile); 176 return nil; 177 } 178 179 NSMutableData *data = [NSMutableData new]; 180 181 unsigned buffer[BUFFER_SIZE]; 182 int bytesRead = 0; 183 while ((bytesRead = unzReadCurrentFile(unzipFile, buffer, sizeof(buffer))) > 0) { 184 //append the data until we are finished 185 [data appendData:[NSData dataWithBytes:(const void *)buffer length:bytesRead]]; 186 } 187 188 //we no longer need the file, so close it 189 unzCloseCurrentFile(unzipFile); 190 191 NSData *returnValue = [NSData dataWithData:data]; 192 [data release]; 193 194 return returnValue; 195} 196 197/* contentDataFileFromZip extracts the file content.xml from the zip file and returns it as an NSData* structure 198 or nil if the metadata is not present */ 199- (NSData*) contentDataFileFromZip:(unzFile)unzipFile 200{ 201 //search and set the cursor to content.xml 202 if (unzLocateFile(unzipFile, "content.xml", CASESENSITIVITY) != UNZ_OK) { 203 //we hit an error, do cleanup 204 unzCloseCurrentFile(unzipFile); 205 return nil; 206 } 207 208 //open the current file 209 if (unzOpenCurrentFile(unzipFile) != UNZ_OK) { 210 //we hit an error, do cleanup 211 unzCloseCurrentFile(unzipFile); 212 unzClose(unzipFile); 213 return nil; 214 } 215 216 NSMutableData *data = [NSMutableData new]; 217 218 unsigned buffer[BUFFER_SIZE]; 219 int bytesRead = 0; 220 while ((bytesRead = unzReadCurrentFile(unzipFile, buffer, sizeof(buffer))) > 0) { 221 //append the data 222 [data appendData:[NSData dataWithBytes:(const void *)buffer length:bytesRead]]; 223 } 224 225 //we no longer need the file, so close it 226 unzCloseCurrentFile(unzipFile); 227 228 NSData *returnValue = [NSData dataWithData:data]; 229 [data release]; 230 231 return returnValue; 232} 233 234 235@end 236