diff -r 000000000000 -r c8caa15ef882 xdmprotocols/XcapProtocol/XcapOperations/src/XcapRetrieval.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xdmprotocols/XcapProtocol/XcapOperations/src/XcapRetrieval.cpp Tue Feb 02 01:05:17 2010 +0200 @@ -0,0 +1,320 @@ +/* +* 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: CXcapRetrieval +* +*/ + + + + +// INCLUDES +#include "XcapCache.h" +#include "XcapAppUsage.h" +#include "XcapDocument.h" +#include "XcapProtocol.h" +#include "XcapRetrieval.h" +#include "XcapUriParser.h" +#include "XdmXmlParser.h" +#include "XcapHttpReqGet.h" +#include "XcapHttpTransport.h" +#include "XcapOperationFactory.h" + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// C++ constructor can NOT contain any code, that +// might leave. +// --------------------------------------------------------- +// +CXcapRetrieval::CXcapRetrieval( CXcapDocument& aParentDoc, + CXcapDocumentNode* aTargetNode, + CXcapOperationFactory& aOperationFactory ) : + CXcapHttpOperation( aParentDoc, aTargetNode, aOperationFactory ), + iCacheOperation( EFalse ), + iOperationType( aTargetNode == NULL ? + EXdmDocument : EXdmPartialDocument ) + { + } + +// --------------------------------------------------------- +// CXcapRetrieval::NewL +// +// --------------------------------------------------------- +// +CXcapRetrieval* CXcapRetrieval::NewL( CXcapDocument& aParentDoc, + CXcapDocumentNode* aTargetNode, + CXcapOperationFactory& aOperationFactory ) + { + CXcapRetrieval* self = new ( ELeave ) CXcapRetrieval( aParentDoc, aTargetNode, aOperationFactory ); + CleanupStack::PushL( self ); + self->BaseConstructL(); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// --------------------------------------------------------- +// CXcapRetrieval::ConstructL +// +// --------------------------------------------------------- +// +void CXcapRetrieval::ConstructL() + { +#ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( "-> CXcapRetrieval::ConstructL" ) ); +#endif + CXcapHttpReqGet* request = Transport().GetL( iTargetDoc.Name() ); + CleanupStack::PushL( request ); + User::LeaveIfError( iRequestQueue.Append( request ) ); + request->SetExpiryTimeL( NULL, KDefaultHttpRequestTimeout * 1000000 ); + CleanupStack::Pop(); //request + if( iOperationType != EXdmDocument && iDocumentSubset != NULL ) + { + iUriParser->SetDocumentSubset( iDocumentSubset ); + //Add namespace mappings + User::LeaveIfError( iTargetDoc.ApplicationUsage().Validate( + *iDocumentSubset, iUriParser, ETrue ) ); + } +#ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( "<- CXcapRetrieval::ConstructL" ) ); +#endif + } + +// --------------------------------------------------------- +// CXcapRetrieval::ExecuteL +// +// --------------------------------------------------------- +// +void CXcapRetrieval::ExecuteL() + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( "CXcapRetrieval::ExecuteL()" ) ); + #endif + TPtrC8 eTag = iTargetDoc.ETag(); + if( eTag.Length() > 0 ) + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " Using ETag \"%S\" - Length: %d" ), + &eTag, eTag.Length() ); + #endif + //iActiveRequest->SetHeaderL( KHttpHeaderIfNoneMatch, eTag ); + } + TRAPD( error, iUriParser->ParseL( iActiveRequest->RequestUriL() ) ); + if( error == KErrNone ) + { + TPtrC8 uri = iUriParser->DesC8(); + HBufC8* escape = CXcapHttpOperation::EscapeLC( uri ); + iActiveRequest->UpdateRequestUriL( escape->Des() ); + CleanupStack::PopAndDestroy(); //escape + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " New URI: %S" ), &uri ); + #endif + } + } + +// --------------------------------------------------------- +// CXcapRetrieval::OperationCompleteL +// +/* const TDesC8& aETag, + const TDesC& aDocumentName, + const TDesC8& aRootLocation, + const TDesC8& aResponseData*/ +// --------------------------------------------------------- +// +void CXcapRetrieval::OperationCompleteL() + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( "CXcapRetrieval::OperationCompleteL()" ) ); + #endif + TInt generalErr = ReinterpretStatus( iRequestData->iHttpStatus ); + if( generalErr == KErrNone ) + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " No general errors found" ) ); + #endif + iCacheOperation ? HandleCacheOperationL() : HandleNetworkOperationL(); + } + else + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " General errors found - Status: %d Error: %d" ), + iRequestData->iHttpStatus, generalErr ); + #endif + iCompleted = ETrue; + iResult = generalErr; + } + } + +// --------------------------------------------------------- +// CXcapRetrieval::HandleCacheOperationL +// +// --------------------------------------------------------- +// +void CXcapRetrieval::HandleCacheOperationL() + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( "CXcapRetrieval::HandleCacheOperationL() - Operation type: %d Target node: %x" ), + iOperationType, iDocumentSubset ); + #endif + TPtrC8 responseData = Descriptor( iRequestData->iResponseData ); + iOperationType == EXdmDocument && iDocumentSubset == NULL ? + iXmlParser->ParseDocumentL( &iTargetDoc, responseData ) : + iXmlParser->ParseDocumentL( &iTargetDoc, responseData, iDocumentSubset ); + iCompleted = ETrue; + } + +// --------------------------------------------------------- +// CXcapRetrieval::HandleNetworkOperationL +// +// --------------------------------------------------------- +// +void CXcapRetrieval::HandleNetworkOperationL() + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( "CXcapRetrieval::HandleNetworkOperationL()" ) ); + #endif + TPtrC name = iTargetDoc.Name(); + TPtrC8 root = Transport().RootUri(); + switch( iRequestData->iHttpStatus ) + { + case 200: //ETag was stale + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " Status 200 - ETag was stale" ) ); + #endif + TPtrC8 responseData = Descriptor( iRequestData->iResponseData ); + if( responseData.Length() <= 0 ) + break; + if( iOperationType == EXdmDocument ) + { + TPtrC8 eTag = Descriptor( iRequestData->iETag ); + //If the ETag has not changed, server should return + //304 (Not modified), but just in case, let's check the + //ETag value, anyway. + if( eTag.Length() > 0 && eTag.Compare( iTargetDoc.ETag() ) != 0 ) + { + iTargetDoc.SetETag( eTag ); + RXcapCache* cache = iTargetDoc.Protocol().Cache(); + if( cache && !( iOptionFlags & KNoCache ) ) + cache->Store( iTargetDoc.ETag(), name, root, responseData ); + } + else + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " ETag values match, do not update cache" ) ); + #endif + } + iXmlParser->ParseDocumentL( &iTargetDoc, responseData ); + } + else if( iOperationType == EXdmPartialDocument ) + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " Parse a partial document" ) ); + #endif + //The target node must be emptied before inserting new content + iDocumentSubset->SetEmptyNode( ETrue ); + iDocumentSubset->SetEmptyNode( EFalse ); + iXmlParser->ParseDocumentL( responseData, iDocumentSubset ); + } + iCompleted = ETrue; + } + break; + case 304: + { + RXcapCache* cache = iTargetDoc.Protocol().Cache(); + if( cache ) + { + #ifdef _DEBUG //ETag is up to date - cache still valid + iOperationFactory.WriteToLog( _L8( " Status 304 - Cached version is valid" ) ); + #endif + TInt length = iTargetDoc.DataLength(); + __ASSERT_DEBUG( length > 0, User::Panic( _L( "CXcapRetrieval" ), 1 ) ); + delete iRequestData->iResponseData; + iRequestData->iResponseData = NULL; + iRequestData->iResponseData = HBufC8::NewL( length ); + TPtr8 desc( iRequestData->iResponseData->Des() ); + cache->FetchDocumentContent( desc, name, root ); + if( iOperationType == EXdmDocument && !iTargetDoc.DocumentRoot() ) + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " No content => parse cached document" ) ); + #endif + iXmlParser->ParseDocumentL( &iTargetDoc, desc ); + } + else if( iOperationType == EXdmPartialDocument ) + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " Parse a partial document" ) ); + #endif + iXmlParser->ParseDocumentL( &iTargetDoc, desc, iDocumentSubset ); + } + } + iCompleted = ETrue; + } + break; + default: + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( " Default case - Status: %d" ), + iRequestData->iHttpStatus ); + #endif + iCompleted = ETrue; + break; + } + } + +// --------------------------------------------------------- +// CXcapRetrieval::OperationFailedL +// +// --------------------------------------------------------- +// +void CXcapRetrieval::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; + } + +// --------------------------------------------------------- +// CXcapRetrieval::Result +// +// --------------------------------------------------------- +// +TInt CXcapRetrieval::Result() const + { + return iRequestData->iCompletion; + } + +// --------------------------------------------------------- +// CXcapRetrieval::~CXcapRetrieval +// +// --------------------------------------------------------- +// +CXcapRetrieval::~CXcapRetrieval() + { + #ifdef _DEBUG + iOperationFactory.WriteToLog( _L8( "CXcapRetrieval::~CXcapRetrieval()" ) ); + #endif + } + +// End of File +