webservices/wsrestplugin/src/senrestservicesession.cpp
changeset 0 62f9d29f7211
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsrestplugin/src/senrestservicesession.cpp	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,419 @@
+/*
+* Copyright (c) 2002-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:           
+*
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+// INCLUDE FILES
+#include "senrestservicesession.h"
+#include "senservicesession.h"
+#include "SenSoapMessage.h"
+#include "senwsdescription.h"
+#include "msencoreservicemanager.h"
+#include "msenremoteserviceconsumer.h"
+#include "SenXmlUtils.h"
+#include "SenDateUtils.h"
+#include "msentransport.h"
+#include "SenServiceConnection.h"
+#include "sendebug.h"
+#include "senlogger.h"
+// #include "SenHttpTransportProperties.h"
+
+CSenRestServiceSession* CSenRestServiceSession::NewL(MSIF& aFramework)
+    {
+    CSenRestServiceSession* pNew =
+        CSenRestServiceSession::NewLC(aFramework);
+    CleanupStack::Pop();
+    return pNew;
+    }
+
+CSenRestServiceSession* CSenRestServiceSession::NewLC(MSIF& aFramework)
+    {
+    CSenRestServiceSession* pNew =
+        new (ELeave) CSenRestServiceSession(ERestServiceSession,
+                                                aFramework);
+    CleanupStack::PushL(pNew);
+    pNew->ConstructL();
+    return pNew;
+    }
+
+CSenRestServiceSession::CSenRestServiceSession(TDescriptionClassType aType, MSIF& aFramework)
+: CSenWebServiceSession(aType, aFramework)
+    {
+    }
+
+void CSenRestServiceSession::ConstructL()
+    {
+    // sets the local name to "ServiceDescription" and
+    // initiates the inner ipElement
+    CSenWebServiceSession::ConstructL();
+    }
+
+CSenRestServiceSession::~CSenRestServiceSession()
+    {
+    }
+
+// Override compute status to make REST sessions to be ALWAYS valid (ready)
+TInt CSenRestServiceSession::ComputeStatusL()
+    {
+    // session is ready, if an endpoint is defined
+    return CSenServiceSession::ComputeStatusL();
+    }
+
+TInt CSenRestServiceSession::SendSoapL( const TDesC8& aSoapMessage, 
+                                        const TDesC8& aTransportProperties,
+                                        MSenRemoteServiceConsumer& aConsumer,
+                                        TInt& aTxnId,
+                                        HBufC8*& /*aRevalidationError*/ ) 
+    {
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenRestServiceSession::SendSoapL");
+    TPtrC8 endpoint = Endpoint();
+#ifdef _SENDEBUG
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"///////////////////////////////////////////////////////");
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KMinLogLevel, _L8("- Endpoint: %S"), &endpoint));
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KMaxLogLevel, _L8("- Request (%d bytes):"), aSoapMessage.Length()));
+    CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,(aSoapMessage));
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"///////////////////////////////////////////////////////");
+#endif
+
+
+
+    TInt retVal( aConsumer.TransportL().SendL( endpoint, 
+                                               aSoapMessage,
+                                               aTransportProperties, 
+                                               *this, 
+                                               aConsumer, 
+                                               aTxnId) );
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KNormalLogLevel, _L8("- Transaction ID: %d"), aTxnId));
+    return retVal;
+    }
+
+TInt CSenRestServiceSession::SubmitSoapL(const TDesC8& aSoapMessage, 
+                                         const TDesC8& aTransportProperties,
+                                         MSenRemoteServiceConsumer& aConsumer,
+                                         HBufC8*& aResponse)
+    {
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenRestServiceSession::SubmitSoapL");
+    TPtrC8 endpoint = Endpoint();
+#ifdef _SENDEBUG
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"///////////////////////////////////////////////////////");
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KMinLogLevel, _L8("- Endpoint: %S"), &endpoint));
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KMaxLogLevel, _L8("- Request (%d bytes):"), aSoapMessage.Length()));
+    CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,(aSoapMessage));
+   	CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"///////////////////////////////////////////////////////");
+#endif
+
+    MSenTransport& transport = aConsumer.TransportL();
+    SetFrameworkPropertiesL(transport);
+    TInt retVal = transport.SubmitL( endpoint,
+                                     aSoapMessage, 
+                                     aTransportProperties, 
+                                     aResponse,
+									 aConsumer);
+    if ( !aResponse )
+        {
+        // response was NULL: probably either out
+        // of heap or some transport malfunction.
+        return retVal;
+        }
+    else if ( aResponse->Length() < KSenSoapEnvelopeName().Length()*2 )
+        {
+        // no use parsing, Envelope -root element not there
+        // deliver non-soap body to consumer
+        return retVal;
+        }
+
+    CleanupStack::PushL(aResponse);
+
+    CSenSoapMessage* pResponseSoapMsg = NULL;
+    TInt leaveCode(KErrNone);
+
+    // attempt to parse the response
+    // here. SOAP faults are to be
+    // searched after,
+
+    TInt parseRetCode(KErrNone);
+    TRAP( leaveCode, (parseRetCode =
+        ParseResponseL(*aResponse, pResponseSoapMsg)) );
+
+    if(leaveCode!=KErrNone)
+        {
+        // THE RESPONSE could not be parsed
+        delete pResponseSoapMsg;
+
+        // THE RESPONSE IS NOT SOAP
+        if(retVal==KErrNone)
+            {
+            // indicate with return value, that response is
+            // invalid - even though submit was ok, the
+            // response could NOT be parsed!
+            retVal = leaveCode;
+            }
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"(NOK) Response is not a SOAP message");
+        }
+    else
+        {
+
+        if (parseRetCode != KErrNone)
+            {
+            CSLOG_FORMAT((aConsumer.ConnectionId()   , KMinLogLevel, _L8("(NOK) Parsing SOAP msg failed (%d)"),
+                    parseRetCode));
+
+            if(retVal==KErrNone) // submit was ok
+                {
+                // indicate with return value, that response is
+                // invalid - even though submit was ok, the
+                // response could NOT be parsed!
+                retVal = parseRetCode;
+                }
+
+            // THE RESPONSE could not be parsed
+            delete pResponseSoapMsg;
+            }
+        else
+            {
+            CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"REST: (OK) Response is a SOAP message");
+            CleanupStack::PushL(pResponseSoapMsg);
+
+            TBool completeServerMessages(ETrue);
+            HasFacetL(KCompleteMessagesFacet, completeServerMessages);
+
+            // response is OK and in SOAP form.
+			if(pResponseSoapMsg)
+			   {
+			   if (pResponseSoapMsg->IsFault())
+                   {
+                	// response is SOAP fault
+                	CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"REST: Response is a SOAP fault.");
+                	retVal = KErrSenSoapFault;
+
+                if (!completeServerMessages)
+                    {
+                    // try to detach the SOAP fault
+                    HBufC8* pDetached = NULL;
+                    CleanupStack::Pop(pResponseSoapMsg);
+                    retVal = CSenWebServiceSession::HandleSoapFaultL(pResponseSoapMsg, pDetached);
+                    if(retVal == KErrSenSoapFault || retVal == KErrNone)
+                        {
+                        // KErrNone means that original fault was handled
+                        // properly and we now have the wanted result 
+                        // and consumer may receive it (message body)
+
+                        // Note: currently we don't handle any SOAP faults
+                        // in WebServiceSession class, so KErrNone should
+                        // not be returned. The OR clause (||) here is 
+                        // only for future extensions.
+                        delete aResponse;
+                        aResponse = NULL;
+                        aResponse = pDetached;
+                        pDetached = NULL;
+                        }
+                    else if(retVal == KErrNotFound)
+                        {
+                        // SOAP fault element  could not be found
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"REST: Major; SOAP fault element not found \
+                                    even though assumed SOAP fault.");
+                        retVal = KErrSenInternal;
+                        }
+                    }
+                else
+                    {
+                    CleanupStack::PopAndDestroy(pResponseSoapMsg);
+                    }
+                }
+            else
+                {
+                // Check complete server messages on/off
+                if (!completeServerMessages)
+                    {
+                    HBufC8* pBody = pResponseSoapMsg->BodyAsStringL();
+                    if(pBody)
+                        {
+                        delete aResponse;
+                        aResponse = NULL;
+                        aResponse = pBody;
+                        pBody = NULL;
+                        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"- Detached SOAP message body.");
+                        }
+                    }
+                CleanupStack::PopAndDestroy(pResponseSoapMsg);
+				}
+              }
+            }
+        }
+
+#ifdef _SENDEBUG
+    if(aResponse)
+        {
+        CleanupStack::PushL(aResponse);
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"--------------------------------------------------");
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"CSenRestServiceSession::SubmitSoapL:");
+        CSLOG_FORMAT((aConsumer.ConnectionId()   , KMaxLogLevel, _L8("- Response (%d bytes):"), 
+            aResponse->Length()));
+        CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,(*aResponse));
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"--------------------------------------------------");
+        CleanupStack::Pop(); // aResponse
+        }
+#endif
+    CleanupStack::Pop(); // aResponse
+    return retVal;
+    }
+
+TInt CSenRestServiceSession::CompleteServerMessagesOnOffL(const TBool& aCompleteOnOff)
+    {
+    // Now REST SIF supports CompleteServerMessagesOnOff
+    return CSenServiceSession::CompleteServerMessagesOnOffL(aCompleteOnOff);
+    }
+
+
+TInt CSenRestServiceSession::SubmitL( const TDesC8& aMessage, 
+                                      const TDesC8& aTransportProperties,
+                                      MSenRemoteServiceConsumer& aConsumer,
+                                      HBufC8*& aResponse )
+    {
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenRestServiceSession::SubmitL(TDesC8&)");
+    TPtrC8 endpoint = Endpoint();
+#ifdef _SENDEBUG
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"///////////////////////////////////////////////////////");
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KMaxLogLevel, _L8("- Endpoint: %S"), &endpoint));
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KMaxLogLevel, _L8("- Request (%d bytes):"), aMessage.Length()));
+    CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,(aMessage));
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"///////////////////////////////////////////////////////");
+#endif
+
+    MSenTransport& transport = aConsumer.TransportL();
+    SetFrameworkPropertiesL( transport );
+    TInt retVal( transport.SubmitL( endpoint, 
+                                    aMessage, 
+                                    aTransportProperties, 
+                                    aResponse,
+									aConsumer) );
+
+#ifdef _SENDEBUG
+    if(aResponse)
+        {
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"---------------------------------------------------");
+        CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenRestServiceSession::SubmitL:");
+        CSLOG_FORMAT((aConsumer.ConnectionId()   , KMaxLogLevel, _L8("- Response (%d bytes):"), aResponse->Length()));
+        CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,( *aResponse ));
+        CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"---------------------------------------------------");
+        }
+#endif
+
+    return retVal;
+    }
+
+
+TInt CSenRestServiceSession::SendL( const TDesC8& aMessage, 
+                                    const TDesC8& aTransportProperties,
+                                    MSenRemoteServiceConsumer& aConsumer,
+                                    TInt& aTxnId,
+                                    HBufC8*& /* aRevalidationError*/ )
+    {
+    // One could call the base class implementation in CSenServiceSession as well...
+    CSLOG_L(aConsumer.ConnectionId()  , KMinLogLevel,"CSenRestServiceSession::SendL");
+    TPtrC8 endpoint = Endpoint();
+#ifdef _SENDEBUG
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"///////////////////////////////////////////////////////");
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KMaxLogLevel, _L8("- Endpoint: %S"), &endpoint));
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KMaxLogLevel, _L8("- Request (%d bytes):"), aMessage.Length()));
+    CSLOG_ALL(aConsumer.ConnectionId()  , KMaxLogLevel,( aMessage ));
+    CSLOG_L(aConsumer.ConnectionId()  , KMaxLogLevel,"///////////////////////////////////////////////////////");
+#endif
+    
+    MSenTransport& transport = aConsumer.TransportL();
+    SetFrameworkPropertiesL(transport);
+
+    TInt retVal ( transport.SendL( endpoint, 
+                                   aMessage,
+                                   aTransportProperties,
+                                   *this, 
+                                   aConsumer, 
+                                   aTxnId) );
+    CSLOG_FORMAT((aConsumer.ConnectionId()   , KNormalLogLevel, _L8("- Transaction id: %d"), aTxnId));
+    return retVal;
+    }
+
+
+
+
+TInt CSenRestServiceSession::SendToConsumerL(HBufC8* apMessage,
+                                             const TInt aTxnId,
+                                             MSenRemoteServiceConsumer& aConsumer,
+                                             MSenProperties* aResponseTransportProperties)
+    {
+    TInt retVal(KErrNone);
+
+    aConsumer.HandleMessageL(apMessage, aTxnId, aResponseTransportProperties);
+
+    return retVal;
+    }
+
+// THIS IS WHAT TRANSPORT SEES:
+TInt CSenRestServiceSession::SendErrorToConsumerL(const TInt aErrorCode,
+                                                  HBufC8* apError,
+                                                  const TInt aTxnId,
+                                                  MSenRemoteServiceConsumer& aConsumer,
+                                                  MSenProperties* aResponseTransportProperties)
+    {
+    TInt retVal(KErrNone);
+
+    retVal = HandleErrorL(aErrorCode, apError, aTxnId, aConsumer, aResponseTransportProperties);
+    return retVal;
+    }
+
+TInt CSenRestServiceSession::HandleErrorL(const TInt aErrorCode,
+                                          HBufC8* apError,
+                                          const TInt aTxnId,
+                                          MSenRemoteServiceConsumer& aConsumer,
+                                          MSenProperties* aResponseTransportProperties)
+    {
+    TInt retVal(KErrNone);
+    // Implementation does not handle non-SOAP errors.
+    retVal = aConsumer.HandleErrorL(apError, aErrorCode, aTxnId, aResponseTransportProperties); 
+    return retVal;
+    }
+
+TBool CSenRestServiceSession::HasSuperClass( TDescriptionClassType aType )
+    {
+    if( aType == MSenServiceDescription::EWebServiceSession ) // direct superclass!
+        {
+        // If asked type is the know *direct* father/mother, return true:
+        return ETrue; 
+        } 
+    else
+        {
+        // Otherwise, ask from superclass (chain, recursively)
+        return CSenWebServiceSession::HasSuperClass( aType ); 
+        }
+    }
+
+// TEMPORARY: remove when "message context"- and "transport factory taking 
+// properties from all layers"- tasks are ready
+TInt CSenRestServiceSession::SetFrameworkPropertiesL(MSenTransport& aTransport)
+    {
+    return iFramework.SetTransportPropertiesL(aTransport);
+    }
+//  End of File