ncdengine/provider/server/src/ncdparentoftransparentnode.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006 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:   Implements CNcdParentOfTransparentNode class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32err.h>
       
    20 #include <e32base.h>
       
    21 
       
    22 #include "ncdparentoftransparentnode.h"
       
    23 #include "ncdchildentity.h"
       
    24 #include "ncdnodeidentifier.h"
       
    25 #include "catalogsutils.h"
       
    26 #include "catalogsbasemessage.h"
       
    27 #include "ncdnodefunctionids.h"
       
    28 #include "ncdnodeclassids.h"
       
    29 #include "catalogsconstants.h"
       
    30 #include "ncdsearchnodefolder.h"
       
    31 #include "ncdnodetransparentfolder.h"
       
    32 
       
    33 
       
    34 
       
    35 CNcdParentOfTransparentNode::CNcdParentOfTransparentNode( CNcdNodeManager& aNodeManager,
       
    36                                                           NcdNodeClassIds::TNcdNodeClassId aNodeClassId ) 
       
    37 : CNcdNodeFolder( aNodeManager, aNodeClassId ) 
       
    38     {
       
    39     }
       
    40 
       
    41 void CNcdParentOfTransparentNode::ConstructL( const CNcdNodeIdentifier& aIdentifier ) 
       
    42     {
       
    43     CNcdNodeFolder::ConstructL( aIdentifier );
       
    44     }
       
    45     
       
    46 CNcdParentOfTransparentNode::~CNcdParentOfTransparentNode() 
       
    47     {
       
    48     }
       
    49 
       
    50 
       
    51 void CNcdParentOfTransparentNode::ExternalizeL( RWriteStream& aStream ) 
       
    52     {
       
    53     DLTRACEIN((""));
       
    54     CNcdNodeFolder::ExternalizeL( aStream );
       
    55     DLTRACEOUT((""));
       
    56     }
       
    57     
       
    58 void CNcdParentOfTransparentNode::InternalizeL( RReadStream& aStream ) 
       
    59     {
       
    60     DLTRACEIN((""));
       
    61     CNcdNodeFolder::InternalizeL( aStream );
       
    62     DLTRACEOUT((""));
       
    63     }
       
    64 
       
    65 
       
    66                                     
       
    67 void CNcdParentOfTransparentNode::ExternalizeDataForRequestL( RWriteStream& aStream ) const
       
    68     {
       
    69     DLTRACEIN(("this: %X", this));
       
    70 
       
    71     // Just delegate the command forward
       
    72     CNcdNodeFolder::ExternalizeDataForRequestL( aStream );
       
    73     
       
    74     // This will give the correct child count that may be needed in proxy side.
       
    75     // Because the child count may differ there if transparent child folders are
       
    76     // replaced by their children.
       
    77     aStream.WriteInt32L( ChildArray().Count() );
       
    78 
       
    79     DLTRACEOUT((""));
       
    80     }
       
    81     
       
    82 
       
    83 void CNcdParentOfTransparentNode::ExternalizeChildArrayForRequestL( RWriteStream& aStream ) const
       
    84     {
       
    85     DLTRACEIN(("this: %X", this));
       
    86     DPROFILING_BEGIN( x );
       
    87     
       
    88     // Fixes PRECLI-1539
       
    89     // This method doesn't support paging and the parent implementation doesn't support
       
    90     // transparents but since search folders need paging but not transparents we call the
       
    91     // base class
       
    92     //
       
    93     // Note: No sense overriding this method in CNcdSearchNodeFolder because its
       
    94     // children need this implementation so we would have to implement overrides also
       
    95     // to them
       
    96     if ( ClassId() == NcdNodeClassIds::ENcdSearchFolderNodeClassId ) 
       
    97         {
       
    98         DLTRACE(("No need for transparent support, call CNcdNodeFolder-method"));
       
    99         CNcdNodeFolder::ExternalizeChildArrayForRequestL( aStream );
       
   100         return;
       
   101         }
       
   102     
       
   103     CNcdNode* childNode( NULL );
       
   104     CNcdNodeFolder* transparentFolder( NULL );
       
   105     const CNcdNodeIdentifier* childIdentifier( NULL );
       
   106     const CNcdNodeIdentifier* transparentChildIdentifier( NULL );
       
   107 
       
   108     // This array will contain the identifiers of the children that are set for
       
   109     // the proxy side
       
   110     RPointerArray<CNcdChildEntity> childEntitys;
       
   111     CleanupResetAndDestroyPushL( childEntitys );
       
   112     
       
   113     // Remember to check if this folder contains any transparent folders.
       
   114     // Add all the children into the temporary array that will contain
       
   115     // the identifiers of the children for the proxy folder.    
       
   116     // child entitys need an index as well as identifier
       
   117     
       
   118   
       
   119     const RPointerArray<CNcdChildEntity>& childArray( ChildArray() );
       
   120     TInt childCount = childArray.Count();
       
   121     childEntitys.ReserveL( childCount );
       
   122     DLTRACE(( "Externalizing at least %d children", childCount ));
       
   123     TInt childIndex = 0;    
       
   124     for ( TInt i = 0; i < childCount; ++i ) 
       
   125         {
       
   126         childNode = NULL;
       
   127         childIdentifier = &childArray[i]->Identifier();
       
   128         DASSERT( childIdentifier );
       
   129         if ( childArray[i]->IsTransparent() ) 
       
   130             {
       
   131             DLTRACE(("child is likely transparent"));
       
   132             childNode = NodeManager().NodePtrL( *childIdentifier );
       
   133 
       
   134             // This is as a backup
       
   135             if ( childNode != NULL 
       
   136                 && (childNode->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId ||
       
   137                     (childNode->ClassId() == NcdNodeClassIds::ENcdSearchFolderNodeClassId &&
       
   138                     NodeManager().SearchFolderL( *childIdentifier ).IsTransparent() ) ) )
       
   139                 {
       
   140                 DLINFO(("Transparent folder found for child array"));
       
   141                 // Because the transparent folder is replaced,
       
   142                 // add the the children of the transparent folder here.
       
   143                 transparentFolder = static_cast<CNcdNodeFolder*>(childNode);
       
   144                 const RPointerArray<CNcdChildEntity>& children = transparentFolder->ChildArray();
       
   145                 DLINFO((("Transparent folder has %d children"), children.Count() ));
       
   146                 for( TInt j = 0; j < children.Count(); ++j )
       
   147                     {
       
   148                     transparentChildIdentifier = &children[j]->Identifier();
       
   149 
       
   150                     DLINFO(("Child of transparent to array."));
       
   151                     CNcdChildEntity* childEntity = 
       
   152                         CNcdChildEntity::NewLC( 
       
   153                             childIndex++,
       
   154                             *transparentChildIdentifier,
       
   155                             children[j]->IsTransparent(),
       
   156                             children[j]->NodeType() );
       
   157                     childEntitys.AppendL( childEntity );
       
   158                     CleanupStack::Pop( childEntity );
       
   159                     }
       
   160                 }
       
   161             else 
       
   162                 {
       
   163                 // In case childNode was found but it wasn't really transparent
       
   164                 childNode = NULL;
       
   165                 }
       
   166             
       
   167             }
       
   168         
       
   169         // Handle non-transparents and nodes that were not found from node manager
       
   170         if ( !childNode )        
       
   171             {
       
   172             DLINFO(("Normal child. Add to the array."));
       
   173             DLNODEID(( *childIdentifier ));
       
   174             
       
   175             // Child was normal child.                
       
   176             CNcdChildEntity* childEntity = CNcdChildEntity::NewLC( 
       
   177                 childIndex++, 
       
   178                 *childIdentifier, 
       
   179                 childArray[i]->IsTransparent(),
       
   180                 childArray[i]->NodeType() );
       
   181             childEntitys.AppendL( childEntity );
       
   182             CleanupStack::Pop( childEntity );            
       
   183             }
       
   184         }
       
   185 
       
   186     // First insert the size of the child array
       
   187     aStream.WriteInt32L( childEntitys.Count() );
       
   188     
       
   189     // Insert all the child identifier info for the proxy into the stream
       
   190     for( TInt i = 0; i < childEntitys.Count(); ++i )
       
   191         {
       
   192         // Inform that the next class is child entity
       
   193         aStream.WriteInt32L( NcdNodeClassIds::ENcdChildEntityClassId );
       
   194         childEntitys[ i ]->ExternalizeL( aStream );
       
   195         }    
       
   196 
       
   197     // Close the array, but do not delete its elements that are owned else where.
       
   198     CleanupStack::PopAndDestroy( &childEntitys );
       
   199     DPROFILING_END( x );
       
   200     DLTRACEOUT((""));
       
   201     }
       
   202     
       
   203     
       
   204 void CNcdParentOfTransparentNode::ReceiveMessage( MCatalogsBaseMessage* aMessage,
       
   205                                TInt aFunctionNumber )
       
   206     {
       
   207     DLTRACEIN(("handle: %d, function: %d", aMessage->Handle(), 
       
   208         aFunctionNumber));
       
   209 
       
   210     DASSERT( aMessage );
       
   211     
       
   212     // Now, we can be sure that rest of the time iMessage exists.
       
   213     // This member variable is set for the CounterPartLost function.
       
   214     iMessage = aMessage;
       
   215         
       
   216     TInt trapError( KErrNone );
       
   217     
       
   218     switch( aFunctionNumber )
       
   219         {
       
   220         case NcdNodeFunctionIds::ENcdIsTransparentChildExpired:
       
   221             TRAP( trapError, IsTransparentChildExpiredL( *aMessage ) );
       
   222             break;
       
   223             
       
   224         default:
       
   225             // Let base class handle this message
       
   226             iMessage = NULL;
       
   227             CNcdNodeFolder::ReceiveMessage( aMessage, aFunctionNumber );
       
   228             return;
       
   229         }
       
   230 
       
   231     if ( trapError != KErrNone )
       
   232         {
       
   233         // Because something went wrong the complete has not been
       
   234         // yet called for the message.
       
   235         // So, inform the client about the error.
       
   236         DLTRACEIN(("Complete with error message"));
       
   237         aMessage->CompleteAndRelease( trapError );
       
   238         }
       
   239 
       
   240     // Because the message should not be used after this, set it NULL.
       
   241     // So, CounterPartLost function will know that no messages are
       
   242     // waiting the response at the moment.
       
   243     iMessage = NULL;
       
   244 
       
   245     DLTRACEOUT((""));
       
   246     }
       
   247 
       
   248 void CNcdParentOfTransparentNode::IsTransparentChildExpiredL( MCatalogsBaseMessage& aMessage ) const
       
   249     {
       
   250     DLTRACEIN((""));
       
   251     
       
   252     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   253     CleanupStack::PushL( buf );
       
   254     
       
   255     RBufWriteStream stream( *buf );
       
   256     CleanupClosePushL( stream );
       
   257 
       
   258     // Write the value to the stream
       
   259     stream.WriteInt32L( IsTransparentChildExpiredL() );
       
   260     
       
   261     // Commits data to the stream when closing.
       
   262     CleanupStack::PopAndDestroy( &stream );
       
   263 
       
   264     if ( buf->Size() > 0 ) 
       
   265         {
       
   266         DLINFO(( "Completing the message, buf len: %d", buf->Ptr(0).Length() ));
       
   267         }
       
   268         
       
   269     // If this leaves ReceiveMessage function will complete the message.
       
   270     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );
       
   271         
       
   272     
       
   273     DLINFO(("Deleting the buf"));
       
   274     CleanupStack::PopAndDestroy( buf );
       
   275         
       
   276     DLTRACEOUT((""));
       
   277     }
       
   278     
       
   279 TBool CNcdParentOfTransparentNode::IsTransparentChildExpiredL() const
       
   280     {
       
   281     DLTRACEIN((""));
       
   282     TBool isTransparentChildExpired = EFalse;
       
   283     for( TInt i = 0 ; i < ServerChildCountL() ; i++ )
       
   284         {
       
   285         CNcdNode* child = NULL;
       
   286         TRAPD( err, child = &NodeManager().NodeL( ChildByServerIndexL(i) ) );
       
   287         if( err == KErrNotFound || 
       
   288             ( err == KErrNone  &&
       
   289                 child->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId &&
       
   290                 child->State() != MNcdNode::EStateInitialized ) )
       
   291             {
       
   292             DLTRACE(("At least one child was expired/uninitialized/not found."));
       
   293             isTransparentChildExpired = ETrue;
       
   294             break;
       
   295             }
       
   296         else if ( err == KErrNone &&
       
   297             child->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId &&
       
   298             child->State() == MNcdNode::EStateInitialized )
       
   299             {
       
   300             DLTRACE(("Transparent child folder, check it's children"));
       
   301             CNcdNodeTransparentFolder* transpFolder =
       
   302                 static_cast<CNcdNodeTransparentFolder*>(child);
       
   303             if ( transpFolder->HasExpiredOrMissingChildrenL() )
       
   304                 {
       
   305                 DLTRACE(("Transparent child folder's child expired or missing."));
       
   306                 isTransparentChildExpired = ETrue;
       
   307                 break;
       
   308                 }
       
   309             }
       
   310         else if ( err != KErrNone && err != KErrNotFound )
       
   311             {
       
   312             DLTRACE(("Error: %d", err));
       
   313             User::Leave( err );
       
   314             }
       
   315         }
       
   316     return isTransparentChildExpired;
       
   317     }