diff -r 000000000000 -r ba25891c3a9e ncdengine/provider/server/src/ncdnodeuserdataimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ncdengine/provider/server/src/ncdnodeuserdataimpl.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,332 @@ +/* +* Copyright (c) 2006 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: Implements CNcdNodeUserData class +* +*/ + + +#include "ncdnodeuserdataimpl.h" +#include "ncdnodemanager.h" +#include "ncdnodeidentifier.h" +#include "catalogssession.h" +#include "catalogsbasemessage.h" +#include "ncdnodefunctionids.h" +#include "ncdnodeclassids.h" +#include "catalogsconstants.h" +#include "ncd_pp_dataentity.h" +#include "ncd_cp_query.h" +#include "catalogsutils.h" +#include "catalogsdebug.h" + + +CNcdNodeUserData::CNcdNodeUserData( NcdNodeClassIds::TNcdNodeClassId aClassId, + CNcdNodeManager& aManager ) +: CCatalogsCommunicable(), + iClassId( aClassId ), + iManager( aManager ) + { + } + +void CNcdNodeUserData::ConstructL( const CNcdNodeIdentifier& aIdentifier ) + { + DLTRACEIN(("")); + + // These values have to be set. + + iIdentifier = + CNcdNodeIdentifier::NewL( aIdentifier ); + + + // Notice that the user data is left here to be NULL. + // The value is set from db during the first query for the user data. + // This is checked by comparing the user data value to NULL. + // Also, notice that the Internalization can not be done here because + // this class object may be created from the node when it is been internalized. + // Multiple internalizations from the same db at the same time are not allowed. + + DLTRACEOUT(("")); + } + + +CNcdNodeUserData* CNcdNodeUserData::NewL( const CNcdNodeIdentifier& aIdentifier, + CNcdNodeManager& aManager ) + { + CNcdNodeUserData* self = + CNcdNodeUserData::NewLC( aIdentifier, aManager ); + CleanupStack::Pop( self ); + return self; + } + +CNcdNodeUserData* CNcdNodeUserData::NewLC( const CNcdNodeIdentifier& aIdentifier, + CNcdNodeManager& aManager ) + { + CNcdNodeUserData* self = + new( ELeave ) CNcdNodeUserData( + NcdNodeClassIds::ENcdNodeUserDataClassId, aManager ); + CleanupClosePushL( *self ); + self->ConstructL( aIdentifier ); + return self; + } + + +CNcdNodeUserData::~CNcdNodeUserData() + { + DLTRACEIN(("")); + + // Delete member variables here + delete iIdentifier; + iIdentifier = NULL; + + delete iUserData; + iUserData = NULL; + + // Do not delete manager because this class object does not own it. + + DLTRACEOUT(("")); + } + +NcdNodeClassIds::TNcdNodeClassId CNcdNodeUserData::ClassId() const + { + return iClassId; + } + + +void CNcdNodeUserData::ReceiveMessage( MCatalogsBaseMessage* aMessage, + TInt aFunctionNumber ) + { + DLTRACEIN(("")); + + DASSERT( aMessage ); + + // Now, we can be sure that rest of the time iMessage exists. + // This member variable is set for the CounterPartLost function. + iMessage = aMessage; + + TInt trapError( KErrNone ); + + // Check which function is called by the proxy side object. + // Function number are located in ncdnodefunctinoids.h file. + switch( aFunctionNumber ) + { + case NcdNodeFunctionIds::ENcdUserData: + TRAP( trapError, UserDataRequestL( *aMessage ) ); + break; + + case NcdNodeFunctionIds::ENcdSetUserData: + TRAP( trapError, SetUserDataRequestL( *aMessage ) ); + break; + + case NcdNodeFunctionIds::ENcdClearUserData: + TRAP( trapError, ClearUserDataRequestL( *aMessage ) ); + break; + + case NcdNodeFunctionIds::ENcdRelease: + // The proxy does not want to use this object anymore. + // So, release the handle from the session. + ReleaseRequest( *aMessage ); + break; + + default: + DLERROR(("Unidentified function request")); + DASSERT( EFalse ); + break; + } + + if ( trapError != KErrNone ) + { + // Because something went wrong, the complete has not been + // yet called for the message. + // So, inform the client about the error if the + // message is still available. + aMessage->CompleteAndRelease( trapError ); + } + + // Because the message should not be used after this, set it NULL. + // So, CounterPartLost function will know that no messages are + // waiting the response at the moment. + iMessage = NULL; + + DLTRACEOUT(("")); + } + +void CNcdNodeUserData::CounterPartLost( const MCatalogsSession& aSession ) + { + DLTRACEIN(("")); + + // This function may be called whenever -- when the message is waiting + // response or when the message does not exist. + // iMessage may be NULL here, because in the end of the + // ReceiveMessage it is set to NULL. The life time of the message + // ends shortly after CompleteAndRelease is called. + if ( iMessage != NULL ) + { + iMessage->CounterPartLost( aSession ); + } + + DLTRACEOUT(("")); + } + + +void CNcdNodeUserData::ExternalizeL( RWriteStream& aStream ) + { + DLTRACEIN(("Data: %S", iUserData)); + + if ( iUserData != NULL ) + { + // Write the class id to the stream in case it should be checked sometime. + aStream.WriteInt32L( iClassId ); + + // Just insert the user data into the stream + ExternalizeDesL( *iUserData, aStream ); + } + + DLTRACEOUT(("")); + } + + +void CNcdNodeUserData::InternalizeL( RReadStream& aStream ) + { + DLTRACEIN(("")); + + // Read the class id first because it is set to the stream in internalize + // function and it is not read from the stream anywhere else. + TInt classId( aStream.ReadInt32L() ); + if ( classId != ClassId() ) + { + DLTRACE(("Wrong class id")); + DASSERT( EFalse ); + // Leave because the stream does not match this class object + User::Leave( KErrCorrupt ); + } + + // Only the user data is part of the stream + // If the length was set to zero, then this function will set the value + // to KNullDesC8. So, after internalization the iUserData will not be NULL. + InternalizeDesL( iUserData, aStream ); + + DLTRACEOUT(("Data: %S", iUserData)); + + } + + +void CNcdNodeUserData::UserDataRequestL( MCatalogsBaseMessage& aMessage ) + { + DLTRACEIN(("")); + + if ( iUserData == NULL ) + { + TInt trapError( KErrNone ); + + // This function will read data from the database and call + // InternalizeL which sets the data to the user data variable. + TRAP( trapError, + iManager.DbLoadUserDataL( *iIdentifier, + *this ) ); + + if ( trapError == KErrNotFound ) + { + // User data was not found from the db. + // So, set it to KNullDesC8 + iUserData = KNullDesC8().AllocL(); + } + else if ( trapError != KErrNone ) + { + // Only KErrNotFound is allowed error. + // Otherwise leave if error occurred. + User::Leave( trapError ); + } + } + + // iUserData is always up to date because the data is read from the db + // when this object is created. Also, when the data is updated the latest + // info will be set into the iUserData same time when it is updated to the + // db. + + // Send complete information back to proxy. + aMessage.CompleteAndReleaseL( *iUserData, KErrNone ); + + DLTRACEOUT(("")); + } + +void CNcdNodeUserData::SetUserDataRequestL( MCatalogsBaseMessage& aMessage ) + { + DLTRACEIN(("")); + + // Get the session that will contain the user data + MCatalogsSession& requestSession( aMessage.Session() ); + + // Get the user data + HBufC8* data = HBufC8::NewLC( aMessage.InputLength() ); + + // Read data that proxy sent into the created buffer. + TPtr8 dataPtr( data->Des() ); + TInt err = aMessage.ReadInput( dataPtr ); + + User::LeaveIfError( err ); + + DLTRACE(("Replace old information")); + + // Replace old information by the new. + delete iUserData; + iUserData = data; + CleanupStack::Pop( data ); + + // ExternalizeL of this class object will be called + // and the iUserData is saved to the stream there. + iManager.DbSaveUserDataL( *iIdentifier, *this ); + + DLTRACE(("Complete message")); + + // Send complete information back to proxy. + aMessage.CompleteAndRelease( KErrNone ); + + DLTRACEOUT(("")); + } + +void CNcdNodeUserData::ClearUserDataRequestL( MCatalogsBaseMessage& aMessage ) + { + DLTRACEIN(("")); + + // Clear the db data using the manager. + iManager.DbRemoveUserDataL( *iIdentifier ); + + // Also, delete the old info from here and the user data empty. + HBufC8* tmpUserData = KNullDesC8().AllocL(); + delete iUserData; + iUserData = tmpUserData; + + // Send complete information back to proxy. + aMessage.CompleteAndRelease( KErrNone ); + + DLTRACEOUT(("")); + } + +void CNcdNodeUserData::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const + { + DLTRACEIN(("")); + + // Decrease the reference count for this object. + // When the reference count reaches zero, this object will be destroyed + // and removed from the session. + MCatalogsSession& requestSession( aMessage.Session() ); + TInt handle( aMessage.Handle() ); + + // Send complete information back to proxy. + aMessage.CompleteAndRelease( KErrNone ); + + // Remove this object from the session. + requestSession.RemoveObject( handle ); + + DLTRACEOUT(("")); + }