ncdengine/provider/client/src/ncdsubscriptiongroupproxy.cpp
changeset 0 ba25891c3a9e
--- /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;
+    }