xdmprotocols/XcapProtocol/src/XcapDocument.cpp
branchRCL_3
changeset 35 fbd2e7cec7ef
equal deleted inserted replaced
34:2669f8761a99 35:fbd2e7cec7ef
       
     1 /*
       
     2 * Copyright (c) 2005 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: CXcapDocument
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <f32file.h>
       
    23 #include <XdmErrors.h>
       
    24 #include "XdmOperationFactory.h"
       
    25 #include "XcapProtocol.h"
       
    26 #include "XcapDocument.h"
       
    27 #include "XcapAppUsage.h"
       
    28 #include "XdmXmlParser.h"
       
    29 #include "XdmNamespace.h"
       
    30 #include "CommonDefines.h"
       
    31 #include "XcapDocumentNode.h"
       
    32 #include "XcapHttpRequest.h"
       
    33 #include "XcapHttpOperation.h"
       
    34 #include "XcapHttpTransport.h"
       
    35 
       
    36 // ================= MEMBER FUNCTIONS =======================
       
    37 //
       
    38 
       
    39 
       
    40 // ----------------------------------------------------------
       
    41 // CXcapDocument::CXcapDocument
       
    42 // 
       
    43 // ----------------------------------------------------------
       
    44 //
       
    45 CXcapDocument::CXcapDocument( TXdmDocType aDocumentType,
       
    46                               const CXdmEngine& aXdmEngine,
       
    47                               const CXcapProtocol& aXcapProtocol ) :
       
    48                               CXdmDocument( CONST_CAST( CXdmEngine&, aXdmEngine ) ),
       
    49                               iDocumentType( aDocumentType ),
       
    50                               iXcapProtocol( CONST_CAST( CXcapProtocol&, aXcapProtocol ) )
       
    51                                                 
       
    52     { 
       
    53     }
       
    54 
       
    55 // ----------------------------------------------------------
       
    56 // CXcapDocument::NewL
       
    57 // 
       
    58 // ----------------------------------------------------------
       
    59 //
       
    60 CXcapDocument* CXcapDocument::NewL( TXdmDocType aDocumentType,
       
    61                                     const TDesC& aDocumentName,
       
    62                                     const CXdmEngine& aXdmEngine,
       
    63                                     const CXcapProtocol& aXcapProtocol )
       
    64     {
       
    65     CXcapDocument* self = new ( ELeave ) CXcapDocument( aDocumentType, aXdmEngine, aXcapProtocol );
       
    66     CleanupStack::PushL( self );
       
    67     self->BaseConstructL( KXcapOperationFactory, aDocumentName );
       
    68     self->ConstructL();
       
    69     CleanupStack::Pop();
       
    70     return self;
       
    71     }
       
    72 
       
    73 // ----------------------------------------------------------
       
    74 // CXcapDocument::NewL
       
    75 // 
       
    76 // ----------------------------------------------------------
       
    77 //
       
    78 CXcapDocument* CXcapDocument::NewL( TXdmDocType aDocumentType,
       
    79                                     const TDesC8& aDocumentName,
       
    80                                     const CXdmEngine& aXdmEngine,
       
    81                                     const CXcapProtocol& aXcapProtocol )
       
    82     {
       
    83     CXcapDocument* self = new ( ELeave ) CXcapDocument( aDocumentType, aXdmEngine, aXcapProtocol );
       
    84     CleanupStack::PushL( self );
       
    85     self->ConstructL( aDocumentName );
       
    86     CleanupStack::Pop();
       
    87     return self;
       
    88     }
       
    89 
       
    90 // ----------------------------------------------------------
       
    91 // CXcapDocument::ConstructL
       
    92 // 
       
    93 // ----------------------------------------------------------
       
    94 //
       
    95 void CXcapDocument::ConstructL( const TDesC8& aDocumentName )
       
    96     {
       
    97     BaseConstructL( KXcapOperationFactory, aDocumentName );
       
    98     ConstructL();
       
    99     }
       
   100     
       
   101 // ----------------------------------------------------------
       
   102 // CXcapDocument::ConstructL
       
   103 // 
       
   104 // ----------------------------------------------------------
       
   105 //
       
   106 void CXcapDocument::ConstructL()
       
   107     {
       
   108     InstallAppUsageL();
       
   109     iErrorRoot = CXcapDocumentNode::NewL( iXdmEngine, iXcapProtocol );
       
   110     TPtrC8 root( iXcapProtocol.Transport().RootUri() );
       
   111     #ifdef _DEBUG
       
   112         HBufC8* buf = HBufC8::NewLC( iDocumentName->Des().Length() );
       
   113         buf->Des().Copy( iDocumentName->Des() );
       
   114         TPtr8 nameDesc( buf->Des() );
       
   115         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::ConstructL()" ) );
       
   116         iXcapProtocol.WriteToLog( _L8( "  Root URI:   %S" ), &root );
       
   117         iXcapProtocol.WriteToLog( _L8( "  Document:   %S" ), &nameDesc );
       
   118         CleanupStack::PopAndDestroy();  //buf
       
   119     #endif
       
   120     RXcapCache* cache = iXcapProtocol.Cache();
       
   121     if( cache )
       
   122         UpdateDocumentInfoL( cache );
       
   123     else
       
   124         {
       
   125         #ifdef _DEBUG
       
   126             iXcapProtocol.WriteToLog( _L8( "  Cache disabled, no info for the document" ) );
       
   127         #endif
       
   128         }
       
   129     CActiveScheduler::Add( this );
       
   130     }
       
   131 
       
   132 // ----------------------------------------------------
       
   133 // CXcapDocument::~CXcapDocument
       
   134 // 
       
   135 // ----------------------------------------------------
       
   136 //
       
   137 CXcapDocument::~CXcapDocument()
       
   138     {
       
   139     #ifdef _DEBUG
       
   140         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::~CXcapDocument()" ) );
       
   141     #endif
       
   142     Cancel();
       
   143     delete iTempCopy;
       
   144     delete iEightBitName;
       
   145     delete iDocumentRoot;
       
   146     delete iErrorRoot;
       
   147     delete iAppUsage;
       
   148     iNamespaces.ResetAndDestroy();
       
   149     iNamespaces.Close();
       
   150     }
       
   151 
       
   152 // ----------------------------------------------------------
       
   153 // CXcapDocument::ResetContents
       
   154 // 
       
   155 // ----------------------------------------------------------
       
   156 //
       
   157 void CXcapDocument::ResetContents()
       
   158     {
       
   159     iOptions = 0;
       
   160     delete iDocumentRoot;
       
   161     iDocumentRoot = NULL;
       
   162     delete iErrorRoot;
       
   163     iErrorRoot = NULL;
       
   164     delete iTempCopy;
       
   165     iTempCopy = NULL;
       
   166     iNamespaces.ResetAndDestroy();
       
   167     }
       
   168     
       
   169 // ----------------------------------------------------------
       
   170 // CXcapDocument::UpdateDocumentInfoL
       
   171 // 
       
   172 // ----------------------------------------------------------
       
   173 //
       
   174 void CXcapDocument::UpdateDocumentInfoL( RXcapCache* aCacheClient )
       
   175     {
       
   176     #ifdef _DEBUG
       
   177         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::UpdateDocumentInfo()" ) );
       
   178     #endif
       
   179     iETagBuffer.Zero();
       
   180     TCacheEntryInfo cacheEntryInfo;
       
   181     TPtrC8 root( iXcapProtocol.Transport().RootUri() );
       
   182     TInt error = aCacheClient->FetchDocumentInfo( 
       
   183                  iETagBuffer, iDocumentName->Des(), root, cacheEntryInfo );    
       
   184     if( error == KErrNone )
       
   185         {
       
   186         iLastAccess = cacheEntryInfo.iLastAccess;
       
   187         iLastModification = cacheEntryInfo.iLastUpdate;
       
   188         iDataLength = cacheEntryInfo.iDataLength;
       
   189         #ifdef _DEBUG
       
   190             const TInt KDateTimeMaxSize = 100;
       
   191             TBuf8<KDateTimeMaxSize> printBuffer;
       
   192             TBuf<KDateTimeMaxSize> dateTimeBuffer;
       
   193             _LIT( KDateTimeFormat, "%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S");
       
   194             iLastModification.FormatL( dateTimeBuffer, KDateTimeFormat );
       
   195             printBuffer.Copy( dateTimeBuffer );
       
   196             iXcapProtocol.WriteToLog( _L8( "  ETag:        %S" ), &iETagBuffer );
       
   197             iXcapProtocol.WriteToLog( _L8( "  Size:        %d bytes" ), iDataLength );
       
   198             iXcapProtocol.WriteToLog( _L8( "  Time stamp:  %S" ), &printBuffer );
       
   199         #endif
       
   200         }
       
   201     else
       
   202         {
       
   203         #ifdef _DEBUG
       
   204             iXcapProtocol.WriteToLog( _L8( "  Cache read complete - Error: %d" ), error );
       
   205         #endif
       
   206         }
       
   207     }
       
   208     
       
   209 // ----------------------------------------------------
       
   210 // CXcapDocument::InstallAppUsageL
       
   211 // 
       
   212 // ----------------------------------------------------
       
   213 //
       
   214 void CXcapDocument::InstallAppUsageL()
       
   215     {
       
   216     #ifdef _DEBUG
       
   217         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::InstallAppUsageL()" ) );
       
   218     #endif  
       
   219     HBufC8* docName = NULL;
       
   220     iAppUsage = CXcapAppUsage::NewL( iXdmEngine, iDocumentType );
       
   221     #ifdef _DEBUG
       
   222         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::InstallAppUsageL() type = %d" ), iDocumentType );
       
   223     #endif  
       
   224     TPtrC8 auid = iAppUsage->AUID();
       
   225     if( IsGlobalTree( auid ) )
       
   226         {
       
   227         docName = HBufC8::NewLC( auid.Length() + KGlobalDirName().Length() + 
       
   228                                  KXcapGlobalDocName().Length() );
       
   229         docName->Des().Copy( auid );
       
   230         docName->Des().Append( KGlobalDirName );
       
   231         docName->Des().Append( KXcapGlobalDocName );
       
   232         delete iDocumentName;
       
   233         iDocumentName = NULL;
       
   234         iDocumentName = HBufC::NewL( docName->Des().Length() );
       
   235         iDocumentName->Des().Copy( docName->Des() );
       
   236         CleanupStack::PopAndDestroy();  //docName
       
   237         }
       
   238     else
       
   239         {
       
   240         TPtrC8 user = iXcapProtocol.UserName();
       
   241         docName = HBufC8::NewLC( auid.Length() + user.Length() + 
       
   242                                  KUserDirName().Length() + 1 /*'/'*/ + 
       
   243                                  iDocumentName->Des().Length() );
       
   244         docName->Des().Copy( auid );
       
   245         docName->Des().Append( KUserDirName );
       
   246         docName->Des().Append( user );
       
   247         docName->Des().Append( KSlash );
       
   248         docName->Des().Append( iDocumentName->Des() );
       
   249         delete iDocumentName;
       
   250         iDocumentName = NULL;
       
   251         iDocumentName = HBufC::NewL( docName->Des().Length() );
       
   252         iDocumentName->Des().Copy( docName->Des() );
       
   253         CleanupStack::PopAndDestroy();  //docName
       
   254         }
       
   255     
       
   256     }
       
   257 
       
   258 // ----------------------------------------------------
       
   259 // CXcapDocument::IsGlobalTree
       
   260 // 
       
   261 // ----------------------------------------------------
       
   262 //
       
   263 TBool CXcapDocument::IsGlobalTree( const TDesC8& aAuid )
       
   264     {
       
   265     #ifdef _DEBUG
       
   266         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::IsGlobalTree()" ) );
       
   267     #endif
       
   268     TBool found = EFalse;
       
   269     //Update this array when necessary
       
   270     const TPtrC8 KGlobalTreeAuids[] = { TPtrC8( KXdmCapabilityUsageAUID ) };
       
   271     const TInt count = sizeof( KGlobalTreeAuids ) / sizeof( KGlobalTreeAuids[0] );
       
   272     for( TInt i = 0;!found && i < count;i++ )
       
   273         found = aAuid.Compare( KGlobalTreeAuids[i] ) == 0;
       
   274     return found;
       
   275     }
       
   276     
       
   277 // ----------------------------------------------------
       
   278 // CXcapDocument::CreateTempCopyL
       
   279 // 
       
   280 // ----------------------------------------------------
       
   281 //
       
   282 void CXcapDocument::CreateTempCopyL()
       
   283     {
       
   284     #ifdef _DEBUG
       
   285         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::CreateTempCopyL()" ) );
       
   286     #endif
       
   287     CXdmDocument* copy = iXdmEngine.CreateDocumentModelL( Name(), iDocumentType );
       
   288     iTempCopy = ( CXcapDocument* )copy;
       
   289     }
       
   290 
       
   291 // ----------------------------------------------------
       
   292 // CXcapDocument::TempCopyL
       
   293 // 
       
   294 // ----------------------------------------------------
       
   295 //
       
   296 EXPORT_C CXcapDocument* CXcapDocument::TempCopyL()
       
   297     {
       
   298     return CXcapDocument::NewL( iDocumentType, Name(), iXdmEngine, iXcapProtocol );
       
   299     }
       
   300 
       
   301 // ----------------------------------------------------
       
   302 // CXcapDocument::CreateRootL
       
   303 // 
       
   304 // ----------------------------------------------------
       
   305 //
       
   306 CXdmDocumentNode* CXcapDocument::CreateRootL()
       
   307     {
       
   308     #ifdef _DEBUG
       
   309         iXcapProtocol.WriteToLog( _L8( "CXdmDocument::CreateRootL()" ) );
       
   310     #endif
       
   311     delete iDocumentRoot;
       
   312     iDocumentRoot = NULL;
       
   313     iDocumentRoot = CXcapDocumentNode::NewL( iXdmEngine, iXcapProtocol );
       
   314     return iDocumentRoot;
       
   315     }
       
   316 
       
   317 // ----------------------------------------------------
       
   318 // CXcapDocument::AppendPathPartL
       
   319 // 
       
   320 // ----------------------------------------------------
       
   321 //
       
   322 void CXcapDocument::AppendPathPartL( const TDesC& aString )
       
   323     {
       
   324     #ifdef _DEBUG
       
   325         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::PathPartL()" ) );
       
   326     #endif
       
   327     if( iDocumentRoot != NULL )
       
   328         {
       
   329         CXdmDocumentNode* node = NULL;
       
   330         CXdmDocumentNode* parent = iDocumentRoot;
       
   331         while( parent->NextNode() != NULL )
       
   332             parent = parent->NextNode();
       
   333         node = CXcapDocumentNode::NewL( iXdmEngine, aString, iXcapProtocol, parent );
       
   334         parent->SetNextNode( node );
       
   335         }
       
   336     else iDocumentRoot = CXcapDocumentNode::NewL( iXdmEngine, aString, iXcapProtocol );
       
   337     }
       
   338 
       
   339 // ----------------------------------------------------
       
   340 // CXcapDocument::CurrentExtent
       
   341 // 
       
   342 // ----------------------------------------------------
       
   343 //
       
   344 CXdmDocumentNode* CXcapDocument::CurrentExtent() const
       
   345     {
       
   346     #ifdef _DEBUG
       
   347         iXcapProtocol.WriteToLog( _L8( "CXdmDocument::CurrentExtent()" ) );
       
   348     #endif
       
   349     CXdmDocumentNode* ret = NULL;
       
   350     if( iDocumentRoot != NULL )
       
   351         {
       
   352         CXdmDocumentNode* node = iDocumentRoot;
       
   353         while( node->NextNode() != NULL )
       
   354             node = node->NextNode();
       
   355         ret = node;
       
   356         }
       
   357     else
       
   358         {
       
   359         #ifdef _DEBUG
       
   360             iXcapProtocol.WriteToLog( _L8( " This document does not yet have a root, leave with KErrGeneral" ) );
       
   361         #endif
       
   362         User::Leave( KErrGeneral );
       
   363         }
       
   364     return ret;
       
   365     }
       
   366     
       
   367 // ----------------------------------------------------
       
   368 // CXcapDocument::DocumentRoot
       
   369 // 
       
   370 // ----------------------------------------------------
       
   371 //
       
   372 CXdmDocumentNode* CXcapDocument::DocumentRoot() const
       
   373     {
       
   374     return iDocumentRoot;
       
   375     }     
       
   376 
       
   377 // ----------------------------------------------------
       
   378 // CXcapDocument::ErrorRoot
       
   379 // 
       
   380 // ----------------------------------------------------
       
   381 //
       
   382 CXdmDocumentNode* CXcapDocument::ErrorRoot()
       
   383     {
       
   384     if( !iErrorRoot )
       
   385         {
       
   386         iErrorRoot = CXcapDocumentNode::NewL( iXdmEngine, iXcapProtocol );
       
   387         }
       
   388     return iErrorRoot;
       
   389     }
       
   390 
       
   391 // ----------------------------------------------------
       
   392 // CXcapDocument::ResetSubset
       
   393 // 
       
   394 // ----------------------------------------------------
       
   395 //
       
   396 EXPORT_C void CXcapDocument::ResetSubset()
       
   397     {
       
   398     CXdmDocument::ResetSubset();
       
   399     delete iDocumentRoot;
       
   400     iDocumentRoot = NULL;
       
   401     iOptions = 0;
       
   402     }
       
   403            
       
   404 // ----------------------------------------------------
       
   405 // CXcapDocument::ETag
       
   406 // 
       
   407 // ----------------------------------------------------
       
   408 //
       
   409 EXPORT_C TDesC8& CXcapDocument::ETag()
       
   410     {
       
   411     return iETagBuffer;
       
   412     }
       
   413         
       
   414 // ----------------------------------------------------
       
   415 // CXcapDocument::SetETag
       
   416 // 
       
   417 // ----------------------------------------------------
       
   418 //     
       
   419 EXPORT_C void CXcapDocument::SetETag( const TDesC8& aETagDesc )
       
   420     {
       
   421     iETagBuffer.Zero();
       
   422     iETagBuffer.Copy( aETagDesc );
       
   423     #ifdef _DEBUG
       
   424         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::SetETag()" ) );
       
   425         iXcapProtocol.WriteToLog( _L8( "  New ETag: %S" ), &iETagBuffer );
       
   426     #endif
       
   427     }
       
   428 
       
   429 // ----------------------------------------------------
       
   430 // CXcapDocument::DataLength
       
   431 // 
       
   432 // ----------------------------------------------------
       
   433 //
       
   434 EXPORT_C TInt CXcapDocument::DataLength() const
       
   435     {
       
   436     return iDataLength;
       
   437     }
       
   438 
       
   439 // ----------------------------------------------------
       
   440 // CXcapDocument::ApplicationUsage
       
   441 // 
       
   442 // ----------------------------------------------------
       
   443 //
       
   444 EXPORT_C CXcapAppUsage& CXcapDocument::ApplicationUsage() const
       
   445     {
       
   446     return *iAppUsage;
       
   447     }
       
   448 
       
   449 // ----------------------------------------------------
       
   450 // CXcapDocument::Protocol
       
   451 // 
       
   452 // ----------------------------------------------------
       
   453 //
       
   454 EXPORT_C CXcapProtocol& CXcapDocument::Protocol() const
       
   455     {
       
   456     return iXcapProtocol;
       
   457     }
       
   458     
       
   459 // ----------------------------------------------------
       
   460 // CXcapDocument::RemoveData
       
   461 // 
       
   462 // ----------------------------------------------------
       
   463 //
       
   464 EXPORT_C void CXcapDocument::RemoveData( CXcapDocumentNode* aDocumentNode )
       
   465     {
       
   466     #ifdef _DEBUG
       
   467         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::RemoveData()" ) );
       
   468     #endif
       
   469     CXcapDocumentNode* parent = ( CXcapDocumentNode* )aDocumentNode->Parent();
       
   470     if( parent != NULL )
       
   471         parent->RemoveNode( aDocumentNode );
       
   472     }
       
   473     
       
   474 // ----------------------------------------------------
       
   475 // CXcapDocument::StartUpdateL
       
   476 // 
       
   477 // ----------------------------------------------------
       
   478 //
       
   479 void CXcapDocument::StartUpdateL()
       
   480     {
       
   481     #ifdef _DEBUG
       
   482         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::StartUpdateL()" ) );
       
   483     #endif
       
   484     TInt resolverError = 0;
       
   485     if( iXcapProtocol.IsSimRequestPending( resolverError ) )
       
   486         {
       
   487         #ifdef _DEBUG
       
   488             iXcapProtocol.WriteToLog( _L8( "  IMS Resolver pending => add to queue" ) );
       
   489         #endif
       
   490         iXcapProtocol.AppendNotifyeeL( this );
       
   491         }
       
   492     else
       
   493         {
       
   494         if( resolverError == KErrNone && !IsActive() && iChangeRequests.Count() > 0 )
       
   495             {
       
   496             iUpdateIndex = 0;
       
   497             iDocumentState = EXdmDocUpdating;
       
   498             iOperationCount = iChangeRequests.Count();
       
   499             ActivateOperationL();
       
   500             }
       
   501         else
       
   502             {
       
   503             #ifdef _DEBUG
       
   504                 iXcapProtocol.WriteToLog( _L8(
       
   505                  "  Already active, no operations or IMS resolver failed => complete with error" ) );
       
   506             #endif
       
   507             TInt error = resolverError == KErrNone ? KErrNotReady : resolverError; 
       
   508             User::RequestComplete( iClientStatus, error );
       
   509             }
       
   510         }
       
   511     }
       
   512 
       
   513 // ----------------------------------------------------
       
   514 // CXcapDocument::StartInternalL
       
   515 // 
       
   516 // ----------------------------------------------------
       
   517 //
       
   518 void CXcapDocument::StartInternalL( TRequestStatus& aStatus )
       
   519     {
       
   520     #ifdef _DEBUG
       
   521         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::StartInternalL()" ) );
       
   522     #endif
       
   523     aStatus = KRequestPending;
       
   524     iClientStatus = &aStatus;
       
   525     StartUpdateL();
       
   526     }
       
   527 
       
   528 // ----------------------------------------------------
       
   529 // CXcapDocument::NotifyResolverCompleteL
       
   530 // 
       
   531 // ----------------------------------------------------
       
   532 //
       
   533 void CXcapDocument::NotifyResolverCompleteL( TInt aError )
       
   534     {
       
   535     #ifdef _DEBUG
       
   536         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::NotifyResolverCompleteL()" ) );
       
   537     #endif
       
   538     if( aError == KErrNone )
       
   539         {
       
   540         #ifdef _DEBUG
       
   541             iXcapProtocol.WriteToLog( _L8( "  IMS Resolver ready" ) );
       
   542         #endif
       
   543         StartUpdateL();
       
   544         }
       
   545     else
       
   546         {
       
   547         #ifdef _DEBUG
       
   548             iXcapProtocol.WriteToLog( _L8( "  IMS Resolver failed => complete with %d" ), aError );
       
   549         #endif
       
   550         DequeueAll();
       
   551         User::RequestComplete( iClientStatus, aError );
       
   552         }
       
   553     }
       
   554     
       
   555 // ----------------------------------------------------
       
   556 // CXcapDocument::ActivateOperationL
       
   557 // 
       
   558 // ----------------------------------------------------
       
   559 //
       
   560 void CXcapDocument::ActivateOperationL()
       
   561     {
       
   562     MXdmOperation* request = iChangeRequests[iUpdateIndex];
       
   563     #ifdef _DEBUG
       
   564         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::ActivateOperation() - Operation: %x" ), request );
       
   565     #endif
       
   566     if( iDocSubset )
       
   567         {
       
   568         #ifdef _DEBUG
       
   569             iXcapProtocol.WriteToLog( _L8( " Document subset => set KXdmOption1 and KXdmOption2" ) );
       
   570         #endif
       
   571         SetOption( KXdmOption1 );
       
   572         SetOption( KXdmOption2 );
       
   573         }
       
   574     if( iXcapProtocol.AuthType() == EXcapAuthEarlyIms )
       
   575         {
       
   576         #ifdef _DEBUG
       
   577             iXcapProtocol.WriteToLog( _L8( " EarlyIMS is in use => set KXdmOption4" ) );
       
   578         #endif
       
   579         SetOption( KXdmOption4 );
       
   580         }
       
   581     request->ExecuteL( iStatus, iOptions );
       
   582     SetActive();
       
   583     }
       
   584 
       
   585 // ----------------------------------------------------
       
   586 // CXcapDocument::SetOption
       
   587 // 
       
   588 // ----------------------------------------------------
       
   589 //
       
   590 void CXcapDocument::SetOption( TInt aOption )
       
   591     {
       
   592     #ifdef _DEBUG
       
   593         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::SetOption()" ) );
       
   594     #endif
       
   595     iOptions |= aOption;
       
   596     }
       
   597        
       
   598 // ----------------------------------------------------
       
   599 // CXcapDocument::CancelUpdate
       
   600 // 
       
   601 // ----------------------------------------------------
       
   602 //
       
   603 void CXcapDocument::CancelUpdate()
       
   604     {
       
   605     #ifdef _DEBUG
       
   606         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::CancelUpdate()" ) );
       
   607     #endif
       
   608     TInt resolverError = 0;
       
   609     if( iXcapProtocol.IsSimRequestPending( resolverError ) )
       
   610         {
       
   611         iXcapProtocol.CancelImsResolver();
       
   612         }
       
   613     else
       
   614         {
       
   615         switch( iDocumentState )
       
   616             {
       
   617             case EResolvingAsyncConflict:
       
   618                 iTempCopy->CancelUpdate();
       
   619                 break;
       
   620             default:
       
   621                 {
       
   622                 TInt count = iChangeRequests.Count();
       
   623                 if( count > 0 )
       
   624                     {
       
   625                     MXdmOperation* request = iChangeRequests[iUpdateIndex];
       
   626                     request->CancelOperation();
       
   627                     #ifdef _DEBUG
       
   628                         iXcapProtocol.WriteToLog( _L8( "  Operation %x cancelled" ), request );
       
   629                     #endif
       
   630                     }
       
   631                 }
       
   632             }
       
   633         }
       
   634     User::RequestComplete( iClientStatus, KErrCancel );
       
   635     }
       
   636 
       
   637 // ---------------------------------------------------------
       
   638 // CXcapDocument::RunL()
       
   639 // 
       
   640 // ---------------------------------------------------------
       
   641 //
       
   642 void CXcapDocument::RunL()
       
   643     {
       
   644     #ifdef _DEBUG
       
   645         HBufC8* buf = HBufC8::NewLC( iDocumentName->Des().Length() );
       
   646         buf->Des().Copy( iDocumentName->Des() );
       
   647         TPtr8 nameDesc( buf->Des() );
       
   648         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::RunL()" ) );
       
   649         iXcapProtocol.WriteToLog( _L8( "  Name:         %S" ), &nameDesc );
       
   650         iXcapProtocol.WriteToLog( _L8( "  Error:        %d" ), iStatus.Int() );
       
   651         iXcapProtocol.WriteToLog( _L8( "  Update index: %d" ), iUpdateIndex );
       
   652         CleanupStack::PopAndDestroy();  //buf
       
   653     #endif
       
   654     if( iStatus == KErrNone )
       
   655         {
       
   656         switch( iDocumentState )
       
   657             {
       
   658             case EXdmDocUpdating:
       
   659                 #ifdef _DEBUG
       
   660                     iXcapProtocol.WriteToLog( _L8( "  Document state: EXdmDocUpdating" ) );
       
   661                 #endif
       
   662                 HandleRequestCompletionL();
       
   663                 break;
       
   664             case EResolvingAsyncConflict:
       
   665                 #ifdef _DEBUG
       
   666                     iXcapProtocol.WriteToLog( _L8( "  Document state: EResolvingAsyncConflict" ) );
       
   667                 #endif
       
   668                 ResolveAsyncConflictL();
       
   669                 break;
       
   670             case ERetryingFailedOperation:
       
   671                 #ifdef _DEBUG
       
   672                     iXcapProtocol.WriteToLog( _L8( "  Document state: ERetryingFailedOperation" ) );
       
   673                 #endif
       
   674                 ResolveAsyncConflictL();
       
   675                 break;
       
   676             default:
       
   677                 break;
       
   678             }
       
   679         }
       
   680     else HandleErrorL();
       
   681     #ifdef _DEBUG
       
   682         TInt biggestBlock( 0 );
       
   683         TInt memory( User::Available( biggestBlock ) );
       
   684         iXcapProtocol.WriteToLog( _L8( "** RunL() completes - Available memory: %d" ), memory );
       
   685     #endif
       
   686     }
       
   687 
       
   688 // ---------------------------------------------------------
       
   689 // CXcapDocument::HandleRequestCompletionL
       
   690 // 
       
   691 // ---------------------------------------------------------
       
   692 //
       
   693 void CXcapDocument::HandleRequestCompletionL()
       
   694     {
       
   695     #ifdef _DEBUG
       
   696         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::HandleRequestCompletionL()" ) );
       
   697     #endif
       
   698     MXdmOperation* request = iChangeRequests[iUpdateIndex];
       
   699     const TXdmCompletionData& data = request->CompletionData();
       
   700     switch( data.iCompletion )
       
   701         {
       
   702         case KInsertConflict:
       
   703             ResolveAsyncConflictL();
       
   704             break;
       
   705         default:
       
   706             {
       
   707             RXcapCache* cache = iXcapProtocol.Cache();
       
   708             if( cache )
       
   709                 UpdateDocumentInfoL( cache );
       
   710             DequeueOperation( request );
       
   711             CheckOperationQueueL();
       
   712             break;
       
   713             }
       
   714         }
       
   715     }
       
   716 
       
   717 // ---------------------------------------------------------
       
   718 // CXcapDocument::ResolveAsyncConflictL
       
   719 // 
       
   720 // ---------------------------------------------------------
       
   721 //
       
   722 void CXcapDocument::ResolveAsyncConflictL()
       
   723     {
       
   724     #ifdef _DEBUG
       
   725         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::ResolveAsyncConflictL()" ) );
       
   726     #endif
       
   727     switch( iDocumentState )
       
   728         {
       
   729         //This means the cached version of this document
       
   730         //is out-of-date and that it needs to be updated.
       
   731         case EXdmDocUpdating:
       
   732             {
       
   733             CreateTempCopyL();
       
   734             iTempCopy->SetETag( iETagBuffer );
       
   735             iTempCopy->FetchDataL();
       
   736             iTempCopy->SaveClientStatus( iStatus );
       
   737             iTempCopy->StartUpdateL();
       
   738             iDocumentState = EResolvingAsyncConflict;
       
   739             SetActive();
       
   740             }
       
   741             break;
       
   742         case EResolvingAsyncConflict:
       
   743             #ifdef _DEBUG
       
   744                 iXcapProtocol.WriteToLog( _L8( "  Async conflict resolved, retry insert" ) );
       
   745             #endif
       
   746             //CheckOperationQueueL() will increment the index
       
   747             iUpdateIndex--;
       
   748             SetETag( iTempCopy->ETag() );
       
   749             iDocumentState = ERetryingFailedOperation;
       
   750             CheckOperationQueueL();
       
   751             break;
       
   752         case ERetryingFailedOperation:
       
   753             #ifdef _DEBUG
       
   754                 iXcapProtocol.WriteToLog( _L8( "  Operation retry ready" ) );
       
   755             #endif
       
   756             //Nothing can be done now but instruct the
       
   757             //client to re-fetch the whole document and
       
   758             //retry the failed operation.
       
   759             User::RequestComplete( iClientStatus, KErrPathNotFound );
       
   760             break;
       
   761         default:
       
   762             break;
       
   763         }
       
   764     }
       
   765     
       
   766 // ---------------------------------------------------------
       
   767 // CXcapDocument::HandleErrorL
       
   768 // 
       
   769 // ---------------------------------------------------------
       
   770 //
       
   771 void CXcapDocument::HandleErrorL()
       
   772     {
       
   773     #ifdef _DEBUG
       
   774         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::HandleErrorL()" ) );
       
   775     #endif
       
   776     TInt clientCode = KErrGeneral;
       
   777     MXdmOperation* request = request = iChangeRequests[iUpdateIndex];
       
   778     //The TXdmCompletionData is guaranteed to point at something 
       
   779     const TXdmCompletionData& data = request->CompletionData();
       
   780     switch( data.iCompletion )
       
   781         {
       
   782         case KErrCancel:
       
   783             #ifdef _DEBUG
       
   784                 iXcapProtocol.WriteToLog( _L8( " Update cancelled" ) );
       
   785             #endif
       
   786             clientCode = KErrCancel;
       
   787             break;
       
   788         case ERetryingFailedOperation:
       
   789             #ifdef _DEBUG
       
   790                 iXcapProtocol.WriteToLog( _L8( "  Operation retry failed" ) );
       
   791             #endif
       
   792             //Nothing can be done now but instruct the
       
   793             //client to re-fetch the whole document and
       
   794             //retry the failed operation.
       
   795             User::RequestComplete( iClientStatus, KXcapErrorUnrecoverableConflict );
       
   796             break;
       
   797         case KXcapErrorHttpConflict:
       
   798             #ifdef _DEBUG
       
   799                 iXcapProtocol.WriteToLog( _L8( "  Conflict, parse error document if available" ) );
       
   800             #endif
       
   801             if( data.iResponseData != NULL )
       
   802                 {
       
   803                 TInt error = KErrNone;
       
   804                 TPtrC8 errorData( data.iResponseData->Des() );
       
   805                 TRAP( error, iXcapProtocol.Parser().ParseDocumentL( errorData, ErrorRoot() ) );
       
   806                 #ifdef _DEBUG
       
   807                     iXcapProtocol.WriteToLog( _L8( "  Parsing completed: %d" ), error );
       
   808                     ErrorRoot()->Print();
       
   809                 #endif
       
   810                 //Suppress build warning
       
   811                 error = KErrNone;
       
   812                 }
       
   813 		        User::RequestComplete( iClientStatus, KXcapErrorHttpConflict );
       
   814             break;
       
   815         case KXcapErrorNetworkNotAvailabe:
       
   816             {
       
   817             #ifdef _DEBUG
       
   818                 iXcapProtocol.WriteToLog( _L8( "  Network not available, check cache" ) );
       
   819             #endif
       
   820             if( iDataLength > 0 )
       
   821                 {
       
   822                 RXcapCache* cache = iXcapProtocol.Cache();
       
   823                 if( cache != NULL )
       
   824                     {
       
   825                     TPtrC name( Name() );
       
   826                     TInt error = KErrNone;
       
   827                     TPtrC8 root = iXcapProtocol.Transport().RootUri();
       
   828                     HBufC8* data = HBufC8::NewLC( iDataLength );
       
   829                     TPtr8 dataPtr( data->Des() );
       
   830                     cache->FetchDocumentContent( dataPtr, name, root );
       
   831                     TRAP( error, iXcapProtocol.Parser().ParseDocumentL( this, dataPtr ) );
       
   832                     #ifdef _DEBUG
       
   833                         iXcapProtocol.WriteToLog( _L8( "  Parsing completed: %d" ), error );
       
   834                     #endif
       
   835                     //Suppress build warning
       
   836                     error = KErrNone;
       
   837                     CleanupStack::PopAndDestroy();  //data
       
   838                     }
       
   839                 }
       
   840             else
       
   841                 {
       
   842                 #ifdef _DEBUG
       
   843                     iXcapProtocol.WriteToLog( _L8( "  No data in cache, nothing to do" ) );
       
   844                 #endif
       
   845                 }
       
   846             User::RequestComplete( iClientStatus, KXcapErrorNetworkNotAvailabe );
       
   847             }
       
   848             break;
       
   849         default:
       
   850             #ifdef _DEBUG
       
   851                 iXcapProtocol.WriteToLog( _L8( " Default case - Result: %d" ), data.iCompletion );
       
   852             #endif
       
   853             clientCode = iStatus.Int();
       
   854             User::RequestComplete( iClientStatus, clientCode );
       
   855         }
       
   856     DequeueOperation( request );
       
   857     }
       
   858      
       
   859 // ---------------------------------------------------------
       
   860 // CXcapDocument::CheckOperationQueueL
       
   861 // 
       
   862 // ---------------------------------------------------------
       
   863 //
       
   864 void CXcapDocument::CheckOperationQueueL()
       
   865     {
       
   866     #ifdef _DEBUG
       
   867         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::CheckOperationQueueL()" ) );
       
   868     #endif
       
   869     iUpdateIndex++;
       
   870     if( iUpdateIndex < iOperationCount )
       
   871         ActivateOperationL();
       
   872     else
       
   873         {
       
   874         DequeueAll();
       
   875         iUpdateIndex = 0;
       
   876         iXcapProtocol.CheckActivity();
       
   877         User::RequestComplete( iClientStatus, KErrNone );   
       
   878         }
       
   879     }
       
   880 
       
   881 // ---------------------------------------------------------
       
   882 // CXcapDocument::DequeueOperation
       
   883 // 
       
   884 // ---------------------------------------------------------
       
   885 //
       
   886 void CXcapDocument::DequeueOperation( MXdmOperation* aOperation )
       
   887     {
       
   888     #ifdef _DEBUG
       
   889         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::DequeueOperation()" ) );
       
   890     #endif
       
   891     TInt index = iChangeRequests.Find( aOperation );
       
   892     if( index >= 0 )
       
   893     	{	
       
   894 		iChangeRequests.Remove( index );    
       
   895         aOperation->Destroy();
       
   896         aOperation = NULL;
       
   897     	}  
       
   898    	iOperationCount = iChangeRequests.Count();
       
   899     }
       
   900 
       
   901 // ---------------------------------------------------------
       
   902 // CXcapDocument::DequeueAll
       
   903 // 
       
   904 // ---------------------------------------------------------
       
   905 //
       
   906 void CXcapDocument::DequeueAll()
       
   907     {
       
   908     #ifdef _DEBUG
       
   909         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::DequeueAll()" ) );
       
   910     #endif
       
   911     
       
   912     while (iChangeRequests.Count() )
       
   913     	{
       
   914     	MXdmOperation* request = iChangeRequests[0];
       
   915     	iChangeRequests.Remove( 0 );
       
   916     	request->Destroy();
       
   917     	request = NULL;
       
   918     	} 
       
   919     }
       
   920       
       
   921 // ---------------------------------------------------------
       
   922 // CXcapDocument::EightBitNameLC
       
   923 // 
       
   924 // ---------------------------------------------------------
       
   925 //
       
   926 HBufC8* CXcapDocument::EightBitNameLC()
       
   927     {
       
   928     /*#ifdef _DEBUG
       
   929         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::EightBitNameLC()" ) );
       
   930     #endif*/
       
   931     __ASSERT_DEBUG( Name().Length() > 0, User::Panic( _L( "CXcapDocument" ), 1 ) );
       
   932     HBufC8* buf = HBufC8::NewLC( Name().Length() );
       
   933     buf->Des().Copy( Name() );
       
   934     return buf;
       
   935     }
       
   936 
       
   937 // ---------------------------------------------------------
       
   938 // CXcapDocument::DocumentType
       
   939 // 
       
   940 // ---------------------------------------------------------
       
   941 //
       
   942 TXdmDocType CXcapDocument::DocumentType() const
       
   943     {
       
   944     return iDocumentType;
       
   945     }
       
   946 
       
   947 // ---------------------------------------------------------
       
   948 // CXcapDocument::AppendNamespaceL
       
   949 // 
       
   950 // ---------------------------------------------------------
       
   951 //
       
   952 void CXcapDocument::AppendNamespaceL( const TDesC8& aUri, const TDesC8& aPrefix )
       
   953     {
       
   954     CXdmNamespace* ns = CXdmNamespace::NewL( aUri, aPrefix );
       
   955     CleanupStack::PushL( ns );
       
   956     User::LeaveIfError( iNamespaces.Append( ns ) );
       
   957     CleanupStack::Pop();  //ns
       
   958     }
       
   959 
       
   960 // ---------------------------------------------------------
       
   961 // CXcapDocument::RemoveNamespace
       
   962 // 
       
   963 // ---------------------------------------------------------
       
   964 //
       
   965 void CXcapDocument::RemoveNamespace( const TDesC8& aUri )
       
   966     {
       
   967     TBool found = EFalse;
       
   968     CXdmNamespace* ns = NULL;
       
   969     TInt count = iNamespaces.Count();
       
   970     for( TInt i = 0;!found && i < count;i++ )
       
   971         {
       
   972         ns = iNamespaces[i];
       
   973         if( ns->Uri().Compare( aUri ) == 0 )
       
   974             {
       
   975             found = ETrue;
       
   976             iNamespaces.Remove( i );
       
   977             delete ns;
       
   978             ns = NULL;
       
   979             }
       
   980         }
       
   981     }
       
   982                     
       
   983 // ---------------------------------------------------------
       
   984 // CXcapDocument::Uri
       
   985 // 
       
   986 // ---------------------------------------------------------
       
   987 //
       
   988 TPtrC8 CXcapDocument::Uri( const TDesC8& aPrefix ) const
       
   989     {
       
   990     TPtrC8 uri( _L8( "" ) );
       
   991     TBool found = EFalse;
       
   992     TInt count = iNamespaces.Count();
       
   993     for( TInt i = 0;!found && i < count ;i++ )
       
   994         {
       
   995         if( iNamespaces[i]->Prefix().Compare( aPrefix ) == 0 )
       
   996             {
       
   997             uri.Set( iNamespaces[i]->Uri() );
       
   998             found = ETrue;
       
   999             }
       
  1000         }
       
  1001     return uri;
       
  1002     }
       
  1003 
       
  1004 // ---------------------------------------------------------
       
  1005 // CXcapDocument::Count
       
  1006 // 
       
  1007 // ---------------------------------------------------------
       
  1008 //
       
  1009 TInt CXcapDocument::Count() const
       
  1010     {
       
  1011     return iNamespaces.Count();
       
  1012     }
       
  1013 
       
  1014 // ---------------------------------------------------------
       
  1015 // CXcapDocument::Prefix
       
  1016 // 
       
  1017 // ---------------------------------------------------------
       
  1018 //
       
  1019 TPtrC8 CXcapDocument::Prefix( TInt aIndex ) const
       
  1020     {
       
  1021     TInt count = iNamespaces.Count();
       
  1022     if( count > 0 && ( aIndex >= 0 && aIndex < count ) )
       
  1023         return iNamespaces[aIndex]->Prefix();
       
  1024     else return TPtrC8();
       
  1025     }
       
  1026     
       
  1027 // ---------------------------------------------------------
       
  1028 // CXcapDocument::Uri
       
  1029 // 
       
  1030 // ---------------------------------------------------------
       
  1031 //
       
  1032 TPtrC8 CXcapDocument::Uri( TInt aIndex ) const
       
  1033     {
       
  1034     TInt count = iNamespaces.Count();
       
  1035     if( count > 0 && ( aIndex >= 0 && aIndex < count ) )
       
  1036         return iNamespaces[aIndex]->Uri();
       
  1037     else return TPtrC8();
       
  1038     }
       
  1039     
       
  1040 // ---------------------------------------------------------
       
  1041 // CXcapDocument::ResetNamespaces
       
  1042 // 
       
  1043 // ---------------------------------------------------------
       
  1044 //
       
  1045 void CXcapDocument::ResetNamespaces( ) 
       
  1046     {   
       
  1047     iNamespaces.ResetAndDestroy();
       
  1048     } 
       
  1049     
       
  1050 // ---------------------------------------------------------
       
  1051 // CXcapDocument::TimeStamp
       
  1052 // 
       
  1053 // ---------------------------------------------------------
       
  1054 //
       
  1055 TTime CXcapDocument::TimeStamp() const
       
  1056     {
       
  1057     return iLastModification;
       
  1058     }
       
  1059 
       
  1060 // ----------------------------------------------------
       
  1061 // CXdmDocument::SaveClientStatus
       
  1062 // 
       
  1063 // ----------------------------------------------------
       
  1064 //
       
  1065 void CXcapDocument::SaveClientStatus( TRequestStatus& aClientStatus )
       
  1066     {
       
  1067     iClientStatus = &aClientStatus;        
       
  1068     }
       
  1069             
       
  1070 // ---------------------------------------------------------
       
  1071 // CXcapDocument::DoCancel
       
  1072 // 
       
  1073 // ---------------------------------------------------------
       
  1074 //
       
  1075 void CXcapDocument::DoCancel()
       
  1076     {
       
  1077     #ifdef _DEBUG
       
  1078         iXcapProtocol.WriteToLog( _L8( "CXcapDocument::DoCancel()" ) );
       
  1079     #endif
       
  1080     if( iClientStatus )
       
  1081         {
       
  1082         User::RequestComplete( iClientStatus, KErrCancel );
       
  1083         #ifdef _DEBUG
       
  1084             iXcapProtocol.WriteToLog( _L8( " Request completed" ) );
       
  1085         #endif
       
  1086         }
       
  1087     else
       
  1088         {
       
  1089         #ifdef _DEBUG
       
  1090             iXcapProtocol.WriteToLog( _L8( " iClientStatus == NULL => do nothing" ) );
       
  1091         #endif
       
  1092         }
       
  1093     }
       
  1094 
       
  1095 
       
  1096 
       
  1097