diff -r 2669f8761a99 -r fbd2e7cec7ef xdmprotocols/XcapProtocol/src/XcapDirectory.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xdmprotocols/XcapProtocol/src/XcapDirectory.cpp Wed Sep 01 12:23:14 2010 +0100 @@ -0,0 +1,501 @@ +/* +* 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: CXcapDirectory +* +*/ + + + + +// INCLUDE FILES +#include +#include +#include "XcapAppUsageDef.h" +#include "XdmProtocol.h" +#include "XcapDocument.h" +#include "XcapProtocol.h" +#include "XcapAppUsage.h" +#include "XcapRetrieval.h" +#include "XcapDirectory.h" +#include "XdmXmlParser.h" +#include "XcapHttpReqGet.h" +#include "XdmDocumentNode.h" +#include "XdmNodeAttribute.h" +#include "XcapHttpTransport.h" +#include "XdmOperationFactory.h" + +// ---------------------------------------------------------- +// CXcapDirectory::CXcapDirectory +// +// ---------------------------------------------------------- +// +CXcapDirectory::CXcapDirectory( CXdmDocument*& aDirectoryDoc, + CXdmEngine& aXdmEngine, + CXcapProtocol& aXcapProtocol ) : + CXdmDirectory( aXdmEngine ), + iDirectoryDoc( ( CXcapDocument* )aDirectoryDoc ), + iXcapProtocol( aXcapProtocol ) + { + } + +// ---------------------------------------------------------- +// CXcapDirectory::NewL +// +// ---------------------------------------------------------- +// +CXcapDirectory* CXcapDirectory::NewL( const TDesC& aAUID, + CXdmEngine& aXdmEngine, + CXdmDocument*& aDirectoryDoc, + CXcapProtocol& aXcapProtocol ) + { + CXcapDirectory* self = new ( ELeave ) CXcapDirectory( aDirectoryDoc, aXdmEngine, aXcapProtocol ); + CleanupStack::PushL( self ); + self->ConstructL( aAUID ); + CleanupStack::Pop(); + return self; + } + +// ---------------------------------------------------- +// CXcapDirectory::~CXcapDirectory +// +// ---------------------------------------------------- +// +CXcapDirectory::~CXcapDirectory() + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::~CXcapDirectory()" ) ); + #endif + Cancel(); + delete iAUID; + delete iDirectoryDoc; + delete iHttpRetrieval; + iUpdateList.Close(); + iDocumentList.Close(); + } + +// ---------------------------------------------------------- +// CXcapDirectory::ConstructL +// +// ---------------------------------------------------------- +// +void CXcapDirectory::ConstructL( const TDesC& aAUID ) + { + if( aAUID.Length() > 0 ) + { + _LIT( KNodePath, "xcap-directory/folder" ); + iAUID = HBufC::NewL( aAUID.Length() ); + iAUID->Des().Copy( aAUID ); + CXdmDocumentNode* node = iDirectoryDoc->DocumentSubsetL( KNodePath ); + CleanupStack::PushL( node ); + CXdmNodeAttribute* auid = node->CreateAttributeL( KAuidAttribute ); + CleanupStack::PushL( auid ); + auid->SetAttributeValueL( aAUID ); + iDirectoryDoc->FetchDataL( node ); + //Set the option that prohibits caching + iDirectoryDoc->SetOption( KXdmOption3 ); + CleanupStack::Pop( 2 ); //auid, node + } + else iDirectoryDoc->FetchDataL(); + CActiveScheduler::Add( this ); + } + +// ---------------------------------------------------------- +// CXcapDirectory::StartUpdateL +// +// ---------------------------------------------------------- +// +void CXcapDirectory::StartUpdateL() + + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::StartUpdateL()" ) ); + #endif + switch( iUpdatePhase ) + { + case EDirPhaseIdle: + User::RequestComplete( iClientStatus, KErrArgument ); + break; + case EUpdateDocumentList: + HandleDocumentListRequestL(); + break; + case ERefreshDocuments: + HandleRefreshRequestL(); + break; + default: + break; + } + } + +// ---------------------------------------------------------- +// CXcapDirectory::SaveRequestData +// +// ---------------------------------------------------------- +// +void CXcapDirectory::SaveRequestData( TDirUpdatePhase aUpdatePhase, + TRequestStatus& aClientStatus ) + { + iUpdatePhase = aUpdatePhase; + iClientStatus = &aClientStatus; + } + +// ---------------------------------------------------- +// CXcapDirectory::HandleDocumentListRequestL +// +// ---------------------------------------------------- +// +void CXcapDirectory::HandleDocumentListRequestL() + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::HandleDocumentListRequestL()" ) ); + #endif + if( !IsActive() ) + { + CXcapDocument* doc = ( CXcapDocument* )iDirectoryDoc; + doc->StartInternalL( iStatus ); + iUpdatePhase = EUpdateDocumentList; + SetActive(); + } + } + +// ---------------------------------------------------- +// CXcapDirectory::HandleRefreshRequestL +// +// ---------------------------------------------------- +// +void CXcapDirectory::HandleRefreshRequestL() + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::HandleRefreshRequestL()" ) ); + #endif + if( iUpdatePhase == EUpdateDocumentList ) + { + if( iUpdateList.Count() > 0 ) + { + iUpdateIndex = -1; + iHttpRetrieval = iXcapProtocol.Transport().GetL( TPtrC() ); + UpdateNextDocumentL(); + iUpdatePhase = ERefreshDocuments; + } + else + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( " All documents are up to date" ) ); + #endif + User::RequestComplete( iClientStatus, KErrNone ); + } + } + else + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( " Wrong state [%d]" ), iUpdatePhase ); + #endif + User::RequestComplete( iClientStatus, KErrNotReady ); + } + } + +// ---------------------------------------------------- +// CXcapDirectory::UpdateNextDocumentL +// +// ---------------------------------------------------- +// +void CXcapDirectory::UpdateNextDocumentL() + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::UpdateNextDocumentL()" ) ); + #endif + iUpdateIndex++; + if( iUpdateIndex < iUpdateList.Count() ) + { + CXdmDocumentNode* node = iUpdateList[iUpdateIndex]; + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( " Index: %d Document: %x" ), iUpdateIndex, node ); + #endif + TPtrC8 root = iXcapProtocol.Transport().RootUri(); + TPtrC docUri( ExtractDocumentUriL( root, node ) ); + HBufC* uri = HBufC::NewLC( root.Length() + docUri.Length() ); + uri->Des().Copy( root ); + uri->Des().Append( docUri ); + iHttpRetrieval->ResetUriL( uri->Des() ); + iHttpRetrieval->SetExpiryTimeL( NULL, KDefaultHttpRequestTimeout * 1000000 ); + iHttpRetrieval->DispatchRequestL( iStatus ); + CleanupStack::PopAndDestroy(); //uri + SetActive(); + } + else + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( " Directory sync complete" ) ); + #endif + User::RequestComplete( iClientStatus, KErrNone ); + } + } + +// --------------------------------------------------------- +// CXcapDirectory::RunL() +// +// --------------------------------------------------------- +// +void CXcapDirectory::RunL() + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::RunL() - Request: %d" ), iStatus.Int() ); + #endif + if( iStatus == KErrNone ) + { + switch( iUpdatePhase ) + { + case EUpdateDocumentList: + { + iDocumentCount = iDirectoryDoc->Find( KDirectoryEntry, iDocumentList ); + if( iDocumentCount > 0 ) + { + TInt index = 0; + while( index < iDocumentCount ) + { + TBool uptodate = CheckLocalCopyL( iDocumentList[index] ); + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( " Cache: %d" ), uptodate ); + #endif + if( !uptodate ) + User::LeaveIfError( iUpdateList.Append( iDocumentList[index] ) ); + index++; + } + } + User::RequestComplete( iClientStatus, iStatus.Int() ); + } + break; + case ERefreshDocuments: + { + CXdmDocumentNode* node = iUpdateList[iUpdateIndex]; + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( " Index: %d" ), iUpdateIndex ); + iXcapProtocol.WriteToLog( _L8( " Document: %x" ), node ); + iXcapProtocol.WriteToLog( _L8( " Error: %d" ), iStatus.Int() ); + #endif + TPtrC8 root = iXcapProtocol.Transport().RootUri(); + TPtrC docName = ExtractDocumentUriL( root, node ); + TXdmCompletionData* data = iHttpRetrieval->ResponseData(); + TPtrC8 responseData( data->iResponseData->Des() ); + TPtrC8 eTag( data->iETag->Des() ); + RXcapCache* cache = iXcapProtocol.Cache(); + cache->Store( eTag, docName, root, responseData ); + iHttpRetrieval->ReleaseResponseData(); + UpdateNextDocumentL(); + } + break; + default: + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( " Default case, unknown state %d - Status: %d" ), + iUpdatePhase, iStatus.Int() ); + #endif + if( iClientStatus != NULL ) + User::RequestComplete( iClientStatus, KErrUnknown ); + break; + } + } + else + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( " Operation failed with %d" ), iStatus.Int() ); + #endif + User::RequestComplete( iClientStatus, iStatus.Int() ); + } + } + +// --------------------------------------------------------- +// CXcapDirectory::CheckLocalCopyL +// +// --------------------------------------------------------- +// +TBool CXcapDirectory::CheckLocalCopyL( const CXdmDocumentNode* aDocumentNode ) + { + /*#ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::CheckLocalCopyL()" ) ); + #endif*/ + TBool ret = EFalse; + TPtrC8 root = iXcapProtocol.Transport().RootUri(); + TPtrC docName = ExtractDocumentUriL( root, aDocumentNode ); + TPtrC etag( aDocumentNode->Attribute( KDocumentETag )->AttributeValue() ); + HBufC8* etag8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( etag ); + CleanupStack::PushL( etag8 ); + RXcapCache* cache = iXcapProtocol.Cache(); + ret = cache != NULL ? cache->IsCurrent( etag8->Des(), docName, root ) == KErrNone : ETrue; + CleanupStack::PopAndDestroy(); //etag8 + return ret; + } + +// --------------------------------------------------------- +// CXcapDirectory::ExtractDocumentUriL +// +// --------------------------------------------------------- +// +TPtrC CXcapDirectory::ExtractDocumentUriL( const TDesC8& aRootUri, + const CXdmDocumentNode* aDocumentNode ) + { + /*#ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::ExtractDocumentUri()" ) ); + #endif*/ + const TUint8 KHttpHostSeparator = 47; + _LIT8( KHttpDoubleHostSeparator, "//" ); + TPtrC uri( aDocumentNode->Attribute( KDocumentUri )->AttributeValue() ); + if( uri[0] == KHttpHostSeparator ) //Relative URI + return uri; + else + { + TInt index = aRootUri.Find( KHttpDoubleHostSeparator ); + TPtrC8 root( aRootUri.Right( aRootUri.Length() - index - 2 ) ); + HBufC8* uri8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( uri ); + CleanupStack::PushL( uri8 ); + TPtr8 desc( uri8->Des() ); + index = desc.Find( root ); + CleanupStack::PopAndDestroy(); //uri8 + return index >= 0 ? uri.Right( uri.Length() - root.Length() - index ) : TPtrC(); + } + } + +// ---------------------------------------------------- +// CXcapDirectory::DocumentCount +// +// ---------------------------------------------------- +// +TInt CXcapDirectory::DocumentCount() + { + return iDocumentCount; + } + +// ---------------------------------------------------- +// CXcapDirectory::DocumentType +// +// ---------------------------------------------------- +// +TXdmDocType CXcapDirectory::DocumentTypeL( TInt aIndex ) const + { + TXdmDocType type = EXdmDocGeneral; + if( iUpdatePhase <= EDirPhaseIdle ) + User::Leave( KErrNotReady ); + else if( iDocumentCount > 0 && ( aIndex >= 0 && aIndex < iDocumentCount ) ) + type = FindAUID( *iDocumentList[aIndex] ); + return type; + } + +// ---------------------------------------------------- +// CXcapDirectory::FindAUID +// +// ---------------------------------------------------- +// +TXdmDocType CXcapDirectory::FindAUID( const CXdmDocumentNode& aEntryNode ) const + { + TXdmDocType documentType = EXdmDocGeneral; + HBufC8* buf = aEntryNode.Attribute( KDocumentUri )->EightBitValueLC(); + if( buf ) + { + TPtrC8 uri( buf->Des() ); + if( uri.Find( KXdmCapabilityUsageAUID ) >= 0 ) + documentType = EXdmCapabilities; + else if( uri.Find( KXdmPocUserAccessUsageAUID ) >= 0 ) + documentType = EXdmPoCUserAccessPolicy; + else if( uri.Find( KXdmPocGroupUsageAUID ) >= 0 ) + documentType = EXdmPoCGroup; + else if( uri.Find( KXdmResourceListsUsageAUID ) >= 0 ) + documentType = EXdmResourceLists; + else if( uri.Find( KXdmOmaPresRulesUsageAUID ) >= 0 ) + documentType = EXdmIetfPresenceRules; + else if( uri.Find( KXdmDirectoryUsageAUID ) >= 0 ) + documentType = EXdmDirectory; + else if( uri.Find( KXdmSharedXDMUsageAUID ) >= 0 ) + documentType = EXdmSharedXdm; + else if( uri.Find( KXdmRlsServicesUsageAUID ) >= 0 ) + documentType = EXdmRlsServices; + CleanupStack::PopAndDestroy(); //EightBitValueLC() + } + return documentType; + } + +// ---------------------------------------------------- +// CXcapDirectory::Document +// +// ---------------------------------------------------- +// +TPtrC CXcapDirectory::Document( TInt aIndex ) const + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::Document() - Index: %d" ), aIndex ); + #endif + TChar slash = 47; + if( aIndex >= 0 && aIndex < iDocumentList.Count() ) + { + TPtrC ret; + TPtrC uri = iDocumentList[aIndex]->Attribute( KDocumentUri )->AttributeValue(); + TInt index = uri.LocateReverse( slash ); + index > 0 ? ret.Set( uri.Right( uri.Length() - index - 1 ) ) : ret.Set( uri ); + return ret; + } + else return TPtrC(); + } + +// ---------------------------------------------------- +// CXcapDirectory::DirectoryPath +// +// ---------------------------------------------------- +// +TPtrC CXcapDirectory::DirectoryPath() const + { + return iAUID != NULL ? iAUID->Des() : TPtrC(); + } + +// ---------------------------------------------------- +// CXcapDirectory::CancelUpdate +// +// ---------------------------------------------------- +// +void CXcapDirectory::CancelUpdate() + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::CancelUpdate()" ) ); + #endif + Cancel(); + } + +// --------------------------------------------------------- +// CXcapDirectory::DoCancel +// +// --------------------------------------------------------- +// +void CXcapDirectory::DoCancel() + { + #ifdef _DEBUG + iXcapProtocol.WriteToLog( _L8( "CXcapDirectory::DoCancel()" ) ); + #endif + switch( iUpdatePhase ) + { + case EDirPhaseIdle: + break; + case EUpdateDocumentList: + { + CXcapDocument* doc = ( CXcapDocument* )iDirectoryDoc; + doc->CancelUpdate(); + } + break; + case ERefreshDocuments: + iHttpRetrieval->CancelRequest(); + break; + default: + break; + } + User::RequestComplete( iClientStatus, KErrCancel ); + } + + + +