xdmprotocols/XcapProtocol/XcapOperations/src/XcapAddition.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:05:17 +0200
changeset 0 c8caa15ef882
permissions -rw-r--r--
Revision: 201003 Kit: 201005

/*
* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:   CXcapAddition
*
*/




// INCLUDES
#include "XcapCache.h"
#include "XcapAppUsage.h"
#include "XcapProtocol.h"
#include "XcapDocument.h"
#include "XcapAddition.h"
#include "XdmXmlParser.h"
#include "XcapUriParser.h"
#include "CommonDefines.h"
#include "XcapHttpReqPut.h"
#include "XcapHttpOperation.h"
#include "XcapHttpTransport.h"
#include "XcapOperationFactory.h"
       
// ---------------------------------------------------------
// CXcapAddition::CXcapAddition
//
// ---------------------------------------------------------
//
CXcapAddition::CXcapAddition( CXcapDocument& aParentDoc,
                              CXcapDocumentNode* aDocumentSubset,
                              CXcapOperationFactory& aOperationFactory ) :
                              CXcapHttpOperation( aParentDoc, aDocumentSubset, aOperationFactory ),
                              iOperationType( aDocumentSubset == NULL ?
                              EXdmDocument : EXdmPartialDocument )
                                                      
    {
    }

// ---------------------------------------------------------
// CXcapAddition::NewL
//
// ---------------------------------------------------------
//
CXcapAddition* CXcapAddition::NewL( CXcapDocument& aParentDoc,
                                    CXcapDocumentNode* aDocumentSubset,
                                    CXcapOperationFactory& aOperationFactory )
    {
    CXcapAddition* self = new ( ELeave ) CXcapAddition( aParentDoc, aDocumentSubset, aOperationFactory );
    CleanupStack::PushL( self );
    self->BaseConstructL();
    self->ConstructL();
    CleanupStack::Pop();
    return self;
    }

// ---------------------------------------------------------
// CXcapAddition::ConstructL
//
// ---------------------------------------------------------
//
void CXcapAddition::ConstructL()
    {
    CXcapHttpReqPut* request = Transport().PutL( iTargetDoc.Name() );
    CleanupStack::PushL( request );
    User::LeaveIfError( iRequestQueue.Append( request ) );
    request->SetExpiryTimeL( NULL, KDefaultHttpRequestTimeout * 1000000 );
    CleanupStack::Pop();  //request
    //If they point to the same node, we're dealing with a complete document
    if( iDocumentSubset != NULL && iTargetDoc.DocumentRoot() != iDocumentSubset )
        iUriParser->SetDocumentSubset( iDocumentSubset );
    }
    
// ---------------------------------------------------------
// CXcapAddition::FormatModRequestL
//
// ---------------------------------------------------------
//
TInt CXcapAddition::FormatModRequestL( const CXdmDocumentNode* aDocumentNode )
    {
    #ifdef _DEBUG
        iOperationFactory.WriteToLog( _L8( "CXcapAddition::FormatModRequestL()" ) );
        iOperationFactory.WriteToLog( _L8( "  Operation type:  %d" ), iOperationType );
        iOperationFactory.WriteToLog( _L8( "  Document subset: %x" ), iDocumentSubset );
    #endif
    TInt validation = CXcapHttpOperation::FormatModRequestL( aDocumentNode );
    if( validation == KErrNone )
        {
        //Then set the properties particular to this type of request
        iOperationType = DetermineOperationType();
        if( iOperationType == EXdmDocument )
            iActiveRequest->SetHeaderL( KHttpHeaderContentType, iTargetDoc.ApplicationUsage().ContentType() );
        }
    else
        {
        #ifdef _DEBUG
            iOperationFactory.WriteToLog( _L8( " AppUsage reported the following error: %d" ), validation );
        #endif
        }
    return validation;
    }

// ---------------------------------------------------------
// CXcapAddition::DetermineOperationType
//
// ---------------------------------------------------------
//
TXdmOperationType CXcapAddition::DetermineOperationType()
    {
    #ifdef _DEBUG
        iOperationFactory.WriteToLog( _L8( "CXcapAddition::DetermineDocType()" ) );
        iOperationFactory.WriteToLog( _L8( "  Operation type:  %d" ), iOperationType );
        iOperationFactory.WriteToLog( _L8( "  Document subset: %x" ), iDocumentSubset );
        iOperationFactory.WriteToLog( _L8( "  Document root:   %x" ), iTargetDoc.DocumentRoot() ); 
    #endif
    return iOperationType == EXdmDocument || ( EXdmPartialDocument &&
                             iDocumentSubset == iTargetDoc.DocumentRoot() ) ?
                             EXdmDocument : EXdmPartialDocument;
    }
      
// ---------------------------------------------------------
// CXcapAddition::ExecuteL
//
// ---------------------------------------------------------
//
void CXcapAddition::ExecuteL()
    {
    #ifdef _DEBUG
        iOperationFactory.WriteToLog( _L8( "CXcapAddition::ExecuteL()" ) );  
    #endif
    CXcapHttpOperation::ExecuteL( iActiveRequest, iDocumentSubset );
    }
        
// ---------------------------------------------------------
// CXcapAddition::OperationCompleteL
//
// ---------------------------------------------------------
//
void CXcapAddition::OperationCompleteL()
    {
    #ifdef _DEBUG
        iOperationFactory.WriteToLog( _L8( "CXcapAddition::OperationCompleteL()" ) );  
    #endif
    TPtrC8 root = Transport().RootUri();
    iRequestData = iActiveRequest->ResponseData();
    TPtrC name = iTargetDoc.Name();
    switch( iRequestData->iHttpStatus )
        {
        case 200:           //Replaced, the document was already there
        case 201:           //"Created" -> Put operation was successful
            {
            #ifdef _DEBUG
                iOperationFactory.WriteToLog( _L8( " Status %d" ), iRequestData->iHttpStatus );  
            #endif
            iResult = KErrNone;
            TPtrC8 eTag = Descriptor( iRequestData->iETag );
            iTargetDoc.SetETag( eTag );
            RXcapCache* cache = iTargetDoc.Protocol().Cache();
            if( cache != NULL )
                {
                CXcapHttpContSupplier* request = ( CXcapHttpContSupplier* )iActiveRequest;
                TPtrC8 payload = request->RequestBody();
                iOperationType == EXdmDocument ? cache->Store( eTag, name, root, payload ) :
                                                 UpdatePartialToCacheL( cache, payload );
                }
            iCompleted = ETrue;
            }
            break;
        default:
            #ifdef _DEBUG
                iOperationFactory.WriteToLog( _L8( " Default case - Status: %d" ),
                                                   iRequestData->iHttpStatus ); 
            #endif
            TInt status = iRequestData->iHttpStatus;
            iResult = ReinterpretStatus( status );
            iCompleted = ETrue;
            break;
        }
    }

// ---------------------------------------------------------
// CXcapAddition::UpdatePartialToCacheL
//
// ---------------------------------------------------------
//
void CXcapAddition::UpdatePartialToCacheL( RXcapCache* aCache, const TDesC8& aNewData )
    {
    #ifdef _DEBUG
        iOperationFactory.WriteToLog( _L8( "CXcapAddition::UpdatePartialToCacheL()" ) );  
    #endif
    HBufC8* newData = NULL;
    TPtrC name = iTargetDoc.Name();
    TPtrC8 root = Transport().RootUri();
    if( iOptionFlags & KFetchMasterFromCache )
        {
        TInt length = iTargetDoc.DataLength();
        //Do nothing, if the document is not in cache
        if( length > 0 )
            {
            HBufC8* data = HBufC8::NewLC( length );
            TPtr8 desc( data->Des() );
            aCache->FetchDocumentContent( desc, name, root );
            CXcapDocument* copy = iTargetDoc.TempCopyL();
            CleanupStack::PushL( copy );
            iXmlParser->ParseDocumentL( copy, desc );
            RPointerArray<CXdmDocumentNode> array;
            CleanupClosePushL( array );
            copy->Find( *iDocumentSubset, array );
            //If the element the subset points to is not present
            //in the original document, the new data must be
            //appended to the the subset element parent, instead.
            CXdmDocumentNode* node = array.Count() > 0 ?
                iDocumentSubset : iDocumentSubset->Parent();
            newData = iXmlParser->FormatToXmlLC( aNewData, copy, node );
            CleanupStack::Pop();  //newData
            CleanupStack::PopAndDestroy( 3 );  //array, tempCopy, data
            CleanupStack::PushL( newData );
            }           
        }
    else
        {
        CXdmDocumentNode* root = iTargetDoc.DocumentRoot();
        newData = iXmlParser->FormatToXmlLC( ETrue, &iTargetDoc, root );
        }
    if( newData )
        {
        aCache->Store( iTargetDoc.ETag(), name, root, newData->Des() );
        CleanupStack::PopAndDestroy();  //newData
        }
    }

// ---------------------------------------------------------
// CXcapAddition::OperationFailedL
//
// ---------------------------------------------------------
//
void CXcapAddition::OperationFailedL()
    {
    #ifdef _DEBUG
        iOperationFactory.WriteToLog( _L8( "CXcapRetrieval::OperationFailedL() - Error: %d" ),
                                           iStatus.Int() );  
    #endif
    if( iStatus.Int() >= KErrNone )
        {
        TInt status = iActiveRequest->ResponseData()->iHttpStatus;
        TInt completion = iActiveRequest->ResponseData()->iCompletion;
        iResult = status < KErrNone || completion < KErrNone ? status : ReinterpretStatus( status );
        }
    else iResult = iStatus.Int();
    iCompleted = ETrue;
    }

// ---------------------------------------------------------
// CXcapAddition::Result
//
// ---------------------------------------------------------
//
TBool CXcapAddition::Result() const
    {
    return ETrue;
    }

// ---------------------------------------------------------
// CXcapAddition::~CXcapAddition
//
// ---------------------------------------------------------
//
CXcapAddition::~CXcapAddition()
    {
    #ifdef _DEBUG
        iOperationFactory.WriteToLog( _L8( "CXcapAddition::~CXcapAddition()" ) );  
    #endif
    }

//  End of File