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