--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/client/src/ncdsubscriptiongroupproxy.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,465 @@
+/*
+* 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 CNcdSubscriptionGroupProxy class implementation
+*
+*/
+
+
+#include "ncdsubscriptiongroupproxy.h"
+
+#include "ncdsubscriptionproxy.h"
+#include "catalogsclientserver.h"
+#include "ncdnodeidentifier.h"
+#include "ncdnodefunctionids.h"
+#include "ncdnodeclassids.h"
+#include "catalogsutils.h"
+#include "catalogsconstants.h"
+#include "ncdnodeidentifier.h"
+
+#include "catalogsdebug.h"
+
+// ======== PUBLIC MEMBER FUNCTIONS ========
+
+CNcdSubscriptionGroupProxy::CNcdSubscriptionGroupProxy(
+ MCatalogsClientServer& aSession,
+ TInt aHandle,
+ CNcdOperationManagerProxy& aOperationManager,
+ CNcdNodeManagerProxy& aNodeManager )
+ : CNcdBaseProxy( aSession, aHandle ),
+ iOperationManager( aOperationManager ),
+ iNodeManager( aNodeManager )
+ {
+ }
+
+
+void CNcdSubscriptionGroupProxy::ConstructL()
+ {
+ // Is it ok if internalization fails here?
+ // Earlier comment: Do not let the internalization leave here.
+ // This object may be reinternalized later.
+ InternalizeL();
+ }
+
+
+CNcdSubscriptionGroupProxy* CNcdSubscriptionGroupProxy::NewL(
+ MCatalogsClientServer& aSession,
+ TInt aHandle,
+ CNcdOperationManagerProxy& aOperationManager,
+ CNcdNodeManagerProxy& aNodeManager )
+ {
+ CNcdSubscriptionGroupProxy* self =
+ CNcdSubscriptionGroupProxy::NewLC( aSession,
+ aHandle,
+ aOperationManager,
+ aNodeManager );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CNcdSubscriptionGroupProxy* CNcdSubscriptionGroupProxy::NewLC(
+ MCatalogsClientServer& aSession,
+ TInt aHandle,
+ CNcdOperationManagerProxy& aOperationManager,
+ CNcdNodeManagerProxy& aNodeManager )
+ {
+ CNcdSubscriptionGroupProxy* self =
+ new( ELeave ) CNcdSubscriptionGroupProxy( aSession,
+ aHandle,
+ aOperationManager,
+ aNodeManager );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+
+CNcdSubscriptionGroupProxy::~CNcdSubscriptionGroupProxy()
+ {
+ DeleteSubscriptions();
+
+ delete iOriginNodeIdentifier;
+ }
+
+
+void CNcdSubscriptionGroupProxy::InternalizeL()
+ {
+ DLTRACEIN((""));
+
+ // Request all the purchase option ids from server side.
+ CDesCArray* poIds = RequestPurchaseOptionIdsL();
+ CleanupStack::PushL( poIds );
+
+ // Delete the subscriptions that don't exist in the server side.
+ DeleteMissingSubscriptions( *poIds );
+
+ TRAPD( err,
+ {
+ // Reinternalize the existing subscriptions.
+ for ( TInt i = 0; i < iSubscriptions.Count(); i++ )
+ {
+ iSubscriptions[i]->InternalizeL();
+ }
+
+ // Remove the existing subscriptions from the array.
+ for ( TInt i = poIds->Count() - 1 ; i >= 0; i-- )
+ {
+ if ( Subscription( (*poIds)[i] ) != NULL )
+ {
+ poIds->Delete( i );
+ }
+ }
+
+ // Internalize the group with the new subscriptions.
+ InternalizeL( *poIds );
+ });
+
+ CleanupStack::PopAndDestroy( poIds );
+
+ if ( err != KErrNone )
+ {
+ DLINFO((( "Internalize error: %d" ), err ));
+ DeleteSubscriptions();
+ User::Leave( err );
+ }
+
+ DLTRACEOUT((""));
+ }
+
+const RPointerArray<CNcdSubscriptionProxy>&
+ CNcdSubscriptionGroupProxy::Subscriptions()
+ {
+ return iSubscriptions;
+ }
+
+CNcdSubscriptionProxy* CNcdSubscriptionGroupProxy::Subscription(
+ const TDesC& aPurchaseOptionId )
+ {
+ DLTRACEIN((""));
+ // Search for the subscriptions
+
+ TInt subscriptionCount( iSubscriptions.Count() );
+ TInt subscriptionIndexer( 0 );
+ while ( subscriptionIndexer < subscriptionCount )
+ {
+
+ TDesC& subscriptionPurchaseOptionId =
+ iSubscriptions[subscriptionIndexer]->PurchaseOptionId();
+
+ if ( aPurchaseOptionId == subscriptionPurchaseOptionId )
+ {
+ DLTRACEOUT(("Found."));
+ return iSubscriptions[subscriptionIndexer];
+ }
+
+ ++subscriptionIndexer;
+ }
+
+ DLTRACEOUT(("Did not find."));
+ return NULL;
+ }
+
+const CNcdNodeIdentifier& CNcdSubscriptionGroupProxy::Identifier() const
+ {
+ return *iOriginNodeIdentifier;
+ }
+
+const TDesC& CNcdSubscriptionGroupProxy::EntityId() const
+ {
+ return iOriginNodeIdentifier->NodeId();
+ }
+
+const TDesC& CNcdSubscriptionGroupProxy::Namespace() const
+ {
+ return iOriginNodeIdentifier->NodeNameSpace();
+ }
+
+const TDesC& CNcdSubscriptionGroupProxy::ServerUri() const
+ {
+ return iOriginNodeIdentifier->ServerUri();
+ }
+
+// ---------------------------------------------------------------------------
+// Icon data is not stored on the proxies. It is retrieved from the server
+// side every time the data is requested.
+// ---------------------------------------------------------------------------
+//
+HBufC8* CNcdSubscriptionGroupProxy::IconL() const
+ {
+ HBufC8* icon( RequestIconDataL() );
+ return icon;
+ }
+
+CNcdOperationManagerProxy&
+ CNcdSubscriptionGroupProxy::OperationManager() const
+ {
+ return iOperationManager;
+ }
+
+
+// Other functions
+
+
+void CNcdSubscriptionGroupProxy::InternalizeDataL( RReadStream& aStream )
+ {
+ DLTRACEIN((""));
+
+ if ( !iOriginNodeIdentifier )
+ {
+ iOriginNodeIdentifier = CNcdNodeIdentifier::NewL();
+ }
+ iOriginNodeIdentifier->InternalizeL( aStream );
+
+ DLTRACE(( _L(" Internalizing subscriptiongroup info in proxy, EntityId: %S, Namespace: %S, server uri: %S"),
+ &iOriginNodeIdentifier->NodeId(),
+ &iOriginNodeIdentifier->NodeNameSpace(),
+ &iOriginNodeIdentifier->ServerUri() ));
+
+ TInt handleAmount( 0 );
+ handleAmount = aStream.ReadInt32L();
+
+ DLTRACE(( "Amount of subscription handles received: %d",
+ handleAmount ));
+
+ TInt tmpProxyHandle( -1 ); // handle of a proxy read from stream
+
+ // temporary pointer to subscription that is going to be
+ // added to subscriptions-array
+ CNcdSubscriptionProxy* tmpSubscription( NULL );
+
+ // In error handling, objects with received handles
+ // should be released from the server side session
+ // if proxies for them cannot be created.
+
+ TInt handleIndex( 0 );
+ while ( handleIndex < handleAmount )
+ {
+ tmpProxyHandle = aStream.ReadInt32L();
+
+ DLTRACE(( "Received subscription handle: %i",
+ tmpProxyHandle ));
+
+ tmpSubscription = CNcdSubscriptionProxy::NewL(
+ ClientServerSession(),
+ tmpProxyHandle,
+ OperationManager(),
+ iNodeManager,
+ *this );
+
+
+ TRAPD( addError, iSubscriptions.AppendL( tmpSubscription ) );
+ if ( addError != KErrNone )
+ {
+ delete tmpSubscription;
+ User::Leave( addError );
+ }
+
+ tmpSubscription->InternalAddRef();
+
+ ++handleIndex;
+ }
+
+ DLTRACEOUT((""));
+ }
+
+void CNcdSubscriptionGroupProxy::DeleteSubscriptions()
+ {
+
+ // If references to subscriptions are left, set it obsolete.
+
+ TInt subscriptionsCount( iSubscriptions.Count() );
+ TInt subscriptionsIndexer( 0 );
+ while ( subscriptionsIndexer < subscriptionsCount )
+ {
+ DeleteSubscription( iSubscriptions[subscriptionsIndexer] );
+ ++subscriptionsIndexer;
+ }
+
+ iSubscriptions.Reset();
+ }
+
+CDesCArray* CNcdSubscriptionGroupProxy::RequestPurchaseOptionIdsL() const
+ {
+ DLTRACEIN((""));
+
+ HBufC8* data( NULL );
+
+ // Because we do not know the exact size of the data, use
+ // the alloc method, which creates the buffer of the right size
+ // and sets the pointer to point to the created buffer.
+ User::LeaveIfError(
+ ClientServerSession().
+ SendSyncAlloc( NcdNodeFunctionIds::ENcdPurchaseOptionIds,
+ KNullDesC8,
+ data,
+ Handle(),
+ 0 ) );
+
+ if ( data == NULL )
+ {
+ DLERROR((""));
+ User::Leave( KErrNotFound );
+ }
+
+ CleanupStack::PushL( data );
+
+ // Read the data from the stream and create the array
+ RDesReadStream stream( *data );
+ CleanupClosePushL( stream );
+
+ CDesCArray* poIds = new( ELeave ) CDesCArrayFlat( 5 );
+ CleanupStack::PushL( poIds );
+
+ TInt idCount = stream.ReadInt32L();
+ for ( TInt i = 0; i < idCount; i++ )
+ {
+ HBufC* id( NULL );
+ InternalizeDesL( id, stream );
+ CleanupStack::PushL( id );
+ poIds->AppendL( *id );
+ CleanupStack::PopAndDestroy( id );
+ }
+
+ CleanupStack::Pop( poIds );
+ CleanupStack::PopAndDestroy( &stream );
+ CleanupStack::PopAndDestroy( data );
+
+ return poIds;
+ }
+
+void CNcdSubscriptionGroupProxy::DeleteMissingSubscriptions(
+ const CDesCArray& aPurchaseOptionIds )
+ {
+ DLTRACEIN((""));
+
+ for ( TInt i = iSubscriptions.Count() - 1; i >= 0; i-- )
+ {
+ TInt pos( 0 );
+ if ( aPurchaseOptionIds.Find( iSubscriptions[i]->PurchaseOptionId(), pos )
+ != 0 )
+ {
+ DeleteSubscription( iSubscriptions[i] );
+ iSubscriptions.Remove( i );
+ }
+ }
+ }
+
+void CNcdSubscriptionGroupProxy::DeleteSubscription(
+ CNcdSubscriptionProxy* aSubscription )
+ {
+ if ( aSubscription->TotalRefCount() > 1 )
+ {
+ aSubscription->SetObsolete();
+ }
+ aSubscription->InternalRelease();
+ }
+
+void CNcdSubscriptionGroupProxy::InternalizeL(
+ const CDesCArray& aPurchaseOptionIds )
+ {
+ DLTRACEIN((""));
+
+ CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
+ CleanupStack::PushL( buf );
+
+ RBufWriteStream writeStream( *buf );
+ CleanupClosePushL( writeStream );
+
+ writeStream.WriteInt32L( aPurchaseOptionIds.Count() );
+ for ( TInt i = 0; i < aPurchaseOptionIds.Count(); i++ )
+ {
+ ExternalizeDesL( aPurchaseOptionIds[i], writeStream );
+ }
+
+ HBufC8* outputData = HBufC8::NewL( buf->Size() );
+ outputData->Des().Copy( buf->Ptr( 0 ) );
+
+ CleanupStack::PopAndDestroy( &writeStream );
+ CleanupStack::PopAndDestroy( buf );
+
+ CleanupStack::PushL( outputData );
+
+ HBufC8* inputData( NULL );
+
+ // Because we do not know the exact size of the data, use
+ // the alloc method, which creates the buffer of the right size
+ // and sets the pointer to point to the created buffer.
+ User::LeaveIfError(
+ ClientServerSession().
+ SendSyncAlloc( NcdNodeFunctionIds::ENcdInternalize,
+ *outputData,
+ inputData,
+ Handle(),
+ 0 ) );
+
+ if ( inputData == NULL )
+ {
+ DLERROR((""));
+ User::Leave( KErrNotFound );
+ }
+
+ CleanupStack::PopAndDestroy( outputData );
+ CleanupStack::PushL( inputData );
+
+ // Read the data from the stream and create the array
+ RDesReadStream stream( *inputData );
+ CleanupClosePushL( stream );
+
+ InternalizeDataL( stream );
+
+ CleanupStack::PopAndDestroy( &stream );
+ CleanupStack::PopAndDestroy( inputData );
+ }
+
+
+HBufC8* CNcdSubscriptionGroupProxy::RequestIconDataL() const
+ {
+ DLTRACEIN((""));
+
+ HBufC8* data( NULL );
+
+ // Because we do not know the exact size of the data, use
+ // the alloc method, which creates the buffer of the right size
+ // and sets the pointer to point to the created buffer.
+ // Get the icon data from the subscription group implementation
+ // on the server side.
+ User::LeaveIfError(
+ ClientServerSession().
+ SendSyncAlloc( NcdNodeFunctionIds::ENcdSubscriptionIconData,
+ KNullDesC8,
+ data,
+ Handle(),
+ 0 ) );
+
+ if ( data == NULL )
+ {
+ DLERROR((""));
+ User::Leave( KErrNotFound );
+ }
+
+ CleanupStack::PushL( data );
+
+ // Read the data from the stream and insert it to variables
+ RDesReadStream stream( *data );
+ CleanupClosePushL( stream );
+
+ HBufC8* iconData( NULL );
+ InternalizeDesL( iconData, stream );
+
+ // Closes the stream
+ CleanupStack::PopAndDestroy( &stream );
+ CleanupStack::PopAndDestroy( data );
+
+ DLTRACEOUT((""));
+ return iconData;
+ }