webservices/wsutils/src/sensoapenvelope.cpp
changeset 0 62f9d29f7211
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 FILES
       
    26 #include <s32strm.h>
       
    27 
       
    28 #include <SenXmlElement.h>
       
    29 #include <SenXmlUtils.h>
       
    30 #include <SenDomFragment.h>
       
    31 
       
    32 #include "SenSoapEnvelope.h"
       
    33 #include "SenSoapFault.h"
       
    34 #include "senlogger.h"
       
    35 
       
    36 #ifdef _SENDEBUG
       
    37 namespace
       
    38     {
       
    39      _LIT8(KVersionMismatchFormat8,  "Fault.SOAP1.2 : %S");
       
    40     }
       
    41 
       
    42 #endif // _SENDEBUG
       
    43 
       
    44 EXPORT_C CSenSoapEnvelope* CSenSoapEnvelope::NewL()
       
    45     {
       
    46     CSenSoapEnvelope* pNew = new (ELeave) CSenSoapEnvelope();
       
    47     CleanupStack::PushL(pNew);
       
    48     pNew->BaseConstructL();
       
    49     CleanupStack::Pop(); // pNew;
       
    50     return pNew;
       
    51     }
       
    52 
       
    53 EXPORT_C void CSenSoapEnvelope::BaseConstructL(TSOAPVersion aVersion)
       
    54     {
       
    55     if (aVersion != ESOAP12)
       
    56         {
       
    57         CSenBaseFragment::BaseConstructL(KSenSoapEnvelopeXmlns, KSenSoapEnvelopeName, KSenSoapEnvelopeQName);
       
    58         }
       
    59     else
       
    60         {
       
    61         CSenBaseFragment::BaseConstructL(KSenSoap12EnvelopeXmlns, KSenSoapEnvelopeName, KSenSoapEnvelopeQName);
       
    62         }
       
    63     }
       
    64 
       
    65 EXPORT_C void CSenSoapEnvelope::BaseConstructL()
       
    66     {
       
    67     BaseConstructL(ESOAP11);
       
    68     }
       
    69 
       
    70 CSenSoapEnvelope::CSenSoapEnvelope()
       
    71 :   ipBodyFragment(NULL),
       
    72     ipHeaderFragment(NULL),
       
    73     ipSoapAction(NULL),
       
    74     iFault(EFalse)
       
    75     {
       
    76     }
       
    77 
       
    78 EXPORT_C CSenSoapEnvelope::~CSenSoapEnvelope()
       
    79     {
       
    80     if(ipBodyFragment)
       
    81         {
       
    82         ipBodyFragment->ExtractElement();
       
    83         delete ipBodyFragment;
       
    84         }
       
    85     if(ipHeaderFragment)
       
    86         {
       
    87         ipHeaderFragment->ExtractElement(); // // delegate's element is owned by us
       
    88         delete ipHeaderFragment;
       
    89         }
       
    90     delete ipSoapAction;
       
    91     }
       
    92 
       
    93 EXPORT_C void CSenSoapEnvelope::StartElementL(const TDesC8& aNsUri,
       
    94                                               const TDesC8& aLocalName, 
       
    95                                               const TDesC8& aQName,
       
    96                                               const RAttributeArray& aAttributes)
       
    97     {
       
    98     switch (iState)
       
    99         {
       
   100         case KStateIgnore:
       
   101             {
       
   102             // check if we encounter the start of a soap:Envelope...
       
   103             if(!ipElement && aNsUri == NsUri() &&
       
   104                 aLocalName == KSenSoapEnvelopeName)
       
   105                 {
       
   106                 ipElement = CSenXmlElement::NewL(aNsUri, aLocalName, aQName);
       
   107                 }
       
   108             if (ipElement && aLocalName == KSenSoapEnvelopeName && aNsUri!=NsUri())
       
   109                 {
       
   110                 TLSLOG_FORMAT((KSenFaultsLogChannel, KSenFaultsLogLevel, KVersionMismatchFormat8, &KVersionMismatch()));
       
   111                 delete ipElement;
       
   112                 ipElement = NULL;
       
   113                 CSenBaseFragment::BaseConstructL(aNsUri, aLocalName, aQName);
       
   114                 }
       
   115             if(ipElement && ipElement->LocalName() == aLocalName &&
       
   116                             ipElement->NamespaceURI() == aNsUri)
       
   117                 {
       
   118                 if ( ipElement->NsPrefix() != SenXmlUtils::NsPrefix(aQName) )
       
   119                     {
       
   120                     delete ipElement;
       
   121                     ipElement = NULL;
       
   122                     CSenBaseFragment::BaseConstructL(aNsUri, aLocalName, aQName);
       
   123                     }
       
   124                 else
       
   125                     {
       
   126                     ipElement->Set(aNsUri, aLocalName, aQName);
       
   127                     }
       
   128 
       
   129                 SetAttributesL(aAttributes);    // results in
       
   130                 }
       
   131 
       
   132             else if(aNsUri == NsUri())
       
   133                 {
       
   134                 // we are interested in SOAP Header
       
   135                 if(aLocalName == KSenSoapEnvelopeHeaderName)
       
   136                     {
       
   137                     iState = KStateParsingSoapHeader;
       
   138 
       
   139                     // Make sure that header element exists:
       
   140                     // == this ensures that we add a "Header"
       
   141                     // element to the children:
       
   142                     CSenElement& header = HeaderL();
       
   143                     header.Set(aNsUri, aLocalName, aQName);
       
   144                     header.AddAttributesL(aAttributes);
       
   145                     }
       
   146                 else if(aLocalName == KSenSoapEnvelopeBodyName)
       
   147                     {
       
   148                     iState = KStateParsingSoapBody;
       
   149 
       
   150                     CSenElement& body = BodyL();
       
   151                     body.Set(aNsUri, aLocalName, aQName);
       
   152                     body.AddAttributesL(aAttributes);
       
   153                     }
       
   154                 //ESLI-6WEN9V
       
   155                 //This case is to handle fault which lies outside the body or without body
       
   156                 else if(aLocalName == KSenSoapFaultName)
       
   157                     {
       
   158                     iFault = ETrue;
       
   159                     // delegate parsing to a SOAPFaultFragment to keep
       
   160                     // a structured representation.
       
   161                     CSenSoapFault* pSOAPFault =
       
   162                         CSenSoapFault::NewL(aNsUri, aLocalName, aQName, aAttributes);
       
   163                     CleanupStack::PushL(pSOAPFault);
       
   164                     // use DOM fragment copy constructor to get correct type
       
   165                     // of element inside of it.
       
   166                     ipBodyFragment = CSenDomFragment::NewL(*pSOAPFault);
       
   167                     CleanupStack::PopAndDestroy(); // pSOAPFault
       
   168                     ipBodyFragment->SetOwner(*this);
       
   169                     BodyL().AddElementL(ipBodyFragment->AsElement());
       
   170                     ipBodyFragment->ParseWithL(*Reader());
       
   171                     }
       
   172                 //ESLI-6WEN9V
       
   173                 }
       
   174             break;
       
   175             }
       
   176         case KStateParsingSoapHeader:
       
   177             {
       
   178             ParseHeaderL(aNsUri, aLocalName, aQName, aAttributes);
       
   179             }
       
   180             break;
       
   181         case KStateParsingSoapBody:
       
   182             {
       
   183             if(ipBodyFragment)
       
   184                 {
       
   185                 ipBodyFragment->ExtractElement();
       
   186                 delete ipBodyFragment;
       
   187                 ipBodyFragment = NULL;
       
   188                 }
       
   189 
       
   190             // check if we encounter a Fault
       
   191             if (aLocalName == KSenSoapFaultName)
       
   192                 {
       
   193                 iFault = ETrue;
       
   194                 // delegate parsing to a SOAPFaultFragment to keep
       
   195                 // a structured representation.
       
   196                 CSenSoapFault* pSOAPFault =
       
   197                     CSenSoapFault::NewL(aNsUri, aLocalName, aQName, aAttributes);
       
   198                 CleanupStack::PushL(pSOAPFault);
       
   199                 // use DOM fragment copy constructor to get correct type
       
   200                 // of element inside of it.
       
   201                 ipBodyFragment = CSenDomFragment::NewL(*pSOAPFault);
       
   202                 CleanupStack::PopAndDestroy(); // pSOAPFault
       
   203                 ipBodyFragment->SetOwner(*this);
       
   204                 BodyL().AddElementL(ipBodyFragment->AsElement());
       
   205                 ipBodyFragment->ParseWithL(*Reader());
       
   206                 }
       
   207             else
       
   208                 {
       
   209                 ipBodyFragment =
       
   210                     CSenBaseFragment::NewL( aNsUri,
       
   211                                             aLocalName,
       
   212                                             aQName,
       
   213                                             aAttributes);
       
   214 
       
   215                 ipBodyFragment->SetOwner(*this);
       
   216                 BodyL().AddElementL(ipBodyFragment->AsElement());
       
   217                 ipBodyFragment->ParseWithL(*Reader());
       
   218                 }
       
   219             }
       
   220             break;
       
   221         default:
       
   222             break;
       
   223         }
       
   224     }
       
   225 
       
   226 EXPORT_C void CSenSoapEnvelope::EndElementL(const TDesC8& aNsUri, 
       
   227                                             const TDesC8& aLocalName,
       
   228                                             const TDesC8& /*aQName*/)
       
   229     {
       
   230     switch (iState)
       
   231         {
       
   232         case KStateIgnore:
       
   233             {
       
   234             break;
       
   235             }
       
   236         case KStateParsingSoapHeader:
       
   237             {
       
   238             if (aNsUri == NsUri() && aLocalName == KSenSoapEnvelopeHeaderName)
       
   239                 {
       
   240                 iState = KStateIgnore;
       
   241                 }
       
   242             break;
       
   243             }
       
   244         case KStateParsingSoapBody:
       
   245             {
       
   246             if (aNsUri == NsUri() && aLocalName == KSenSoapEnvelopeBodyName)
       
   247                 {
       
   248                 iState = KStateIgnore;
       
   249                 }
       
   250 /*
       
   251               else
       
   252                 {
       
   253                 if(ipBodyFragment)
       
   254                     {
       
   255                     //ipBodyFragment->EnsureNamespacesL();
       
   256                     }
       
   257                 } 
       
   258 */
       
   259             }
       
   260             break;
       
   261         default:
       
   262             break;
       
   263         }
       
   264     }
       
   265 
       
   266 EXPORT_C TPtrC8 CSenSoapEnvelope::SetBodyL(const TDesC8& aBody)
       
   267     {
       
   268     return BodyL().SetContentL(aBody);
       
   269     }
       
   270 
       
   271 EXPORT_C CSenElement& CSenSoapEnvelope::BodyL()
       
   272     {
       
   273     CSenElement& envelope = this->AsElement();
       
   274     CSenElement* pBody = envelope.Element(NsUri(), KSenSoapEnvelopeBodyName);
       
   275     if (pBody == NULL)
       
   276         {
       
   277         pBody = &envelope.AddElementL(NsUri(), KSenSoapEnvelopeBodyName);
       
   278         }
       
   279     return *pBody;
       
   280     }
       
   281 
       
   282 EXPORT_C CSenElement& CSenSoapEnvelope::HeaderL()
       
   283     {
       
   284     CSenElement& envelope = this->AsElement();
       
   285     CSenElement* pHeader = envelope.Element(NsUri(), KSenSoapEnvelopeHeaderName);
       
   286     if (!pHeader)
       
   287         {
       
   288         // add it
       
   289         CSenElement& body = BodyL();
       
   290         pHeader = envelope.CreateElementL(envelope.NsPrefix(), KSenSoapEnvelopeHeaderName);
       
   291         if (pHeader)
       
   292             {
       
   293             envelope.InsertElementL(*pHeader,body);
       
   294             }
       
   295         }
       
   296     return *pHeader; 
       
   297     }
       
   298 
       
   299 EXPORT_C CSenElement& CSenSoapEnvelope::AddHeaderL(CSenElement& aHeaderElement)
       
   300     {
       
   301     return (HeaderL().AddElementL(aHeaderElement));
       
   302     }
       
   303 
       
   304 EXPORT_C void CSenSoapEnvelope::ParseHeaderL(const TDesC8& aNsUri,
       
   305                                              const TDesC8& aLocalName,
       
   306                                              const TDesC8& aQName,
       
   307                                              const RAttributeArray& aAttributes)
       
   308     {
       
   309     if(ipHeaderFragment)
       
   310         {
       
   311         ipHeaderFragment->ExtractElement();
       
   312         delete ipHeaderFragment;
       
   313         ipHeaderFragment = NULL;
       
   314         }
       
   315     ipHeaderFragment = CSenDomFragment::NewL(aNsUri, aLocalName, aQName, aAttributes);
       
   316     ipHeaderFragment->SetOwner(*this); // to ensure we will return to this class' endElement method
       
   317     
       
   318     HeaderL().AddElementL(ipHeaderFragment->AsElement()); // transfers ownership
       
   319     ipHeaderFragment->ParseWithL(*iXmlReader);
       
   320     }
       
   321 
       
   322 
       
   323 EXPORT_C HBufC8* CSenSoapEnvelope::BodyAsStringL()
       
   324     {
       
   325     CSenElement& body = BodyL();
       
   326 
       
   327 
       
   328     HBufC8* bodyAsXML = NULL;
       
   329 
       
   330     // Note, that difference to Jave ref-implementation here is,
       
   331     // that in *EVERY* case, no matter if SOAP BODY has no child 
       
   332     // element at all OR if it has one or more childer, the whole
       
   333     // <S:Body> element is ALWAYS returned -- [never just the only
       
   334     // child, and never a of zero-length string, even if no children]
       
   335     CSenElement* pDetachedElement = body.DetachL();
       
   336     if(pDetachedElement)
       
   337         {
       
   338         CleanupStack::PushL(pDetachedElement);
       
   339         bodyAsXML = pDetachedElement->AsXmlL();
       
   340         CleanupStack::PopAndDestroy(); // pDetachedElement
       
   341         return bodyAsXML;
       
   342         }
       
   343         
       
   344     // Function now returns NULL only if SOAP-ENV does not contain
       
   345     // a body at all(!)
       
   346     return bodyAsXML;
       
   347     }
       
   348 
       
   349 EXPORT_C TBool CSenSoapEnvelope::IsFault()
       
   350     {
       
   351     return iFault;
       
   352     }
       
   353 
       
   354 // NOTE: caller takes ownership of the NEW fault element
       
   355 EXPORT_C CSenSoapFault* CSenSoapEnvelope::DetachFaultL()
       
   356     {
       
   357     CSenElement* pNotOwned = this->BodyL().Element(NsUri(), KSenSoapFaultName);
       
   358     if(pNotOwned)
       
   359         {
       
   360         CSenElement* pDetached = pNotOwned->DetachL();
       
   361         if(pDetached)
       
   362             {
       
   363             CleanupStack::PushL(pDetached);
       
   364             CSenSoapFault* pAnswer = CSenSoapFault::NewL(*pDetached);
       
   365             CleanupStack::PopAndDestroy(); // pDetached
       
   366             return pAnswer;
       
   367             }
       
   368         }
       
   369     return NULL;
       
   370     }
       
   371 
       
   372 
       
   373 EXPORT_C CSenSoapFault* CSenSoapEnvelope::FaultL()
       
   374     {
       
   375     CSenSoapFault* pFault = NULL;
       
   376     if(iFault)
       
   377         {
       
   378         // trust that the element is actually
       
   379         // CSenSoapFault added in StartElementL()
       
   380 
       
   381         pFault = (CSenSoapFault*)this->BodyL().Element(NsUri(), KSenSoapFaultName);
       
   382 
       
   383         }
       
   384     return pFault;
       
   385     }
       
   386 
       
   387 EXPORT_C TPtrC8 CSenSoapEnvelope::SetSoapActionL(const TDesC8& aSoapAction)
       
   388     {
       
   389 
       
   390     _LIT8(KQuote, "\"");
       
   391 
       
   392     HBufC8* pTemp = HBufC8::NewLC(aSoapAction.Length()+(2*KQuote().Length()));  
       
   393 
       
   394     TPtr8 temp = pTemp->Des();
       
   395 
       
   396     if(aSoapAction != KNullDesC8()
       
   397      && !SenXmlUtils::StartsWith(aSoapAction, KQuote))
       
   398         {
       
   399         temp.Append(KQuote);
       
   400         }
       
   401         
       
   402     temp.Append(aSoapAction);
       
   403 
       
   404     if(aSoapAction != KNullDesC8() && !SenXmlUtils::EndsWith(*pTemp, KQuote))
       
   405         {
       
   406         temp.Append(KQuote);
       
   407         }
       
   408 
       
   409     if(ipSoapAction)
       
   410         {
       
   411         delete ipSoapAction;
       
   412         ipSoapAction = NULL;
       
   413         }
       
   414         
       
   415    	ipSoapAction = pTemp;
       
   416     
       
   417     CleanupStack::Pop(); // pTemp is now safe
       
   418     return SoapAction2();
       
   419     }
       
   420 
       
   421 
       
   422 EXPORT_C TPtrC8 CSenSoapEnvelope::SoapAction()
       
   423     {
       
   424     if(ipSoapAction)
       
   425         {
       
   426         return ipSoapAction->Des();
       
   427         }
       
   428     else
       
   429         {
       
   430 		return KSoapActionHeaderValueEmpty();
       
   431         }
       
   432     
       
   433     }
       
   434 
       
   435 
       
   436 EXPORT_C void CSenSoapEnvelope::ParseL(const TDesC8& aXml)
       
   437     {
       
   438     CSenBaseFragment::ParseL(aXml);
       
   439 //    CSenElement& envelope = this->AsElement();
       
   440 
       
   441     /*
       
   442     // SOAP Header is not mandatory:
       
   443     CSenElement* pHeader = envelope.Element(KSenSoapEnvelopeXmlns, KSenSoapEnvelopeHeaderName);
       
   444     if(!pHeader)
       
   445         {
       
   446         User::Leave(KErrSenNoSoapHeader);
       
   447         }
       
   448     */
       
   449 
       
   450     // We could check body, but then this class could not
       
   451     // be used in cases, where header is parsed from file
       
   452     // or some other source, prior setting the body via
       
   453     // SetBody()
       
   454 
       
   455     /*
       
   456     CSenElement* pBody = envelope.Element(KSenSoapEnvelopeXmlns, KSenSoapEnvelopeBodyName);
       
   457     if(!pBody)
       
   458         {
       
   459         User::Leave(KErrSenNoSoapBody);
       
   460         }
       
   461     */
       
   462     }
       
   463 
       
   464 EXPORT_C TBool CSenSoapEnvelope::HasHeader()
       
   465     {
       
   466     CSenElement& envelope = this->AsElement();
       
   467     // True, if element exists, false otherwise:
       
   468     return (envelope.Element(NsUri(), KSenSoapEnvelopeHeaderName) != NULL);
       
   469     }
       
   470 
       
   471 EXPORT_C TBool CSenSoapEnvelope::HasBody()
       
   472     {
       
   473     CSenElement& envelope = this->AsElement();
       
   474     // True, if element exists, false otherwise:
       
   475     return (envelope.Element(NsUri(), KSenSoapEnvelopeBodyName) != NULL);
       
   476     }
       
   477 
       
   478 EXPORT_C TSOAPVersion CSenSoapEnvelope::SoapVersion()
       
   479     {
       
   480     if( NsUri() == KSenSoap12EnvelopeXmlns )
       
   481         {
       
   482         return ESOAP12;
       
   483         }
       
   484     else 
       
   485         {
       
   486         return ESOAP11;
       
   487         }
       
   488     }
       
   489     
       
   490     
       
   491 EXPORT_C TPtrC8 CSenSoapEnvelope::SoapAction2()
       
   492     {
       
   493     if(ipSoapAction)
       
   494         {
       
   495         return ipSoapAction->Des();
       
   496         }
       
   497     else
       
   498         {
       
   499         // Note, that zero-length descriptor must be returned
       
   500         // if SetSoapActionL() has not been called. Otherwise,
       
   501         // when passing transport properties over IPC boundary,
       
   502         // code cannot determine whether the caller, who utilizes
       
   503         // CSenSoapEnvelope wishes to override any underlying
       
   504         // value of SOAPAction with "empty" value (== "").
       
   505         // If SOAPAction is set in CSenSoapEnvelope, it is stronger
       
   506         // than message level (SendL/SubmitL in CSenServiceConnection)
       
   507         // or session level (SetTransportPropertiesL) definitions.
       
   508         return KNullDesC8();
       
   509         }
       
   510         
       
   511     }
       
   512     
       
   513 // End of File