ncdengine/provider/server/src/ncdnodeuserdataimpl.cpp
changeset 0 ba25891c3a9e
--- /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((""));
+    }