contextframework/cfw/src/basicoperationsplugin/cfclausenode.cpp
changeset 0 2e3d3ce01487
--- /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 <cfcontextinterface.h>
+#include <cfcontextobject.h>
+#include <cfkeyvaluepair.h>
+#include <cfcontextsourcecommand.h>
+#include <cfcontextsourcecommandparameter.h>
+#include <gmxmlnode.h>
+#include <gmxmlelement.h>
+
+// 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 '<publishContext>' 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]",
+                    &paramNodeName );
+            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
+    }