ncdengine/provider/server/src/ncdnodemetadataimpl.cpp
changeset 4 32704c33136d
child 18 3ba40be8e484
equal deleted inserted replaced
-1:000000000000 4:32704c33136d
       
     1 /*
       
     2 * Copyright (c) 2006-2008 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 CNcdNodeMetaData class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdnodemetadataimpl.h"
       
    20 #include "ncdnodeidentifier.h"
       
    21 #include "ncdnodedisclaimer.h"
       
    22 #include "ncdnodeiconimpl.h"
       
    23 #include "ncdnodescreenshotimpl.h"
       
    24 #include "ncdnodeskinimpl.h"
       
    25 #include "ncdnodeupgradeimpl.h"
       
    26 #include "ncdnodedependencyimpl.h"
       
    27 #include "ncdnodeuricontentimpl.h"
       
    28 #include "ncdnodecontentinfoimpl.h"
       
    29 #include "ncdnodepreviewimpl.h"
       
    30 #include "ncdpurchaseoptionimpl.h"
       
    31 #include "ncdpurchasedetails.h"
       
    32 #include "ncdpurchasehistorydbimpl.h"
       
    33 #include "ncdnodedownloadimpl.h"
       
    34 #include "ncdnodeinstallimpl.h"
       
    35 #include "ncdnodeuserdataimpl.h"
       
    36 #include "catalogssession.h"
       
    37 #include "catalogsbasemessage.h"
       
    38 #include "ncdnodefunctionids.h"
       
    39 #include "catalogsconstants.h"
       
    40 #include "ncd_pp_dataentity.h"
       
    41 #include "ncd_pp_dataentitycontent.h"
       
    42 #include "ncd_cp_query.h"
       
    43 #include "ncd_pp_download.h"
       
    44 #include "ncd_pp_purchaseoption.h"
       
    45 #include "ncdprotocoltypes.h"
       
    46 #include "catalogsutils.h"
       
    47 #include "ncdutils.h"
       
    48 #include "ncdkeyvaluepair.h"
       
    49 #include "ncdpanics.h"
       
    50 #include "ncdserversubscribablecontent.h"
       
    51 #include "ncdpurchasehistoryutils.h"
       
    52 #include "ncderrors.h"
       
    53 
       
    54 #include "catalogsdebug.h"
       
    55 
       
    56 
       
    57 CNcdNodeMetaData::CNcdNodeMetaData(
       
    58     NcdNodeClassIds::TNcdNodeClassId aClassId,
       
    59     CNcdNodeManager& aNodeManager )
       
    60 : CCatalogsCommunicable(),
       
    61   iClassId( aClassId ),
       
    62   iNodeManager( aNodeManager )  
       
    63     {
       
    64     DLTRACEIN(("Meta class id: %d", aClassId));
       
    65     }
       
    66 
       
    67 
       
    68 void CNcdNodeMetaData::ConstructL( const CNcdNodeIdentifier& aIdentifier )
       
    69     {
       
    70     DLTRACEIN((""));
       
    71 
       
    72     // These two values has to be set. So, this metadata can be identified.
       
    73     iIdentifier = CNcdNodeIdentifier::NewL( aIdentifier );
       
    74 
       
    75     // The user data is part of the metadata. So, the ui may set its own info
       
    76     // for the node by using this object.
       
    77     iUserData = CNcdNodeUserData::NewL( *iIdentifier, iNodeManager );   
       
    78     
       
    79     iTimeStamp = KNullDesC().AllocL();
       
    80     iName = KNullDesC().AllocL();
       
    81     iDescription = KNullDesC().AllocL();
       
    82     iLayoutType = KNullDesC().AllocL();
       
    83     
       
    84     // This internalization is not related to purchase history so it's done
       
    85     // separately
       
    86     TRAP_IGNORE( InternalizeInstallFromContentInfoL() );
       
    87     
       
    88 
       
    89     TRAPD( phError,
       
    90         {
       
    91         // Get purchase details
       
    92         CNcdPurchaseDetails* details = PurchaseDetailsLC();
       
    93         
       
    94         InternalizeContentInfoL( *details );
       
    95         
       
    96         // Try to internalize URI content from purchase history
       
    97         InternalizeUriContentL( *details );                    
       
    98         
       
    99         InternalizeDependencyL( *details );
       
   100         // Try to internalize node download from purchase history.
       
   101         InternalizeDownloadL( *details );
       
   102         
       
   103         // Try to internalize node install from purchase history
       
   104         InternalizeInstallL( *details );
       
   105         
       
   106         // Try to internalize node icon from purchase history
       
   107         // (does not read icon data to memory)
       
   108         InternalizeIconL( *details );
       
   109     
       
   110         CleanupStack::PopAndDestroy( details );
       
   111         });
       
   112     
       
   113     if( phError != KErrNone && 
       
   114 	phError != KErrNotFound &&
       
   115 	phError != KNcdErrorNoPurchaseInformation )
       
   116         {
       
   117         DLERROR(( "phError: %d", phError ));
       
   118         User::Leave( phError );
       
   119         }
       
   120 
       
   121     DLTRACEOUT((""));
       
   122     }
       
   123 
       
   124 
       
   125 CNcdNodeMetaData::~CNcdNodeMetaData()
       
   126     {
       
   127     DLTRACEIN((""));
       
   128     
       
   129     delete iIdentifier;
       
   130     iIdentifier = NULL;
       
   131         
       
   132     delete iTimeStamp;
       
   133     iTimeStamp = NULL;
       
   134 
       
   135     delete iName;
       
   136     iName = NULL;
       
   137 
       
   138     delete iDescription;
       
   139     iDescription = NULL;
       
   140     
       
   141     delete iLayoutType;
       
   142     iLayoutType = NULL;
       
   143             
       
   144     // Notice that CCatalogsCommunicable classes cannot be destroyed by
       
   145     // calling delete! Instead call Close to them
       
   146 
       
   147     if ( iUserData )
       
   148         {
       
   149         DLINFO(("Closing node user data"));
       
   150         iUserData->Close();       
       
   151         iUserData = NULL; 
       
   152         }
       
   153 
       
   154     if ( iDisclaimer != NULL )
       
   155         {
       
   156         iDisclaimer->Close();
       
   157         iDisclaimer = NULL;
       
   158         }
       
   159     
       
   160     if ( iIcon != NULL )
       
   161         {
       
   162         iIcon->Close();
       
   163         iIcon = NULL;        
       
   164         }
       
   165 
       
   166     if ( iScreenshot != NULL )
       
   167         {
       
   168         iScreenshot->Close();
       
   169         iScreenshot = NULL;
       
   170         }
       
   171 
       
   172     if ( iSkin != NULL )
       
   173         {
       
   174         iSkin->Close();
       
   175         iSkin = NULL;        
       
   176         }
       
   177 
       
   178     if( iUriContent != NULL )
       
   179         {
       
   180         iUriContent->Close();
       
   181         iUriContent = NULL;
       
   182         }
       
   183 
       
   184     if( iContentInfo != NULL )
       
   185         {
       
   186         iContentInfo->Close();
       
   187         iContentInfo = NULL;
       
   188         }
       
   189 
       
   190     if( iPreview != NULL )
       
   191         {
       
   192         iPreview->Close();
       
   193         iPreview = NULL;
       
   194         }
       
   195 
       
   196     if ( iUpgrade != NULL )
       
   197         {
       
   198         iUpgrade->Close();
       
   199         iUpgrade = NULL;
       
   200         }
       
   201 
       
   202     if ( iDependency != NULL )
       
   203         {
       
   204         iDependency->Close();
       
   205         iDependency = NULL;
       
   206         }
       
   207 
       
   208     if ( iDownload )
       
   209         {
       
   210         DLINFO(("Closing node download"));
       
   211         iDownload->Close();
       
   212         iDownload = NULL;
       
   213         }
       
   214 
       
   215     if ( iInstall )
       
   216         {
       
   217         DLINFO(("Closing node install"));
       
   218         iInstall->Close();
       
   219         iInstall = NULL;
       
   220         }
       
   221     
       
   222     if ( iMoreInfo != NULL )
       
   223         {
       
   224         iMoreInfo->Close();
       
   225         iMoreInfo = NULL;
       
   226         }
       
   227     
       
   228     iDetails.ResetAndDestroy();
       
   229     
       
   230     delete iSubscribableContent;
       
   231     iSubscribableContent = NULL;
       
   232     
       
   233     ResetAndCloseArray( iPurchaseOptions );
       
   234     
       
   235     DLTRACEOUT((""));
       
   236     }        
       
   237     
       
   238 
       
   239 CNcdNodeManager& CNcdNodeMetaData::NodeManager() const
       
   240     {
       
   241     return iNodeManager;
       
   242     }
       
   243 
       
   244 
       
   245 const CNcdNodeIdentifier& CNcdNodeMetaData::Identifier() const
       
   246     {
       
   247     return *iIdentifier;
       
   248     }
       
   249 
       
   250 
       
   251 NcdNodeClassIds::TNcdNodeClassId CNcdNodeMetaData::ClassId() const
       
   252     {
       
   253     return iClassId;
       
   254     }    
       
   255     
       
   256 const TDesC& CNcdNodeMetaData::TimeStamp() const
       
   257     {
       
   258     DASSERT( iTimeStamp );
       
   259     return *iTimeStamp;
       
   260     }
       
   261 
       
   262 
       
   263 const TDesC& CNcdNodeMetaData::NodeName() const
       
   264     {
       
   265     DASSERT( iName );
       
   266     return *iName;
       
   267     }
       
   268 
       
   269 void CNcdNodeMetaData::SetNodeNameL( const TDesC& aName )
       
   270     {
       
   271     HBufC* newName = aName.AllocL();
       
   272     delete iName;
       
   273     iName = newName;
       
   274     }
       
   275 
       
   276 const TDesC& CNcdNodeMetaData::Description() const
       
   277     {
       
   278     DASSERT( iDescription );
       
   279     return *iDescription;    
       
   280     }
       
   281     
       
   282 void CNcdNodeMetaData::SetDescriptionL(
       
   283     const TDesC& aDescription ) 
       
   284     {
       
   285     HBufC* newDescription = aDescription.AllocL();
       
   286     delete iDescription;
       
   287     iDescription = newDescription;
       
   288     }
       
   289     
       
   290 const TDesC& CNcdNodeMetaData::LayoutType() const 
       
   291     {
       
   292     DASSERT( iLayoutType );
       
   293     return *iLayoutType;
       
   294     }
       
   295     
       
   296 const CNcdNodeDisclaimer& CNcdNodeMetaData::DisclaimerL() const
       
   297     {
       
   298     if ( iDisclaimer == NULL )
       
   299         {
       
   300         User::Leave( KErrNotFound );
       
   301         }
       
   302         
       
   303     return *iDisclaimer;
       
   304     }
       
   305 
       
   306 void CNcdNodeMetaData::SetDisclaimer( CNcdNodeDisclaimer* aDisclaimer )
       
   307     {
       
   308     if ( iDisclaimer != NULL )
       
   309         {
       
   310         iDisclaimer->Close();        
       
   311         }
       
   312     iDisclaimer = aDisclaimer;
       
   313     }
       
   314 
       
   315 
       
   316 const CNcdNodeDisclaimer& CNcdNodeMetaData::MoreInfoL() const
       
   317     {
       
   318     if ( iMoreInfo == NULL )
       
   319         {
       
   320         User::Leave( KErrNotFound );
       
   321         }
       
   322         
       
   323     return *iMoreInfo;
       
   324     }
       
   325 
       
   326 CNcdNodeIcon& CNcdNodeMetaData::IconL() const
       
   327     {
       
   328     if ( iIcon == NULL )
       
   329         {
       
   330         User::Leave( KErrNotFound );
       
   331         }
       
   332 
       
   333     return *iIcon;
       
   334     }
       
   335 
       
   336 
       
   337 void CNcdNodeMetaData::SetIcon( CNcdNodeIcon* aIcon ) 
       
   338     {
       
   339     if ( iIcon ) 
       
   340         {
       
   341         iIcon->Close();
       
   342         }
       
   343     iIcon = aIcon;
       
   344     }
       
   345   
       
   346     
       
   347 const CNcdNodeScreenshot& CNcdNodeMetaData::ScreenshotL() const
       
   348     {
       
   349     if ( iScreenshot == NULL )
       
   350         {
       
   351         User::Leave( KErrNotFound );
       
   352         }
       
   353 
       
   354     return *iScreenshot;
       
   355     }
       
   356     
       
   357     
       
   358 const CNcdNodeSkin& CNcdNodeMetaData::SkinL() const
       
   359     {
       
   360     DASSERT( iSkin );
       
   361     return *iSkin;
       
   362     }
       
   363 
       
   364 
       
   365 CNcdNodePreview& CNcdNodeMetaData::PreviewL() const
       
   366     {
       
   367     if ( iPreview == NULL )
       
   368         {
       
   369         User::Leave( KErrNotFound );
       
   370         }
       
   371 
       
   372     return *iPreview;
       
   373     }
       
   374     
       
   375 
       
   376 const CNcdNodeUpgrade& CNcdNodeMetaData::UpgradeL() const
       
   377     {
       
   378     if ( iUpgrade == NULL )
       
   379         {
       
   380         User::Leave( KErrNotFound );
       
   381         }
       
   382     return *iUpgrade;
       
   383     }
       
   384 
       
   385 
       
   386 const CNcdNodeDependency& CNcdNodeMetaData::DependencyL() const
       
   387     {
       
   388     if ( iDependency == NULL )
       
   389         {
       
   390         User::Leave( KErrNotFound );
       
   391         }
       
   392     return *iDependency;
       
   393     }
       
   394 
       
   395 
       
   396 const CNcdNodeContentInfo& CNcdNodeMetaData::ContentInfoL() const
       
   397     {
       
   398     if ( iContentInfo == NULL )
       
   399         {
       
   400         User::Leave( KErrNotFound );      
       
   401         }
       
   402     return *iContentInfo;
       
   403     }
       
   404 
       
   405 
       
   406 const CNcdServerSubscribableContent*
       
   407     CNcdNodeMetaData::SubscribableContent() const
       
   408     {
       
   409     return iSubscribableContent;
       
   410     }
       
   411 
       
   412 
       
   413 const RPointerArray<CNcdPurchaseOptionImpl>& CNcdNodeMetaData::PurchaseOptions() const
       
   414     {
       
   415     return iPurchaseOptions;    
       
   416     }
       
   417 
       
   418 CNcdPurchaseOptionImpl& CNcdNodeMetaData::PurchaseOptionByIdL(
       
   419     const TDesC& aPurchaseOptionId ) const 
       
   420     {
       
   421     DLTRACEIN((""));
       
   422     for ( TInt i = 0; i < iPurchaseOptions.Count(); i++ ) 
       
   423         {
       
   424         if ( iPurchaseOptions[i]->Id() == aPurchaseOptionId ) 
       
   425             {
       
   426             return *iPurchaseOptions[i];
       
   427             }
       
   428         }
       
   429         
       
   430     User::Leave( KErrNotFound );
       
   431     CNcdPurchaseOptionImpl* foo( NULL );
       
   432     return *foo;
       
   433     }  
       
   434     
       
   435 TBool CNcdNodeMetaData::AlwaysVisible() const 
       
   436     {
       
   437     return iAlwaysVisible;
       
   438     }
       
   439   
       
   440     
       
   441 void CNcdNodeMetaData::SetAlwaysVisible( TBool aValue ) 
       
   442     {
       
   443     iAlwaysVisible = aValue;
       
   444     }
       
   445  
       
   446     
       
   447 void CNcdNodeMetaData::InternalizeL( MNcdPreminetProtocolDataEntity& aData )
       
   448     {
       
   449     DLTRACEIN((""));
       
   450 
       
   451     // First create the new values
       
   452     HBufC* tmpTimeStamp = aData.Timestamp().AllocLC();
       
   453     HBufC* tmpName = aData.Name().AllocLC();
       
   454     HBufC* tmpDescription = aData.Description().AllocLC();
       
   455     HBufC* tmpLayoutType = aData.LayoutType().AllocLC();
       
   456 
       
   457 
       
   458     DLTRACE(( _L("MetaData timestamp: %S"), tmpTimeStamp ));
       
   459     DLTRACE(( _L("MetaData name: %S"), tmpName ));
       
   460     DLTRACE(( _L("MetaData description: %S"), tmpDescription ));
       
   461 
       
   462 
       
   463     delete iLayoutType;
       
   464     iLayoutType = tmpLayoutType;
       
   465     CleanupStack::Pop( tmpLayoutType );
       
   466 
       
   467     delete iDescription;
       
   468     iDescription = tmpDescription;
       
   469     CleanupStack::Pop( tmpDescription );
       
   470 
       
   471     delete iName;
       
   472     iName = tmpName;
       
   473     CleanupStack::Pop( tmpName );    
       
   474 
       
   475     delete iTimeStamp;
       
   476     iTimeStamp = tmpTimeStamp;
       
   477     CleanupStack::Pop( tmpTimeStamp );
       
   478 
       
   479     if ( aData.Disclaimer() )
       
   480         {
       
   481         // New disclaimer info should be set
       
   482         
       
   483         if ( iDisclaimer == NULL )
       
   484             {
       
   485             // Create disclaimer because it did not exist before.
       
   486             iDisclaimer = CNcdNodeDisclaimer::NewL();
       
   487             }
       
   488         // Update disclaimer info.
       
   489         iDisclaimer->InternalizeL( *aData.Disclaimer() );        
       
   490         }
       
   491     else if ( iDisclaimer )
       
   492         {
       
   493         // Because new data does not contain disclaimer.
       
   494         // Close old one and set the value NULL.
       
   495         // Notice that CCatalogsCommunicalbe classes should be Closed
       
   496         // instead of deleting.
       
   497         // Because this object may still be left hanging for proxy object if it is used by UI,
       
   498         // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   499         // the hanging object.
       
   500         iDisclaimer->SetAsObsolete( ETrue );
       
   501         iDisclaimer->Close();
       
   502         iDisclaimer = NULL;                    
       
   503         }
       
   504 
       
   505     if ( aData.Icon() )
       
   506         {
       
   507         // New icon info should be set.
       
   508         
       
   509         if ( iIcon == NULL )
       
   510             {
       
   511             iIcon = CNcdNodeIcon::NewL( iNodeManager, *this );            
       
   512             }
       
   513         iIcon->InternalizeL( aData );
       
   514         }
       
   515     else if ( iIcon != NULL )
       
   516         {
       
   517         // Notice that icons should not be deleted because
       
   518         // all the CCatalogsCommunicable classes should be Closed instead.
       
   519         // Because this object may still be left hanging for proxy object if it is used by UI,
       
   520         // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   521         // the hanging object.
       
   522         iIcon->SetAsObsolete( ETrue );
       
   523         iIcon->Close();
       
   524         iIcon = NULL;            
       
   525         }
       
   526 
       
   527     if ( aData.ScreenshotCount() > 0 )
       
   528         {
       
   529         // New screenshot info should be set.
       
   530         
       
   531         if ( iScreenshot == NULL )
       
   532             {
       
   533             iScreenshot = CNcdNodeScreenshot::NewL( iNodeManager, *this );            
       
   534             }
       
   535         iScreenshot->InternalizeL( aData );
       
   536         }
       
   537     else if ( iScreenshot != NULL )
       
   538         {
       
   539         // Notice that screenshots should not be deleted because
       
   540         // all the CCatalogsCommunicable classes should be Closed instead.
       
   541         // Because this object may still be left hanging for proxy object if it is used by UI,
       
   542         // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   543         // the hanging object.
       
   544         iScreenshot->SetAsObsolete( ETrue );
       
   545         iScreenshot->Close();
       
   546         iScreenshot = NULL;            
       
   547         }
       
   548 
       
   549     if ( aData.Skin() )
       
   550         {
       
   551         // New skin info should be set.
       
   552 
       
   553         if ( iSkin == NULL )
       
   554             {
       
   555             iSkin = CNcdNodeSkin::NewL();            
       
   556             }
       
   557         iSkin->InternalizeL( aData );
       
   558         }
       
   559     else if ( iSkin != NULL )
       
   560         {
       
   561         // Notice that skins should not be deleted because
       
   562         // all the CCatalogsCommunicable classes should be Closed instead.
       
   563         // Because this object may still be left hanging for proxy object if it is used by UI,
       
   564         // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   565         // the hanging object.
       
   566         iSkin->SetAsObsolete( ETrue );
       
   567         iSkin->Close();
       
   568         iSkin = NULL;            
       
   569         }
       
   570 
       
   571     if ( aData.DownloadableContent() )
       
   572         {
       
   573         // New content info should be set.
       
   574 
       
   575         if ( iContentInfo == NULL )
       
   576             {
       
   577             iContentInfo = CNcdNodeContentInfo::NewL();            
       
   578             }
       
   579         iContentInfo->InternalizeL( aData );
       
   580         InternalizeInstallFromContentInfoL();
       
   581         }
       
   582     else if ( iContentInfo != NULL )
       
   583         {
       
   584         DLINFO(("No downloadable content"));
       
   585         // Notice that content info should not be deleted because
       
   586         // all the CCatalogsCommunicable classes should be Closed instead.
       
   587         // Because this object may still be left hanging for proxy object if it is used by UI,
       
   588         // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   589         // the hanging object.
       
   590         iContentInfo->SetAsObsolete( ETrue );
       
   591         iContentInfo->Close();
       
   592         iContentInfo = NULL;            
       
   593         }
       
   594 
       
   595 	if ( aData.PreviewCount() > 0 )
       
   596         {
       
   597         if ( iPreview == NULL )
       
   598             {
       
   599             iPreview = CNcdNodePreview::NewL( *this, iNodeManager );            
       
   600             }
       
   601         iPreview->InternalizeL( aData );
       
   602         }
       
   603     else if ( iPreview != NULL )
       
   604         {
       
   605         // Because this object may still be left hanging for proxy object if it is used by UI,
       
   606         // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   607         // the hanging object.
       
   608         iPreview->SetAsObsolete( ETrue );
       
   609         iPreview->Close();
       
   610         iPreview = NULL;            
       
   611         }
       
   612 
       
   613     // Create upgrade object if necessary
       
   614     if ( aData.DownloadableContent() != NULL )
       
   615         {
       
   616         if ( iUpgrade == NULL )
       
   617             {
       
   618             iUpgrade = CNcdNodeUpgrade::NewL( *this );
       
   619             }
       
   620         TPtrC version( KNullDesC );    
       
   621         if ( iContentInfo ) 
       
   622             {
       
   623             version.Set( iContentInfo->Version() );
       
   624             }
       
   625         TRAPD( upgradeErr, iUpgrade->InternalizeL( aData, version ) );
       
   626         TBool upgradeExists = HandleContentUpgradeL();
       
   627         
       
   628         // HandleContentUpgradeL checks CNcdNodeContentInfo and
       
   629         // CNcdNodeInstall for the need of upgrade interfaces
       
   630         if ( upgradeErr == KErrNotFound && 
       
   631              !upgradeExists )
       
   632             {
       
   633             DLTRACE(("No upgrade"));                
       
   634             // The given data did not contain any information about upgrade.
       
   635             // So, delete the created upgrade object.
       
   636             // Because this object may still be left hanging for proxy object if it is used by UI,
       
   637             // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   638             // the hanging object.
       
   639             iUpgrade->SetAsObsolete( ETrue );
       
   640             iUpgrade->Close();
       
   641             iUpgrade = NULL;            
       
   642             }
       
   643         
       
   644         LeaveIfNotErrorL( upgradeErr, KErrNotFound );
       
   645         }
       
   646     else if ( iUpgrade != NULL )
       
   647         {
       
   648         // Because this object may still be left hanging for proxy object if it is used by UI,
       
   649         // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   650         // the hanging object.
       
   651         iUpgrade->SetAsObsolete( ETrue );
       
   652         iUpgrade->Close();
       
   653         iUpgrade = NULL;
       
   654         }
       
   655 
       
   656 
       
   657     // Create dependency object if necessary
       
   658     if ( aData.DownloadableContent() != NULL )
       
   659         {
       
   660         if ( iDependency == NULL )
       
   661             {
       
   662             iDependency = CNcdNodeDependency::NewL( *this );
       
   663             }
       
   664         TRAPD( dependencyErr, iDependency->InternalizeL( aData ) );
       
   665         if ( dependencyErr == KErrNotFound )
       
   666             {
       
   667             DLTRACE(("No dependency, deleting the object"));
       
   668             // The given data did not contain any information about dependency.
       
   669             // So, delete the created object.
       
   670             // Because this object may still be left hanging for proxy object if it is used by UI,
       
   671             // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   672             // the hanging object.
       
   673             iDependency->SetAsObsolete( ETrue );
       
   674             iDependency->Close();
       
   675             iDependency = NULL;            
       
   676             }
       
   677         else if ( dependencyErr != KErrNone )
       
   678             {
       
   679             // Some error occurred. So let this leave.
       
   680             User::Leave( dependencyErr );
       
   681             }
       
   682         }
       
   683     else if ( iDependency != NULL )
       
   684         {
       
   685         DLTRACE(("Removing old dependency"));
       
   686         // Because this object may still be left hanging for proxy object if it is used by UI,
       
   687         // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   688         // the hanging object.
       
   689         iDependency->SetAsObsolete( ETrue );
       
   690         iDependency->Close();
       
   691         iDependency = NULL;
       
   692         }
       
   693         
       
   694 
       
   695 
       
   696     // Subscribable content
       
   697     const MNcdPreminetProtocolDataEntityContent* subscribableContent =
       
   698         aData.SubscribableContent();
       
   699     
       
   700     if ( subscribableContent != NULL )
       
   701         {
       
   702         DLINFO(( "Subscribable content element found from protocol-object" ));
       
   703         
       
   704         if ( iSubscribableContent == NULL )
       
   705             {
       
   706             iSubscribableContent = CNcdServerSubscribableContent::NewL();
       
   707             }        
       
   708         iSubscribableContent->InternalizeL( *subscribableContent );
       
   709         }
       
   710         
       
   711         
       
   712     if ( aData.MoreInfo() )
       
   713         {
       
   714         if ( iMoreInfo == NULL )
       
   715             {
       
   716             iMoreInfo = CNcdNodeDisclaimer::NewL();
       
   717             }
       
   718         iMoreInfo->InternalizeL( *aData.MoreInfo() );        
       
   719         }
       
   720     else if ( iMoreInfo )
       
   721         {
       
   722         // Because this object may still be left hanging for proxy object if it is used by UI,
       
   723         // set the object obsolete. So, UI will know this if it is trying to internalize 
       
   724         // the hanging object.
       
   725         iMoreInfo->SetAsObsolete( ETrue );
       
   726         iMoreInfo->Close();
       
   727         iMoreInfo = NULL;                    
       
   728         }
       
   729         
       
   730     iDetails.ResetAndDestroy();        
       
   731         
       
   732     for ( TInt i = 0 ; i < aData.DetailCount() ; i++ )
       
   733         {
       
   734         DLTRACE(( _L("Detail id=%S, value=%S"),
       
   735             &aData.DetailL( i ).Id(), &aData.DetailL( i ).Value()));
       
   736         if( aData.DetailL( i ).Id() == KNullDesC )
       
   737             {
       
   738             DLTRACE(("Empty id -> not adding detail!"));
       
   739             continue;
       
   740             }
       
   741         CNcdKeyValuePair* detail = CNcdKeyValuePair::NewLC(
       
   742             aData.DetailL( i ).Id(), aData.DetailL( i ).Value() );
       
   743         iDetails.AppendL( detail );
       
   744         CleanupStack::Pop( detail );
       
   745         }
       
   746 
       
   747     
       
   748     // Create or reinternalize purchase options :
       
   749     
       
   750     const TInt KPurchaseOptionCount( aData.PurchaseOptionCount() );
       
   751 
       
   752     DLINFO(( "Amount of purchaseoptions found from protocol-object: %d",
       
   753              KPurchaseOptionCount ));
       
   754     
       
   755     TInt purchaseOptionIndex( 0 );
       
   756     while ( purchaseOptionIndex < KPurchaseOptionCount )
       
   757         {
       
   758         const MNcdPreminetProtocolPurchaseOption& tmpOption = 
       
   759             aData.PurchaseOptionL( purchaseOptionIndex );            
       
   760         InternalizePurchaseOptionL( tmpOption );        
       
   761         ++purchaseOptionIndex;
       
   762         }
       
   763     
       
   764     // Remove purchase options that were removed from the server
       
   765     RemoveNotUpdatedPurchaseOptions();
       
   766 
       
   767     DLTRACEOUT((""));
       
   768     }
       
   769 
       
   770 
       
   771 void CNcdNodeMetaData::InternalizeContentInfoL( 
       
   772     const MNcdPurchaseDetails& aDetails )
       
   773     {
       
   774     DLTRACEIN((""));
       
   775     
       
   776     if ( !iContentInfo )
       
   777         {
       
   778         iContentInfo = CNcdNodeContentInfo::NewL();    
       
   779         }
       
   780     
       
   781     iContentInfo->InternalizeL( aDetails );    
       
   782     }
       
   783 
       
   784 
       
   785 void CNcdNodeMetaData::InternalizeUriContentL( 
       
   786     const MNcdPurchaseDetails& aDetails )
       
   787     {
       
   788     DLTRACEIN((""));
       
   789     
       
   790     if ( !iUriContent )
       
   791         {
       
   792         iUriContent = CNcdNodeUriContent::NewL();    
       
   793         if ( !iUriContent->InternalizeL( aDetails ) )
       
   794             {
       
   795             iUriContent->Close();
       
   796             iUriContent = NULL;
       
   797             }
       
   798         }
       
   799     else
       
   800         {
       
   801         iUriContent->InternalizeL( aDetails );
       
   802         }
       
   803         
       
   804     DLTRACEOUT((""));    
       
   805     }
       
   806 
       
   807 
       
   808 CNcdNodeDownload& CNcdNodeMetaData::DownloadL()
       
   809     {
       
   810     if( iDownload == NULL )
       
   811         {
       
   812         User::Leave( KErrNotFound );
       
   813         }
       
   814           
       
   815     return *iDownload;
       
   816     }
       
   817 
       
   818 
       
   819 void CNcdNodeMetaData::InternalizeDownloadL( const MNcdPurchaseDetails& aDetails )
       
   820     {
       
   821     DLTRACEIN((""));    
       
   822 
       
   823     if ( !iDownload ) 
       
   824         {
       
   825         iDownload = CNcdNodeDownload::NewL();
       
   826         
       
   827         // Delete node download if the internalization failed
       
   828         if ( !iDownload->InternalizeL( aDetails ) ) 
       
   829             {
       
   830             iDownload->Close();
       
   831             iDownload = NULL;
       
   832             }
       
   833         }
       
   834     else
       
   835         {
       
   836         iDownload->InternalizeL( aDetails );
       
   837         }
       
   838     DLTRACEOUT((""));
       
   839     }
       
   840 
       
   841 
       
   842 CNcdNodeInstall& CNcdNodeMetaData::InstallL()
       
   843     {
       
   844     if( iInstall == NULL )
       
   845         {
       
   846         User::Leave( KErrNotFound );
       
   847         }
       
   848           
       
   849     return *iInstall;
       
   850     }
       
   851     
       
   852 
       
   853 void CNcdNodeMetaData::InternalizeInstallL( const MNcdPurchaseDetails& aDetails )
       
   854     {
       
   855     DLTRACEIN((""));
       
   856     
       
   857     if ( !iInstall )
       
   858         {
       
   859         iInstall = CNcdNodeInstall::NewL( *this );    
       
   860         if ( !iInstall->InternalizeL( aDetails ) )
       
   861             {
       
   862             iInstall->Close();
       
   863             iInstall = NULL;
       
   864             }
       
   865         }
       
   866     else
       
   867         {
       
   868         iInstall->InternalizeL( aDetails );
       
   869         }
       
   870     
       
   871     // Get version of bought content from purchase history so that
       
   872     // we can compare it with content info in HandleContentUpgradeL
       
   873     TRAPD( err, TCatalogsVersion::ConvertL( 
       
   874         iBoughtContentVersion, aDetails.Version() ) );
       
   875         
       
   876     LeaveIfNotErrorL( err, KErrArgument, KErrGeneral );
       
   877 
       
   878     DLTRACEOUT((""));    
       
   879     }
       
   880     
       
   881     
       
   882 void CNcdNodeMetaData::InternalizeInstallFromContentInfoL()
       
   883     {
       
   884     DLTRACEIN((""));
       
   885     if ( iContentInfo && iContentInfo->Uid() != TUid::Null() )
       
   886         {
       
   887         TBool create = !iInstall;
       
   888         if ( create ) 
       
   889             {
       
   890             DLTRACE(("No install, creating"));
       
   891             iInstall = CNcdNodeInstall::NewL( *this );
       
   892             }
       
   893         
       
   894         // Only delete install if it was created in this method
       
   895         if ( !iInstall->InternalizeContentInfoL() && create ) 
       
   896             {
       
   897             DLTRACE(("App is not installed, deleting install"));
       
   898             iInstall->Close();
       
   899             iInstall = NULL;
       
   900             }
       
   901         }
       
   902     DLTRACEOUT((""));
       
   903     }
       
   904 
       
   905 
       
   906 void CNcdNodeMetaData::InternalizeDependencyL( 
       
   907     const MNcdPurchaseDetails& aDetails ) 
       
   908     {
       
   909     DLTRACEIN((""));
       
   910     if ( !iDependency )
       
   911         {
       
   912         iDependency = CNcdNodeDependency::NewL( *this );    
       
   913         if ( !iDependency->InternalizeFromPurchaseDetailsL( aDetails ) )
       
   914             {
       
   915             iDependency->Close();
       
   916             iDependency = NULL;
       
   917             }
       
   918         }
       
   919     else
       
   920         {
       
   921         iDependency->InternalizeFromPurchaseDetailsL( aDetails );
       
   922         }        
       
   923     DLTRACEOUT(("dependency internalized from purchasehistory"));
       
   924     }
       
   925     
       
   926 void CNcdNodeMetaData::InternalizeIconL( const MNcdPurchaseDetails& aDetails )
       
   927     {
       
   928     DLTRACEIN((""));
       
   929     if( aDetails.HasIcon() )
       
   930         {
       
   931         DLTRACE(("Purchase details have icon"));
       
   932         // Only use icon from PH if there is no icon previously
       
   933         // (icon may change on server whilst the icon in PH is the one that
       
   934         // was available during purchase ).
       
   935         if( !iIcon )
       
   936             {
       
   937             iIcon = CNcdNodeIcon::NewL( iNodeManager, *this, ETrue );
       
   938             }
       
   939         }
       
   940     }
       
   941 
       
   942 CNcdPurchaseDetails* CNcdNodeMetaData::PurchaseDetailsLC( TBool aLoadIcon ) const
       
   943     {
       
   944     DLTRACEIN((""));
       
   945         
       
   946     return NcdPurchaseHistoryUtils::PurchaseDetailsLC( 
       
   947         iNodeManager.PurchaseHistory(),
       
   948         iIdentifier->ClientUid(),
       
   949         *iIdentifier,
       
   950         aLoadIcon );
       
   951     }
       
   952 
       
   953 
       
   954 TBool CNcdNodeMetaData::HandleContentUpgradeL()
       
   955     {
       
   956     DLTRACEIN((""));
       
   957     DLNODEID(( Identifier() ));
       
   958     if ( iContentInfo ) 
       
   959         {
       
   960         DLTRACE(("Content info exists, check if content upgrades something"));
       
   961 
       
   962         TCatalogsVersion version;
       
   963         TRAPD( err, TCatalogsVersion::ConvertL( 
       
   964             version, iContentInfo->Version() ) );
       
   965 
       
   966         LeaveIfNotErrorL( err, KErrArgument, KErrGeneral );
       
   967         
       
   968         // First compare version number to purchase history because it's highest priority
       
   969         if ( version == iBoughtContentVersion ) 
       
   970             {
       
   971             if ( iUpgrade )
       
   972                 {        
       
   973                 // Reset content upgrade status
       
   974                 iUpgrade->SetContentUpgradesL(
       
   975                     EFalse,
       
   976                     TUid::Null(),
       
   977                     KNullDesC );
       
   978                 }            
       
   979             DLTRACEOUT(("Version in contentinfo matches bought version, no upgrade"));
       
   980             return EFalse;            
       
   981             }
       
   982         
       
   983         
       
   984         // ContentCount() ensures that there's actually something installed, otherwise
       
   985         // we would end up checking against the same contentinfo if the content is
       
   986         // a SIS app and some version of it is already installed
       
   987         if ( iInstall && iInstall->ContentCount() ) 
       
   988             {                
       
   989             
       
   990             TCatalogsVersion installVersion( iInstall->ContentVersion() );
       
   991             DLTRACE(("Version from install: %d.%d.%d", 
       
   992                 installVersion.iMajor, installVersion.iMinor, installVersion.iBuild ));
       
   993                 
       
   994             // IsAllContentInstalledL returns true if all content files are installed
       
   995             if ( installVersion != TCatalogsVersion() && 
       
   996                  version > installVersion && 
       
   997                  iInstall->IsAllContentInstalledL() )
       
   998                 {
       
   999                 
       
  1000                 if ( !iUpgrade ) 
       
  1001                     {
       
  1002                     DLTRACE(("Creating upgrade"));
       
  1003                     iUpgrade = CNcdNodeUpgrade::NewL( *this );
       
  1004                     }
       
  1005                 
       
  1006                 // content is an upgrade
       
  1007                 iUpgrade->SetContentUpgradesL(
       
  1008                     ETrue,
       
  1009                     iContentInfo->Uid(),
       
  1010                     iContentInfo->Version() );  
       
  1011                 return ETrue;                  
       
  1012                 }
       
  1013             }        
       
  1014         // If content is an application, check if it upgrades. "Else if" is necessary
       
  1015         // because otherwise content version check could be overridden by application version
       
  1016         // check
       
  1017         else if ( iContentInfo->Uid() != TUid::Null() ) 
       
  1018             {
       
  1019             TNcdApplicationStatus contentVersion( 
       
  1020                 ENcdApplicationNotInstalled );
       
  1021 
       
  1022             TRAPD( err, 
       
  1023                 contentVersion = CNcdProviderUtils::IsApplicationInstalledL( 
       
  1024                 iContentInfo->Uid(), 
       
  1025                 iContentInfo->Version() ) );
       
  1026 
       
  1027             // Ignore errors in version conversion                
       
  1028             LeaveIfNotErrorL( err, KErrArgument, KErrGeneral );
       
  1029                 
       
  1030             if ( contentVersion == ENcdApplicationOlderVersionInstalled ) 
       
  1031                 {
       
  1032                 if ( !iUpgrade ) 
       
  1033                     {
       
  1034                     DLTRACE(("Creating upgrade"));
       
  1035                     iUpgrade = CNcdNodeUpgrade::NewL( *this );
       
  1036                     }
       
  1037                     
       
  1038                 // Set upgrade data which will be available through the API
       
  1039                 iUpgrade->SetContentUpgradesL( 
       
  1040                     ETrue, 
       
  1041                     iContentInfo->Uid(), 
       
  1042                     iContentInfo->Version() );
       
  1043                 
       
  1044                 DLTRACEOUT(("Content upgrades"));    
       
  1045                 return ETrue;
       
  1046                 }
       
  1047             }
       
  1048         }
       
  1049     
       
  1050     if ( iUpgrade )
       
  1051         {        
       
  1052         // Reset content upgrade status
       
  1053         iUpgrade->SetContentUpgradesL(
       
  1054             EFalse,
       
  1055             TUid::Null(),
       
  1056             KNullDesC );
       
  1057         }
       
  1058     return EFalse;                
       
  1059     }
       
  1060 
       
  1061 
       
  1062 void CNcdNodeMetaData::SetDeleteSoon( TBool aDeleteSoon )
       
  1063     {
       
  1064     iDeleteSoon = aDeleteSoon;
       
  1065     }
       
  1066 
       
  1067 
       
  1068 TBool CNcdNodeMetaData::DeleteSoon() const
       
  1069     {
       
  1070     return iDeleteSoon;
       
  1071     }
       
  1072 
       
  1073        
       
  1074 void CNcdNodeMetaData::ExternalizeL( RWriteStream& aStream )
       
  1075     {
       
  1076     DLTRACEIN((""));
       
  1077 
       
  1078     // Set all the membervariable values to the stream. So,
       
  1079     // that the stream may be used later to create a new
       
  1080     // object.
       
  1081 
       
  1082     // First insert data that node manager will use to
       
  1083     // create this class object
       
  1084     DLTRACE(("Meta extern class id: %d", iClassId));
       
  1085     aStream.WriteInt32L( iClassId );
       
  1086     
       
  1087     // Write the data that will be used when internalize function
       
  1088     // is called.
       
  1089     
       
  1090     ExternalizeDesL( TimeStamp(), aStream );
       
  1091     ExternalizeDesL( NodeName(), aStream );
       
  1092     ExternalizeDesL( Description(), aStream );
       
  1093     ExternalizeDesL( LayoutType(), aStream );
       
  1094     
       
  1095     aStream.WriteInt8L( iAlwaysVisible );    
       
  1096     
       
  1097     if ( iDisclaimer )
       
  1098         {
       
  1099         aStream.WriteInt32L( 1 );
       
  1100         iDisclaimer->ExternalizeL( aStream );
       
  1101         }
       
  1102     else
       
  1103         {
       
  1104         aStream.WriteInt32L( 0 );
       
  1105         }
       
  1106     
       
  1107     if ( iIcon )
       
  1108         {
       
  1109         aStream.WriteInt32L( 1 );
       
  1110         iIcon->ExternalizeL( aStream );
       
  1111         }
       
  1112     else
       
  1113         {
       
  1114         aStream.WriteInt32L( 0 );
       
  1115         }
       
  1116 
       
  1117     if ( iScreenshot )
       
  1118         {
       
  1119         aStream.WriteInt32L( 1 );
       
  1120         iScreenshot->ExternalizeL( aStream );
       
  1121         }
       
  1122     else
       
  1123         {
       
  1124         aStream.WriteInt32L( 0 );
       
  1125         }
       
  1126 
       
  1127     if ( iSkin )
       
  1128         {
       
  1129         aStream.WriteInt32L( 1 );
       
  1130         iSkin->ExternalizeL( aStream );
       
  1131         }
       
  1132     else
       
  1133         {
       
  1134         aStream.WriteInt32L( 0 );
       
  1135         }
       
  1136 
       
  1137     if ( iPreview )
       
  1138         {
       
  1139         aStream.WriteInt32L( 1 );
       
  1140         iPreview->ExternalizeL( aStream );
       
  1141         }
       
  1142     else
       
  1143         {
       
  1144         aStream.WriteInt32L( 0 );
       
  1145         }
       
  1146 
       
  1147     if ( iContentInfo ) 
       
  1148         {
       
  1149         aStream.WriteInt32L( 1 );
       
  1150         iContentInfo->ExternalizeL( aStream );
       
  1151         }
       
  1152     else 
       
  1153         {
       
  1154         aStream.WriteInt32L( 0 );
       
  1155         }
       
  1156 
       
  1157     if ( iUpgrade )
       
  1158         {
       
  1159         aStream.WriteInt32L( 1 );
       
  1160         iUpgrade->ExternalizeL( aStream );
       
  1161         }
       
  1162     else
       
  1163         {
       
  1164         aStream.WriteInt32L( 0 );
       
  1165         }
       
  1166 
       
  1167     if ( iDependency )
       
  1168         {
       
  1169         aStream.WriteInt32L( 1 );
       
  1170         iDependency->ExternalizeL( aStream );
       
  1171         }
       
  1172     else
       
  1173         {
       
  1174         aStream.WriteInt32L( 0 );
       
  1175         }
       
  1176 
       
  1177     // Subscribable content
       
  1178     if ( iSubscribableContent )
       
  1179         {
       
  1180         aStream.WriteInt32L( ETrue );
       
  1181         iSubscribableContent->ExternalizeL( aStream );
       
  1182         }
       
  1183     else
       
  1184         {
       
  1185         aStream.WriteInt32L( EFalse );
       
  1186         }
       
  1187    
       
  1188     
       
  1189     // Purchase options
       
  1190         
       
  1191     TInt purchaseOptionCount( iPurchaseOptions.Count() );
       
  1192     DLINFO(("Externalizing purchase options: %d", purchaseOptionCount ));
       
  1193     aStream.WriteInt32L( purchaseOptionCount );
       
  1194 
       
  1195     TInt purchaseOptionIndex( 0 );
       
  1196     while ( purchaseOptionIndex < purchaseOptionCount )
       
  1197         {
       
  1198         iPurchaseOptions[purchaseOptionIndex]->ExternalizeL( aStream );
       
  1199         ++purchaseOptionIndex;
       
  1200         }
       
  1201           
       
  1202     if ( iMoreInfo )
       
  1203         {
       
  1204         aStream.WriteInt32L( 1 );
       
  1205         iMoreInfo->ExternalizeL( aStream );
       
  1206         }
       
  1207     else
       
  1208         {
       
  1209         aStream.WriteInt32L( 0 );
       
  1210         }
       
  1211         
       
  1212     aStream.WriteInt32L( iDetails.Count() );
       
  1213     for( TInt i = 0 ; i < iDetails.Count() ; i++ )
       
  1214         {
       
  1215         iDetails[i]->ExternalizeL( aStream );
       
  1216         }
       
  1217     
       
  1218     DLTRACEOUT((""));
       
  1219     }
       
  1220 
       
  1221 
       
  1222 void CNcdNodeMetaData::InternalizeL( RReadStream& aStream )
       
  1223     {
       
  1224     DLTRACEIN((""));
       
  1225 
       
  1226     // NOTICE that this internalize function supposes that
       
  1227     // classid, namespace and metadataid info, that are
       
  1228     // inserted during externalization, are already read from
       
  1229     // the stream before calling this function.
       
  1230 
       
  1231     InternalizeDesL( iTimeStamp, aStream );
       
  1232     InternalizeDesL( iName, aStream );
       
  1233     InternalizeDesL( iDescription, aStream );
       
  1234     InternalizeDesL( iLayoutType, aStream );
       
  1235     
       
  1236     iAlwaysVisible = aStream.ReadInt8L();
       
  1237     
       
  1238     TInt32 disclaimerExists = aStream.ReadInt32L();
       
  1239     if ( disclaimerExists )
       
  1240         {
       
  1241         if ( iDisclaimer == NULL )
       
  1242             {
       
  1243             iDisclaimer = CNcdNodeDisclaimer::NewL();            
       
  1244             }
       
  1245         iDisclaimer->InternalizeL( aStream );
       
  1246         }
       
  1247     else if ( iDisclaimer )
       
  1248         {
       
  1249         // Because icon should not exist, Close it.
       
  1250         iDisclaimer->Close();
       
  1251         iDisclaimer = NULL;
       
  1252         }
       
  1253 
       
  1254     TInt32 iconExists = aStream.ReadInt32L();
       
  1255     if ( iconExists )
       
  1256         {
       
  1257         if ( iIcon == NULL )
       
  1258             {
       
  1259             iIcon = CNcdNodeIcon::NewL( iNodeManager, *this );            
       
  1260             }
       
  1261         iIcon->InternalizeL( aStream );
       
  1262         }
       
  1263     else if ( iIcon )
       
  1264         {
       
  1265         // Because icon should not exist, delete it.
       
  1266         iIcon->Close();
       
  1267         iIcon = NULL;
       
  1268         }
       
  1269         
       
  1270     TInt32 screenshotExists = aStream.ReadInt32L();
       
  1271     if ( screenshotExists )
       
  1272         {
       
  1273         if ( iScreenshot == NULL )
       
  1274             {
       
  1275             iScreenshot = CNcdNodeScreenshot::NewL( iNodeManager, *this );            
       
  1276             }
       
  1277         iScreenshot->InternalizeL( aStream );
       
  1278         }
       
  1279     else if ( iScreenshot )
       
  1280         {
       
  1281         // Because screenshot should not exist, delete it.
       
  1282         iScreenshot->Close();
       
  1283         iScreenshot = NULL;
       
  1284         }
       
  1285         
       
  1286     TInt32 skinExists = aStream.ReadInt32L();
       
  1287     if ( skinExists )
       
  1288         {
       
  1289         if ( iSkin == NULL )
       
  1290             {
       
  1291             iSkin = CNcdNodeSkin::NewL();            
       
  1292             }
       
  1293         iSkin->InternalizeL( aStream );
       
  1294         }
       
  1295     else if ( iSkin )
       
  1296         {
       
  1297         // Because icon should not exist, Close it.
       
  1298         iSkin->Close();
       
  1299         iSkin = NULL;
       
  1300         }
       
  1301 
       
  1302     TInt32 previewExists = aStream.ReadInt32L();
       
  1303     if ( previewExists )
       
  1304         {
       
  1305         if ( iPreview == NULL )
       
  1306             {
       
  1307             iPreview = CNcdNodePreview::NewL( *this, iNodeManager );            
       
  1308             }
       
  1309         iPreview->InternalizeL( aStream );
       
  1310         }
       
  1311     else if ( iPreview )
       
  1312         {
       
  1313         // Because preview should not exist, Close it.
       
  1314         iPreview->Close();
       
  1315         iPreview = NULL;
       
  1316         }
       
  1317 
       
  1318     DLTRACE(("Internalizing content info"));
       
  1319     TInt32 contentInfoExists = aStream.ReadInt32L();
       
  1320     if ( contentInfoExists )
       
  1321         {
       
  1322         if ( iContentInfo == NULL )
       
  1323             {
       
  1324             iContentInfo = CNcdNodeContentInfo::NewL();            
       
  1325             }
       
  1326         iContentInfo->InternalizeL( aStream );
       
  1327         InternalizeInstallFromContentInfoL();
       
  1328         }
       
  1329     else if ( iContentInfo )
       
  1330         {
       
  1331         // Because content info should not exist, Close it.
       
  1332         iContentInfo->Close();
       
  1333         iContentInfo = NULL;
       
  1334         }
       
  1335 
       
  1336     DLTRACE(("Internalizing upgrade for metadata:"));
       
  1337     DLNODEID(( Identifier() ));
       
  1338     TInt32 upgradeExists = aStream.ReadInt32L();
       
  1339     if ( upgradeExists )
       
  1340         {
       
  1341         if ( iUpgrade == NULL )
       
  1342             {
       
  1343             iUpgrade = CNcdNodeUpgrade::NewL( *this );            
       
  1344             }
       
  1345         iUpgrade->InternalizeL( aStream );
       
  1346         
       
  1347         // This requires that both CNcdNodeContentInfo &
       
  1348         // CNcdNodeInstall are up-to-date
       
  1349         HandleContentUpgradeL();
       
  1350         }
       
  1351     else 
       
  1352         {
       
  1353         if ( iUpgrade )
       
  1354             {
       
  1355             // Because upgrade should not exist, Close it.
       
  1356             iUpgrade->Close();
       
  1357             iUpgrade = NULL;
       
  1358             }
       
  1359         // Upgrade situation may have changed due to software
       
  1360         // uninstallations so we update to current situation
       
  1361         // HandleContentUpgradeL creates iUpgrade if necessary    
       
  1362         HandleContentUpgradeL();
       
  1363         }
       
  1364         
       
  1365     TInt32 dependencyExists = aStream.ReadInt32L();
       
  1366     if ( dependencyExists )
       
  1367         {
       
  1368         if ( iDependency == NULL )
       
  1369             {
       
  1370             iDependency = CNcdNodeDependency::NewL( *this );            
       
  1371             }
       
  1372         iDependency->InternalizeL( aStream );
       
  1373         }
       
  1374     else if ( iDependency )
       
  1375         {
       
  1376         // Because preview should not exist, Close it.
       
  1377         iDependency->Close();
       
  1378         iDependency = NULL;
       
  1379         }
       
  1380 
       
  1381 
       
  1382     // Subscribable content
       
  1383     TBool subscribable = aStream.ReadInt32L();
       
  1384     if ( subscribable )
       
  1385         {
       
  1386         if ( iSubscribableContent == NULL )
       
  1387             {
       
  1388             iSubscribableContent = CNcdServerSubscribableContent::NewL();
       
  1389             }        
       
  1390         iSubscribableContent->InternalizeL( aStream );
       
  1391         }
       
  1392 
       
  1393 
       
  1394     // Create or reinternalize purchase options :
       
  1395     
       
  1396     const TInt KPurchaseOptionCount( aStream.ReadInt32L() );
       
  1397 
       
  1398     DLINFO(( "Amount of purchaseoptions found from the stream: %d",
       
  1399              KPurchaseOptionCount ));
       
  1400     
       
  1401     TInt purchaseOptionIndex( 0 );
       
  1402     while ( purchaseOptionIndex < KPurchaseOptionCount )
       
  1403         {
       
  1404         InternalizePurchaseOptionL( aStream );        
       
  1405         ++purchaseOptionIndex;
       
  1406         }
       
  1407     
       
  1408     // Remove purchase options that were removed from the server
       
  1409     RemoveNotUpdatedPurchaseOptions();
       
  1410 
       
  1411 
       
  1412     TInt32 moreInfoExists = aStream.ReadInt32L();
       
  1413     if ( moreInfoExists )
       
  1414         {
       
  1415         if ( iMoreInfo == NULL )
       
  1416             {
       
  1417             iMoreInfo = CNcdNodeDisclaimer::NewL();            
       
  1418             }
       
  1419         iMoreInfo->InternalizeL( aStream );
       
  1420         }
       
  1421     else if ( iMoreInfo )
       
  1422         {
       
  1423         // Because icon should not exist, Close it.
       
  1424         iMoreInfo->Close();
       
  1425         iMoreInfo = NULL;
       
  1426         }
       
  1427     
       
  1428     iDetails.ResetAndDestroy();
       
  1429     TInt32 detailCount = aStream.ReadInt32L();
       
  1430     for( TInt i = 0 ; i < detailCount ; i++ )
       
  1431         {
       
  1432         CNcdKeyValuePair* detail = CNcdKeyValuePair::NewLC( aStream );
       
  1433         iDetails.AppendL( detail );
       
  1434         CleanupStack::Pop( detail );
       
  1435         }
       
  1436     
       
  1437     DLTRACEOUT((""));
       
  1438     }
       
  1439 
       
  1440 
       
  1441 void CNcdNodeMetaData::ReceiveMessage( MCatalogsBaseMessage* aMessage,
       
  1442                                        TInt aFunctionNumber )
       
  1443     {
       
  1444     DLTRACEIN((""));
       
  1445 
       
  1446     DASSERT( aMessage );
       
  1447         
       
  1448     // Now, we can be sure that rest of the time iMessage exists.
       
  1449     // This member variable is set for the CounterPartLost function.
       
  1450     iMessage = aMessage;
       
  1451     
       
  1452     TInt trapError( KErrNone );
       
  1453     
       
  1454     switch( aFunctionNumber )
       
  1455         {
       
  1456         case NcdNodeFunctionIds::ENcdInternalize:
       
  1457             TRAP( trapError, InternalizeRequestL( *aMessage ) );
       
  1458             break;
       
  1459 
       
  1460         case NcdNodeFunctionIds::ENcdRelease:
       
  1461             ReleaseRequest( *aMessage );
       
  1462             break;
       
  1463 
       
  1464         case NcdNodeFunctionIds::ENcdUserDataHandle:
       
  1465             TRAP( trapError, UserDataHandleRequestL( *aMessage ) );
       
  1466             break;            
       
  1467 
       
  1468         case NcdNodeFunctionIds::ENcdDisclaimerHandle:
       
  1469             TRAP( trapError, DisclaimerHandleRequestL( *aMessage ) );
       
  1470             break;
       
  1471 
       
  1472         case NcdNodeFunctionIds::ENcdIconHandle:
       
  1473             TRAP( trapError, IconHandleRequestL( *aMessage ) );
       
  1474             break;
       
  1475 
       
  1476         case NcdNodeFunctionIds::ENcdScreenshotHandle:
       
  1477             TRAP( trapError, ScreenshotHandleRequestL( *aMessage ) );
       
  1478             break;
       
  1479 
       
  1480         case NcdNodeFunctionIds::ENcdSkinHandle:
       
  1481             TRAP( trapError, SkinHandleRequestL( *aMessage ) );
       
  1482             break;
       
  1483 
       
  1484         case NcdNodeFunctionIds::ENcdUriContentHandle:
       
  1485             TRAP( trapError, UriContentHandleRequestL( *aMessage ) );
       
  1486             break;
       
  1487             
       
  1488         case NcdNodeFunctionIds::ENcdPreviewHandle:
       
  1489             TRAP( trapError, PreviewHandleRequestL( *aMessage ) );
       
  1490             break;            
       
  1491         
       
  1492         case NcdNodeFunctionIds::ENcdContentInfoHandle:
       
  1493             TRAP( trapError, ContentInfoHandleRequestL( *aMessage ) );
       
  1494             break;
       
  1495 
       
  1496         case NcdNodeFunctionIds::ENcdUpgradeHandle:
       
  1497             TRAP( trapError, UpgradeHandleRequestL( *aMessage ) );
       
  1498             break;
       
  1499 
       
  1500         case NcdNodeFunctionIds::ENcdDependencyHandle:
       
  1501             TRAP( trapError, DependencyHandleRequestL( *aMessage ) );
       
  1502             break;
       
  1503 
       
  1504         case NcdNodeFunctionIds::ENcdInternalizePurchaseHistory:
       
  1505             TRAP( trapError, InternalizePurchaseHistoryRequestL( *aMessage ) );
       
  1506             break;            
       
  1507 
       
  1508         case NcdNodeFunctionIds::ENcdInternalizePurchaseMeans:
       
  1509             TRAP( trapError, InternalizePurchaseMeansRequestL( *aMessage ) );
       
  1510             break;            
       
  1511 
       
  1512         case NcdNodeFunctionIds::ENcdPurchaseOptionIds:
       
  1513             TRAP( trapError, PurchaseOptionIdsRequestL( *aMessage ) );
       
  1514             break;
       
  1515 
       
  1516         case NcdNodeFunctionIds::ENcdInstallHandle:
       
  1517             TRAP( trapError, InstallHandleRequestL( *aMessage ) );
       
  1518             break;
       
  1519 
       
  1520         case NcdNodeFunctionIds::ENcdDownloadHandle:
       
  1521             TRAP( trapError, DownloadHandleRequestL( *aMessage ) );
       
  1522             break;
       
  1523         
       
  1524         case NcdNodeFunctionIds::ENcdMoreInfoHandle:
       
  1525             TRAP( trapError, MoreInfoHandleRequestL( *aMessage ) );
       
  1526             break;
       
  1527             
       
  1528         case NcdNodeFunctionIds::ENcdIsPurchaseSupported:
       
  1529             TRAP( trapError, IsPurchaseSupportedRequestL( *aMessage ) );
       
  1530             break;
       
  1531 
       
  1532         default:
       
  1533             DLERROR(("Unidentified function request"));
       
  1534             DASSERT( EFalse );        
       
  1535             break;
       
  1536         }
       
  1537 
       
  1538     if ( trapError != KErrNone )
       
  1539         {
       
  1540         // Because something went wrong the complete has not been
       
  1541         // yet called for the message.
       
  1542         // So, inform the client about the error.
       
  1543         aMessage->CompleteAndRelease( trapError );
       
  1544         }
       
  1545 
       
  1546     // Because the message should not be used after this, set it NULL.
       
  1547     // So, CounterPartLost function will know that no messages are
       
  1548     // waiting the response at the moment.
       
  1549     iMessage = NULL;        
       
  1550 
       
  1551     if ( aFunctionNumber == NcdNodeFunctionIds::ENcdRelease )
       
  1552         {
       
  1553         // Because release was called for this object it may be time to
       
  1554         // delete this object. Inform manager about the release so it may
       
  1555         // close this object and clear the cache if needed.
       
  1556         // Notice that if the manager closes this object then this object will
       
  1557         // be deleted. It is safe to do here because no memeber variables are
       
  1558         // needed here after the call.
       
  1559         NodeManager().MetaDataReleased( *this );       
       
  1560         }
       
  1561                     
       
  1562     DLTRACEOUT((""));
       
  1563     }
       
  1564 
       
  1565 
       
  1566 void CNcdNodeMetaData::CounterPartLost( const MCatalogsSession& aSession )
       
  1567     {
       
  1568     // This function may be called whenever -- when the message is waiting
       
  1569     // response or when the message does not exist.
       
  1570     // iMessage may be NULL here, because in the end of the
       
  1571     // ReceiveMessage it is set to NULL. The life time of the message
       
  1572     // ends shortly after CompleteAndRelease is called.
       
  1573     if ( iMessage != NULL )
       
  1574         {
       
  1575         iMessage->CounterPartLost( aSession );
       
  1576         }    
       
  1577     }
       
  1578 
       
  1579 void CNcdNodeMetaData::InternalizeRequestL( MCatalogsBaseMessage& aMessage ) const
       
  1580     {
       
  1581     DLTRACEIN((""));
       
  1582     
       
  1583     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
  1584     CleanupStack::PushL( buf );
       
  1585     
       
  1586     RBufWriteStream stream( *buf );
       
  1587     CleanupClosePushL( stream );
       
  1588 
       
  1589 
       
  1590     // Include all the necessary node data to the stream
       
  1591     ExternalizeDataForRequestL( stream );     
       
  1592     
       
  1593     
       
  1594     // Commits data to the stream when closing.
       
  1595     CleanupStack::PopAndDestroy( &stream );
       
  1596 
       
  1597 
       
  1598     if ( buf->Size() > 0 ) 
       
  1599         {
       
  1600         DLINFO(( "Completing the message, buf len: %d", buf->Ptr(0).Length() ));
       
  1601         }
       
  1602     // If this leaves, ReceiveMessge will complete the message.
       
  1603     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );
       
  1604         
       
  1605     
       
  1606     DLINFO(("Deleting the buf"));
       
  1607     CleanupStack::PopAndDestroy( buf );
       
  1608         
       
  1609     DLTRACEOUT((""));
       
  1610     }
       
  1611     
       
  1612 
       
  1613 void CNcdNodeMetaData::ExternalizeDataForRequestL( RWriteStream& aStream ) const
       
  1614     {
       
  1615     DLTRACEIN((""));
       
  1616 
       
  1617     DLINFO(("Class ID: %d", ClassId() ));
       
  1618     // Metadata existed. So, insert info that meta data was found.
       
  1619     aStream.WriteInt32L( ClassId() );
       
  1620     
       
  1621     iIdentifier->ExternalizeL( aStream );
       
  1622     ExternalizeDesL( NodeName(), aStream );
       
  1623     ExternalizeDesL( Description(), aStream );
       
  1624     ExternalizeDesL( LayoutType(), aStream );
       
  1625     
       
  1626     aStream.WriteInt8L( iAlwaysVisible );
       
  1627     
       
  1628     aStream.WriteInt32L( iDetails.Count() );
       
  1629     for( TInt i = 0 ; i < iDetails.Count() ; i++ )
       
  1630         {
       
  1631         iDetails[i]->ExternalizeL( aStream );
       
  1632         }
       
  1633 
       
  1634     DLTRACEOUT((""));
       
  1635     }
       
  1636 
       
  1637 
       
  1638 void CNcdNodeMetaData::InternalizePurchaseMeansRequestL(
       
  1639     MCatalogsBaseMessage& aMessage ) const
       
  1640     {
       
  1641     DLTRACEIN((""));
       
  1642     
       
  1643     // Parse the input message and create a descriptor array containing
       
  1644     // the purchase option ids which should be externalized for the request.
       
  1645     CDesCArray* purchaseOptionIds = new( ELeave ) CDesCArrayFlat( 5 );
       
  1646     CleanupStack::PushL( purchaseOptionIds );
       
  1647     HBufC8* input = HBufC8::NewLC( aMessage.InputLength() );
       
  1648     TPtr8 inputPtr = input->Des();
       
  1649     aMessage.ReadInput( inputPtr );
       
  1650     RDesReadStream inputStream( *input );
       
  1651     CleanupClosePushL( inputStream );
       
  1652     
       
  1653     TInt poCount = inputStream.ReadInt32L();
       
  1654     for ( TInt i = 0; i < poCount; i++ ) 
       
  1655         {
       
  1656         HBufC* tmpId( NULL );
       
  1657         InternalizeDesL( tmpId, inputStream );
       
  1658         CleanupStack::PushL( tmpId );
       
  1659         purchaseOptionIds->AppendL( *tmpId );
       
  1660         CleanupStack::PopAndDestroy( tmpId );
       
  1661         }
       
  1662         
       
  1663     CleanupStack::PopAndDestroy( &inputStream );
       
  1664     CleanupStack::PopAndDestroy( input );
       
  1665         
       
  1666     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
  1667     CleanupStack::PushL( buf );
       
  1668     
       
  1669     RBufWriteStream stream( *buf );
       
  1670     CleanupClosePushL( stream );
       
  1671 
       
  1672     // Include all the necessary purchase data to the stream
       
  1673     MCatalogsSession& session = aMessage.Session();
       
  1674     ExternalizePurchaseMeansForRequestL( *purchaseOptionIds, stream, session ); 
       
  1675     
       
  1676     // Commits data to the stream when closing.
       
  1677     CleanupStack::PopAndDestroy( &stream );
       
  1678 
       
  1679 
       
  1680     if ( buf->Size() > 0 ) 
       
  1681         {
       
  1682         DLINFO(( "Completing the message, buf len: %d", buf->Ptr(0).Length() ));
       
  1683         }
       
  1684     // If this leaves, ReceiveMessge will complete the message.
       
  1685     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );
       
  1686         
       
  1687     
       
  1688     DLINFO(("Deleting the buf"));
       
  1689     CleanupStack::PopAndDestroy( buf );
       
  1690     CleanupStack::PopAndDestroy( purchaseOptionIds );
       
  1691         
       
  1692     DLTRACEOUT((""));    
       
  1693     }
       
  1694 
       
  1695 
       
  1696 void CNcdNodeMetaData::ExternalizePurchaseMeansForRequestL(
       
  1697     const CDesCArray& aPurchaseOptionIds,
       
  1698     RWriteStream& aStream,
       
  1699     MCatalogsSession& aSession ) const
       
  1700     {
       
  1701 
       
  1702     // Subscribable content
       
  1703     if ( iSubscribableContent != NULL )
       
  1704         {
       
  1705         aStream.WriteInt32L( ETrue );
       
  1706         iSubscribableContent->ExternalizeL( aStream );
       
  1707         }
       
  1708     else
       
  1709         {
       
  1710         aStream.WriteInt32L( EFalse );
       
  1711         }
       
  1712     
       
  1713     
       
  1714     // this is the same as handle amount
       
  1715     TInt purchaseOptionAmount( aPurchaseOptionIds.Count() );
       
  1716     aStream.WriteInt32L( purchaseOptionAmount );
       
  1717     
       
  1718     for ( TInt i = 0; i < purchaseOptionAmount; i++ ) 
       
  1719         {
       
  1720         CNcdPurchaseOptionImpl& tmpPurchaseOption = PurchaseOptionByIdL(
       
  1721             aPurchaseOptionIds[i] );      
       
  1722         TInt tmpHandle( aSession.AddObjectL( &tmpPurchaseOption ) );
       
  1723         
       
  1724         TRAPD( addError, aStream.WriteInt32L( tmpHandle ) );
       
  1725         if ( addError != KErrNone )
       
  1726             {
       
  1727             // Should all other added objects be removed from
       
  1728             //       the session also?
       
  1729             aSession.RemoveObject( tmpHandle );
       
  1730             User::Leave( addError );
       
  1731             }
       
  1732         }    
       
  1733     }
       
  1734 
       
  1735 
       
  1736 void CNcdNodeMetaData::InternalizePurchaseHistoryRequestL( MCatalogsBaseMessage& aMessage ) const
       
  1737     {
       
  1738     DLTRACEIN((""));
       
  1739     
       
  1740     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
  1741     CleanupStack::PushL( buf );
       
  1742     
       
  1743     RBufWriteStream stream( *buf );
       
  1744     CleanupClosePushL( stream );
       
  1745 
       
  1746 
       
  1747     // Include all the necessary data to the stream
       
  1748     ExternalizePurchaseHistoryForRequestL( stream );     
       
  1749     
       
  1750     
       
  1751     // Commits data to the stream when closing.
       
  1752     CleanupStack::PopAndDestroy( &stream );
       
  1753 
       
  1754     if ( buf->Size() > 0 ) 
       
  1755         {
       
  1756         DLINFO(( "Completing the message, buf len: %d", buf->Ptr(0).Length() ));
       
  1757         }
       
  1758         
       
  1759     // If this leaves ReceiveMessage function will complete the message.
       
  1760     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );
       
  1761         
       
  1762     
       
  1763     DLINFO(("Deleting the buf"));
       
  1764     CleanupStack::PopAndDestroy( buf );
       
  1765         
       
  1766     DLTRACEOUT((""));
       
  1767     }
       
  1768 
       
  1769 void CNcdNodeMetaData::ExternalizePurchaseHistoryForRequestL( RWriteStream& aStream ) const
       
  1770     {
       
  1771     DLTRACEIN((""));
       
  1772 
       
  1773     // Insert node class id just in case somebody wants to check that
       
  1774     // the data is of the right type
       
  1775     aStream.WriteInt32L( ClassId() );
       
  1776 
       
  1777     // Get up to date purchase info straight from purchase history
       
  1778     CNcdPurchaseDetails* purchaseDetails = NULL;
       
  1779     
       
  1780     TRAPD( error, 
       
  1781         {        
       
  1782         purchaseDetails = PurchaseDetailsLC();
       
  1783         CleanupStack::Pop( purchaseDetails );
       
  1784         });    
       
  1785     
       
  1786     // there's no problem in pushing a NULL pointer as long as it's
       
  1787     // pushed with PushL or CleanupDeletePushL
       
  1788     CleanupStack::PushL( purchaseDetails );
       
  1789     
       
  1790     if ( error == KNcdErrorNoPurchaseInformation
       
  1791          ||  ( purchaseDetails && 
       
  1792                purchaseDetails->PurchaseOptionId() == KNullDesC ) )
       
  1793         {
       
  1794         // If no info is found it means that the node is
       
  1795         // not purchased.
       
  1796         // Also, purchase option id is checked here. In some situations,
       
  1797         // dummy purchase details may be inserted into the purchase history
       
  1798         // from outside the engine. So, then the purchase option id is most likely
       
  1799         // not set correctly.
       
  1800         aStream.WriteInt32L( EFalse );
       
  1801         CleanupStack::PopAndDestroy( purchaseDetails );
       
  1802         return;
       
  1803         }
       
  1804     else if ( error == KErrNone )
       
  1805         {
       
  1806         aStream.WriteInt32L( ETrue );
       
  1807         }
       
  1808     else
       
  1809         {
       
  1810         User::Leave( error );
       
  1811         }    
       
  1812     
       
  1813      
       
  1814     const TDesC& purchasedOptionId = purchaseDetails->PurchaseOptionId();
       
  1815     ExternalizeDesL( purchasedOptionId, aStream );
       
  1816 
       
  1817     TTime timeOfPurchase = purchaseDetails->PurchaseTime();
       
  1818     const TInt64& integerTimeOfPurchase = timeOfPurchase.Int64();
       
  1819     // Store framework provides the necessary implementation for 
       
  1820     // the operator<< to externalise the 64-bit integer
       
  1821     aStream << integerTimeOfPurchase;
       
  1822     
       
  1823     const TDesC& finalPrice = purchaseDetails->FinalPrice();
       
  1824     ExternalizeDesL( finalPrice, aStream );
       
  1825 
       
  1826 
       
  1827     CleanupStack::PopAndDestroy( purchaseDetails );
       
  1828     DLTRACEOUT((""));
       
  1829     }
       
  1830  
       
  1831     
       
  1832 void CNcdNodeMetaData::PurchaseOptionIdsRequestL(
       
  1833     MCatalogsBaseMessage& aMessage ) const 
       
  1834     {
       
  1835     DLTRACEIN((""));
       
  1836     
       
  1837     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
  1838     CleanupStack::PushL( buf );
       
  1839     
       
  1840     RBufWriteStream stream( *buf );
       
  1841     CleanupClosePushL( stream );
       
  1842     
       
  1843     stream.WriteInt32L( iPurchaseOptions.Count() );
       
  1844     for ( TInt i = 0; i < iPurchaseOptions.Count(); i++ ) 
       
  1845         {
       
  1846         ExternalizeDesL( iPurchaseOptions[i]->Id(), stream );
       
  1847         }
       
  1848         
       
  1849     CleanupStack::PopAndDestroy( &stream );
       
  1850     
       
  1851     // If this leaves, ReceiveMessage will complete the message.
       
  1852     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );
       
  1853     CleanupStack::PopAndDestroy( buf );
       
  1854     }
       
  1855         
       
  1856 
       
  1857 void CNcdNodeMetaData::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const
       
  1858     {
       
  1859     DLTRACEIN((""));
       
  1860 
       
  1861     // Decrease the reference count for this object.
       
  1862     // When the reference count reaches zero, this object will be destroyed
       
  1863     // and removed from the session.
       
  1864     MCatalogsSession& requestSession( aMessage.Session() );
       
  1865     TInt handle( aMessage.Handle() );
       
  1866     aMessage.CompleteAndRelease( KErrNone );
       
  1867     requestSession.RemoveObject( handle );
       
  1868                 
       
  1869     DLTRACEOUT((""));
       
  1870     }
       
  1871 
       
  1872 
       
  1873 void CNcdNodeMetaData::IconIdRequestL( MCatalogsBaseMessage& aMessage ) const
       
  1874     {
       
  1875     DLTRACEIN((""));
       
  1876 
       
  1877     // If this leaves, ReceiveMessage will complete the message.    
       
  1878 
       
  1879     if ( ! iIcon )
       
  1880         {
       
  1881         User::Leave( KErrNotFound );
       
  1882         }
       
  1883 
       
  1884     aMessage.CompleteAndReleaseL( iIcon->IconId(), KErrNone );
       
  1885 
       
  1886     DLTRACEOUT((""));
       
  1887     }
       
  1888 
       
  1889 
       
  1890 void CNcdNodeMetaData::IconDataRequestL( MCatalogsBaseMessage& aMessage ) const
       
  1891     {
       
  1892     DLTRACEIN((""));
       
  1893 
       
  1894     // If this leaves, ReceiveMessage will complete the message.    
       
  1895 
       
  1896     if ( iIcon == NULL )
       
  1897         {
       
  1898         User::Leave( KErrNotFound );
       
  1899         }
       
  1900 
       
  1901     HBufC8* icon = iIcon->IconDataL();
       
  1902     CleanupStack::PushL( icon );
       
  1903 
       
  1904     aMessage.CompleteAndReleaseL( *icon, KErrNone );
       
  1905     
       
  1906     CleanupStack::PopAndDestroy( icon );
       
  1907     
       
  1908     DLTRACEOUT((""));
       
  1909     }
       
  1910 
       
  1911 
       
  1912 void CNcdNodeMetaData::UserDataHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  1913     {
       
  1914     DLTRACEIN((""));
       
  1915 
       
  1916     if( iUserData == NULL )
       
  1917         {
       
  1918         DLINFO(("User data NULL"));
       
  1919         User::Leave( KErrNotFound );        
       
  1920         }
       
  1921 
       
  1922     // Get the session that will contain the handle of the node
       
  1923     MCatalogsSession& requestSession( aMessage.Session() );
       
  1924 
       
  1925     // Add the node again to the session and get the new handle.
       
  1926     // If the node already existed in the session we will still
       
  1927     // get a new handle to the same object.
       
  1928     TInt32 handle( requestSession.AddObjectL( iUserData ) );
       
  1929 
       
  1930     DLINFO(("User data handle: %d", handle ));
       
  1931         
       
  1932     // Send the information to the client side
       
  1933     // If this leaves, ReceiveMessage will complete the message.
       
  1934     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  1935         
       
  1936     DLTRACEOUT((""));
       
  1937     }
       
  1938 
       
  1939 
       
  1940 void CNcdNodeMetaData::DisclaimerHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  1941     {
       
  1942     DLTRACEIN((""));    
       
  1943     
       
  1944     if( iDisclaimer == NULL )
       
  1945         {
       
  1946         DLINFO(("Disclaimer NULL"));
       
  1947         User::Leave( KErrNotFound );
       
  1948         }
       
  1949 
       
  1950     // Get the session that will contain the handle of the node.
       
  1951     MCatalogsSession& requestSession( aMessage.Session() );
       
  1952 
       
  1953     // Add the icon to the session and get the handle.
       
  1954     // If the node already existed in the session we will still
       
  1955     // get a new handle to the same object.
       
  1956     TInt32 handle( requestSession.AddObjectL( iDisclaimer ) );
       
  1957 
       
  1958     DLINFO(("Disclaimer handle: %d", handle ));
       
  1959         
       
  1960     // Send the information to the client side
       
  1961     // If this leaves, ReceiveMessage will complete the message.
       
  1962     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  1963 
       
  1964     DLTRACEOUT((""));        
       
  1965     }
       
  1966 
       
  1967 
       
  1968 void CNcdNodeMetaData::IconHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  1969     {
       
  1970     DLTRACEIN((""));    
       
  1971     
       
  1972     if( iIcon == NULL )
       
  1973         {
       
  1974         DLINFO(("Icon NULL"));
       
  1975         User::Leave( KErrNotFound );
       
  1976         }
       
  1977         
       
  1978     if ( !iIcon->IconDataReady() ) 
       
  1979         {
       
  1980         DLINFO(("Icon data not ready"));
       
  1981         User::Leave( KErrNotFound );
       
  1982         }
       
  1983         
       
  1984     if ( iIcon->IconId() == KNullDesC ) 
       
  1985         {
       
  1986         DLINFO(("Icon id not set"));
       
  1987         User::Leave( KErrNotFound );
       
  1988         }
       
  1989 
       
  1990     // Get the session that will contain the handle of the node.
       
  1991     MCatalogsSession& requestSession( aMessage.Session() );
       
  1992 
       
  1993     // Add the icon to the session and get the handle.
       
  1994     // If the node already existed in the session we will still
       
  1995     // get a new handle to the same object.
       
  1996     TInt32 handle( requestSession.AddObjectL( iIcon ) );
       
  1997 
       
  1998     DLINFO(("Icon handle: %d", handle ));
       
  1999         
       
  2000     // Send the information to the client side
       
  2001     // If this leaves, ReceiveMessage will complete the message.
       
  2002     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2003 
       
  2004     DLTRACEOUT((""));        
       
  2005     }
       
  2006 
       
  2007 
       
  2008 void CNcdNodeMetaData::ScreenshotHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  2009     {
       
  2010     DLTRACEIN((""));    
       
  2011     
       
  2012     if( iScreenshot == NULL )
       
  2013         {
       
  2014         DLINFO(("Screenshot NULL"));
       
  2015         User::Leave( KErrNotFound );
       
  2016         }
       
  2017 
       
  2018     // Get the session that will contain the handle of the node.
       
  2019     MCatalogsSession& requestSession( aMessage.Session() );
       
  2020 
       
  2021     // Add the screenshot to the session and get the handle.
       
  2022     // If the node already existed in the session we will still
       
  2023     // get a new handle to the same object.
       
  2024     TInt32 handle( requestSession.AddObjectL( iScreenshot ) );
       
  2025 
       
  2026     DLINFO(("Screenshot handle: %d", handle ));
       
  2027         
       
  2028     // Send the information to the client side
       
  2029     // If this leaves, ReceiveMessage will complete the message.
       
  2030     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2031 
       
  2032     DLTRACEOUT((""));        
       
  2033     }
       
  2034 
       
  2035 
       
  2036 void CNcdNodeMetaData::SkinHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  2037     {
       
  2038     DLTRACEIN((""));    
       
  2039     
       
  2040     if( iSkin == NULL )
       
  2041         {
       
  2042         DLINFO(("Skin NULL"));
       
  2043         User::Leave( KErrNotFound );
       
  2044         }
       
  2045 
       
  2046     // Get the session that will contain the handle of the node.
       
  2047     MCatalogsSession& requestSession( aMessage.Session() );
       
  2048 
       
  2049     // Add the skin to the session and get the handle.
       
  2050     // If the node already existed in the session we will still
       
  2051     // get a new handle to the same object.
       
  2052     TInt32 handle( requestSession.AddObjectL( iSkin ) );
       
  2053 
       
  2054     DLINFO(("Skin handle: %d", handle ));
       
  2055         
       
  2056     // Send the information to the client side
       
  2057     // If this leaves, ReceiveMessage will complete the message.
       
  2058     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2059 
       
  2060     DLTRACEOUT((""));        
       
  2061     }
       
  2062 
       
  2063 
       
  2064 void CNcdNodeMetaData::UriContentHandleRequestL(
       
  2065     MCatalogsBaseMessage& aMessage ) const
       
  2066     {
       
  2067     DLTRACEIN((""));    
       
  2068     
       
  2069     if( iUriContent == NULL )
       
  2070         {
       
  2071         DLINFO(("UriContent NULL"));
       
  2072         User::Leave( KErrNotFound );
       
  2073         }
       
  2074 
       
  2075     // Get the session that will contain the handle of the node.
       
  2076     MCatalogsSession& requestSession( aMessage.Session() );
       
  2077 
       
  2078 
       
  2079     // Add the uri content to the session and get the handle.
       
  2080     // If the node already existed in the session we will still
       
  2081     // get a new handle to the same object.
       
  2082     TInt32 handle( requestSession.AddObjectL( iUriContent ) );
       
  2083 
       
  2084     DLINFO(("Uri content handle: %d", handle ));
       
  2085         
       
  2086     // Send the information to the client side
       
  2087     // If this leaves, ReceiveMessage will complete the message.
       
  2088     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2089 
       
  2090     DLTRACEOUT((""));        
       
  2091     }
       
  2092 
       
  2093 
       
  2094 void CNcdNodeMetaData::ContentInfoHandleRequestL(
       
  2095     MCatalogsBaseMessage& aMessage ) const
       
  2096     {
       
  2097     DLTRACEIN((""));    
       
  2098     
       
  2099     if( iContentInfo == NULL )
       
  2100         {
       
  2101         DLINFO(("ContentInfo NULL"));
       
  2102         User::Leave( KErrNotFound );
       
  2103         }
       
  2104 
       
  2105     // Get the session that will contain the handle of the node.
       
  2106     MCatalogsSession& requestSession( aMessage.Session() );
       
  2107 
       
  2108 
       
  2109     // Add the content info to the session and get the handle.
       
  2110     // If the node already existed in the session we will still
       
  2111     // get a new handle to the same object.
       
  2112     TInt32 handle( requestSession.AddObjectL( iContentInfo ) );
       
  2113 
       
  2114     DLINFO(("Content info handle: %d", handle ));
       
  2115         
       
  2116     // Send the information to the client side.
       
  2117     // If this leaves, ReceiveMessage will complete the message.
       
  2118     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2119 
       
  2120     DLTRACEOUT((""));        
       
  2121     }
       
  2122 
       
  2123 
       
  2124 void CNcdNodeMetaData::PreviewHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  2125     {
       
  2126     DLTRACEIN((""));    
       
  2127     
       
  2128     if( iPreview == NULL )
       
  2129         {
       
  2130         DLINFO(("Preview NULL"));
       
  2131         User::Leave( KErrNotFound );
       
  2132         }
       
  2133 
       
  2134     // Get the session that will contain the handle of the preview.
       
  2135     MCatalogsSession& requestSession( aMessage.Session() );
       
  2136 
       
  2137 
       
  2138     // Add the preview to the session and get the handle.
       
  2139     // If the preview already existed in the session we will still
       
  2140     // get a new handle to the same object.
       
  2141     TInt32 handle( requestSession.AddObjectL( iPreview ) );
       
  2142 
       
  2143     DLINFO(("Preview handle: %d", handle ));
       
  2144         
       
  2145     // Send the information to the client side
       
  2146     // If this leaves, ReceiveMessage will complete the message.
       
  2147     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2148 
       
  2149     DLTRACEOUT((""));        
       
  2150     }
       
  2151 
       
  2152 
       
  2153 void CNcdNodeMetaData::UpgradeHandleRequestL( MCatalogsBaseMessage& aMessage )
       
  2154     {
       
  2155     DLTRACEIN((""));    
       
  2156     DLNODEID(( Identifier() ));
       
  2157     HandleContentUpgradeL();
       
  2158     // Upgrade interface should be provided in proxy side only if the upgrade
       
  2159     // exists in server side and it has some identifiers or content that can be used to 
       
  2160     // load node upgrades from web.
       
  2161     if( !iUpgrade 
       
  2162         || ( iUpgrade->AllUpgradesInstalledL() && !iUpgrade->ContentUpgrades() ) )
       
  2163         {
       
  2164         DLINFO(("Upgrade NULL or no node targets available"));
       
  2165         User::Leave( KErrNotFound );
       
  2166         }
       
  2167 
       
  2168     // Get the session that will contain the handle of the preview.
       
  2169     MCatalogsSession& requestSession( aMessage.Session() );
       
  2170 
       
  2171 
       
  2172     // Add the preview to the session and get the handle.
       
  2173     // If the object already existed in the session we will still
       
  2174     // get a new handle to the same object.
       
  2175     TInt32 handle( requestSession.AddObjectL( iUpgrade ) );
       
  2176 
       
  2177     DLINFO(("Upgrade handle: %d", handle ));
       
  2178         
       
  2179     // Send the information to the client side
       
  2180     // If this leaves, ReceiveMessage will complete the message.
       
  2181     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2182 
       
  2183     DLTRACEOUT((""));        
       
  2184     }
       
  2185 
       
  2186 
       
  2187 void CNcdNodeMetaData::DependencyHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  2188     {
       
  2189     DLTRACEIN((""));    
       
  2190     
       
  2191     // Dependency interface should be provided in proxy side only if the dependency
       
  2192     // exists in server side and it has some identifiers or content that can be used to 
       
  2193     // load dependencies from web.
       
  2194     // NOTE: interface will be visible even if all of the dependencies are installed
       
  2195     if( !iDependency ) 
       
  2196         {
       
  2197         DLINFO(("Dependency NULL"));
       
  2198         User::Leave( KErrNotFound );
       
  2199         }
       
  2200 
       
  2201     // Get the session that will contain the handle of the preview.
       
  2202     MCatalogsSession& requestSession( aMessage.Session() );
       
  2203 
       
  2204 
       
  2205     // Add the preview to the session and get the handle.
       
  2206     // If the preview already existed in the session we will still
       
  2207     // get a new handle to the same object.
       
  2208     TInt32 handle( requestSession.AddObjectL( iDependency ) );
       
  2209 
       
  2210     DLINFO(("Dependency handle: %d", handle ));
       
  2211         
       
  2212     // Send the information to the client side
       
  2213     // If this leaves, ReceiveMessage will complete the message.
       
  2214     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2215 
       
  2216     DLTRACEOUT((""));        
       
  2217     }
       
  2218 
       
  2219 
       
  2220 void CNcdNodeMetaData::DownloadHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  2221     {
       
  2222     DLTRACEIN((""));    
       
  2223     
       
  2224     if( iDownload == NULL )
       
  2225         {
       
  2226         DLINFO(("Node download NULL"));
       
  2227         User::Leave( KErrNotFound );
       
  2228         }
       
  2229 
       
  2230     // Get the session that will contain the handle of the node
       
  2231     MCatalogsSession& requestSession( aMessage.Session() );
       
  2232 
       
  2233     // Add the download to the session and get the handle.
       
  2234     // If the node already existed in the session we will still
       
  2235     // get a new handle to the same object.
       
  2236     TInt32 handle( requestSession.AddObjectL( iDownload ) );
       
  2237 
       
  2238     DLINFO(("Download handle: %d", handle ));
       
  2239         
       
  2240     // Send the information to the client side
       
  2241     // If this leaves, ReceiveMessage will complete the message.
       
  2242     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2243 
       
  2244     DLTRACEOUT((""));        
       
  2245     }
       
  2246 
       
  2247 
       
  2248 void CNcdNodeMetaData::InstallHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  2249     {
       
  2250     DLTRACEIN((""));    
       
  2251     
       
  2252     if( iInstall == NULL )
       
  2253         {
       
  2254         DLINFO(("Node install NULL"));
       
  2255         User::Leave( KErrNotFound );
       
  2256         }
       
  2257 
       
  2258     // Get the session that will contain the handle of the node
       
  2259     MCatalogsSession& requestSession( aMessage.Session() );
       
  2260 
       
  2261     // Add the install to the session and get the handle.
       
  2262     // If the node already existed in the session we will still
       
  2263     // get a new handle to the same object.
       
  2264     TInt32 handle( requestSession.AddObjectL( iInstall ) );
       
  2265 
       
  2266     DLINFO(("Install handle: %d", handle ));
       
  2267         
       
  2268     // Send the information to the client side
       
  2269     // If this leaves, ReceiveMessage will complete the message.
       
  2270     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2271 
       
  2272     DLTRACEOUT((""));        
       
  2273     }
       
  2274 
       
  2275 void CNcdNodeMetaData::MoreInfoHandleRequestL( MCatalogsBaseMessage& aMessage ) const
       
  2276     {
       
  2277     DLTRACEIN((""));    
       
  2278     
       
  2279     if( iMoreInfo == NULL )
       
  2280         {
       
  2281         DLINFO(("More info NULL"));
       
  2282         User::Leave( KErrNotFound );
       
  2283         }
       
  2284 
       
  2285     // Get the session that will contain the handle of the node.
       
  2286     MCatalogsSession& requestSession( aMessage.Session() );
       
  2287 
       
  2288     // Add the more info to the session and get the handle.
       
  2289     // If the node already existed in the session we will still
       
  2290     // get a new handle to the same object.
       
  2291     TInt32 handle( requestSession.AddObjectL( iMoreInfo ) );
       
  2292 
       
  2293     DLINFO(("More info handle: %d", handle ));
       
  2294         
       
  2295     // Send the information to the client side
       
  2296     // If this leaves, ReceiveMessage will complete the message.
       
  2297     aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  2298 
       
  2299     DLTRACEOUT((""));        
       
  2300     }
       
  2301 
       
  2302 void CNcdNodeMetaData::IsPurchaseSupportedRequestL( MCatalogsBaseMessage& aMessage ) const
       
  2303     {
       
  2304     DLTRACEIN((""));
       
  2305     TBool isPurchaseSupported = EFalse;
       
  2306     if( iPurchaseOptions.Count() > 0 )
       
  2307         {
       
  2308         isPurchaseSupported = ETrue;
       
  2309         }
       
  2310     
       
  2311     // Send the information to the client side
       
  2312     // If this leaves, ReceiveMessage will complete the message.
       
  2313     aMessage.CompleteAndReleaseL( isPurchaseSupported, KErrNone );
       
  2314     }
       
  2315 
       
  2316 void CNcdNodeMetaData::InternalizePurchaseOptionL(
       
  2317     const MNcdPreminetProtocolPurchaseOption& aData )
       
  2318     {
       
  2319     DLTRACEIN((""));
       
  2320     CNcdPurchaseOptionImpl& option(
       
  2321         CreateOrGetPurchaseOptionL( aData.Id() ) );
       
  2322     
       
  2323     TRAPD( error, option.InternalizeL( aData ) );
       
  2324     if ( error != KErrNone )
       
  2325         {
       
  2326         // If internalization fails, let's remove the option so
       
  2327         // no incomplete data is left to be used
       
  2328         
       
  2329         // If an error occurs in the removal we don't want to
       
  2330         // pass that forward. Let's pass the original error.
       
  2331         TRAP_IGNORE( RemovePurchaseOptionL( aData.Id() ) );
       
  2332         
       
  2333         User::Leave( error );
       
  2334         }
       
  2335     
       
  2336     // Set the option recently updated so we can later in
       
  2337     // RemoveRecentlyUpdatedPurchaseOptions() differentiate
       
  2338     // options that should be removed because they were not
       
  2339     // received from the server anymore.
       
  2340     option.SetRecentlyUpdated( ETrue );
       
  2341     
       
  2342     // Updates content URI if necessary
       
  2343     HandleContentUriUpdateL( option );
       
  2344     DLTRACEOUT(("Purchase option internalized successfully"));
       
  2345     }
       
  2346     
       
  2347 
       
  2348 CNcdPurchaseOptionImpl& CNcdNodeMetaData::CreateOrGetPurchaseOptionL(
       
  2349     const TDesC& aPurchaseOptionId )
       
  2350     {
       
  2351     DLTRACEIN((""));
       
  2352     CNcdPurchaseOptionImpl* option( NULL );
       
  2353     TRAPD( error, option = &PurchaseOptionByIdL( aPurchaseOptionId ) );
       
  2354     if ( error != KErrNone && error != KErrNotFound )
       
  2355         {
       
  2356         User::Leave( error );
       
  2357         }
       
  2358     else if ( error == KErrNotFound )
       
  2359         {
       
  2360         // Not found, have to create
       
  2361         option = CNcdPurchaseOptionImpl::NewL( *this );
       
  2362         // Set option id already here so if something goes wrong
       
  2363         // after appending the option into array, the option can be
       
  2364         // identified and removed.
       
  2365         option->SetIdL( aPurchaseOptionId );
       
  2366             
       
  2367         error = KErrNone;
       
  2368         error = iPurchaseOptions.Append( option );
       
  2369         if ( error != KErrNone )
       
  2370             {
       
  2371             DLERROR(("Appending purchase option failed with %d", error ));
       
  2372             // When CObject base object is created its reference count
       
  2373             // is set to one. Therefore close is said once.
       
  2374             option->Close();
       
  2375             User::Leave( error );
       
  2376             }
       
  2377         }
       
  2378     return *option;
       
  2379     }
       
  2380 
       
  2381 void CNcdNodeMetaData::RemovePurchaseOptionL(
       
  2382     const TDesC& aPurchaseOptionId )
       
  2383     {
       
  2384     DLTRACEIN((""));
       
  2385     const TInt KAmountOfOptions( iPurchaseOptions.Count() );
       
  2386     for ( TInt i = 0; i < KAmountOfOptions; i++ ) 
       
  2387         {
       
  2388         if ( iPurchaseOptions[i]->Id() == aPurchaseOptionId ) 
       
  2389             {
       
  2390             // Meta data has one reference count to all objects
       
  2391             // so that for one Close is said to the option.
       
  2392             iPurchaseOptions[i]->Close();
       
  2393             iPurchaseOptions.Remove( i );
       
  2394             return;
       
  2395             }
       
  2396         }        
       
  2397     User::Leave( KErrNotFound );  
       
  2398     }
       
  2399 
       
  2400 void CNcdNodeMetaData::RemoveNotUpdatedPurchaseOptions()
       
  2401     {
       
  2402     DLTRACEIN((""));
       
  2403     TInt optionsIndexer( iPurchaseOptions.Count() - 1 );
       
  2404     while ( optionsIndexer > -1 )
       
  2405         {
       
  2406         if ( !iPurchaseOptions[optionsIndexer]->RecentlyUpdated() )
       
  2407             {
       
  2408             DLINFO(( "Removing purchase option that is removed from server." ));
       
  2409             // Meta data has one reference count to all objects
       
  2410             // so that for one Close is said to the option.
       
  2411             iPurchaseOptions[optionsIndexer]->Close();
       
  2412             iPurchaseOptions.Remove( optionsIndexer );
       
  2413             }
       
  2414         else
       
  2415             {
       
  2416             DLINFO(( "Resettting recently updated info of po." ));
       
  2417             // Resetting the flag for later use
       
  2418             iPurchaseOptions[optionsIndexer]->
       
  2419                 SetRecentlyUpdated( EFalse );
       
  2420             }                
       
  2421         --optionsIndexer;
       
  2422         }
       
  2423     DLTRACEOUT((""));
       
  2424     }
       
  2425 
       
  2426 // ---------------------------------------------------------------------------
       
  2427 // Internalization from a stream is a little harder now than
       
  2428 // than internalizing from the protocol object. It is done
       
  2429 // so that the po is first internalized into temp option and then
       
  2430 // needed info is taken from it for example to identify the option
       
  2431 // among the already existing options. If the option is already
       
  2432 // found the temp option is externalized to stream and then
       
  2433 // internalized into the already existing option. If no option
       
  2434 // with same id is found then created temp option is appended to
       
  2435 // array. Usually when internalizing from a stream it means that
       
  2436 // we are internalizing from the database and we don't have the
       
  2437 // object created yet. So the latter case is the usual case.
       
  2438 
       
  2439 // One drawback with this implementation is that we can use only
       
  2440 // little of the functions which are used when internalizing from
       
  2441 // the protocol.
       
  2442 
       
  2443 // One other way to implement this could be 
       
  2444 // just to move the purchase option id first in the
       
  2445 // internalize/externalize so that the option id could be retrieved
       
  2446 // easily without no temp externalization/internalization.
       
  2447 // This would need some changes and would bind the order of
       
  2448 // externalization/internalization of variables so it is not done
       
  2449 // now. Also if current implementation is kept, the externalization
       
  2450 // internalization could be replaced with assignment opertators in
       
  2451 // purchase option and its composite classes.
       
  2452 // ---------------------------------------------------------------------------
       
  2453 //
       
  2454 void CNcdNodeMetaData::InternalizePurchaseOptionL(
       
  2455     RReadStream& aStream )
       
  2456     {
       
  2457     DLTRACEIN((""));
       
  2458     
       
  2459     // Temp option for reading option id
       
  2460     CNcdPurchaseOptionImpl* tmpOption =
       
  2461         CNcdPurchaseOptionImpl::NewLC( *this );
       
  2462     tmpOption->InternalizeL( aStream );
       
  2463     const TDesC& poId( tmpOption->Id() );
       
  2464     
       
  2465     // Search for the option requires the purchase option id so it is the
       
  2466     // only reason why the temp option is needed always in this function.
       
  2467     CNcdPurchaseOptionImpl* option( NULL );
       
  2468     TRAPD( error, option = &PurchaseOptionByIdL( poId ) );
       
  2469     if ( error != KErrNone && error != KErrNotFound )
       
  2470         {
       
  2471         User::Leave( error );
       
  2472         }
       
  2473         
       
  2474     CleanupStack::Pop( tmpOption );
       
  2475                 
       
  2476     if ( option == NULL )
       
  2477         {
       
  2478         DLTRACE((""));
       
  2479         // Purchase option not found, append the temp option into
       
  2480         // array of purchase options
       
  2481         option = tmpOption;
       
  2482         
       
  2483         error = KErrNone;
       
  2484         error = iPurchaseOptions.Append( option );
       
  2485         if ( error != KErrNone )
       
  2486             {
       
  2487             DLERROR(("Appending purchase option failed with %d", error ));
       
  2488             // When CObject base object is created its reference count
       
  2489             // is set to one. Therefore close is said once.
       
  2490             option->Close();
       
  2491             User::Leave( error );
       
  2492             }
       
  2493         }
       
  2494     else
       
  2495         {
       
  2496         DLTRACE((""));
       
  2497         CleanupClosePushL( *tmpOption );
       
  2498         // We externalize the content of a option into a stream.
       
  2499         // This is done to copy the content from the temp option
       
  2500         // into the option already found from the array.
       
  2501 		
       
  2502         // This could be replaced with an assignment operation
       
  2503         // in CNcdPurchaseOptionImpl and in all of its composite
       
  2504         // classes. Because at the moment this is a rare situation
       
  2505         // (never happens at the moment) we don't use
       
  2506         // any effort into it at the moment.
       
  2507         //       
       
  2508         CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
  2509         CleanupStack::PushL( buf );
       
  2510             
       
  2511         RBufWriteStream writeStream( *buf );
       
  2512         CleanupClosePushL( writeStream );
       
  2513         DLINFO(( "Externalizing option in copy" ));
       
  2514         tmpOption->ExternalizeL( writeStream );
       
  2515         // Commits data to the stream when closing.
       
  2516         CleanupStack::PopAndDestroy( &writeStream );
       
  2517         
       
  2518         // Now we internalize the option already found in the
       
  2519         // array from the stream.        
       
  2520         RDesReadStream readStream( buf->Ptr( 0 ) );
       
  2521         CleanupClosePushL( readStream );
       
  2522         DLINFO(( "Internalizing option in copy" ));
       
  2523         TRAPD( error, option->InternalizeL( readStream ) );
       
  2524         if ( error != KErrNone )
       
  2525             {
       
  2526             // If internalization fails, let's remove the option so
       
  2527             // no incomplete data is left to be used
       
  2528             
       
  2529             // If an error occurs in the removal we don't want to
       
  2530             // pass that forward. Let's pass the original error.
       
  2531             TRAP_IGNORE( RemovePurchaseOptionL( poId ) );
       
  2532             
       
  2533             User::Leave( error );
       
  2534             }            
       
  2535         // Closes the stream
       
  2536         CleanupStack::PopAndDestroy( &readStream );
       
  2537         
       
  2538         CleanupStack::PopAndDestroy( buf );
       
  2539         CleanupStack::PopAndDestroy( tmpOption );
       
  2540         }
       
  2541     
       
  2542     // Set the option recently updated so we can later in
       
  2543     // RemoveRecentlyUpdatedPurchaseOptions() differentiate
       
  2544     // options that should be removed because they were not
       
  2545     // received from the server anymore.
       
  2546     option->SetRecentlyUpdated( ETrue );
       
  2547     }
       
  2548 
       
  2549 
       
  2550 // ---------------------------------------------------------------------------
       
  2551 // Updates URI content interface if necessary
       
  2552 // ---------------------------------------------------------------------------
       
  2553 //
       
  2554 void CNcdNodeMetaData::HandleContentUriUpdateL( 
       
  2555     const CNcdPurchaseOptionImpl& aOption )
       
  2556     {
       
  2557     DLTRACEIN((""));    
       
  2558     if ( !iUriContent || 
       
  2559          !aOption.IsFree() ||          
       
  2560          aOption.DownloadInfoCount() == 0 ) 
       
  2561         {
       
  2562         DLTRACEOUT(("No bought URI content or not free content so nothing to do"));
       
  2563         return;
       
  2564         }
       
  2565     
       
  2566     TInt count = aOption.DownloadInfoCount();
       
  2567     TInt index = KErrNotFound;                
       
  2568     
       
  2569     DLINFO(("Going through %d download infos", count));    
       
  2570     for ( TInt i = 0; i < count; ++i ) 
       
  2571         {
       
  2572         if ( aOption.DownloadInfo( i ).ContentUsage() == 
       
  2573              MNcdPurchaseDownloadInfo::EConsumable )
       
  2574             {
       
  2575             DLINFO(("Download in index %d is consumable!", i));
       
  2576             index = i;
       
  2577             // Only one uri is supported so break immediately as we
       
  2578             // come across it
       
  2579             break;
       
  2580             }
       
  2581         }
       
  2582     
       
  2583     if ( index == KErrNotFound || 
       
  2584          aOption.DownloadInfo( index ).ContentUri() == iUriContent->Uri() ) 
       
  2585         {
       
  2586         DLTRACEOUT(("Option doesn't contain URI content or URI has not changed"));
       
  2587         return;
       
  2588         }
       
  2589     
       
  2590     
       
  2591     DLTRACE(("New URI differs from the old one. Updating..."));
       
  2592     DLINFO(( _L("New URI: %S"), 
       
  2593         &aOption.DownloadInfo( index ).ContentUri() ));
       
  2594     
       
  2595     CNcdPurchaseDetails* details = PurchaseDetailsLC();
       
  2596     
       
  2597     // Ensure that ids match, otherwise 
       
  2598     // we would be updating wrong purchase option
       
  2599     if ( details->PurchaseOptionId() == aOption.Id() )
       
  2600         {
       
  2601         // Find the correct download info for updating
       
  2602         TArray<MNcdPurchaseDownloadInfo*> dlInfo ( details->DownloadInfoL() );
       
  2603         
       
  2604         TInt oldIndex = KErrNotFound;                
       
  2605         for ( TInt i = 0; i < dlInfo.Count(); ++i )
       
  2606             {
       
  2607             if ( dlInfo[i]->ContentUsage() == 
       
  2608                  MNcdPurchaseDownloadInfo::EConsumable )
       
  2609                 {
       
  2610                 DLINFO(("Download in index %d is consumable!", i));
       
  2611                 oldIndex = i;
       
  2612                 // Only one uri is supported so break immediately as we
       
  2613                 // come across it
       
  2614                 break;
       
  2615                 }
       
  2616             }
       
  2617             
       
  2618         NCD_ASSERT_ALWAYS( oldIndex != KErrNotFound, ENcdPanicNoData );
       
  2619         
       
  2620         CNcdPurchaseDownloadInfo* modDownload = 
       
  2621             static_cast<CNcdPurchaseDownloadInfo*>( dlInfo[oldIndex] );
       
  2622         
       
  2623         DLTRACE(("Updating the URI to download info"));
       
  2624         modDownload->SetContentUriL( 
       
  2625             aOption.DownloadInfo( index ).ContentUri() );
       
  2626         
       
  2627         DLTRACE(("Saving purchase"));
       
  2628         iNodeManager.PurchaseHistory().SavePurchaseL( *details );
       
  2629         DLTRACE(("Purchase updated"));
       
  2630 
       
  2631         iUriContent->InternalizeL( *details );
       
  2632         DLTRACE(("URI content internalized"));
       
  2633         }
       
  2634 
       
  2635     CleanupStack::PopAndDestroy( details );        
       
  2636     
       
  2637     DLTRACEOUT(("All is well"));
       
  2638     }
       
  2639