diff -r 000000000000 -r 2e3d3ce01487 contextframework/cfw/src/basicoperationsplugin/cfclausenode.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contextframework/cfw/src/basicoperationsplugin/cfclausenode.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,477 @@ +/* +* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CCFClauseNode class implementation. +* +*/ + + + +// INCLUDES +#include "cfclausenode.h" +#include "cfscriptaction.h" +#include "cfnotifyaction.h" +#include "cfpublishcontextaction.h" +#include "cfsourcecommandaction.h" +#include "cfbasicoptrace.h" + +#include +#include +#include +#include +#include +#include +#include + +// CONSTANTS +_LIT( KScriptActionsName, "actions" ); + +_LIT( KScriptPublishContextName, "publishContext" ); +_LIT( KScriptDefineName, "define" ); +_LIT( KScriptTrueName, "true" ); +_LIT( KScriptContextRefName, "contextRef" ); +_LIT( KScriptSourceAttribute, "source" ); +_LIT( KScriptTypeAttribute, "type" ); +_LIT( KScriptValueAttribute, "value" ); +_LIT( KScriptSourceCommandActionName, "sourceCommand" ); + +// ======== LOCAL FUNCTIONS ======== + +// Cleans up RKeyValueArray instance. +LOCAL_C void CleanupKeyValueArray( TAny* aArray ) + { + static_cast< RKeyValueArray* >( aArray )->ResetAndDestroy(); + } + +// Cleanup item for RKeyValueArray object. +LOCAL_C void CleanupResetAndDestroyPushL( RKeyValueArray& aArray ) + { + TCleanupItem item( CleanupKeyValueArray, &aArray ); + CleanupStack::PushL( item ); + } + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CCFClauseNode::CCFClauseNode +// C++ default constructor can NOT contain any code, that might leave. +// --------------------------------------------------------------------------- +// +CCFClauseNode::CCFClauseNode( MCFOperationServices& aServices, + CCFOperationNode* aParent ) + : CCFOperationNode( aServices, aParent ) + { + FUNC_LOG; + } + + +// Destructor +CCFClauseNode::~CCFClauseNode() + { + FUNC_LOG; + } + + +// ----------------------------------------------------------------------------- +// CCFClauseNode::ParseActionsL +// ----------------------------------------------------------------------------- +// +void CCFClauseNode::ParseActionsL( CMDXMLNode& aNode, + RPointerArray< CCFScriptAction >& aActions ) + { + FUNC_LOG; + + if ( aNode.NodeName().CompareF( KScriptActionsName ) != 0 ) + { + TPtrC nodeName( aNode.NodeName() ); + ERROR_GEN_1( "CCFClauseNode::ParseActionsL - Unknown actions name [%S]", + &nodeName ); + User::Leave( KErrNotSupported ); + } + + // Parse actions. + CMDXMLNode* actionNode = aNode.FirstChild(); + while ( actionNode ) + { + if ( actionNode->NodeType() == CMDXMLNode::EElementNode ) + { + if ( actionNode->NodeName().CompareF( + KScriptPublishContextName ) == 0 ) + { + CMDXMLNode* publishNode = actionNode->FirstChild(); + while ( publishNode ) + { + if ( publishNode->NodeType() == CMDXMLNode::EElementNode + && publishNode->NodeName().CompareF( + KScriptContextRefName ) == 0 ) + { + CCFScriptAction* action + = ParsePublishContextActionL( *publishNode ); + if ( action ) + { + CleanupStack::PushL( action ); // CLEANUP<< action + aActions.AppendL( action ); + CleanupStack::Pop( action ); // CLEANUP>> action + } + else + { + TPtrC nodeName( publishNode->NodeName() ); + ERROR_GEN_1( "CCFClauseNode::ParseActionsL - Skipping publish context action node [%S]", + &nodeName ); + } + } + else if ( publishNode->NodeType() + != CMDXMLNode::ECommentNode ) + { + TPtrC nodeName( publishNode->NodeName() ); + ERROR_GEN_1( "CCFClauseNode::ParseActionsL - Unknown publish context action node [%S]", + &nodeName ); + User::Leave( KErrNotSupported ); + } + publishNode = publishNode->NextSibling(); + } + } + else + { + CCFScriptAction* action = NULL; + if ( actionNode->NodeName().CompareF( + KScriptSourceCommandActionName ) == 0 ) + { + action = ParseSourceCommandActionL( *actionNode ); + } + else + { + action = ParseNotifyActionL( *actionNode ); + } + + if ( action ) + { + CleanupStack::PushL( action ); // CLEANUP<< action + aActions.AppendL( action ); + CleanupStack::Pop( action ); // CLEANUP>> action + } + else + { + TPtrC nodeName( actionNode->NodeName() ); + ERROR_GEN_1( "CCFClauseNode::ParseActionsL - Skipping action node [%S]", + &nodeName ); + } + } + } + actionNode = actionNode->NextSibling(); + } + } + +// ----------------------------------------------------------------------------- +// CCFClauseNode::ParseNotifyActionL +// ----------------------------------------------------------------------------- +// +CCFScriptAction* CCFClauseNode::ParseNotifyActionL( CMDXMLNode& aNode ) + { + FUNC_LOG; + + // Notify action. + // below // CLEANUP<< notifyAction + HBufC* notifyAction = aNode.NodeName().AllocLC(); + + INFO_1( "Reading action definition for [%S]", &( *notifyAction ) ); + + RKeyValueArray keysAndValues; + CleanupResetAndDestroyPushL( keysAndValues ); // CLEANUP<< keysAndValues + if ( aNode.NodeType() == CMDXMLNode::EElementNode ) + { + // Set attributes for the action. + CMDXMLElement& element = static_cast< CMDXMLElement& >( aNode ); + TInt numAttributes = element.NumAttributes(); + TPtrC attributeName( KNullDesC ); + TPtrC attributeValue( KNullDesC ); + for ( TInt i = 0; i < numAttributes; ++i ) + { + if ( KErrNone == element.AttributeDetails( + i, attributeName, attributeValue ) ) + { + INFO_2( "Found action attribute: '%S'='%S'", + &attributeName, + &attributeValue ); + + // below // CLEANUP<< keyValue + CCFKeyValuePair* keyValue = CCFKeyValuePair::NewLC( + attributeName, + attributeValue ); + keysAndValues.AppendL( keyValue ); + CleanupStack::Pop( keyValue ); // CLEANUP>> keyValue + } + } + } + + CCFScriptAction* action = CCFNotifyAction::NewL( iServices, + *notifyAction, + keysAndValues ); + + INFO_1( "Created Notify Action for [%S]", &( *notifyAction ) ); + + CleanupStack::PopAndDestroy( &keysAndValues );// CLEANUP>> keysAndValues + CleanupStack::PopAndDestroy( notifyAction );// CLEANUP>> notifyAction + + return action; + } + +// ----------------------------------------------------------------------------- +// CCFClauseNode::ParsePublishContextActionL +// ----------------------------------------------------------------------------- +// +CCFScriptAction* CCFClauseNode::ParsePublishContextActionL( CMDXMLNode& aNode ) + { + FUNC_LOG; + + CCFScriptAction* action = NULL; + CMDXMLNode* parentNode = aNode.ParentNode(); + if ( parentNode + && parentNode->NodeName().CompareF( KScriptPublishContextName ) == 0 + && aNode.NodeName().CompareF( KScriptContextRefName ) == 0 ) + { + // Publish context action. + if ( aNode.NodeType() != CMDXMLNode::EElementNode ) + { + TPtrC nodeName( aNode.NodeName() ); + ERROR_GEN_1( "CCFClauseNode::ParsePublishContextActionL - Unknown publish context action node [%S]", + &nodeName ); + User::Leave( KErrNotSupported ); + } + + TPtrC contextSource; + TPtrC contextType; + TPtrC contextValue; + CMDXMLElement& element = static_cast< CMDXMLElement& >( aNode ); + element.GetAttribute( KScriptSourceAttribute, contextSource ); + element.GetAttribute( KScriptTypeAttribute, contextType ); + element.GetAttribute( KScriptValueAttribute, contextValue ); + if ( contextSource.Length() == 0 || contextType.Length() == 0 + || contextValue.Length() == 0 ) + { + ERROR_GEN( "CCFClauseNode::ParsePublishContextActionL - Publish context action contextRef element is missing attributes" ); + User::Leave( KErrNotSupported ); + } + + CCFContextObject* co = CCFContextObject::NewLC(); // CLEANUP<< co + co->SetSourceL( contextSource ); + co->SetTypeL( contextType ); + co->SetValueL( contextValue ); + co->SetTimestampToHomeTime(); + + // Check from the parent node '' if there are attributes + // set for 'define' + TBool autoDefine( EFalse ); + if( parentNode->NodeType() == CMDXMLNode::EElementNode ) + { + // Check if the attribute is 'define' + CMDXMLElement& parentElement = static_cast< CMDXMLElement& >( *parentNode ); + TInt err( KErrNone ); + TPtrC name( KNullDesC ); + TPtrC value( KNullDesC ); + TInt numOfAttribs( parentElement.NumAttributes() ); + for( TInt i = 0; i < numOfAttribs; i++ ) + { + err = parentElement.AttributeDetails( i, name, value ); + if( err == KErrNone ) + { + // Check for 'define' attribute + if( name.CompareF( KScriptDefineName ) == KErrNone ) + { + // Check if the value is 'true' + if( value.CompareF( KScriptTrueName ) == KErrNone ) + { + autoDefine = ETrue; + } + } + } + } + } + + // Create a new action object giving it context object ownership. + action = CCFPublishContextAction::NewL( iServices, co, autoDefine ); + CleanupStack::Pop( co ); // CLEANUP>> co + + INFO_4( "Created PublishContext Action for [%S: %S: %S], Auto define: [%d]", + &contextSource, &contextType, &contextValue, autoDefine ); + } + else + { + TPtrC nodeName( aNode.NodeName() ); + if ( parentNode ) + { + nodeName.Set( parentNode->NodeName() ); + } + ERROR_GEN_1( "CCFClauseNode::ParsePublishContextActionL - Unknown publish context action node [%S]", + &nodeName ); + } + + return action; + } + +// ----------------------------------------------------------------------------- +// CCFClauseNode::ParseSourceCommandActionL +// ----------------------------------------------------------------------------- +// +CCFScriptAction* CCFClauseNode::ParseSourceCommandActionL( CMDXMLNode& aNode ) + { + FUNC_LOG; + + TPtrC commandNodeName( aNode.NodeName() ); + if ( commandNodeName.CompareF( KScriptSourceCommandActionName ) != 0 ) + { + ERROR_GEN_1( "CCFClauseNode::ParseSourceCommandActionL - Unknown source command action node [%S]", + &commandNodeName ); + return NULL; + } + + INFO_1( "Reading action definition for [%S]", &commandNodeName ); + + RKeyValueArray keysAndValues; + CleanupResetAndDestroyPushL( keysAndValues ); // CLEANUP<< keysAndValues + + GetAttributesL( aNode, keysAndValues ); + + // below // CLEANUP<< command + CCFContextSourceCommand* command = CCFContextSourceCommand::NewLC(); + command->SetNameL( commandNodeName ); + command->AddAttributesL( keysAndValues ); + + // Get command parameters. + CMDXMLNode* paramNode = aNode.FirstChild(); + while ( paramNode ) + { + TPtrC paramNodeName( paramNode->NodeName() ); + if ( paramNode->NodeType() == CMDXMLNode::EElementNode ) + { + GetAttributesL( *paramNode, keysAndValues ); + + // below // CLEANUP<< param + CCFContextSourceCommandParameter* param + = CCFContextSourceCommandParameter::NewLC(); + param->SetNameL( paramNodeName ); + param->AddAttributesL( keysAndValues ); + + GetNestedSourceCommandParametersL( *paramNode, *param ); + + command->AddParameterL( param ); + + CleanupStack::Pop( param ); // CLEANUP>> param + } + else if ( paramNode->NodeType() != CMDXMLNode::ECommentNode ) + { + ERROR_GEN_1( "CCFClauseNode::ParseSourceCommandActionL - Unsupported node type [%S]", + ¶mNodeName ); + User::Leave( KErrNotSupported ); + } + paramNode = paramNode->NextSibling(); + } + + // Create command's sender identity. + TCFSourceCommandSenderId senderId; + RThread thread; + senderId.iSender = thread.SecureId(); + thread.Close(); + senderId.iScriptId = iServices.ScriptId(); + command->SetSender( senderId ); + + CCFSourceCommandAction* action = CCFSourceCommandAction::NewL( iServices, + command ); + + CleanupStack::Pop( command ); // CLEANUP>> command + CleanupStack::PopAndDestroy( &keysAndValues ); // CLEANUP>> keysAndValues + + INFO_1( "Created Source Command Action for [%S]", &commandNodeName ); + + return action; + } + +// ----------------------------------------------------------------------------- +// CCFClauseNode::GetAttributesL +// ----------------------------------------------------------------------------- +// +void CCFClauseNode::GetAttributesL( CMDXMLNode& aNode, + RKeyValueArray& aAttributes ) + { + FUNC_LOG; + + if ( aNode.NodeType() == CMDXMLNode::EElementNode ) + { + CMDXMLElement& element = static_cast< CMDXMLElement& >( aNode ); + TInt numAttributes = element.NumAttributes(); + TPtrC attributeName( KNullDesC ); + TPtrC attributeValue( KNullDesC ); + for ( TInt i = 0; i < numAttributes; ++i ) + { + if ( KErrNone == element.AttributeDetails( + i, attributeName, attributeValue ) ) + { + INFO_2( "Found action attribute: '%S'='%S'", + &attributeName, + &attributeValue ); + + // below // CLEANUP<< keyValue + CCFKeyValuePair* keyValue = CCFKeyValuePair::NewLC( + attributeName, + attributeValue ); + aAttributes.AppendL( keyValue ); + CleanupStack::Pop( keyValue ); // CLEANUP>> keyValue + } + } + } + } + +// ----------------------------------------------------------------------------- +// CCFClauseNode::GetNestedSourceCommandParametersL +// ----------------------------------------------------------------------------- +// +void CCFClauseNode::GetNestedSourceCommandParametersL( CMDXMLNode& aNode, + CCFContextSourceCommandParameter& aParent ) + { + FUNC_LOG; + + RKeyValueArray keysAndValues; + CleanupResetAndDestroyPushL( keysAndValues ); // CLEANUP<< keysAndValues + + CMDXMLNode* nestedNode = aNode.FirstChild(); + while ( nestedNode ) + { + TPtrC nestedNodeName( nestedNode->NodeName() ); + if ( nestedNode->NodeType() == CMDXMLNode::EElementNode ) + { + GetAttributesL( *nestedNode, keysAndValues ); + + // below // CLEANUP<< parameter + CCFContextSourceCommandParameter* parameter + = CCFContextSourceCommandParameter::NewLC(); + parameter->SetNameL( nestedNodeName ); + parameter->AddAttributesL( keysAndValues ); + + aParent.AddParameterL( parameter ); + + CleanupStack::Pop( parameter ); // CLEANUP>> parameter + + GetNestedSourceCommandParametersL( *nestedNode, *parameter ); + } + else if ( nestedNode->NodeType() != CMDXMLNode::ECommentNode ) + { + ERROR_GEN_1( "CCFClauseNode::GetNestedSourceCommandParameterL - Unsupported node type [%S]", + &nestedNodeName ); + User::Leave( KErrNotSupported ); + } + nestedNode = nestedNode->NextSibling(); + } + + CleanupStack::PopAndDestroy( &keysAndValues ); // CLEANUP>> keysAndValues + }