/*!
@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