diff -r 000000000000 -r 62f9d29f7211 webservices/wsrestplugin/src/senrestplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webservices/wsrestplugin/src/senrestplugin.cpp Thu Jan 07 16:19:19 2010 +0200 @@ -0,0 +1,454 @@ +/* +* 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 "senrestplugin.h" +#include "MSenServiceDescription.h" +#include "SenServiceConnection.h" // framework IDs, error codes.. +#include "msencoreservicemanager.h" +#include "senrestservicesession.h" +#include "sendebug.h" +#include "SenFacet.h" +#include "senlogger.h" + +#include + + +namespace + { + _LIT8(KFrameworkLocalname, "Framework"); +#ifdef _SENDEBUG + const TInt KFLATBUFSIZE = 64; +#endif // _SENDEBUG + _LIT8(KTextWwwFormContentType, "application/x-www-form-urlencoded; charset=UTF-8"); + } + +// Create instance of concrete ECOM interface implementation +CSenRestPlugin* CSenRestPlugin::NewL(TAny* aManager) + { + MSenCoreServiceManager* manager = + reinterpret_cast(aManager); + + CSenRestPlugin* self = new (ELeave) CSenRestPlugin(*manager); + CleanupStack::PushL (self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// Constructor +CSenRestPlugin::CSenRestPlugin(MSenCoreServiceManager& aManager) + : iManager(aManager) + { + } + +CSenRestPlugin::~CSenRestPlugin() + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,(_L("CSenRestPlugin::~CSenRestPlugin()"))); + } + +// Second phase construction. +void CSenRestPlugin::ConstructL() + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,(_L("CSenRestPlugin::ConstructL"))); + + BaseConstructL(KRestFrameworkXMLNS, KFrameworkLocalname); + } + +/*RFileLogger* CSenRestPlugin::Log() const + { + return iManager.Log(); + } +*/ + + +TInt CSenRestPlugin::RegisterServiceDescriptionL(MSenServiceDescription& aServiceDescription) + { + TInt retVal(KErrNone); + +#ifdef _SENDEBUG + TPtrC8 contract = aServiceDescription.Contract(); + TPtrC8 endpoint = aServiceDescription.Endpoint(); + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CSenRestPlugin::RegisterServiceDescriptionL"); + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel," - creating session from description."); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8(" - Endpoint: '%S'"), &endpoint)); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8(" - Contract: '%S'"), &contract)); +#endif + + if( aServiceDescription.Endpoint().Length() == 0 ) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel," - Endpoint is zero-lenght(!), cannot register such SD."); + return KErrSenNoEndpoint; + } + + + // REST sessions are matched by consumer id. + // This way we can avoid session sharing/multiple consumers + + CSenRestServiceSession* pSession = CSenRestServiceSession::NewLC(*this); + retVal = pSession->InitializeFromL(aServiceDescription); + + + if(retVal == KErrNone) + { + // Takes the ownership of this session + retVal = Manager().AddServiceDescriptionL(pSession); + CleanupStack::Pop(pSession); + } + else + { + CleanupStack::PopAndDestroy(pSession); + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CSenRestPlugin::RegisterServiceDescriptionL:"); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("- Session->InitializeFromL failed: %d"), retVal)); + } + return retVal; + } + +TInt CSenRestPlugin::UnregisterServiceDescriptionL(MSenServiceDescription& aServiceDescription ) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CSenRestPlugin::UnregisterServiceDescriptionL"); + TInt retVal(KErrNone); + CSenRestServiceSession *pSession = NULL; + + if(aServiceDescription.DescriptionClassType() == MSenServiceDescription::ERestServiceSession) + { + pSession = (CSenRestServiceSession*) &aServiceDescription; + retVal = Manager().RemoveServiceDescriptionL(*pSession); + } + else + { +#ifdef _SENDEBUG + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"Creating session from description..."); + TPtrC8 con = aServiceDescription.Contract(); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("-contract: '%S'"), &con)); +#endif // _SENDEBUG + + pSession = CSenRestServiceSession::NewLC(*this); + retVal = pSession->InitializeFromL(aServiceDescription); + if (retVal == KErrNone) + { + retVal = Manager().RemoveServiceDescriptionL(*pSession); + } + CleanupStack::PopAndDestroy(pSession); + } + return retVal; + } + + + +const TDesC8& CSenRestPlugin::Id() + { + return KDefaultRestServicesFrameworkID(); // "REST" + } + +TInt CSenRestPlugin::AddServiceDescriptionL( MSenServiceDescription& aPattern, + MSenRemoteServiceConsumer& /* aRemoteConsumer */, + HBufC8*& /* aErrorMsg */ ) + { + + // Currently, accept only SDs, which explicitly declare REST framework ID. + if(aPattern.FrameworkId() != KDefaultRestServicesFrameworkID) + { + return 0; + } + + TPtrC8 endpoint = aPattern.Endpoint(); + if( endpoint.Length() > 0 ) + { + CSenRestServiceSession* pNewSession = + (CSenRestServiceSession*) NewServiceDescriptionL(); + CleanupStack::PushL(pNewSession); + + // InitializeFromL call copies the contract and endpoint, + // and possibly any facets set by Service Management API: + TInt retVal = pNewSession->InitializeFromL( aPattern ); + if( retVal != KErrNone ) + { + CleanupStack::PopAndDestroy(); + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CSenRestPlugin::AddServiceDescriptionL:"); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("- New session->InitializeFromL failed: %d"), retVal)); + return 0; + } + else // init ok + { + // Core / XML DAO takes ownership of new session: + // - if duplicate (equal primary keys) exists, it is deleted + Manager().AddServiceDescriptionL(pNewSession); + CleanupStack::Pop(pNewSession); + return 1; // one new session added + } + } + else + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel," - No endpoint; new session could not be added."); + return 0; // zero added + } + + + + // alternative version: + /* + CSenServiceSession* pNewSession = NULL; + HBufC8* pErrMsg = NULL; + TInt retVal = CreateServiceSessionL(aPattern, aPattern, + pNewSession, aRemoteConsumer, pErrMsg); + delete pErrMsg; + + if(retVal==KErrNone) + { + return 1; // one added; + } + else + { + return 0; // zero added; // no endpoint for REST service session + } + */ + } + +TInt CSenRestPlugin::CreateServiceSessionL( MSenServiceDescription& aServiceDescription, + MSenServiceDescription& /* aPattern */, + CSenServiceSession*& aNewSession, + MSenRemoteServiceConsumer& /* aRemoteConsumer */, + HBufC8*& /* aErrorMsg */ ) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CSenRestPlugin::CreateServiceSessionL"); + CSenRestServiceSession* pNewSession = NULL; + + TInt retVal(KErrNone); + if(aServiceDescription.DescriptionClassType() == MSenServiceDescription::ERestServiceSession) + { + pNewSession = (CSenRestServiceSession*) &aServiceDescription; + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"- Service description is already a REST service session"); + //pNewSession->CopyFacetsFromL(aPattern); // not performed with REST + retVal = KErrNone; + } + else + { + TPtrC8 endpoint = aServiceDescription.Endpoint(); + if( endpoint.Length() > 0 ) + { + pNewSession = (CSenRestServiceSession*) NewServiceDescriptionL(); + CleanupStack::PushL(pNewSession); + + // InitializeFromL call copies the contract and endpoint: + retVal = pNewSession->InitializeFromL(aServiceDescription); + +#ifdef _SENDEBUG + CBufFlat* pBuf = CBufFlat::NewL( KFLATBUFSIZE ); + CleanupStack::PushL(pBuf); + RBufWriteStream writeStream; + writeStream.Open(*pBuf); + CleanupClosePushL(writeStream); + pNewSession->WriteAsXMLToL(writeStream); + TPtr8 ptr = pBuf->Ptr(0); + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"- New REST service session as XML:"); + TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel,( ptr )); + CleanupStack::PopAndDestroy(2); // writeStream.Close(), pBuf +#endif // _SENDEBUG + + if( retVal == KErrNone ) // initialize from pattern OK + { + // NOTE: Core ALWAYS takes ownership of new session: + // - if some session with equal primary keys exists, it is deleted + retVal = Manager().AddServiceDescriptionL(pNewSession); // 2006-07-06: now retVal is taken in use in here(!) + CleanupStack::Pop(pNewSession); +#ifdef _SENDEBUG + if(retVal!=KErrNone) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CSenRestPlugin::CreateServiceSessionL:"); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8(" - CoreServiceMngr::AddServiceDescriptionL returned: %d"), retVal)); + } +#endif + } + else // initialize from pattern failed! + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CSenRestPlugin::CreateServiceSessionL:"); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("- New session->InitializeFromL failed: %d"), retVal)); + CleanupStack::PopAndDestroy(pNewSession); + } + } + else + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel," - No endpoint - ; returning KErrSenNoEndpoint"); + retVal = KErrSenNoEndpoint; // no endpoint for REST web service session + } + } + aNewSession = pNewSession; + return retVal; + } + +TInt CSenRestPlugin::OnEvent(const TInt /* aEvent */, + TAny* /* apArgument */) + { + //LOG_WRITE_L("CSenRestPlugin::OnEvent"); + //LOG_WRITEFORMAT((_L8("-event code: %d"), aEvent)); + TInt retVal(KErrNone); + + return retVal; + } + +TAny* CSenRestPlugin::ExtendedInterface() + { + // There is no extended interface in REST framework at the moment + return NULL; + } + +CSenWSDescription* CSenRestPlugin::NewServiceDescriptionL() + { + CSenRestServiceSession* pSD = + CSenRestServiceSession::NewLC(*this); + pSD->SetFrameworkIdL(KDefaultRestServicesFrameworkID); + CSenFacet* pCompleteOn = CSenFacet::NewL(); + CleanupStack::PushL(pCompleteOn); + pCompleteOn->SetNameL(KCompleteMessagesFacet); + pSD->SetFacetL(*pCompleteOn); + CleanupStack::PopAndDestroy(pCompleteOn); + CleanupStack::Pop(pSD); + return pSD; + } + +/** +* Return the ServiceManager for which this instance is working. +* This is used by the ServiceSession instances created by this framework. +* +* Note, in Sen, MSenCoreServiceManager so all Frameworks +* return their "owner" - i.e. - the only service manager in Sen Framework +* +* @return (MSenCoreServiceManager) +*/ + +MSenCoreServiceManager& CSenRestPlugin::Manager() + { + return iManager; + } + +/** +* Set the ServiceManager to which this instance reports. +* The (singleton) ServiceManager calls this method when +* it instantiates a framework. +* +* @param aServiceManager The singleton ServiceManager in the system. +*/ +void CSenRestPlugin::SetManager(MSenCoreServiceManager& aServiceManager) + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,(_L("CSenRestPlugin::SetManager(.)"))); + iManager = aServiceManager; + } + +/** +* Return an object that can do SAX based parsing of a XML fragment +* that contains framework specific configuration information. +* The ServiceManager asks for this BaseFragment upon startup +* in order to give this framework a chance to read its configuration +* information from the central ServiceManager configuration document. +* +* @return (CSenBaseFragment) +*/ +CSenBaseFragment& CSenRestPlugin::ConfigParser() + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,(_L("CSenRestPlugin::ConfigParser()"))); + return *this; + } + +/** +* Write the ServiceInvocationFramework configuration as XML to a HBufC8. +* +* This method is invoked by the ServiceManager when it saves +* its state and/or configuration. +* +* Upon startup the chunk of XML that is written will be passed back to +* the configuation parser of the framework. +* +* The "schema" that shall be adhered to is: +*
+* <element name="Framework">
+*       <any/><!-- this is where implementations write additional
+*       information -->
+*       <attribute name="class" type="String">
+*    <!-- In Symbian the class attribute is used as cue for
+*    the ECOM Resolver -->
+* </element>
+* 
+* +* @param aTo - a HBufC8 to which the framework should write its configuration +*/ + + +void CSenRestPlugin::EndElementL(const TDesC8& aNsUri, + const TDesC8& aLocalName, + const TDesC8& aQName) + { + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("REST plugin @ end of element: %S (xmlns='%S', localname='%S')"), + &aQName, &aNsUri, &aLocalName)); + CSIF::EndElementL(aNsUri,aLocalName,aQName); + } + +// over-ride CSenBaseFragment +HBufC* CSenRestPlugin::AsXmlUnicodeL() + { + HBufC8* pUtf8 = AsXmlL(); + CleanupStack::PushL(pUtf8); + HBufC* pAsXmlInUnicode = SenXmlUtils::ToUnicodeLC(*pUtf8); + CleanupStack::Pop(pAsXmlInUnicode); + CleanupStack::PopAndDestroy(pUtf8); + return pAsXmlInUnicode; + } + +HBufC8* CSenRestPlugin::AsXmlL() + { + _LIT8(KLessFramework,"\n"); + HBufC8* pAsXml = HBufC8::NewLC(256); + TPtr8 ptr = pAsXml->Des(); + ptr.Append(KLessFramework); + ptr.Append(KXmlns); + ptr.Append(KRestFrameworkXMLNS); + ptr.Append(KQuot); + + ptr.Append(KClassQuot); + ptr.Append(KRestFrameworkCue); + ptr.Append(KQuotNewLine); + CleanupStack::Pop(pAsXml); + return pAsXml; + } + +TInt CSenRestPlugin::SetTransportPropertiesL(MSenTransport& aTransport) + { + // Set default REST transport properties + CSenHttpTransportProperties* pProps = CSenHttpTransportProperties::NewLC(); + pProps->SetContentTypeL(KTextWwwFormContentType); + HBufC8* pPropsAsXml = pProps->AsUtf8L(); + CleanupStack::PopAndDestroy(pProps); + + CleanupStack::PushL( pPropsAsXml ); + TInt retVal = aTransport.SetPropertiesL( *pPropsAsXml, MSenLayeredProperties::ESenFrameworkLayer, NULL ); + CleanupStack::PopAndDestroy( pPropsAsXml ); + return retVal; + } + +// END OF FILE + +