/*! @header FTImportDefaultXMLRule @abstract Module of FT @availability OS X, GNUstep @copyright 2004, 2005, 2006 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  -------------------------------------------------------------------------
  Modification history

  05.08.06 ola     initial version
  23.08.06 ola     license changed
  -------------------------------------------------------------------------
  
*/ #include #include #define __nr_bundled_transactions 10 @implementation FTImportDefaultXMLRule - initForImport: (FTImport *) anImport { self = [super init]; self->import = [anImport retain]; self->graph = nil; self->graphObjectToIdMapper = nil; self->currentNodeId = nil; self->currentServiceNodeId = nil; return self; } - (void) dealloc { [self->import release]; [self releaseResources]; [self->currentNodeId release]; [self->currentServiceNodeId release]; [super dealloc]; } - addGraphForEvent: (ECXMLControlContext *) context { NSMutableDictionary *attributes; NSString *doCreateGraphEntry; BOOL doCreateGraph = NO; id defaultObjectToIdMapper; id graphManager; id graphId; id transaction; if( nil != self->graph ) { return self; } if( [[FTImport log] isTraceEnabled] ) { [[FTImport log] trace: @"FTImportDefaultXMLRule::addGraph"]; } EC_AUTORELEASEPOOL_BEGIN attributes = [[context event] attributes]; doCreateGraphEntry = [self attribute: @"createGraph" withinContext: context]; if( nil != doCreateGraphEntry ) { if( NSOrderedSame == [doCreateGraphEntry caseInsensitiveCompare: @"YES"] ) { doCreateGraph = YES; } } defaultObjectToIdMapper = [[self->import session] defaultObjectToIdMapper]; graphManager = [[self->import session] graphManager]; transaction = [[self->import session] beginTransactionWithParent: nil withSettings: nil]; graphId = [defaultObjectToIdMapper mapObject: [self->import targetGraphName]]; if( YES == doCreateGraph ) { if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addGraphForEvent: "\ "Creating graph %@...", [import targetGraphName]]; } self->graph = [[graphManager createGraphWithId: graphId] retain]; if( nil == self->graph ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addGraphForEvent:"\ "Graph could NOT be created!"]; } else { if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addGraphForEvent: "\ "Graph created!"]; } } } else { if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addGraphForEvent: "\ "Loading graph %@...", [import targetGraphName]]; } self->graph = [[graphManager graphWithId: graphId] retain]; if( nil == self->graph ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addGraphForEvent:"\ "Graph could NOT be loaded!"]; } else { if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addGraphForEvent: "\ "Graph created!"]; } } } self->graphObjectToIdMapper = [[self->graph objectToIdMapper] retain]; [transaction commit]; EC_AUTORELEASEPOOL_END return self; } - addNodeIdForEvent: (ECXMLControlContext *) context { NSString *nodeIdString; if( [[FTImport log] isTraceEnabled] ) { [[FTImport log] trace: @"FTImportDefaultXMLRule::addNodeId"]; } if( nil == self->graph ) { return self; } nodeIdString = [self attribute: @"nodeId" withinContext: context]; if( nil == nodeIdString ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addNodeIdForEvent: "\ "nodeId not specified for node: %@", [[context event] elementName]]; return self; } EC_AUTORELEASEPOOL_BEGIN id transaction; id nodeId; if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addNodeIdForEvent: "\ "adding node with id=%@", nodeIdString]; } transaction = [[self->import session] beginTransactionWithParent: nil withSettings: nil]; nodeId = [self->graphObjectToIdMapper mapObject: nodeIdString]; [self->graph createNodeWithId: nodeId]; [transaction commit]; EC_AUTORELEASEPOOL_END return self; } - addNodeReference: (ECXMLControlContext *) context { NSString *targetNodeIdString; NSString *edgeIdString; if( [[FTImport log] isTraceEnabled] ) { [[FTImport log] trace: @"FTImportDefaultXMLRule::addNodeReference"]; } if( nil == self->graph ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addNodeReference:"\ "No graph open!"]; return self; } if( nil == self->currentNodeId ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addNodeReference:"\ "No current node given!"]; return self; } targetNodeIdString = [self attribute: @"targetNodeId" withinContext: context]; edgeIdString = [self attribute: @"edgeId" withinContext: context]; if( nil == targetNodeIdString ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addNodeReference: "\ "targetNodeId not specified for node: %@", self->currentNodeId]; return self; } if( nil == edgeIdString ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addNodeReference: "\ "edgeId not specified for node: %@", self->currentNodeId]; return self; } EC_AUTORELEASEPOOL_BEGIN id transaction; id srcNodeId; id targetNodeId; id edgeId; id srcNode, targetNode; if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addNodeReference: "\ "adding reference from=%@ to=%@ with edgeId=%@", self->currentNodeId, targetNodeIdString, edgeIdString]; } transaction = [[self->import session] beginTransactionWithParent: nil withSettings: nil]; srcNodeId = [self->graphObjectToIdMapper mapObject: self->currentNodeId]; targetNodeId = [self->graphObjectToIdMapper mapObject: targetNodeIdString]; edgeId = [self->graphObjectToIdMapper mapObject: edgeIdString]; srcNode = [self->graph nodeWithId: srcNodeId]; targetNode = [self->graph nodeWithId: targetNodeId]; if( nil == srcNode ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addNodeReference: "\ "Source node with id=%@ could not be found!", self->currentNodeId]; [transaction abort]; EC_AUTORELEASEPOOL_RELEASE; return self; } if( nil == targetNode ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addNodeReference: "\ "Target node with id=%@ could not be found!", targetNodeId ]; [transaction abort]; EC_AUTORELEASEPOOL_RELEASE; return self; } [srcNode createAndAppendEdgeWithId: edgeId withTargetNode: targetNode]; [transaction commit]; EC_AUTORELEASEPOOL_END return self; } - addNodeReferenceList: (ECXMLControlContext *) context { if( [[FTImport log] isTraceEnabled] ) { [[FTImport log] trace: @"FTImportDefaultXMLRule::addNodeReferenceList"]; } if( nil == self->graph ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addNodeReferenceList:"\ " No graph opened!" ]; return self; } if( nil != self->currentNodeId ) { [self->currentNodeId release]; self->currentNodeId = nil; } self->currentNodeId = [[self attribute: @"ofNodeId" withinContext: context] retain]; if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addNodeReferenceList:"\ "Examining references of nodeId=%@", self->currentNodeId ]; } return self; } - addServiceData: (ECXMLControlContext *) context { if( [[FTImport log] isTraceEnabled] ) { [[FTImport log] trace: @"FTImportDefaultXMLRule::addServiceData"]; } if( nil == self->graph ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceData:"\ " No graph opened!" ]; return self; } if( nil != self->currentServiceNodeId ) { [self->currentServiceNodeId release]; self->currentServiceNodeId = nil; } self->currentServiceNodeId = [[self attribute: @"nodeId" withinContext: context] retain]; if( nil == self->currentServiceNodeId) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceData: target node id not "\ "given"]; } else { if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addServiceData:"\ "Examining service data of nodeId=%@", self->currentServiceNodeId ]; } } return self; } - addServiceDataItem: (ECXMLControlContext *) context { NSString *serviceName; NSString *fileName; if( [[FTImport log] isTraceEnabled] ) { [[FTImport log] trace: @"FTImportDefaultXMLRule::addServiceDataItem"]; } if( nil == self->graph ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem:"\ " No graph opened!" ]; return self; } if( nil == self->currentServiceNodeId ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem: No target node id "\ "set. Ignoring current data item!"]; return self; } serviceName = [self attribute: @"forService" withinContext: context]; if( nil == serviceName ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem: No service "\ "name set. Ignoring current data item!"]; return self; } fileName = [self attribute: @"file" withinContext: context]; if( nil == fileName ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem: No file name "\ "set. Ignoring current data item!"]; return self; } EC_AUTORELEASEPOOL_BEGIN id transaction; id targetNodeId; id targetNode; id service; NSString *filePath; NSData *fileContent; NSString *key; NSKeyedUnarchiver *unarchiver; id content; if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addServiceDataItem: "\ "adding file with name=%@ to node with id=%@", fileName, self->currentServiceNodeId]; } transaction = [[self->import session] beginTransactionWithParent: nil withSettings: nil]; targetNodeId = [self->graphObjectToIdMapper mapObject: self->currentServiceNodeId]; targetNode = [self->graph nodeWithId: targetNodeId]; if( nil == targetNode ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem: "\ "Target node with id=%@ could not be found!", targetNodeId ]; [transaction abort]; EC_AUTORELEASEPOOL_RELEASE; return self; } service = (id ) [targetNode serviceWithId: serviceName]; if( nil == service ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem: "\ "Unable to get service with name=%@", serviceName]; [transaction abort]; EC_AUTORELEASEPOOL_RELEASE; return self; } filePath = [[[NSString alloc] initWithFormat: @"%@/%@", [self->import sourceBaseDirectory], fileName] autorelease]; if( ![[NSFileManager defaultManager] fileExistsAtPath: filePath] ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem: "\ "file does not exist: %@", filePath ]; [transaction abort]; EC_AUTORELEASEPOOL_RELEASE; return self; } fileContent = [NSData dataWithContentsOfFile: filePath]; if( nil == fileContent ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem: "\ "Unable to read content from file: %@", filePath ]; [transaction abort]; EC_AUTORELEASEPOOL_RELEASE; return self; } unarchiver = [[[NSKeyedUnarchiver alloc] initForReadingWithData: fileContent] autorelease]; key = [unarchiver decodeObjectForKey: @"key"]; if( nil == key ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem: "\ "Data file is corrupt. Unable to fetch KEY"]; [unarchiver finishDecoding]; [transaction abort]; EC_AUTORELEASEPOOL_RELEASE; return self; } content = [unarchiver decodeObjectForKey: @"value"]; if( nil == content ) { [[FTImport log] error: @"FTImportDefaultXMLRule::addServiceDataItem: "\ "Data file is corrupt. Unable to fetch content for key=value"]; [unarchiver finishDecoding]; [transaction abort]; EC_AUTORELEASEPOOL_RELEASE; return self; } [service setObject: content forKey: key]; if( [[FTImport log] isDebugEnabled] ) { [[FTImport log] debug: @"FTImportDefaultXMLRule::addServiceDataItem: "\ "adding content for key=%@ to dictionary of node with id=%@", key, self->currentServiceNodeId]; } [transaction commit]; [unarchiver finishDecoding]; EC_AUTORELEASEPOOL_END return self; } - (NSString *) attribute: (NSString *) attributeName withinContext: (ECXMLControlContext *) context { NSMutableDictionary *attributes; attributes = [[context event] attributes]; return [attributes objectForKey: attributeName]; } - (void) releaseResources { [self->currentNodeId release]; self->currentNodeId = nil; [self->graphObjectToIdMapper release]; [self->graph close]; [self->graph release]; self->graph = nil; } @end