ncdengine/provider/client/src/ncdnodefolderproxy.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:   Contains CNcdNodeFolderProxy class implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdnodefolderproxy.h"
       
    20 #include "ncdnodemetadataproxy.h"
       
    21 #include "catalogsclientserver.h"
       
    22 #include "ncdnodemanagerproxy.h"
       
    23 #include "ncdoperationmanagerproxy.h"
       
    24 #include "ncdnodeidentifier.h"
       
    25 #include "catalogsdebug.h"
       
    26 #include "ncdnodefunctionids.h"
       
    27 #include "ncdnodeclassids.h"
       
    28 #include "catalogsinterfaceidentifier.h"
       
    29 #include "ncdloadnodeoperationproxy.h"
       
    30 #include "ncdnodesearchimpl.h"
       
    31 #include "catalogsutils.h"
       
    32 #include "ncdchildentity.h"
       
    33 #include "ncdproviderdefines.h"
       
    34 #include "ncdnodeuricontentproxy.h"
       
    35 #include "ncdcapabilities.h"
       
    36 #include "ncdnodeseenfolderproxy.h"
       
    37 #include "ncderrors.h"
       
    38 
       
    39 CNcdNodeFolderProxy::CNcdNodeFolderProxy( MCatalogsClientServer& aSession,
       
    40                                           TInt aHandle,
       
    41                                           CNcdNodeManagerProxy& aNodeManager,
       
    42                                           CNcdOperationManagerProxy& aOperationManager,
       
    43                                           CNcdFavoriteManagerProxy& aFavoriteManager ) 
       
    44 : CNcdNodeProxy( aSession, aHandle, aNodeManager, aOperationManager, aFavoriteManager )
       
    45     {
       
    46     }
       
    47 
       
    48 
       
    49 void CNcdNodeFolderProxy::ConstructL()
       
    50     {
       
    51     CNcdNodeProxy::ConstructL(); 
       
    52 
       
    53     // Add the interface information to the list
       
    54     MNcdNodeContainer* container( this );
       
    55     AddInterfaceL( 
       
    56         CCatalogsInterfaceIdentifier::NewL( container, this, MNcdNodeContainer::KInterfaceUid ) );                    
       
    57     }
       
    58 
       
    59 
       
    60 CNcdNodeFolderProxy* CNcdNodeFolderProxy::NewL( MCatalogsClientServer& aSession,
       
    61                                                 TInt aHandle,
       
    62                                                 CNcdNodeManagerProxy& aNodeManager,
       
    63                                                 CNcdOperationManagerProxy& aOperationManager,
       
    64                                                 CNcdFavoriteManagerProxy& aFavoriteManager )
       
    65     {
       
    66     CNcdNodeFolderProxy* self = 
       
    67         CNcdNodeFolderProxy::NewLC(
       
    68             aSession, aHandle, aNodeManager, aOperationManager, aFavoriteManager );
       
    69     CleanupStack::Pop( self );
       
    70     return self;
       
    71     }
       
    72 
       
    73 CNcdNodeFolderProxy* CNcdNodeFolderProxy::NewLC( MCatalogsClientServer& aSession,
       
    74                                                  TInt aHandle,
       
    75                                                  CNcdNodeManagerProxy& aNodeManager,
       
    76                                                  CNcdOperationManagerProxy& aOperationManager,
       
    77                                                  CNcdFavoriteManagerProxy& aFavoriteManager )
       
    78     {
       
    79     CNcdNodeFolderProxy* self = 
       
    80         new( ELeave ) CNcdNodeFolderProxy(
       
    81             aSession, aHandle, aNodeManager, aOperationManager, aFavoriteManager );  
       
    82     // Using PushL because the object does not have any references yet
       
    83     CleanupStack::PushL( self );
       
    84     self->ConstructL();
       
    85     return self;
       
    86     }
       
    87 
       
    88 
       
    89 CNcdNodeFolderProxy::~CNcdNodeFolderProxy()
       
    90     {
       
    91     // Remove interfaces implemented by this class from the interface list.
       
    92     // So, the interface list is up to date when this class object is deleted.
       
    93     RemoveInterface( MNcdNodeContainer::KInterfaceUid );
       
    94     RemoveInterface( MNcdNodeSearch::KInterfaceUid );
       
    95 
       
    96     // Delete the objects that are owned by this class and provide functionality
       
    97     // through the api.
       
    98     // Notice that the api-objects are Released (not deleted) from the UI side.
       
    99     // The node owns the data and the reference counter of the node keeps
       
   100     // track of the api objects it owns. When the reference counter of the node
       
   101     // reaches zero, it means that nobody is using the node or the classes owned
       
   102     // by the node. If somebody is using the object owned by the node, the reference
       
   103     // counter can not be zero until everything is released.
       
   104     // Thus, the node may delete the data here.
       
   105 
       
   106     delete iSearch;
       
   107     iSearch = NULL;
       
   108     
       
   109     delete iNodeSeenFolder;
       
   110     iNodeSeenFolder = NULL;
       
   111     
       
   112     iChildren.ResetAndDestroy();
       
   113     }
       
   114 
       
   115 
       
   116 
       
   117 
       
   118 TInt CNcdNodeFolderProxy::ExpectedChildCount() const
       
   119     {
       
   120     return iExpectedChildCount;
       
   121     }
       
   122 
       
   123 
       
   124 MNcdLoadNodeOperation* CNcdNodeFolderProxy::LoadL(
       
   125     MNcdLoadNodeOperationObserver& aObserver ) 
       
   126     {
       
   127     DLTRACEIN((_L("This ns: %S, id: %S"), &Namespace(), &Id() ));    
       
   128     return CNcdNodeProxy::LoadL( aObserver );
       
   129     }
       
   130 
       
   131 
       
   132 TInt CNcdNodeFolderProxy::ChildCount() const
       
   133     {
       
   134     return iExpectedChildCount;
       
   135     }
       
   136 
       
   137 
       
   138 MNcdNode* CNcdNodeFolderProxy::ChildL( TInt aIndex )
       
   139     {
       
   140     DLTRACEIN(( _L("This parent: %S, %S"), &Namespace(), &Id(), aIndex ));
       
   141     DLINFO(("aIndex = %d, expected childcount= %d, real child count = %d",
       
   142         aIndex, iExpectedChildCount, iChildren.Count() ));
       
   143         
       
   144     if ( aIndex < 0 || aIndex >= iExpectedChildCount )
       
   145         {
       
   146         // Nothing to be done 
       
   147         DLERROR(( "Index error. expected child count: %d Given index: %d", 
       
   148                   iExpectedChildCount, aIndex ));
       
   149         DASSERT( EFalse );
       
   150         User::Leave( KErrArgument );   
       
   151         }
       
   152         
       
   153     // search for a child with given index
       
   154     const CNcdNodeIdentifier* child = NULL;
       
   155     for( TInt i = 0 ; i < iChildren.Count() ; i++ )
       
   156         {
       
   157         if ( iChildren[i]->Index() == aIndex )
       
   158             {
       
   159             child = &iChildren[i]->Identifier();
       
   160             }
       
   161         else if ( iChildren[i]->Index() > aIndex )
       
   162             {
       
   163             // no sense in searching further
       
   164             break;
       
   165             }
       
   166         }
       
   167 
       
   168     if( child == NULL )
       
   169         {
       
   170         return NULL;
       
   171         }
       
   172     
       
   173     MNcdNode* node( NULL );
       
   174     
       
   175     TRAPD( err, node = &NodeManager().NodeL( *child ) );    
       
   176 
       
   177     if ( err == KErrNotFound ) 
       
   178         {
       
   179         return NULL;
       
   180         }
       
   181 
       
   182     User::LeaveIfError( err );
       
   183     
       
   184     // Increase the reference counter by one
       
   185     node->AddRef();
       
   186     
       
   187     DLTRACEOUT((""));
       
   188 
       
   189     return node;
       
   190     }
       
   191     
       
   192     
       
   193 MNcdLoadNodeOperation* CNcdNodeFolderProxy::LoadChildrenL( TInt aIndex, 
       
   194                                                            TInt aSize,
       
   195                                                            TNcdChildLoadMode aMode,
       
   196                                                            MNcdLoadNodeOperationObserver& aObserver )
       
   197     {
       
   198     DLTRACEIN(("aIndex: %d, aSize: %d, expected child count: %d, load mode: %d",
       
   199         aIndex, aSize, iExpectedChildCount, aMode ));
       
   200 
       
   201     if ( aSize < 1 
       
   202          || aIndex < 0 
       
   203          || ( aMode == ELoadMetadata 
       
   204               && aSize != KMaxTInt 
       
   205               && aIndex + aSize > ChildCount() ) )
       
   206         {
       
   207         // Nothing to be done 
       
   208         DLERROR(( "Argument error. ChildCount: %d Given index: %d, size: %d",
       
   209                   ChildCount(), aIndex, aSize ));
       
   210         User::Leave( KErrArgument );
       
   211         }
       
   212 
       
   213     if ( aSize == KMaxTInt )
       
   214         {
       
   215         // Because aSize is KMaxTInt, reduce it by the aIndex value.
       
   216         // This way we will not have possible overload if aIndex is later added
       
   217         // to the aSize value. It does not really matter what the aSize value is
       
   218         // after this. KMaxTInt is so great value, that in all the cases the server
       
   219         // request should give all the required items.
       
   220         aSize -= aIndex;
       
   221         DLINFO(("aSize was KMaxTInt. Reduced by index: %d", aSize));
       
   222         }
       
   223 
       
   224     DLTRACE(( _L("Node: %S, %S"), &Namespace(), &Id() ));
       
   225     
       
   226     CNcdLoadNodeOperationProxy* operation = 
       
   227         OperationManager().CreateLoadNodeOperationL( 
       
   228             *this, ETrue, aSize, aIndex, 1, aMode );
       
   229 
       
   230     if ( !operation )
       
   231         {
       
   232         DLTRACEOUT(("NULL"));     
       
   233         return NULL;
       
   234         }
       
   235 
       
   236     operation->AddObserverL( this );
       
   237     operation->AddObserverL( &aObserver );
       
   238 
       
   239     DLTRACEOUT((""));        
       
   240 
       
   241     return operation;
       
   242     }
       
   243     
       
   244 TNcdContainerType CNcdNodeFolderProxy::ContainerType() const
       
   245     {
       
   246     if ( IsRemote() ) 
       
   247         {
       
   248         return ECatalog;
       
   249         }
       
   250     else 
       
   251         {
       
   252         return EFolder;
       
   253         }
       
   254     }
       
   255 
       
   256 void CNcdNodeFolderProxy::OperationComplete( 
       
   257     MNcdLoadNodeOperation& /*aOperation*/, TInt aError )
       
   258     {
       
   259     DLTRACEIN(( "Error: %d", aError ));
       
   260     
       
   261     if ( aError == KErrNone || aError == KNcdErrorSomeCatalogsFailedToLoad )
       
   262         {
       
   263         // update proxy's status from the server
       
   264         TRAP_IGNORE( InternalizeL() );
       
   265         }
       
   266     }
       
   267 
       
   268 void CNcdNodeFolderProxy::InternalizeL()
       
   269     {
       
   270     DLTRACEIN((""));
       
   271 
       
   272     // First call the parent internalizator. So, all the parent stuff will
       
   273     // be initialized before folder specific data.
       
   274     CNcdNodeProxy::InternalizeL();
       
   275 
       
   276     // Add the search interface because it is availabe for all the folders
       
   277     // that have at least one child.
       
   278     
       
   279     // check that is search supported for this node
       
   280     TBool isSearchSupported = IsSearchSupportedL();
       
   281         
       
   282     DLINFO(( "isSearchSupported: %d, child count: %d", isSearchSupported, 
       
   283         ChildCount() ));
       
   284     if ( isSearchSupported )
       
   285         {
       
   286         DLTRACE(("add search interface"));
       
   287         if ( iSearch == NULL )
       
   288             {
       
   289             // Create new search because old one did not exist.
       
   290             // Notice that the creation adds the interface to the node interface list
       
   291             // automatically.
       
   292             iSearch = CNcdNodeSearch::NewL( *this, OperationManager() );    
       
   293             }
       
   294         }
       
   295     else
       
   296         {
       
   297         DLTRACE(("remove search interface"));        
       
   298         delete iSearch;
       
   299         iSearch = NULL;
       
   300         }
       
   301         
       
   302     InternalizeNodeSeenFolderL();        
       
   303                    
       
   304     DLTRACEOUT((""));
       
   305     }
       
   306 
       
   307 
       
   308 void CNcdNodeFolderProxy::InternalizeNodeDataL( RReadStream& aStream )
       
   309     {
       
   310     DLTRACEIN((""));
       
   311     
       
   312     // First internalize parent data
       
   313     CNcdNodeProxy::InternalizeNodeDataL( aStream );
       
   314 
       
   315     // Get the children data here.
       
   316 
       
   317     DLTRACE(("Handle children"));
       
   318 
       
   319     // Clear the buffer because new childs will be appended
       
   320     iChildren.ResetAndDestroy();
       
   321     
       
   322     TInt childrenCount( aStream.ReadInt32L() );
       
   323     DLTRACE(("Children: %d", childrenCount ));
       
   324 
       
   325     TInt classObjectType( NcdNodeClassIds::ENcdNullObjectClassId );
       
   326 
       
   327     for ( TInt i = 0; i < childrenCount; ++i )
       
   328         {
       
   329         // This is safe casting because enum is same as TInt
       
   330         classObjectType = 
       
   331             static_cast<NcdNodeClassIds::TNcdNodeClassId>(aStream.ReadInt32L());
       
   332         if ( NcdNodeClassIds::ENcdChildEntityClassId == classObjectType )
       
   333             {
       
   334             CNcdChildEntity* childEntity = CNcdChildEntity::NewLC( aStream );
       
   335             iChildren.AppendL( childEntity );
       
   336             CleanupStack::Pop( childEntity );            
       
   337             DLINFO((_L("Added child, id: %S, array index: %d, real index: %d"),
       
   338             &childEntity->Identifier().NodeId(), i, childEntity->Index() ));
       
   339             }
       
   340         else
       
   341             {
       
   342             // For debug purposes
       
   343             DLERROR(("Wrong class id"));
       
   344             DASSERT( EFalse );
       
   345 
       
   346             // Wrong kind of class object info
       
   347             User::Leave( KErrCorrupt );
       
   348             }
       
   349         }
       
   350         
       
   351     // Show node info here, after the internalization has been done.        
       
   352     DLTRACEOUT(( _L("Node: %S, %S, %d"), 
       
   353                  &Namespace(), &Id(), NodeIdentifier().ClientUid().iUid ));
       
   354     }
       
   355 
       
   356 
       
   357 void CNcdNodeFolderProxy::InternalizeNodeLinkDataL( RReadStream& aStream )
       
   358     {
       
   359     DLTRACEIN(( _L("Node: %S, %S"), &Namespace(), &Id() ));
       
   360     
       
   361     // First internalize parent data
       
   362     CNcdNodeProxy::InternalizeNodeLinkDataL( aStream );
       
   363 
       
   364     // Then, set the data for this class object
       
   365     
       
   366     iExpectedChildCount = aStream.ReadInt32L();
       
   367 
       
   368     DLTRACEOUT((""));
       
   369     }
       
   370 
       
   371 TBool CNcdNodeFolderProxy::IsSearchSupportedL()
       
   372     {
       
   373     DLTRACEIN((""));
       
   374     // check if this node has search capability set
       
   375     return NodeManager().IsCapabilitySupportedL( NodeIdentifier(),
       
   376         NcdCapabilities::KSearch );
       
   377     }
       
   378     
       
   379 
       
   380 void CNcdNodeFolderProxy::InternalizeNodeSeenFolderL() 
       
   381     {
       
   382     DLTRACEIN((""));
       
   383     
       
   384     if ( iNodeSeenFolder )
       
   385         {
       
   386         iNodeSeenFolder->InternalizeL();
       
   387         }
       
   388     else 
       
   389         {
       
   390         // Create the object.  
       
   391         // Get the handle at first.
       
   392         TInt handle( 0 );
       
   393         User::LeaveIfError(
       
   394             ClientServerSession().SendSync(
       
   395                 NcdNodeFunctionIds::ENcdNodeSeenFolderHandle,
       
   396                 KNullDesC(),
       
   397                 handle,
       
   398                 Handle() ) );
       
   399         
       
   400         DLINFO(( "handle: %d", handle ));
       
   401        
       
   402         iNodeSeenFolder = CNcdNodeSeenFolderProxy::NewL(
       
   403             ClientServerSession(), handle, *this );
       
   404         }
       
   405     }
       
   406                     
       
   407