simpleengine/engine/src/simplepublisher.cpp
changeset 0 c8caa15ef882
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/simpleengine/engine/src/simplepublisher.cpp	Tue Feb 02 01:05:17 2010 +0200
@@ -0,0 +1,496 @@
+/*
+* 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:    Simple Engine
+*
+*/
+
+
+
+
+// INCLUDE FILES
+
+#include <e32std.h>
+#include <s32mem.h>
+
+// own simple
+#include "msimpleconnection.h"
+#include "simpleconnection.h"
+#include "simplecommon.h"
+#include "simpleenginerequest.h"
+#include "msimpledocument.h"
+#include "msimplepublishobserver.h"
+#include "msimpleetagobserver.h"
+#include "simplepublisher.h"
+
+
+#include "simplesipconnection.h"
+
+#ifdef _DEBUG
+#include "simpledebugutils.h"
+#endif
+
+const TInt KSimpleExpandSize = 512;
+
+// ================= MEMBER FUNCTIONS =======================
+//
+
+// ----------------------------------------------------------
+// CSimplePublisher::CSimplePublisher
+// ----------------------------------------------------------
+//
+CSimplePublisher::CSimplePublisher(
+    MSimpleConnection& aConn,
+    MSimplePublishObserver& aObserver )
+: CSimpleClient( aConn ),
+  iPublished( EFalse ),
+  iObserver( aObserver ), iBuffer(NULL), iETagObserver( NULL )
+    {
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::~CSimplePublisher
+// ----------------------------------------------------------
+//
+CSimplePublisher::~CSimplePublisher()
+    {
+#ifdef _DEBUG
+    TSimpleLogger::Log(_L("Publisher: Destructor this=%d" ), (TInt)this );
+#endif    
+    delete iBuffer;
+    delete iETag;
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::ConstructL
+// ----------------------------------------------------------
+//
+void CSimplePublisher::ConstructL()
+    {
+    BaseConstructL();
+    iBuffer = CBufFlat::NewL(KSimpleExpandSize);
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::NewL
+// ----------------------------------------------------------
+//
+CSimplePublisher* CSimplePublisher::NewL(
+    MSimpleConnection& aConn,
+    MSimplePublishObserver& aObserver )
+    {
+    CSimplePublisher* self = new (ELeave) CSimplePublisher(
+        aConn, aObserver );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+#ifdef _DEBUG
+    TSimpleLogger::Log(_L("Publisher: NewL this=%d" ), (TInt)self );
+#endif    
+    return self;
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::SIPStatus
+// ----------------------------------------------------------
+//
+TUint CSimplePublisher::SIPStatus()
+    {
+    return DoSIPStatus();
+    }
+    
+// ----------------------------------------------------------
+// CSimplePublisher::SIPRetryAfter
+// ----------------------------------------------------------
+//
+TUint CSimplePublisher::SIPRetryAfter()
+    {
+    return DoRetryAfter();
+    }    
+
+// ----------------------------------------------------------
+// CSimplePublisher::Connection
+// ----------------------------------------------------------
+//
+const MSimpleConnection& CSimplePublisher::Connection()
+    {
+    return iConn;
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::StartPublishL
+// ----------------------------------------------------------
+//
+TInt CSimplePublisher::StartPublishL( MSimpleDocument& aDocument,
+    TBool aRefresh )
+    {
+
+    IncreaseOpId();
+
+#ifdef _DEBUG
+    TSimpleLogger::Log(_L("Publisher: StartPublishL opid=%d" ), iOpId );
+#endif
+
+    if ( iRequest != MSimpleEngineRequest::ENone )
+        {
+        User::Leave( KErrInUse );
+        }
+        
+    return DoStartPublishL( aDocument, aRefresh, KNullDesC8 );        
+    }
+    
+// ----------------------------------------------------------
+// CSimplePublisher::ContinuePublishL
+// ----------------------------------------------------------
+//
+TInt CSimplePublisher::ContinuePublishL( MSimpleDocument& aDocument,
+    TBool aRefresh, const TDesC8& aETag )
+    {
+    
+    IncreaseOpId();
+
+#ifdef _DEBUG
+    TBuf<100> myETag;
+    myETag.Copy( aETag );
+    TSimpleLogger::Log(_L("Publisher: ContinuePublishL opid=%d ETag=%S" ), iOpId, &myETag );
+#endif 
+
+    return DoStartPublishL( aDocument, aRefresh, aETag ); 
+    
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::ModifyPublishL
+// ----------------------------------------------------------
+//
+TInt CSimplePublisher::ModifyPublishL( MSimpleDocument& aDocument )
+    {
+
+#ifdef _DEBUG
+    TSimpleLogger::Log(_L("Publisher: ModifyPublishL opid=%d" ), iOpId );
+#endif
+
+    // use the old opid and request
+    CSimpleEngineRequest* req = SearchRequests( iOpId );
+    if ( !req )
+        {
+        User::Leave( KErrNotFound );
+        }
+    req->ModifyType( MSimpleEngineRequest::EPublishModify );
+
+    // add request data
+    StreamDocumentL( *req, aDocument );
+    
+    // Set MIME type of the request
+    RPointerArray<MSimpleContent> contents;
+    CleanupClosePushL( contents );     
+    aDocument.GetDirectContentsL( contents );
+    if ( contents.Count() )
+        {                                            
+        req->SetRequestContentTypeL( KSimpleMultipartType );
+        }
+    else
+        {
+        req->SetRequestContentTypeL( KSimpleDocumentType );
+        }
+    CleanupStack::PopAndDestroy( &contents );    
+
+    // send a request to engine DLL
+    SendReqL( *req );
+
+    iRequest = MSimpleEngineRequest::EPublishModify;
+    iSipStatus = 0;
+    return iOpId;
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::StopPublishL
+// ----------------------------------------------------------
+//
+TInt CSimplePublisher::StopPublishL()
+    {
+
+#ifdef _DEBUG
+    TSimpleLogger::Log(_L("Publisher: StopPublishL opid=%d" ), iOpId );
+#endif
+
+    // use the old opid and request
+    CSimpleEngineRequest* req = SearchRequests( iOpId );
+    if ( !req )
+        {
+        User::Leave( KErrNotFound );
+        }
+    req->ModifyType( MSimpleEngineRequest::EStopPublish );
+
+    // send a request to engine DLL
+    SendReqL( *req );
+
+    iRequest = MSimpleEngineRequest::EStopPublish;
+    iPublished = EFalse;
+    iSipStatus = 0;
+    return iOpId;
+    }
+    
+// ----------------------------------------------------------
+// CSimplePublisher::StopPublishL
+// ----------------------------------------------------------
+//
+TInt CSimplePublisher::StopPublishL( const TDesC8& aETag )
+    {
+
+#ifdef _DEBUG
+    TBuf<100> myETag;
+    myETag.Copy( aETag );
+    TSimpleLogger::Log(_L("Publisher: StopPublishL opid=%d ETag=%S" ), iOpId, &myETag );
+#endif
+
+    // use the old opid and request
+    CSimpleEngineRequest* req = SearchRequests( iOpId );
+
+    if ( iRequest != MSimpleEngineRequest::ENone && !req )
+        {
+        User::Leave( KErrNotFound );
+        }
+    else if ( !req )
+        {
+        IncreaseOpId();
+        // create a new request when starting from scratch
+        req = CSimpleEngineRequest::NewL(
+            *this, MSimpleEngineRequest::EStopPublish, iOpId );
+        iRequestList.AddLast( *req );              
+        }
+        
+    req->ModifyType( MSimpleEngineRequest::EStopPublish );
+    req->SetETagL( aETag );
+
+    // send a request to engine DLL
+    SendReqL( *req );
+
+    iRequest = MSimpleEngineRequest::EStopPublish;
+    iPublished = EFalse;
+    iSipStatus = 0;
+    return iOpId;
+    }    
+    
+// ----------------------------------------------------------
+// CSimplePublisher::SIPETag
+// ----------------------------------------------------------
+TPtrC8 CSimplePublisher::SIPETag()
+    {
+    return iETag ? iETag->Des() : TPtrC8();
+    }
+    
+// ----------------------------------------------------------
+// CSimplePublisher::SetSIPETagObserver
+// ----------------------------------------------------------
+void CSimplePublisher::SetSIPETagObserver( MSimpleETagObserver* aObs )
+    {
+    iETagObserver = aObs;     
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::Close
+// ----------------------------------------------------------
+//
+void CSimplePublisher::Close( )
+    {
+    delete this;
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::Complete
+// ----------------------------------------------------------
+//
+void CSimplePublisher::Complete(
+    TInt aOpId, TInt aStatus, MSimpleEngineRequest& aReq )
+    {
+#ifdef _DEBUG
+    TSimpleLogger::Log(_L("Publisher: Complete opid=%d, status=%d" ),
+    aOpId, aStatus );
+#endif
+
+    MSimpleEngineRequest::TSimpleRequest origRequest = iRequest;
+    TBool myTerminated( EFalse );
+
+    GetSIPStatus( aOpId );
+    
+    // Allocate ETag when needed and call callback
+    if ( SIPETag().CompareF( aReq.ETag() ))
+        {
+        delete iETag;
+        iETag = NULL;
+        TRAPD( errMem, iETag = aReq.ETag().AllocL() );  
+        if ( iETagObserver && !errMem )
+            {
+            TRAP_IGNORE( iETagObserver->NewETagL( iETag->Des() ));                                  
+            }
+        }
+        
+    if ( aReq.ResponseMethod() == MSimpleEngineRequest:: EStatusETag )
+        {
+        // If only ETag was updated then all is done this time.
+        return;
+        }
+
+    // Reset data buffer
+    iBuffer->Reset();
+
+    // Set the member to point to stack variable
+    TBool   destroyed( EFalse );
+    iDestroyedPtr = &destroyed;
+
+    if ( !aStatus && origRequest == MSimpleEngineRequest::EStartPublish )
+        {
+        iPublished = ETrue;
+        }
+
+    // Select the right callback method
+    if ( iPublished &&
+         origRequest == MSimpleEngineRequest::EStartPublish &&
+         aStatus )
+        {
+#ifdef _DEBUG
+        TSimpleLogger::Log(_L("Publisher: call PublishTerminatedL opid=%d" ), aOpId );
+#endif
+        myTerminated = ETrue;
+        TRAP_IGNORE( iObserver.PublishTerminatedL( aOpId ));
+        // Check whether an application has called destructor in callback method.
+        // Destructor will handle deletion of all the open requests.
+        if ( destroyed )
+            {
+            return;
+            }
+        }
+    else
+        {
+        // If modify fails then it does not always mean the whole
+        // publish is failed.
+#ifdef _DEBUG
+        TSimpleLogger::Log(_L("Publisher: call PublishReqCompleteL opid=%d status=%d" ),
+            aOpId, aStatus );
+#endif
+        TRAP_IGNORE( iObserver.PublishReqCompleteL( aOpId, aStatus ) );
+        // Check whether an application has called destructor in callback method.
+        // Destructor will handle deletion of all the open requests.
+        if ( destroyed )
+            {
+            return;
+            }
+        if ( aStatus == KErrCompletion || aStatus == KErrDisconnected )
+            {
+            myTerminated = ETrue;            
+            // KErrCompletion error code is used when publication is terminated.
+            TRAP_IGNORE( iObserver.PublishTerminatedL( aOpId ) );
+            // Check whether an application has called destructor in callback method.
+            // Destructor will handle deletion of all the open requests.
+            if ( destroyed )
+                {
+                return;
+                }
+            }
+        }
+
+    // Delete a request when not needed anymore.
+    if (( aStatus != KErrNone && origRequest == MSimpleEngineRequest::EStartPublish ) ||
+          origRequest == MSimpleEngineRequest::EStopPublish  ||
+          myTerminated )
+        {
+        iRequest = MSimpleEngineRequest::ENone;
+        iPublished = EFalse;
+
+        // delete corresponding request from another DLL too.
+        aReq.ModifyType( MSimpleEngineRequest::EDestroy );
+        TRAP_IGNORE( SendReqL( aReq ));
+        // delete request from this DLL.
+        aReq.Destroy();
+        }
+
+    // Set iRequest back to EStartPublish after Modify request.
+    // This helps to handle error situations above.
+    else if ( origRequest == MSimpleEngineRequest::EPublishModify )
+        {
+        iRequest = MSimpleEngineRequest::EStartPublish;
+        aReq.ModifyType( MSimpleEngineRequest::EStartPublish );        
+        }
+
+    iDestroyedPtr = NULL; 
+    }
+
+// ----------------------------------------------------------
+// CSimplePublisher::StreamDocumentL
+// ----------------------------------------------------------
+//
+void CSimplePublisher::StreamDocumentL(
+    CSimpleEngineRequest& aReq,
+    MSimpleDocument& aDocument )
+    {            
+    // add request data
+    // externalize the document a stream
+    iBuffer->Reset();
+    RBufWriteStream stream( *iBuffer );
+    stream.Open( *iBuffer );
+    aDocument.ExternalizeL( stream );
+    stream.Close();
+    aReq.SetRequestData( iBuffer->Ptr(0) );
+    }
+    
+// ----------------------------------------------------------
+// CSimplePublisher::DoStartPublishL
+// ----------------------------------------------------------
+//
+TInt CSimplePublisher::DoStartPublishL( MSimpleDocument& aDocument,
+    TBool aRefresh, const TDesC8& aETag )
+    {
+    if ( iRequest != MSimpleEngineRequest::ENone )
+        {
+        User::Leave( KErrInUse );
+        }           
+
+    CSimpleEngineRequest* req = CSimpleEngineRequest::NewL(
+        *this, MSimpleEngineRequest::EStartPublish, iOpId );
+    CleanupStack::PushL( req );
+    req->SetRefresh( aRefresh );
+    // add remote uri
+    const TDesC8* p8 = aDocument.EntityURI();
+    req->SetRemoteURIL( *p8 );
+    // set ETag
+    req->SetETagL( aETag );
+
+    // add request data
+    StreamDocumentL( *req, aDocument );
+    
+    // Set MIME type of the request
+    RPointerArray<MSimpleContent> contents;
+    CleanupClosePushL( contents );     
+    aDocument.GetDirectContentsL( contents );
+    if ( contents.Count() )
+        {                                            
+        req->SetRequestContentTypeL( KSimpleMultipartType );
+        }
+    else
+        {
+        req->SetRequestContentTypeL( KSimpleDocumentType );
+        }
+    CleanupStack::PopAndDestroy( &contents );        
+
+    // send a request to engine DLL
+    SendReqL( *req );
+    iRequestList.AddLast( *req );
+    CleanupStack::Pop( req );
+
+    iRequest = MSimpleEngineRequest::EStartPublish;
+    iSipStatus = 0;
+    return iOpId;
+    }    
+
+