contextframework/cfw/src/basicoperationsplugin/cfcount.cpp
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 /*
       
     2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  CCFCount class implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDES
       
    21 #include "cfcount.h"
       
    22 #include "cfcountoneshot.h"
       
    23 #include "cfcountrepeating.h"
       
    24 #include "cfcontextoperationutils.h"
       
    25 #include "cfbasicoptrace.h"
       
    26 
       
    27 #include <cfcontextobject.h>
       
    28 #include <gmxmlelement.h>
       
    29 #include <s32strm.h>
       
    30 
       
    31 // CONSTANTS
       
    32 _LIT( KScriptCountName,               "count"               );
       
    33 _LIT( KScriptRepeatIntervalAttribute, "repeatInterval"      );
       
    34 _LIT( KScriptOneShotAtAttribute,      "oneShotAt"           );
       
    35 
       
    36 static const TUint KInitialCount = 0;
       
    37 
       
    38 
       
    39 // ======== MEMBER FUNCTIONS ========
       
    40 
       
    41 // ---------------------------------------------------------------------------
       
    42 // CCFCount::CCFCount
       
    43 // C++ default constructor can NOT contain any code, that might leave.
       
    44 // ---------------------------------------------------------------------------
       
    45 //
       
    46 CCFCount::CCFCount( MCFOperationServices& aServices,
       
    47     CCFOperationNode* aParent,
       
    48     HBufC* aName,
       
    49     HBufC* aSource,
       
    50     const CCFContextOperation::TCmpType aType,
       
    51     const TUint aCount,
       
    52     const TCountType aCountType )
       
    53     :   CCFContextOperation( aServices, aParent, aName, aSource ),
       
    54         iType( aType ),
       
    55         iCurrentCount( KInitialCount ),
       
    56         iActive( EFalse ),
       
    57         iFinished( EFalse ),
       
    58         iCmpCount( aCount ),
       
    59         iCountType( aCountType )
       
    60     {
       
    61     FUNC_LOG;
       
    62 
       
    63     if ( iCmpCount == KInitialCount )
       
    64         {
       
    65         iValue = ECFConditionTrue;
       
    66         }
       
    67     else
       
    68         {
       
    69         iValue = ECFConditionFalse;
       
    70         }
       
    71     }
       
    72 
       
    73 // ---------------------------------------------------------------------------
       
    74 // CCFCount::ConstructL
       
    75 // Symbian 2nd phase constructor can leave.
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 void CCFCount::ConstructL( const TDesC& aCmpVal )
       
    79     {
       
    80     FUNC_LOG;
       
    81 
       
    82     iCmpValue = aCmpVal.AllocL();
       
    83     }
       
    84 
       
    85 // -----------------------------------------------------------------------------
       
    86 // CCFCount::ParseL
       
    87 // Construction with parsing from a DOM node.
       
    88 // -----------------------------------------------------------------------------
       
    89 //
       
    90 CCFCount* CCFCount::ParseL( MCFOperationServices& aServices,
       
    91     CCFOperationNode* aParent,
       
    92     CMDXMLNode& aNode )
       
    93     {
       
    94     FUNC_LOG;
       
    95 
       
    96     if ( aNode.NodeName().CompareF( KScriptCountName ) != 0
       
    97         || aNode.NodeType() != CMDXMLNode::EElementNode )
       
    98         {
       
    99         return NULL; // Cannot create count operation from the given node.
       
   100         }
       
   101 
       
   102     CCFCount* self = NULL;
       
   103     // Check & get count attribute.
       
   104     CMDXMLElement& element = static_cast< CMDXMLElement& >( aNode );
       
   105     TPtrC countAttributeValue;
       
   106     if ( KErrNone == element.GetAttribute( KScriptRepeatIntervalAttribute,
       
   107             countAttributeValue ) )
       
   108         {
       
   109         self = CCFCountRepeating::ParseL( aServices, aParent, aNode );
       
   110         }
       
   111     else if ( KErrNone == element.GetAttribute( KScriptOneShotAtAttribute,
       
   112             countAttributeValue ) )
       
   113         {
       
   114         self = CCFCountOneShot::ParseL( aServices, aParent, aNode );
       
   115         }
       
   116     else
       
   117         {
       
   118         INFO( "CCFCount::ParseL - count missing required attribute" );
       
   119         }
       
   120 
       
   121     CREATE_DOM_INFO( self, aNode );
       
   122 
       
   123     return self;
       
   124     }
       
   125 
       
   126 
       
   127 // Destructor
       
   128 CCFCount::~CCFCount()
       
   129     {
       
   130     FUNC_LOG;
       
   131 
       
   132     delete iCmpValue;
       
   133     delete iPersistencyFile;
       
   134     }
       
   135 
       
   136 
       
   137 //-----------------------------------------------------------------------------
       
   138 // CCFCount::InternalizeL
       
   139 //-----------------------------------------------------------------------------
       
   140 //
       
   141 void CCFCount::InternalizeL( RReadStream& aStream )
       
   142     {
       
   143     FUNC_LOG;
       
   144 
       
   145     iValue = static_cast< TCFConditionValue >( aStream.ReadInt32L() );
       
   146     iCurrentCount = aStream.ReadUint32L();
       
   147     iFinished = aStream.ReadInt8L();
       
   148     iReEvaluateFromNextContext = aStream.ReadInt8L();
       
   149     }
       
   150 
       
   151 //-----------------------------------------------------------------------------
       
   152 // CCFCount::ExternalizeL
       
   153 //-----------------------------------------------------------------------------
       
   154 //
       
   155 void CCFCount::ExternalizeL( RWriteStream& aStream )
       
   156     {
       
   157     FUNC_LOG;
       
   158 
       
   159     aStream.WriteInt32L( iValue );
       
   160     aStream.WriteUint32L( iCurrentCount );
       
   161     aStream.WriteInt8L( iFinished );
       
   162     aStream.WriteInt8L( iReEvaluateFromNextContext );
       
   163     }
       
   164 
       
   165 //-----------------------------------------------------------------------------
       
   166 // CCFCount::Cleanup
       
   167 //-----------------------------------------------------------------------------
       
   168 //
       
   169 void CCFCount::Cleanup()
       
   170     {
       
   171     FUNC_LOG;
       
   172 
       
   173     if ( iPersistencyFile )
       
   174         {
       
   175         iServices.Delete( *iPersistencyFile );
       
   176         }
       
   177     }
       
   178 
       
   179 
       
   180 // ---------------------------------------------------------------------------
       
   181 // CCFCount::IsAllRequired
       
   182 // ---------------------------------------------------------------------------
       
   183 //
       
   184 TBool CCFCount::IsAllRequired() const
       
   185     {
       
   186     FUNC_LOG;
       
   187 
       
   188     if ( iCountType == ECountTypeTrigger )
       
   189         {
       
   190         return ETrue;
       
   191         }
       
   192     else
       
   193         {
       
   194         return EFalse;
       
   195         }
       
   196     }
       
   197 
       
   198 // ---------------------------------------------------------------------------
       
   199 // CCFCount::Evaluate
       
   200 // ---------------------------------------------------------------------------
       
   201 //
       
   202 TBool CCFCount::Evaluate( const CCFContextObject& aContext,
       
   203     TInt& aContextLevelDelay )
       
   204     {
       
   205     FUNC_LOG;
       
   206 
       
   207     DOM_INFO( "CCFCount::Evaluate" );
       
   208 
       
   209     TBool evaluated( EFalse );
       
   210     TInt err( KErrNone );
       
   211     TRAP( err, evaluated = DoEvaluateL( aContext ) );
       
   212     ERROR( err, "CCFCount::Evaluate - call to DoEvaluateL leaved" );
       
   213 
       
   214     aContextLevelDelay = iContextLevelDelay;
       
   215     return evaluated;
       
   216     }
       
   217 
       
   218 // ---------------------------------------------------------------------------
       
   219 // CCFCount::ActivateL
       
   220 // ---------------------------------------------------------------------------
       
   221 //
       
   222 void CCFCount::ActivateL()
       
   223     {
       
   224     FUNC_LOG;
       
   225 
       
   226     if ( !iFinished && iPersistencyFile )
       
   227         {
       
   228         iServices.RestoreL( *iPersistencyFile, *this );
       
   229         }
       
   230 
       
   231     if ( !iFinished && !iActive )
       
   232         {
       
   233         iServices.SubscribeContextL( this );
       
   234         // Activate now to prevent pre-evaluation with possible cached context.
       
   235         iActive = ETrue;
       
   236         }
       
   237 
       
   238     // Assure that parent will be initialized correctly.
       
   239     if ( iParent )
       
   240         {
       
   241         iParent->Evaluate();
       
   242         }
       
   243     }
       
   244 
       
   245 // ---------------------------------------------------------------------------
       
   246 // CCFCount::Deactivate
       
   247 // ---------------------------------------------------------------------------
       
   248 //
       
   249 void CCFCount::Deactivate()
       
   250     {
       
   251     FUNC_LOG;
       
   252 
       
   253     if ( iActive )
       
   254         {
       
   255         iActive = EFalse;
       
   256         iServices.RemoveSubscription( this );
       
   257         }
       
   258 
       
   259     if ( iPersistencyFile )
       
   260         {
       
   261         TRAP_IGNORE( iServices.StoreL( *iPersistencyFile, *this ) );
       
   262         }
       
   263     }
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // CCFCount::DoEvaluateL
       
   267 // ---------------------------------------------------------------------------
       
   268 //
       
   269 TBool CCFCount::DoEvaluateL( const CCFContextObject& aContext )
       
   270     {
       
   271     FUNC_LOG;
       
   272 
       
   273     TBool evaluated( ETrue );
       
   274     if ( !iActive )
       
   275         {
       
   276         INFO( "CCFCount::Evaluate - SKIPPED, count not active!" );
       
   277         evaluated = EFalse;
       
   278 
       
   279         return evaluated;
       
   280         }
       
   281 
       
   282     if ( !CountContextL( aContext ) )
       
   283         {
       
   284         if ( iReEvaluateFromNextContext
       
   285                 && iCountType == CCFCount::ECountTypeTrigger )
       
   286             {
       
   287             INFO( "CCFCount::Evaluate - Trigger type, re-evaluating parent" );
       
   288 
       
   289             iReEvaluateFromNextContext = EFalse;
       
   290             if ( iParent )
       
   291                 {
       
   292                 iParent->Evaluate();
       
   293                 }
       
   294 
       
   295             if ( iPersistencyFile )
       
   296                 {
       
   297                 iServices.StoreL( *iPersistencyFile, *this );
       
   298                 }
       
   299             }
       
   300         else
       
   301             {
       
   302             INFO( "CCFCount::Evaluate - SKIPPED, count not counting this context!" );
       
   303             evaluated = EFalse;
       
   304             }
       
   305 
       
   306         return evaluated;
       
   307         }
       
   308 
       
   309     // Ask concrete implementation if it is true.
       
   310     TBool val = IsTrueL( aContext );
       
   311 
       
   312     // Evaluate parents if value changed.
       
   313     if ( val != iValue )
       
   314         {
       
   315         INFO_1( "CCFCount::Evaluate - Value changed to (-1=undefined, 0=false, 1=true): %d", val );
       
   316 
       
   317         iValue = static_cast< TCFConditionValue >( val );
       
   318         if ( iParent )
       
   319             {
       
   320             iParent->Evaluate();
       
   321             }
       
   322         iReEvaluateFromNextContext = EFalse;
       
   323 
       
   324         if ( iValue == CCFOperationNode::ECFConditionTrue
       
   325                 && iCountType == CCFCount::ECountTypeTrigger )
       
   326             {
       
   327             INFO( "CCFCount::Evaluate - Trigger type, value changed to false" );
       
   328 
       
   329             iValue = CCFOperationNode::ECFConditionFalse;
       
   330             iReEvaluateFromNextContext = ETrue;
       
   331             }
       
   332         }
       
   333     else
       
   334         {
       
   335         INFO_1( "CCFCount::Evaluate - Value still (-1=undefined, 0=false, 1=true): %d", val );
       
   336 
       
   337         if ( iValue == CCFOperationNode::ECFConditionFalse
       
   338                 && iCountType == CCFCount::ECountTypeTrigger
       
   339                 && iReEvaluateFromNextContext )
       
   340             {
       
   341             INFO( "CCFCount::Evaluate - Trigger type, parent re-evaluated now!" );
       
   342 
       
   343             iReEvaluateFromNextContext = EFalse;
       
   344             if ( iParent )
       
   345                 {
       
   346                 iParent->Evaluate();
       
   347                 }
       
   348             }
       
   349         }
       
   350 
       
   351     if ( iPersistencyFile )
       
   352         {
       
   353         iServices.StoreL( *iPersistencyFile, *this );
       
   354         }
       
   355 
       
   356     return evaluated;
       
   357     }
       
   358 
       
   359 // ---------------------------------------------------------------------------
       
   360 // CCFCount::CountContextL
       
   361 // ---------------------------------------------------------------------------
       
   362 //
       
   363 TBool CCFCount::CountContextL( const CCFContextObject& aContext )
       
   364     {
       
   365     FUNC_LOG;
       
   366 
       
   367     TBool counted( EFalse );
       
   368     if ( aContext.Source() == Source() && aContext.Type() == Type() )
       
   369         {
       
   370         if ( iCmpValue->Length() == 0 )
       
   371             {
       
   372             ++iCurrentCount;
       
   373             counted = ETrue;
       
   374             }
       
   375         else
       
   376             {
       
   377             TBool cmpValue( EFalse );
       
   378             switch ( iType )
       
   379                 {
       
   380                 case CCFContextOperation::EIntCmp:
       
   381                     {
       
   382                     TInt a = CFContextOperationUtils::StringToIntL(
       
   383                             *iCmpValue );
       
   384                     TInt b = CFContextOperationUtils::StringToIntL(
       
   385                             aContext.Value() );
       
   386                     cmpValue = ( a == b );
       
   387                     break;
       
   388                     }
       
   389                 case CCFContextOperation::ETimeCmp:
       
   390                     {
       
   391                     TTime a = CFContextOperationUtils::StringToTimeL(
       
   392                             *iCmpValue );
       
   393                     TTime b = CFContextOperationUtils::StringToTimeL(
       
   394                             aContext.Value() );
       
   395                     cmpValue = ( a == b );
       
   396                     break;
       
   397                     }
       
   398                 case CCFContextOperation::EFloatCmp:
       
   399                     {
       
   400                     TReal a = CFContextOperationUtils::StringToRealL(
       
   401                             *iCmpValue );
       
   402                     TReal b = CFContextOperationUtils::StringToRealL(
       
   403                             aContext.Value() );
       
   404                     cmpValue = ( a == b );
       
   405                     break;
       
   406                     }
       
   407                 case CCFContextOperation::EStringCmp:
       
   408                 default:
       
   409                     {
       
   410                     cmpValue = ( *iCmpValue == aContext.Value() );
       
   411                     break;
       
   412                     }
       
   413                 }
       
   414     
       
   415             if ( cmpValue )
       
   416                 {
       
   417                 ++iCurrentCount;
       
   418                 counted = ETrue;
       
   419                 }
       
   420             }
       
   421         }
       
   422     else
       
   423         {
       
   424         // Count type must be trigger.
       
   425         if ( iCountType != CCFCount::ECountTypeTrigger )
       
   426             {
       
   427             ERROR_GEN( "CCFCount::CountContext - count is NOT trigger type!" );
       
   428             }
       
   429         }
       
   430 
       
   431     return counted;
       
   432     }