blob: dc4fbbeb63adbfdf722c307622414a52b1780d5c [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#import "OOoSpotlightImporter.h"
#import "OOoMetaDataParser.h"
#import "OOoContentDataParser.h"
#define CASESENSITIVITY (0)
#define BUFFER_SIZE (4096)
/* a dictionary to hold the UTIs */
static NSDictionary *uti2kind;
@implementation OOoSpotlightImporter
/* initialize is only called once the first time this class is loaded */
+ (void)initialize
{
static BOOL isInitialized = NO;
if (isInitialized == NO) {
NSMutableDictionary *temp = [NSMutableDictionary new];
[temp setObject:@"OpenOffice.org 1.0 Text" forKey:@"org.openoffice.text"];
[temp setObject:@"OpenDocument Text" forKey:@"org.oasis.opendocument.text"];
[temp setObject:@"OpenOffice.org 1.0 Spreadsheet" forKey:@"org.openoffice.spreadsheet"];
[temp setObject:@"OpenDocument Spreadsheet" forKey:@"org.oasis.opendocument.spreadsheet"];
[temp setObject:@"OpenOffice.org 1.0 Presentation" forKey:@"org.openoffice.presentation"];
[temp setObject:@"OpenDocument Presentation" forKey:@"org.oasis.opendocument.presentation"];
[temp setObject:@"OpenOffice.org 1.0 Drawing" forKey:@"org.openoffice.graphics"];
[temp setObject:@"OpenDocument Drawing" forKey:@"org.oasis.opendocument.graphics"];
[temp setObject:@"OpenOffice.org 1.0 Master" forKey:@"org.openoffice.text-master"];
[temp setObject:@"OpenDocument Master" forKey:@"org.oasis.opendocument.text-master"];
[temp setObject:@"OpenOffice.org 1.0 Formula" forKey:@"org.openoffice.formula"];
[temp setObject:@"OpenDocument Formula" forKey:@"org.oasis.opendocument.formula"];
[temp setObject:@"OpenOffice.org 1.0 Text Template" forKey:@"org.openoffice.text-template"];
[temp setObject:@"OpenDocument Text Template" forKey:@"org.oasis.opendocument.text-template"];
[temp setObject:@"OpenOffice.org 1.0 Spreadsheet Template" forKey:@"org.openoffice.spreadsheet-template"];
[temp setObject:@"OpenDocument Spreadsheet Template" forKey:@"org.oasis.opendocument.spreadsheet-template"];
[temp setObject:@"OpenOffice.org 1.0 Presentation Template" forKey:@"org.openoffice.presentation-template"];
[temp setObject:@"OpenDocument Presentation Template" forKey:@"org.oasis.opendocument.presentation-template"];
[temp setObject:@"OpenOffice.org 1.0 Drawing Template" forKey:@"org.openoffice.graphics-template"];
[temp setObject:@"OpenDocument Drawing Template" forKey:@"org.oasis.opendocument.graphics-template"];
[temp setObject:@"OpenOffice.org 1.0 Database" forKey:@"org.openoffice.database"];
[temp setObject:@"OpenDocument Chart" forKey:@"org.oasis.opendocument.chart"];
uti2kind = [[NSDictionary dictionaryWithDictionary:temp] retain];
[temp release];
isInitialized = YES;
}
}
/* importDocument is the real starting point for our plugin */
- (BOOL)importDocument:(NSString*)pathToFile contentType:(NSString*)contentTypeUTI attributes:(NSMutableDictionary*)attributes
{
//NSLog(contentTypeUTI);
//NSLog(pathToFile);
NSString *itemKind = [uti2kind objectForKey:contentTypeUTI];
if (itemKind != nil) {
[attributes setObject:itemKind forKey:(NSString*)kMDItemKind];
}
//first check to see if this is a valid zipped file that contains a file "meta.xml"
unzFile unzipFile = [self openZipFileAtPath:pathToFile];
//
if (unzipFile == nil) {
//NSLog(@"zip file not open");
return YES;
}
//first get the metadata
NSData *metaData = [self metaDataFileFromZip:unzipFile];
if (metaData == nil) {
unzClose(unzipFile);
return YES;
}
[metaData retain];
OOoMetaDataParser *parser = [OOoMetaDataParser new];
if (parser != nil) {
//parse and extract the data
[parser parseXML:metaData intoDictionary:attributes];
}
[metaData release];
[parser release];
//and now get the content
NSData *contentData = [self contentDataFileFromZip:unzipFile];
if (contentData == nil) {
unzClose(unzipFile);
return YES;
}
[contentData retain];
OOoContentDataParser *parser2 = [OOoContentDataParser new];
if (parser2 != nil) {
//parse and extract the data
[parser2 parseXML:contentData intoDictionary:attributes];
}
[contentData release];
[parser2 release];
unzClose(unzipFile);
return YES;
}
/* openZipFileAtPath returns the file as a valid data structure or nil otherwise*/
- (unzFile)openZipFileAtPath:(NSString*)pathToFile
{
unzFile unzipFile = nil;
const char *zipfilename = [pathToFile UTF8String];
if (zipfilename != nil)
{
unzipFile = unzOpen(zipfilename);
}
if (unzipFile == nil)
{
//NSLog(@"Cannot open %s",zipfilename);
return nil;
}
//NSLog(@"%s opened",zipfilename);
return unzipFile;
}
/* metaDataFileFromZip extracts the file meta.xml from the zip file and returns it as an NSData* structure
or nil if the metadata is not present */
- (NSData*) metaDataFileFromZip:(unzFile)unzipFile
{
//search and set the cursor to meta.xml
if (unzLocateFile(unzipFile, "meta.xml", CASESENSITIVITY) != UNZ_OK) {
//we hit an error, do cleanup
unzCloseCurrentFile(unzipFile);
return nil;
}
//open the current file
if (unzOpenCurrentFile(unzipFile) != UNZ_OK) {
//we hit an error, do cleanup
unzCloseCurrentFile(unzipFile);
unzClose(unzipFile);
return nil;
}
NSMutableData *data = [NSMutableData new];
unsigned buffer[BUFFER_SIZE];
int bytesRead = 0;
while ((bytesRead = unzReadCurrentFile(unzipFile, buffer, sizeof(buffer))) > 0) {
//append the data until we are finished
[data appendData:[NSData dataWithBytes:(const void *)buffer length:bytesRead]];
}
//we no longer need the file, so close it
unzCloseCurrentFile(unzipFile);
NSData *returnValue = [NSData dataWithData:data];
[data release];
return returnValue;
}
/* contentDataFileFromZip extracts the file content.xml from the zip file and returns it as an NSData* structure
or nil if the metadata is not present */
- (NSData*) contentDataFileFromZip:(unzFile)unzipFile
{
//search and set the cursor to content.xml
if (unzLocateFile(unzipFile, "content.xml", CASESENSITIVITY) != UNZ_OK) {
//we hit an error, do cleanup
unzCloseCurrentFile(unzipFile);
return nil;
}
//open the current file
if (unzOpenCurrentFile(unzipFile) != UNZ_OK) {
//we hit an error, do cleanup
unzCloseCurrentFile(unzipFile);
unzClose(unzipFile);
return nil;
}
NSMutableData *data = [NSMutableData new];
unsigned buffer[BUFFER_SIZE];
int bytesRead = 0;
while ((bytesRead = unzReadCurrentFile(unzipFile, buffer, sizeof(buffer))) > 0) {
//append the data
[data appendData:[NSData dataWithBytes:(const void *)buffer length:bytesRead]];
}
//we no longer need the file, so close it
unzCloseCurrentFile(unzipFile);
NSData *returnValue = [NSData dataWithData:data];
[data release];
return returnValue;
}
@end