--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/client/src/ncdnodefolderproxy.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,407 @@
+/*
+* Copyright (c) 2006 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: Contains CNcdNodeFolderProxy class implementation
+*
+*/
+
+
+#include "ncdnodefolderproxy.h"
+#include "ncdnodemetadataproxy.h"
+#include "catalogsclientserver.h"
+#include "ncdnodemanagerproxy.h"
+#include "ncdoperationmanagerproxy.h"
+#include "ncdnodeidentifier.h"
+#include "catalogsdebug.h"
+#include "ncdnodefunctionids.h"
+#include "ncdnodeclassids.h"
+#include "catalogsinterfaceidentifier.h"
+#include "ncdloadnodeoperationproxy.h"
+#include "ncdnodesearchimpl.h"
+#include "catalogsutils.h"
+#include "ncdchildentity.h"
+#include "ncdproviderdefines.h"
+#include "ncdnodeuricontentproxy.h"
+#include "ncdcapabilities.h"
+#include "ncdnodeseenfolderproxy.h"
+#include "ncderrors.h"
+
+CNcdNodeFolderProxy::CNcdNodeFolderProxy( MCatalogsClientServer& aSession,
+ TInt aHandle,
+ CNcdNodeManagerProxy& aNodeManager,
+ CNcdOperationManagerProxy& aOperationManager,
+ CNcdFavoriteManagerProxy& aFavoriteManager )
+: CNcdNodeProxy( aSession, aHandle, aNodeManager, aOperationManager, aFavoriteManager )
+ {
+ }
+
+
+void CNcdNodeFolderProxy::ConstructL()
+ {
+ CNcdNodeProxy::ConstructL();
+
+ // Add the interface information to the list
+ MNcdNodeContainer* container( this );
+ AddInterfaceL(
+ CCatalogsInterfaceIdentifier::NewL( container, this, MNcdNodeContainer::KInterfaceUid ) );
+ }
+
+
+CNcdNodeFolderProxy* CNcdNodeFolderProxy::NewL( MCatalogsClientServer& aSession,
+ TInt aHandle,
+ CNcdNodeManagerProxy& aNodeManager,
+ CNcdOperationManagerProxy& aOperationManager,
+ CNcdFavoriteManagerProxy& aFavoriteManager )
+ {
+ CNcdNodeFolderProxy* self =
+ CNcdNodeFolderProxy::NewLC(
+ aSession, aHandle, aNodeManager, aOperationManager, aFavoriteManager );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CNcdNodeFolderProxy* CNcdNodeFolderProxy::NewLC( MCatalogsClientServer& aSession,
+ TInt aHandle,
+ CNcdNodeManagerProxy& aNodeManager,
+ CNcdOperationManagerProxy& aOperationManager,
+ CNcdFavoriteManagerProxy& aFavoriteManager )
+ {
+ CNcdNodeFolderProxy* self =
+ new( ELeave ) CNcdNodeFolderProxy(
+ aSession, aHandle, aNodeManager, aOperationManager, aFavoriteManager );
+ // Using PushL because the object does not have any references yet
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+
+CNcdNodeFolderProxy::~CNcdNodeFolderProxy()
+ {
+ // Remove interfaces implemented by this class from the interface list.
+ // So, the interface list is up to date when this class object is deleted.
+ RemoveInterface( MNcdNodeContainer::KInterfaceUid );
+ RemoveInterface( MNcdNodeSearch::KInterfaceUid );
+
+ // Delete the objects that are owned by this class and provide functionality
+ // through the api.
+ // Notice that the api-objects are Released (not deleted) from the UI side.
+ // The node owns the data and the reference counter of the node keeps
+ // track of the api objects it owns. When the reference counter of the node
+ // reaches zero, it means that nobody is using the node or the classes owned
+ // by the node. If somebody is using the object owned by the node, the reference
+ // counter can not be zero until everything is released.
+ // Thus, the node may delete the data here.
+
+ delete iSearch;
+ iSearch = NULL;
+
+ delete iNodeSeenFolder;
+ iNodeSeenFolder = NULL;
+
+ iChildren.ResetAndDestroy();
+ }
+
+
+
+
+TInt CNcdNodeFolderProxy::ExpectedChildCount() const
+ {
+ return iExpectedChildCount;
+ }
+
+
+MNcdLoadNodeOperation* CNcdNodeFolderProxy::LoadL(
+ MNcdLoadNodeOperationObserver& aObserver )
+ {
+ DLTRACEIN((_L("This ns: %S, id: %S"), &Namespace(), &Id() ));
+ return CNcdNodeProxy::LoadL( aObserver );
+ }
+
+
+TInt CNcdNodeFolderProxy::ChildCount() const
+ {
+ return iExpectedChildCount;
+ }
+
+
+MNcdNode* CNcdNodeFolderProxy::ChildL( TInt aIndex )
+ {
+ DLTRACEIN(( _L("This parent: %S, %S"), &Namespace(), &Id(), aIndex ));
+ DLINFO(("aIndex = %d, expected childcount= %d, real child count = %d",
+ aIndex, iExpectedChildCount, iChildren.Count() ));
+
+ if ( aIndex < 0 || aIndex >= iExpectedChildCount )
+ {
+ // Nothing to be done
+ DLERROR(( "Index error. expected child count: %d Given index: %d",
+ iExpectedChildCount, aIndex ));
+ DASSERT( EFalse );
+ User::Leave( KErrArgument );
+ }
+
+ // search for a child with given index
+ const CNcdNodeIdentifier* child = NULL;
+ for( TInt i = 0 ; i < iChildren.Count() ; i++ )
+ {
+ if ( iChildren[i]->Index() == aIndex )
+ {
+ child = &iChildren[i]->Identifier();
+ }
+ else if ( iChildren[i]->Index() > aIndex )
+ {
+ // no sense in searching further
+ break;
+ }
+ }
+
+ if( child == NULL )
+ {
+ return NULL;
+ }
+
+ MNcdNode* node( NULL );
+
+ TRAPD( err, node = &NodeManager().NodeL( *child ) );
+
+ if ( err == KErrNotFound )
+ {
+ return NULL;
+ }
+
+ User::LeaveIfError( err );
+
+ // Increase the reference counter by one
+ node->AddRef();
+
+ DLTRACEOUT((""));
+
+ return node;
+ }
+
+
+MNcdLoadNodeOperation* CNcdNodeFolderProxy::LoadChildrenL( TInt aIndex,
+ TInt aSize,
+ TNcdChildLoadMode aMode,
+ MNcdLoadNodeOperationObserver& aObserver )
+ {
+ DLTRACEIN(("aIndex: %d, aSize: %d, expected child count: %d, load mode: %d",
+ aIndex, aSize, iExpectedChildCount, aMode ));
+
+ if ( aSize < 1
+ || aIndex < 0
+ || ( aMode == ELoadMetadata
+ && aSize != KMaxTInt
+ && aIndex + aSize > ChildCount() ) )
+ {
+ // Nothing to be done
+ DLERROR(( "Argument error. ChildCount: %d Given index: %d, size: %d",
+ ChildCount(), aIndex, aSize ));
+ User::Leave( KErrArgument );
+ }
+
+ if ( aSize == KMaxTInt )
+ {
+ // Because aSize is KMaxTInt, reduce it by the aIndex value.
+ // This way we will not have possible overload if aIndex is later added
+ // to the aSize value. It does not really matter what the aSize value is
+ // after this. KMaxTInt is so great value, that in all the cases the server
+ // request should give all the required items.
+ aSize -= aIndex;
+ DLINFO(("aSize was KMaxTInt. Reduced by index: %d", aSize));
+ }
+
+ DLTRACE(( _L("Node: %S, %S"), &Namespace(), &Id() ));
+
+ CNcdLoadNodeOperationProxy* operation =
+ OperationManager().CreateLoadNodeOperationL(
+ *this, ETrue, aSize, aIndex, 1, aMode );
+
+ if ( !operation )
+ {
+ DLTRACEOUT(("NULL"));
+ return NULL;
+ }
+
+ operation->AddObserverL( this );
+ operation->AddObserverL( &aObserver );
+
+ DLTRACEOUT((""));
+
+ return operation;
+ }
+
+TNcdContainerType CNcdNodeFolderProxy::ContainerType() const
+ {
+ if ( IsRemote() )
+ {
+ return ECatalog;
+ }
+ else
+ {
+ return EFolder;
+ }
+ }
+
+void CNcdNodeFolderProxy::OperationComplete(
+ MNcdLoadNodeOperation& /*aOperation*/, TInt aError )
+ {
+ DLTRACEIN(( "Error: %d", aError ));
+
+ if ( aError == KErrNone || aError == KNcdErrorSomeCatalogsFailedToLoad )
+ {
+ // update proxy's status from the server
+ TRAP_IGNORE( InternalizeL() );
+ }
+ }
+
+void CNcdNodeFolderProxy::InternalizeL()
+ {
+ DLTRACEIN((""));
+
+ // First call the parent internalizator. So, all the parent stuff will
+ // be initialized before folder specific data.
+ CNcdNodeProxy::InternalizeL();
+
+ // Add the search interface because it is availabe for all the folders
+ // that have at least one child.
+
+ // check that is search supported for this node
+ TBool isSearchSupported = IsSearchSupportedL();
+
+ DLINFO(( "isSearchSupported: %d, child count: %d", isSearchSupported,
+ ChildCount() ));
+ if ( isSearchSupported )
+ {
+ DLTRACE(("add search interface"));
+ if ( iSearch == NULL )
+ {
+ // Create new search because old one did not exist.
+ // Notice that the creation adds the interface to the node interface list
+ // automatically.
+ iSearch = CNcdNodeSearch::NewL( *this, OperationManager() );
+ }
+ }
+ else
+ {
+ DLTRACE(("remove search interface"));
+ delete iSearch;
+ iSearch = NULL;
+ }
+
+ InternalizeNodeSeenFolderL();
+
+ DLTRACEOUT((""));
+ }
+
+
+void CNcdNodeFolderProxy::InternalizeNodeDataL( RReadStream& aStream )
+ {
+ DLTRACEIN((""));
+
+ // First internalize parent data
+ CNcdNodeProxy::InternalizeNodeDataL( aStream );
+
+ // Get the children data here.
+
+ DLTRACE(("Handle children"));
+
+ // Clear the buffer because new childs will be appended
+ iChildren.ResetAndDestroy();
+
+ TInt childrenCount( aStream.ReadInt32L() );
+ DLTRACE(("Children: %d", childrenCount ));
+
+ TInt classObjectType( NcdNodeClassIds::ENcdNullObjectClassId );
+
+ for ( TInt i = 0; i < childrenCount; ++i )
+ {
+ // This is safe casting because enum is same as TInt
+ classObjectType =
+ static_cast<NcdNodeClassIds::TNcdNodeClassId>(aStream.ReadInt32L());
+ if ( NcdNodeClassIds::ENcdChildEntityClassId == classObjectType )
+ {
+ CNcdChildEntity* childEntity = CNcdChildEntity::NewLC( aStream );
+ iChildren.AppendL( childEntity );
+ CleanupStack::Pop( childEntity );
+ DLINFO((_L("Added child, id: %S, array index: %d, real index: %d"),
+ &childEntity->Identifier().NodeId(), i, childEntity->Index() ));
+ }
+ else
+ {
+ // For debug purposes
+ DLERROR(("Wrong class id"));
+ DASSERT( EFalse );
+
+ // Wrong kind of class object info
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ // Show node info here, after the internalization has been done.
+ DLTRACEOUT(( _L("Node: %S, %S, %d"),
+ &Namespace(), &Id(), NodeIdentifier().ClientUid().iUid ));
+ }
+
+
+void CNcdNodeFolderProxy::InternalizeNodeLinkDataL( RReadStream& aStream )
+ {
+ DLTRACEIN(( _L("Node: %S, %S"), &Namespace(), &Id() ));
+
+ // First internalize parent data
+ CNcdNodeProxy::InternalizeNodeLinkDataL( aStream );
+
+ // Then, set the data for this class object
+
+ iExpectedChildCount = aStream.ReadInt32L();
+
+ DLTRACEOUT((""));
+ }
+
+TBool CNcdNodeFolderProxy::IsSearchSupportedL()
+ {
+ DLTRACEIN((""));
+ // check if this node has search capability set
+ return NodeManager().IsCapabilitySupportedL( NodeIdentifier(),
+ NcdCapabilities::KSearch );
+ }
+
+
+void CNcdNodeFolderProxy::InternalizeNodeSeenFolderL()
+ {
+ DLTRACEIN((""));
+
+ if ( iNodeSeenFolder )
+ {
+ iNodeSeenFolder->InternalizeL();
+ }
+ else
+ {
+ // Create the object.
+ // Get the handle at first.
+ TInt handle( 0 );
+ User::LeaveIfError(
+ ClientServerSession().SendSync(
+ NcdNodeFunctionIds::ENcdNodeSeenFolderHandle,
+ KNullDesC(),
+ handle,
+ Handle() ) );
+
+ DLINFO(( "handle: %d", handle ));
+
+ iNodeSeenFolder = CNcdNodeSeenFolderProxy::NewL(
+ ClientServerSession(), handle, *this );
+ }
+ }
+
+