webservices/wsrestplugin/src/senrestplugin.cpp
changeset 0 62f9d29f7211
child 1 272b002df977
equal deleted inserted replaced
-1:000000000000 0:62f9d29f7211
       
     1 /*
       
     2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:        
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 #include "senrestplugin.h"
       
    26 #include "MSenServiceDescription.h"
       
    27 #include "SenServiceConnection.h" // framework IDs, error codes..
       
    28 #include "msencoreservicemanager.h"
       
    29 #include "senrestservicesession.h"
       
    30 #include "sendebug.h"
       
    31 #include "SenFacet.h" 
       
    32 #include "senlogger.h" 
       
    33 
       
    34 #include <SenHttpTransportProperties.h>
       
    35 
       
    36 
       
    37 namespace
       
    38     {
       
    39     _LIT8(KFrameworkLocalname,   "Framework");
       
    40 #ifdef _SENDEBUG
       
    41         const TInt KFLATBUFSIZE = 64;
       
    42 #endif // _SENDEBUG
       
    43     _LIT8(KTextWwwFormContentType,  "application/x-www-form-urlencoded; charset=UTF-8");
       
    44     }
       
    45 
       
    46 // Create instance of concrete ECOM interface implementation
       
    47 CSenRestPlugin* CSenRestPlugin::NewL(TAny* aManager)
       
    48     {
       
    49     MSenCoreServiceManager* manager =
       
    50         reinterpret_cast<MSenCoreServiceManager*>(aManager);
       
    51     
       
    52     CSenRestPlugin* self = new (ELeave) CSenRestPlugin(*manager);
       
    53     CleanupStack::PushL (self);
       
    54     self->ConstructL();
       
    55     CleanupStack::Pop();
       
    56     return self;
       
    57     }
       
    58 
       
    59 // Constructor
       
    60 CSenRestPlugin::CSenRestPlugin(MSenCoreServiceManager& aManager)
       
    61     : iManager(aManager)
       
    62     {
       
    63     }
       
    64 
       
    65 CSenRestPlugin::~CSenRestPlugin()
       
    66     {
       
    67     TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenRestPlugin::~CSenRestPlugin()")));
       
    68     }
       
    69 
       
    70 // Second phase construction.
       
    71 void CSenRestPlugin::ConstructL()
       
    72     {
       
    73     TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenRestPlugin::ConstructL")));
       
    74     
       
    75     BaseConstructL(KRestFrameworkXMLNS, KFrameworkLocalname);
       
    76     }
       
    77 
       
    78 /*RFileLogger* CSenRestPlugin::Log() const
       
    79     {
       
    80     return iManager.Log();
       
    81     }
       
    82 */
       
    83 
       
    84 
       
    85 TInt CSenRestPlugin::RegisterServiceDescriptionL(MSenServiceDescription& aServiceDescription)
       
    86     {
       
    87     TInt retVal(KErrNone);
       
    88 
       
    89 #ifdef _SENDEBUG
       
    90     TPtrC8 contract = aServiceDescription.Contract();
       
    91     TPtrC8 endpoint = aServiceDescription.Endpoint();
       
    92     TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenRestPlugin::RegisterServiceDescriptionL");
       
    93     TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel," - creating session from description.");
       
    94     TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8(" - Endpoint: '%S'"), &endpoint));
       
    95     TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8(" - Contract: '%S'"), &contract));
       
    96 #endif
       
    97 
       
    98     if( aServiceDescription.Endpoint().Length() == 0 )
       
    99         {
       
   100         TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel," - Endpoint is zero-lenght(!), cannot register such SD.");
       
   101         return KErrSenNoEndpoint;
       
   102         }
       
   103 
       
   104 
       
   105     // REST sessions are matched by consumer id.
       
   106     // This way we can avoid session sharing/multiple consumers
       
   107      
       
   108     CSenRestServiceSession* pSession = CSenRestServiceSession::NewLC(*this);
       
   109     retVal = pSession->InitializeFromL(aServiceDescription);
       
   110 
       
   111 
       
   112     if(retVal == KErrNone)
       
   113         {
       
   114         // Takes the ownership of this session
       
   115         retVal = Manager().AddServiceDescriptionL(pSession);
       
   116         CleanupStack::Pop(pSession);
       
   117         }
       
   118     else
       
   119         {
       
   120         CleanupStack::PopAndDestroy(pSession);
       
   121         TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenRestPlugin::RegisterServiceDescriptionL:");
       
   122         TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("- Session->InitializeFromL failed: %d"), retVal));
       
   123         }
       
   124     return retVal;
       
   125     }
       
   126 
       
   127 TInt CSenRestPlugin::UnregisterServiceDescriptionL(MSenServiceDescription& aServiceDescription )
       
   128     {
       
   129     TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenRestPlugin::UnregisterServiceDescriptionL");
       
   130     TInt retVal(KErrNone);
       
   131     CSenRestServiceSession *pSession = NULL;
       
   132         
       
   133     if(aServiceDescription.DescriptionClassType() == MSenServiceDescription::ERestServiceSession)
       
   134         {
       
   135         pSession = (CSenRestServiceSession*) &aServiceDescription;
       
   136         retVal = Manager().RemoveServiceDescriptionL(*pSession);
       
   137         }
       
   138      else
       
   139      {
       
   140 #ifdef _SENDEBUG
       
   141             TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"Creating session from description...");
       
   142             TPtrC8 con = aServiceDescription.Contract();
       
   143             TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("-contract: '%S'"), &con));
       
   144 #endif // _SENDEBUG
       
   145 
       
   146             pSession = CSenRestServiceSession::NewLC(*this);
       
   147             retVal = pSession->InitializeFromL(aServiceDescription);
       
   148             if (retVal == KErrNone)
       
   149                 {
       
   150                 retVal = Manager().RemoveServiceDescriptionL(*pSession);
       
   151                 }
       
   152             CleanupStack::PopAndDestroy(pSession);     	
       
   153      }
       
   154     return retVal;
       
   155     }
       
   156     
       
   157 
       
   158 
       
   159 const TDesC8& CSenRestPlugin::Id()
       
   160     {   
       
   161     return KDefaultRestServicesFrameworkID(); // "REST"
       
   162     }
       
   163 
       
   164 TInt CSenRestPlugin::AddServiceDescriptionL( MSenServiceDescription& aPattern,
       
   165                                              MSenRemoteServiceConsumer& /* aRemoteConsumer */,
       
   166                                              HBufC8*& /* aErrorMsg */ )
       
   167     {
       
   168 
       
   169     // Currently, accept only SDs, which explicitly declare REST framework ID.
       
   170     if(aPattern.FrameworkId() != KDefaultRestServicesFrameworkID)
       
   171         {
       
   172         return 0;
       
   173         }
       
   174 
       
   175     TPtrC8 endpoint = aPattern.Endpoint();
       
   176     if( endpoint.Length() > 0 )
       
   177         {
       
   178         CSenRestServiceSession* pNewSession =
       
   179             (CSenRestServiceSession*) NewServiceDescriptionL();
       
   180         CleanupStack::PushL(pNewSession);
       
   181 
       
   182         // InitializeFromL call copies the contract and endpoint, 
       
   183         // and possibly any facets set by Service Management API:
       
   184         TInt retVal = pNewSession->InitializeFromL( aPattern );
       
   185         if( retVal != KErrNone )
       
   186             {
       
   187             CleanupStack::PopAndDestroy();
       
   188             TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenRestPlugin::AddServiceDescriptionL:");
       
   189             TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("- New session->InitializeFromL failed: %d"), retVal));
       
   190             return 0;
       
   191             }
       
   192         else // init ok
       
   193             {
       
   194             // Core / XML DAO takes ownership of new session:
       
   195             // - if duplicate (equal primary keys) exists, it is deleted
       
   196             Manager().AddServiceDescriptionL(pNewSession); 
       
   197             CleanupStack::Pop(pNewSession);
       
   198             return 1; // one new session added
       
   199             }
       
   200         }
       
   201     else
       
   202         {
       
   203         TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel," - No endpoint; new session could not be added.");
       
   204         return 0; // zero added
       
   205         }
       
   206 
       
   207 
       
   208 
       
   209     // alternative version:
       
   210     /*
       
   211     CSenServiceSession* pNewSession = NULL;
       
   212     HBufC8* pErrMsg = NULL;
       
   213     TInt retVal = CreateServiceSessionL(aPattern, aPattern, 
       
   214                       pNewSession, aRemoteConsumer, pErrMsg);
       
   215     delete pErrMsg; 
       
   216 
       
   217     if(retVal==KErrNone)
       
   218         {
       
   219         return 1; // one added;
       
   220         }
       
   221     else
       
   222         {
       
   223         return 0; // zero added;  // no endpoint for REST service session
       
   224         }
       
   225     */
       
   226     }
       
   227 
       
   228 TInt CSenRestPlugin::CreateServiceSessionL( MSenServiceDescription& aServiceDescription,
       
   229                                             MSenServiceDescription& /* aPattern */,
       
   230                                             CSenServiceSession*& aNewSession,
       
   231                                             MSenRemoteServiceConsumer& /* aRemoteConsumer */,
       
   232                                             HBufC8*& /* aErrorMsg */ )
       
   233     {
       
   234     TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenRestPlugin::CreateServiceSessionL");
       
   235     CSenRestServiceSession* pNewSession = NULL;
       
   236 
       
   237     TInt retVal(KErrNone);
       
   238     if(aServiceDescription.DescriptionClassType() == MSenServiceDescription::ERestServiceSession)
       
   239         {
       
   240         pNewSession = (CSenRestServiceSession*) &aServiceDescription;
       
   241         TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"- Service description is already a REST service session");
       
   242         //pNewSession->CopyFacetsFromL(aPattern); // not performed with REST
       
   243         retVal = KErrNone;
       
   244         }
       
   245     else
       
   246         {
       
   247         TPtrC8 endpoint = aServiceDescription.Endpoint();
       
   248         if( endpoint.Length() > 0 )
       
   249             {
       
   250             pNewSession = (CSenRestServiceSession*) NewServiceDescriptionL();
       
   251             CleanupStack::PushL(pNewSession);
       
   252 
       
   253             // InitializeFromL call copies the contract and endpoint:
       
   254             retVal = pNewSession->InitializeFromL(aServiceDescription);
       
   255 
       
   256 #ifdef _SENDEBUG
       
   257             CBufFlat* pBuf = CBufFlat::NewL( KFLATBUFSIZE );
       
   258             CleanupStack::PushL(pBuf);
       
   259             RBufWriteStream writeStream;
       
   260             writeStream.Open(*pBuf);
       
   261             CleanupClosePushL(writeStream);
       
   262             pNewSession->WriteAsXMLToL(writeStream);
       
   263             TPtr8 ptr = pBuf->Ptr(0);
       
   264             TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"- New REST service session as XML:");
       
   265             TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,( ptr ));
       
   266             CleanupStack::PopAndDestroy(2); // writeStream.Close(), pBuf
       
   267 #endif // _SENDEBUG        
       
   268             
       
   269             if( retVal == KErrNone ) // initialize from pattern OK
       
   270                 {
       
   271                 // NOTE: Core ALWAYS takes ownership of new session:
       
   272                 // - if some session with equal primary keys exists, it is deleted
       
   273                 retVal = Manager().AddServiceDescriptionL(pNewSession); // 2006-07-06: now retVal is taken in use in here(!)
       
   274                 CleanupStack::Pop(pNewSession);
       
   275 #ifdef _SENDEBUG
       
   276                 if(retVal!=KErrNone)
       
   277                     {
       
   278                     TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenRestPlugin::CreateServiceSessionL:");
       
   279                     TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8(" - CoreServiceMngr::AddServiceDescriptionL returned: %d"), retVal));
       
   280                     }
       
   281 #endif
       
   282                 }
       
   283             else // initialize from pattern failed!
       
   284                 {
       
   285                 TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenRestPlugin::CreateServiceSessionL:");
       
   286                 TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("- New session->InitializeFromL failed: %d"), retVal));
       
   287                 CleanupStack::PopAndDestroy(pNewSession);
       
   288                 }
       
   289             }
       
   290         else
       
   291             {
       
   292             TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel," - No endpoint - ; returning KErrSenNoEndpoint");
       
   293             retVal = KErrSenNoEndpoint; // no endpoint for REST web service session
       
   294             }
       
   295         }
       
   296     aNewSession = pNewSession; 
       
   297     return retVal;
       
   298     }
       
   299 
       
   300 TInt CSenRestPlugin::OnEvent(const TInt /* aEvent */,
       
   301                             TAny* /* apArgument */)
       
   302     {
       
   303     //LOG_WRITE_L("CSenRestPlugin::OnEvent");
       
   304     //LOG_WRITEFORMAT((_L8("-event code: %d"), aEvent));
       
   305     TInt retVal(KErrNone);
       
   306 
       
   307     return retVal;
       
   308     }
       
   309 
       
   310 TAny* CSenRestPlugin::ExtendedInterface()
       
   311     {
       
   312     // There is no extended interface in REST framework at the moment
       
   313     return NULL;
       
   314     }
       
   315 
       
   316 CSenWSDescription* CSenRestPlugin::NewServiceDescriptionL()
       
   317     {
       
   318     CSenRestServiceSession* pSD =
       
   319         CSenRestServiceSession::NewLC(*this);
       
   320     pSD->SetFrameworkIdL(KDefaultRestServicesFrameworkID);
       
   321     CSenFacet* pCompleteOn = CSenFacet::NewL();
       
   322     CleanupStack::PushL(pCompleteOn);
       
   323     pCompleteOn->SetNameL(KCompleteMessagesFacet);
       
   324     pSD->SetFacetL(*pCompleteOn);
       
   325     CleanupStack::PopAndDestroy(pCompleteOn);
       
   326     CleanupStack::Pop(pSD);
       
   327     return pSD;
       
   328     }
       
   329 
       
   330 /**
       
   331 * Return the ServiceManager for which this instance is working.
       
   332 * This is used by the ServiceSession instances created by this framework.
       
   333 *
       
   334 * Note, in Sen, MSenCoreServiceManager so all Frameworks
       
   335 * return their "owner" - i.e. - the only service manager in Sen Framework
       
   336 *
       
   337 * @return (MSenCoreServiceManager)
       
   338 */
       
   339 
       
   340 MSenCoreServiceManager& CSenRestPlugin::Manager()
       
   341     {
       
   342     return iManager;  
       
   343     }
       
   344 
       
   345 /**
       
   346 * Set the ServiceManager to which this instance reports.
       
   347 * The (singleton) ServiceManager calls this method when
       
   348 * it instantiates a framework.
       
   349 *
       
   350 * @param aServiceManager The singleton ServiceManager in the system.
       
   351 */
       
   352 void CSenRestPlugin::SetManager(MSenCoreServiceManager& aServiceManager)
       
   353     {
       
   354     TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenRestPlugin::SetManager(.)")));
       
   355     iManager = aServiceManager;
       
   356     }
       
   357 
       
   358 /**
       
   359 * Return an object that can do SAX based parsing of a XML fragment
       
   360 * that contains framework specific configuration information.
       
   361 * The ServiceManager asks for this BaseFragment upon startup
       
   362 * in order to give this framework a chance to read its configuration
       
   363 * information from the central ServiceManager configuration document.
       
   364 *
       
   365 * @return (CSenBaseFragment)
       
   366 */
       
   367 CSenBaseFragment& CSenRestPlugin::ConfigParser()
       
   368     {
       
   369     TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenRestPlugin::ConfigParser()")));
       
   370     return *this;
       
   371     }
       
   372 
       
   373 /**
       
   374 * Write the ServiceInvocationFramework configuration as XML to a HBufC8.
       
   375 *
       
   376 * This method is invoked by the ServiceManager when it saves
       
   377 * its state and/or configuration.
       
   378 *
       
   379 * Upon startup the chunk of XML that is written will be passed back to
       
   380 * the configuation parser of the framework.
       
   381 *
       
   382 * The "schema" that shall be adhered to is:
       
   383 * <pre>
       
   384 * &lt;element name="Framework"&gt;
       
   385 *       &lt;any/&gt;&lt;!-- this is where implementations write additional
       
   386 *       information --&gt;
       
   387 *       &lt;attribute name="class" type="String"&gt;
       
   388 *    &lt;!-- In Symbian the class attribute is used as cue for
       
   389 *    the ECOM Resolver --&gt;
       
   390 * &lt;/element&gt;
       
   391 * </pre>
       
   392 *
       
   393 * @param aTo - a HBufC8 to which the framework should write its configuration
       
   394 */
       
   395 
       
   396 
       
   397 void CSenRestPlugin::EndElementL(const TDesC8& aNsUri,
       
   398                                 const TDesC8& aLocalName,
       
   399                                 const TDesC8& aQName)
       
   400     {
       
   401     TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("REST plugin @ end of element: %S (xmlns='%S', localname='%S')"),
       
   402         &aQName, &aNsUri, &aLocalName));
       
   403     CSIF::EndElementL(aNsUri,aLocalName,aQName);
       
   404     }
       
   405 
       
   406 // over-ride CSenBaseFragment
       
   407 HBufC* CSenRestPlugin::AsXmlUnicodeL()
       
   408     {
       
   409     HBufC8* pUtf8 = AsXmlL();
       
   410     CleanupStack::PushL(pUtf8);
       
   411     HBufC* pAsXmlInUnicode = SenXmlUtils::ToUnicodeLC(*pUtf8);
       
   412     CleanupStack::Pop(pAsXmlInUnicode);
       
   413     CleanupStack::PopAndDestroy(pUtf8);
       
   414     return pAsXmlInUnicode;
       
   415     }
       
   416 
       
   417 HBufC8* CSenRestPlugin::AsXmlL()
       
   418     {
       
   419     _LIT8(KLessFramework,"<Framework ");//CodeScannerWarning
       
   420     _LIT8(KXmlns,"xmlns=\"");
       
   421     _LIT8(KQuot,"\" ");
       
   422     _LIT8(KClassQuot,"class=\"");
       
   423     _LIT8(KQuotNewLine,"\"/>\n");
       
   424     HBufC8* pAsXml = HBufC8::NewLC(256);
       
   425     TPtr8 ptr = pAsXml->Des();
       
   426     ptr.Append(KLessFramework);
       
   427     ptr.Append(KXmlns);
       
   428     ptr.Append(KRestFrameworkXMLNS);
       
   429     ptr.Append(KQuot);
       
   430     
       
   431     ptr.Append(KClassQuot);
       
   432     ptr.Append(KRestFrameworkCue);
       
   433     ptr.Append(KQuotNewLine);
       
   434     CleanupStack::Pop(pAsXml);
       
   435     return pAsXml;
       
   436     }
       
   437 
       
   438 TInt CSenRestPlugin::SetTransportPropertiesL(MSenTransport& aTransport)
       
   439     {
       
   440     // Set default REST transport properties
       
   441     CSenHttpTransportProperties* pProps = CSenHttpTransportProperties::NewLC();
       
   442     pProps->SetContentTypeL(KTextWwwFormContentType);
       
   443     HBufC8* pPropsAsXml = pProps->AsUtf8L();
       
   444     CleanupStack::PopAndDestroy(pProps);
       
   445 
       
   446     CleanupStack::PushL( pPropsAsXml );
       
   447     TInt retVal = aTransport.SetPropertiesL( *pPropsAsXml, MSenLayeredProperties::ESenFrameworkLayer, NULL );
       
   448     CleanupStack::PopAndDestroy( pPropsAsXml );
       
   449     return retVal;    
       
   450     }
       
   451     
       
   452 // END OF FILE
       
   453 
       
   454