ncdengine/provider/server/src/ncdsubscriptiongroup.cpp
changeset 4 32704c33136d
equal deleted inserted replaced
-1:000000000000 4:32704c33136d
       
     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 CNcdSubscriptionGroupGroup class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdsubscriptiongroup.h"
       
    20 #include "ncdsubscriptionimpl.h"
       
    21 #include "catalogssession.h"
       
    22 #include "catalogsbasemessage.h"
       
    23 #include "ncdnodefunctionids.h"
       
    24 #include "catalogsconstants.h"
       
    25 #include "catalogsutils.h"
       
    26 #include "catalogsdebug.h"
       
    27 #include "ncd_pp_subscription.h"
       
    28 #include "ncdpurchaseoptionimpl.h"
       
    29 #include "ncdserverpartofsubscription.h"
       
    30 #include "ncdserverupgrade.h"
       
    31 #include "ncdnodeidentifier.h"
       
    32 
       
    33 
       
    34 CNcdSubscriptionGroup::CNcdSubscriptionGroup() : CCatalogsCommunicable()
       
    35     {
       
    36     }
       
    37 
       
    38 void CNcdSubscriptionGroup::ConstructL()
       
    39     {
       
    40     iOriginNodeIdentifier = CNcdNodeIdentifier::NewL();
       
    41     iIcon = KNullDesC8().AllocL();
       
    42     } 
       
    43 
       
    44 CNcdSubscriptionGroup* CNcdSubscriptionGroup::NewL()
       
    45     {
       
    46     CNcdSubscriptionGroup* self =   
       
    47         CNcdSubscriptionGroup::NewLC();
       
    48     CleanupStack::Pop( self );
       
    49     return self;        
       
    50     }
       
    51 
       
    52 CNcdSubscriptionGroup* CNcdSubscriptionGroup::NewLC()
       
    53     {
       
    54     CNcdSubscriptionGroup* self = 
       
    55         new( ELeave ) CNcdSubscriptionGroup();
       
    56     CleanupClosePushL( *self );
       
    57     self->ConstructL();
       
    58     return self;        
       
    59     }
       
    60 
       
    61 
       
    62 CNcdSubscriptionGroup::~CNcdSubscriptionGroup()
       
    63     {
       
    64     DLTRACEIN((""));
       
    65 
       
    66     ResetMemberVariables();
       
    67 
       
    68     DLTRACEOUT((""));
       
    69     }
       
    70 
       
    71 void CNcdSubscriptionGroup::InternalizeSubscriptionL(
       
    72     const CNcdPurchaseOptionImpl& aData )
       
    73     {
       
    74     DLTRACEIN((""));
       
    75 
       
    76     // get old subscription or if not found create a new one
       
    77 
       
    78     CNcdSubscription& subscription = SubscriptionL( aData.Id() );
       
    79     
       
    80     // We have index of the subscription so use the purchase
       
    81     // option on it.
       
    82     subscription.InternalizeL( aData );
       
    83     DLTRACEOUT((""));
       
    84     }
       
    85 
       
    86 
       
    87 void CNcdSubscriptionGroup::InternalizeSubscriptionL(
       
    88     MNcdPreminetProtocolSubscription& aSubscription )
       
    89     {
       
    90     DLTRACEIN((""));
       
    91 
       
    92     // get old subscription or if not found create a new one
       
    93 
       
    94     CNcdSubscription& subscription =
       
    95         SubscriptionL( aSubscription.PurchaseOptionId() );
       
    96     
       
    97     // We have index of the subscription so use the protocol
       
    98     // entity on it.
       
    99     subscription.InternalizeL( aSubscription );
       
   100     DLTRACEOUT((""));
       
   101     }
       
   102 
       
   103         
       
   104 void CNcdSubscriptionGroup::RemoveSubscriptionL(
       
   105     const TDesC& aPurchaseOptionId )
       
   106     {
       
   107     TInt index = FindSubscriptionL( aPurchaseOptionId );
       
   108     
       
   109     // Manager has one reference count to all objects
       
   110     // so that for one Close is said to the subscription.
       
   111     iSubscriptions[index]->Close();
       
   112     iSubscriptions.Remove( index );
       
   113     }
       
   114 
       
   115 void CNcdSubscriptionGroup::SetRecentlyUpdatedL(
       
   116     TBool aNewState,
       
   117     const TDesC& aPurchaseOptionId )
       
   118     {
       
   119     DLTRACEIN((""));
       
   120     // Leave if no subscription found.
       
   121     TInt index = FindSubscriptionL( aPurchaseOptionId );
       
   122     DLINFO(("subscription found"));
       
   123     CNcdSubscription* subscription = iSubscriptions[index];
       
   124     subscription->SetRecentlyUpdated( aNewState );
       
   125     DLTRACEOUT((""));
       
   126     }
       
   127    
       
   128 TBool CNcdSubscriptionGroup::RecentlyUpdatedL(
       
   129     const TDesC& aPurchaseOptionId ) const
       
   130     {
       
   131     DLTRACEIN((""));
       
   132     // Leave if no subscription found.
       
   133     TInt index = FindSubscriptionL( aPurchaseOptionId );
       
   134     CNcdSubscription* subscription = iSubscriptions[index];
       
   135     TBool recentlyCreated = subscription->RecentlyUpdated();
       
   136     DLTRACEOUT((""));
       
   137     return recentlyCreated;
       
   138     }
       
   139 
       
   140 TBool CNcdSubscriptionGroup::RemoveUnmarkedSubscriptionsAndUnmarkL()
       
   141     {
       
   142     TBool changesMade( EFalse );
       
   143 
       
   144     TInt subscriptionIndexer( iSubscriptions.Count() - 1 );
       
   145     while ( subscriptionIndexer > -1 )
       
   146         {        
       
   147         if ( !iSubscriptions[subscriptionIndexer]->RecentlyUpdated() )
       
   148             {
       
   149             // Manager has one reference count to all objects
       
   150             // so that for one Close is said to the subscription.
       
   151             iSubscriptions[subscriptionIndexer]->Close();
       
   152             iSubscriptions.Remove( subscriptionIndexer );
       
   153             changesMade = ETrue;
       
   154             }
       
   155         else
       
   156             {
       
   157             // Resetting the flag for later use
       
   158             iSubscriptions[subscriptionIndexer]->
       
   159                 SetRecentlyUpdated( EFalse );
       
   160             }                
       
   161         --subscriptionIndexer;
       
   162         }
       
   163     return changesMade;    
       
   164     }
       
   165 
       
   166     
       
   167 void CNcdSubscriptionGroup::SetEntityInfoL( const TDesC& aEntityId,
       
   168                                             const TDesC& aNamespace,
       
   169                                             const TDesC& aServerUri,
       
   170                                             const TUid aClientUid )
       
   171     {
       
   172     DLTRACEIN((""));
       
   173     
       
   174     delete iOriginNodeIdentifier;
       
   175     iOriginNodeIdentifier = NULL;
       
   176     iOriginNodeIdentifier = CNcdNodeIdentifier::NewL( aNamespace,
       
   177                                                       aEntityId,
       
   178                                                       aServerUri,
       
   179                                                       aClientUid );
       
   180     }
       
   181 
       
   182 const TDesC8& CNcdSubscriptionGroup::Icon()
       
   183     {
       
   184     // Probably would be good just to take a pointer here
       
   185     // not to create a copy
       
   186     DLTRACEIN((""));
       
   187     if( iIcon == NULL )
       
   188         {
       
   189         return KNullDesC8;
       
   190         }
       
   191         
       
   192     return *iIcon;
       
   193     }
       
   194 
       
   195 void CNcdSubscriptionGroup::SetIconL( const TDesC8& aIcon )
       
   196     {
       
   197     DLTRACEIN((""));
       
   198     delete iIcon;
       
   199     iIcon = NULL;
       
   200     iIcon = aIcon.AllocL();
       
   201     }
       
   202 
       
   203 const TDesC& CNcdSubscriptionGroup::EntityId() const
       
   204     {
       
   205     return iOriginNodeIdentifier->NodeId();
       
   206     }
       
   207 
       
   208 const TDesC& CNcdSubscriptionGroup::Namespace() const
       
   209     {
       
   210     return iOriginNodeIdentifier->NodeNameSpace();
       
   211     }
       
   212     
       
   213 const TDesC& CNcdSubscriptionGroup::ServerUri() const
       
   214     {
       
   215     return iOriginNodeIdentifier->ServerUri();
       
   216     }
       
   217 
       
   218 CNcdNodeIdentifier& CNcdSubscriptionGroup::OriginNodeIdentifier() const
       
   219     {
       
   220     return *iOriginNodeIdentifier;
       
   221     }
       
   222 
       
   223 CNcdSubscription& CNcdSubscriptionGroup::SubscriptionIfExistsL(
       
   224     const TDesC& aPurchaseOptionId ) const 
       
   225     {
       
   226     DLTRACEIN((""));
       
   227     TInt index = FindSubscriptionL( aPurchaseOptionId );
       
   228     return *iSubscriptions[index];
       
   229     }
       
   230 
       
   231 TInt CNcdSubscriptionGroup::SubscriptionCount() const
       
   232     {
       
   233     return iSubscriptions.Count();
       
   234     }
       
   235 
       
   236 void CNcdSubscriptionGroup::AppendIncompleteSubscriptionIDsL(
       
   237     RPointerArray<CNcdNodeIdentifier>& aNodeIds,
       
   238     CDesCArrayFlat& aPurchaseOptionIDs )
       
   239     {
       
   240     TInt subscriptionIndex( 0 );
       
   241     const TInt KSubscriptionCount( iSubscriptions.Count() );
       
   242     while( subscriptionIndex < KSubscriptionCount )
       
   243         {
       
   244         if ( iSubscriptions[subscriptionIndex]->Name() == KNullDesC ||
       
   245              iIcon == NULL || *iIcon == KNullDesC8 )
       
   246             {
       
   247             aNodeIds.AppendL(
       
   248                 CNcdNodeIdentifier::NewL( OriginNodeIdentifier() ) );
       
   249             aPurchaseOptionIDs.AppendL(
       
   250                 iSubscriptions[subscriptionIndex]->PurchaseOptionId() );
       
   251             }
       
   252         ++subscriptionIndex;
       
   253         }
       
   254     }
       
   255       
       
   256 // Internalization from and externalization to the database
       
   257     
       
   258 void CNcdSubscriptionGroup::ExternalizeL( RWriteStream& aStream )
       
   259     {
       
   260     DLTRACEIN((""));
       
   261 
       
   262     // Set all the membervariable values to the stream. So,
       
   263     // that the stream may be used later to create a new
       
   264     // object.
       
   265 
       
   266     iOriginNodeIdentifier->ExternalizeL( aStream );
       
   267 
       
   268     DLTRACE(( _L(" Externalizing subscriptiongroup info, EntityId: %S, Namespace: %S, server uri: %S"),
       
   269               &iOriginNodeIdentifier->NodeId(),
       
   270               &iOriginNodeIdentifier->NodeNameSpace(), 
       
   271               &iOriginNodeIdentifier->ServerUri() ));
       
   272 
       
   273     if ( iIcon != NULL )
       
   274         {
       
   275         ExternalizeDesL( *iIcon, aStream );
       
   276         DLTRACE(( "Externalizing subscription info, icon" ));
       
   277         }
       
   278     else
       
   279         {
       
   280         ExternalizeDesL( KNullDesC8, aStream );
       
   281         DLINFO(( "Externalizing subscription info, no icon found." ));
       
   282         }
       
   283 
       
   284     TInt32 subscriptionAmount( iSubscriptions.Count() );
       
   285     aStream.WriteInt32L( subscriptionAmount );
       
   286 
       
   287     DLTRACE(( _L( "Externalizing also %d subscriptions." ),
       
   288               subscriptionAmount ));
       
   289 
       
   290     
       
   291     TInt32 subscriptionIndexer( 0 );
       
   292     while ( subscriptionIndexer < subscriptionAmount )
       
   293         {        
       
   294         iSubscriptions[subscriptionIndexer]->ExternalizeL( aStream );        
       
   295         ++subscriptionIndexer;
       
   296         }
       
   297 
       
   298     DLTRACEOUT((""));
       
   299     }
       
   300 
       
   301 void CNcdSubscriptionGroup::InternalizeL( RReadStream& aStream )
       
   302     {
       
   303     DLTRACEIN((""));
       
   304 
       
   305     ResetMemberVariables();
       
   306 
       
   307     if ( !iOriginNodeIdentifier )
       
   308         {
       
   309         iOriginNodeIdentifier = CNcdNodeIdentifier::NewL();
       
   310         }        
       
   311     iOriginNodeIdentifier->InternalizeL( aStream );
       
   312 
       
   313     DLTRACE(( _L(" Internalizing subscriptiongroup info, EntityId: %S, Namespace: %S, server uri: %S"),
       
   314               &iOriginNodeIdentifier->NodeId(),
       
   315               &iOriginNodeIdentifier->NodeNameSpace(), 
       
   316               &iOriginNodeIdentifier->ServerUri() ));
       
   317 
       
   318     InternalizeDesL( iIcon, aStream );
       
   319 
       
   320     TInt32 subscriptionAmount( aStream.ReadInt32L() );
       
   321 
       
   322     DLTRACE(( _L( "Internalizing also %d subscriptions." ),
       
   323               subscriptionAmount ));
       
   324     
       
   325     TInt32 subscriptionIndexer( 0 );
       
   326     while ( subscriptionIndexer < subscriptionAmount )
       
   327         {        
       
   328         CNcdSubscription* tempSubscription = CNcdSubscription::NewLC( *this );
       
   329         iSubscriptions.AppendL( tempSubscription );        
       
   330         CleanupStack::Pop( tempSubscription );
       
   331         
       
   332         tempSubscription->InternalizeL( aStream );
       
   333         
       
   334         ++subscriptionIndexer;
       
   335         }
       
   336 
       
   337     DLTRACEOUT((""));
       
   338     }
       
   339 
       
   340 
       
   341 
       
   342 void CNcdSubscriptionGroup::ReceiveMessage( MCatalogsBaseMessage* aMessage,
       
   343                                   TInt aFunctionNumber )
       
   344     {
       
   345     DLTRACEIN((""));    
       
   346 
       
   347     DASSERT( aMessage );
       
   348 
       
   349     // Now, we can be sure that rest of the time iMessage exists.
       
   350     // This member variable is set for the CounterPartLost function.
       
   351     iMessage = aMessage;
       
   352     
       
   353     TInt trapError( KErrNone );
       
   354     
       
   355     // Check which function is called by the proxy side object.
       
   356     // Function number are located in ncdnodefunctinoids.h file.
       
   357     switch( aFunctionNumber )
       
   358         {
       
   359         case NcdNodeFunctionIds::ENcdPurchaseOptionIds:
       
   360             // Purchase option ids of subscriptions requested from proxy side.
       
   361             TRAP( trapError, PurchaseOptionIdsRequestL( *aMessage ) );
       
   362             break;
       
   363             
       
   364         case NcdNodeFunctionIds::ENcdInternalize:
       
   365             // Internalize the proxy side according to the data
       
   366             // of this object.
       
   367             TRAP( trapError, InternalizeRequestL( *aMessage ) );
       
   368             break;
       
   369 
       
   370         case NcdNodeFunctionIds::ENcdSubscriptionIconData:
       
   371             // Icon data of this subscription group
       
   372             TRAP( trapError, IconDataRequestL( *aMessage ) );
       
   373             break;
       
   374 
       
   375         case NcdNodeFunctionIds::ENcdRelease:
       
   376             // The proxy does not want to use this object anymore.
       
   377             // So, release the handle from the session.
       
   378             ReleaseRequest( *aMessage );
       
   379             break;
       
   380                     
       
   381         default:
       
   382             break;
       
   383         }
       
   384 
       
   385     if ( trapError != KErrNone )
       
   386         {
       
   387         // Because something went wrong, the complete has not been
       
   388         // yet called for the message.
       
   389         // So, inform the client about the error if the
       
   390         // message is still available.
       
   391         aMessage->CompleteAndRelease( trapError );
       
   392         }
       
   393 
       
   394     // Because the message should not be used after this, set it NULL.
       
   395     // So, CounterPartLost function will know that no messages are
       
   396     // waiting the response at the moment.
       
   397     iMessage = NULL;        
       
   398     
       
   399     DLTRACEOUT((""));
       
   400     }
       
   401 
       
   402 void CNcdSubscriptionGroup::CounterPartLost(
       
   403     const MCatalogsSession& aSession )
       
   404     {
       
   405     // This function may be called whenever -- when the message is waiting
       
   406     // response or when the message does not exist.
       
   407     // iMessage may be NULL here, because in the end of the
       
   408     // ReceiveMessage it is set to NULL. The life time of the message
       
   409     // ends shortly after CompleteAndRelease is called.
       
   410     if ( iMessage != NULL )
       
   411         {
       
   412         iMessage->CounterPartLost( aSession );
       
   413         }
       
   414     }
       
   415 
       
   416 
       
   417 void CNcdSubscriptionGroup::PurchaseOptionIdsRequestL(
       
   418     MCatalogsBaseMessage& aMessage ) const 
       
   419     {
       
   420     DLTRACEIN((""));
       
   421     
       
   422     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   423     CleanupStack::PushL( buf );
       
   424    
       
   425     RBufWriteStream stream( *buf );
       
   426     CleanupClosePushL( stream );
       
   427     
       
   428     stream.WriteInt32L( iSubscriptions.Count() );
       
   429     for ( TInt i = 0; i < iSubscriptions.Count(); i++ ) 
       
   430         {
       
   431         ExternalizeDesL( iSubscriptions[i]->PurchaseOptionId(), stream );
       
   432         }
       
   433         
       
   434     CleanupStack::PopAndDestroy( &stream );
       
   435     
       
   436     // If this leaves, ReceiveMessage will complete the message.
       
   437     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );
       
   438     CleanupStack::PopAndDestroy( buf );
       
   439     }
       
   440 
       
   441 
       
   442 void CNcdSubscriptionGroup::InternalizeRequestL(
       
   443     MCatalogsBaseMessage& aMessage ) const
       
   444     {
       
   445     DLTRACEIN((""));
       
   446     
       
   447 
       
   448     // Read the purchase option ids from the message obtained.
       
   449     CDesCArray* poIds = new( ELeave ) CDesCArrayFlat( 5 );
       
   450     CleanupStack::PushL( poIds );
       
   451     RBuf8 inputMsg;
       
   452     CleanupClosePushL( inputMsg );
       
   453     inputMsg.CreateL( aMessage.InputLength() );
       
   454     User::LeaveIfError( aMessage.ReadInput( inputMsg ) );
       
   455     
       
   456     RDesReadStream inputStream( inputMsg );
       
   457     CleanupClosePushL( inputStream );
       
   458     
       
   459     TInt subscriptionCount = inputStream.ReadInt32L();
       
   460     for ( TInt i = 0; i < subscriptionCount; i++ ) 
       
   461         {
       
   462         HBufC* poId( NULL );
       
   463         InternalizeDesL( poId, inputStream );
       
   464         CleanupStack::PushL( poId );
       
   465         poIds->AppendL( *poId );
       
   466         CleanupStack::PopAndDestroy( poId );
       
   467         }
       
   468         
       
   469     CleanupStack::PopAndDestroy( &inputStream );
       
   470     CleanupStack::PopAndDestroy( &inputMsg );    
       
   471     
       
   472     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   473     CleanupStack::PushL( buf );
       
   474     
       
   475     RBufWriteStream stream( *buf );
       
   476     CleanupClosePushL( stream );
       
   477 
       
   478     // Session info has to be passed to be able
       
   479     // to register objects as receivers into the session
       
   480     MCatalogsSession& session = aMessage.Session();
       
   481     
       
   482     // Include all the necessary node data to the stream
       
   483     ExternalizeDataForRequestL( session, *poIds, stream );     
       
   484     
       
   485     
       
   486     // Commits data to the stream when closing.
       
   487     CleanupStack::PopAndDestroy( &stream );
       
   488 
       
   489 
       
   490     // If this leaves, ReceiveMessage will complete the message.
       
   491     // NOTE: that here we expect that the buffer contains at least
       
   492     // some data. So, make sure that ExternalizeDataForRequestL inserts
       
   493     // something to the buffer.
       
   494     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );        
       
   495         
       
   496     
       
   497     DLTRACE(("Deleting the buf"));
       
   498     CleanupStack::PopAndDestroy( buf );
       
   499     CleanupStack::PopAndDestroy( poIds );
       
   500         
       
   501     DLTRACEOUT((""));
       
   502     }
       
   503     
       
   504 void CNcdSubscriptionGroup::IconDataRequestL(
       
   505     MCatalogsBaseMessage& aMessage ) const 
       
   506     {
       
   507     DLTRACEIN((""));
       
   508     
       
   509     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   510     CleanupStack::PushL( buf );
       
   511    
       
   512     RBufWriteStream stream( *buf );
       
   513     CleanupClosePushL( stream );
       
   514     
       
   515     ExternalizeDesL( *iIcon, stream );
       
   516 
       
   517     CleanupStack::PopAndDestroy( &stream );
       
   518     
       
   519     // If this leaves, ReceiveMessage will complete the message.
       
   520     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );
       
   521     CleanupStack::PopAndDestroy( buf );
       
   522     }
       
   523 
       
   524 void CNcdSubscriptionGroup::ExternalizeDataForRequestL(
       
   525     MCatalogsSession& aSession,
       
   526     const CDesCArray& aPurchaseOptionIds,
       
   527     RWriteStream& aStream ) const
       
   528     {
       
   529     DLTRACEIN((""));
       
   530 
       
   531 
       
   532     iOriginNodeIdentifier->ExternalizeL( aStream );
       
   533 
       
   534 
       
   535     DLTRACE(( _L(" Externalizing subscriptiongroup info for proxy, EntityId: %S, Namespace: %S, server uri: %S"),
       
   536               &iOriginNodeIdentifier->NodeId(),
       
   537               &iOriginNodeIdentifier->NodeNameSpace(), 
       
   538               &iOriginNodeIdentifier->ServerUri() ));
       
   539 
       
   540     // this is the same as handle amount
       
   541     TInt subscriptionAmount( aPurchaseOptionIds.Count() );
       
   542     aStream.WriteInt32L( subscriptionAmount );
       
   543 
       
   544     DLTRACE(( "Amount of subscription handles sending: %d",
       
   545               subscriptionAmount ));
       
   546     
       
   547     for ( TInt i = 0; i < aPurchaseOptionIds.Count(); i++ ) 
       
   548         {
       
   549         TInt subscriptionIndex = FindSubscriptionL(
       
   550             aPurchaseOptionIds[i] );
       
   551         CNcdSubscription* tmpSubscription = 
       
   552             iSubscriptions[subscriptionIndex];
       
   553         
       
   554         TInt tmpHandle( aSession.AddObjectL( tmpSubscription ) );
       
   555 
       
   556         DLTRACE(( "Sending subscription handle: %i",
       
   557                   tmpHandle ));
       
   558         
       
   559         TRAPD( addError, aStream.WriteInt32L( tmpHandle ) );
       
   560         if ( addError != KErrNone )
       
   561             {
       
   562             // Should all other added objects be also removed from
       
   563             // the session?
       
   564             aSession.RemoveObject( tmpHandle );
       
   565             User::Leave( addError );
       
   566             }                
       
   567         }   
       
   568 
       
   569     DLTRACEOUT((""));
       
   570     }
       
   571 
       
   572 void CNcdSubscriptionGroup::ReleaseRequest(
       
   573     MCatalogsBaseMessage& aMessage ) const
       
   574     {
       
   575     DLTRACEIN((""));
       
   576 
       
   577     // Decrease the reference count for this object.
       
   578     // When the reference count reaches zero, this object will be destroyed
       
   579     // and removed from the session.
       
   580     MCatalogsSession& requestSession( aMessage.Session() );
       
   581     TInt handle( aMessage.Handle() );
       
   582 
       
   583     // Send complete information back to proxy.
       
   584     aMessage.CompleteAndRelease( KErrNone );
       
   585         
       
   586     // Remove this object from the session.
       
   587     requestSession.RemoveObject( handle );
       
   588         
       
   589     DLTRACEOUT((""));
       
   590     }
       
   591 
       
   592 TInt CNcdSubscriptionGroup::FindSubscriptionL(
       
   593     const TDesC& aPurchaseOptionId ) const
       
   594     {
       
   595     DLTRACEIN((""));
       
   596     
       
   597     TInt subscriptionIndex( 0 );
       
   598     const TInt KSubscriptionCount( iSubscriptions.Count() );
       
   599     while( subscriptionIndex < KSubscriptionCount )
       
   600         {
       
   601         if ( iSubscriptions[subscriptionIndex]->PurchaseOptionId() ==
       
   602                  aPurchaseOptionId )
       
   603             {
       
   604             return subscriptionIndex;
       
   605             }
       
   606         ++subscriptionIndex;
       
   607         }
       
   608         
       
   609     DLINFO(("Not found"));
       
   610     User::Leave( KErrNotFound );
       
   611     DLTRACEOUT((""));    
       
   612     return KErrNotFound;
       
   613     }
       
   614 
       
   615 CNcdSubscription& CNcdSubscriptionGroup::SubscriptionL(
       
   616     const TDesC& aPurchaseOptionId )
       
   617     {
       
   618     TInt subscriptionIndex( -1 );
       
   619     TRAPD( searchError,
       
   620            subscriptionIndex =
       
   621                FindSubscriptionL( aPurchaseOptionId ) );
       
   622     if ( searchError == KErrNotFound )
       
   623         {
       
   624         // Let's create new subscription because it was not
       
   625         // found
       
   626         CNcdSubscription* subscription = CNcdSubscription::NewLC( *this );
       
   627         iSubscriptions.AppendL( subscription );        
       
   628         CleanupStack::Pop( subscription );        
       
   629         
       
   630         // set clientIndex to the appended clients subscriptions
       
   631         subscriptionIndex = iSubscriptions.Count() - 1;
       
   632         }
       
   633     else if ( searchError != KErrNone )
       
   634         {
       
   635         // If leave occurs and it is not KErrNotFound, leave.
       
   636         User::Leave( searchError );
       
   637         }
       
   638         
       
   639     return *(iSubscriptions[subscriptionIndex]);
       
   640     }
       
   641 
       
   642 void CNcdSubscriptionGroup::ResetMemberVariables()
       
   643     {
       
   644     delete iOriginNodeIdentifier;
       
   645     iOriginNodeIdentifier = NULL;
       
   646     
       
   647     delete iIcon;
       
   648     iIcon = NULL;
       
   649     
       
   650     ResetAndCloseArray( iSubscriptions );
       
   651     }