src/soap/HeaderBlock.cpp (673 lines of code) (raw):

/* * Copyright 2003-2004 The Apache Software Foundation. // (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // !!! This include file must be first thing in file !!! #include "../platforms/PlatformAutoSense.hpp" #include <iostream> #include <axis/GDefine.hpp> #include <axis/BasicNode.hpp> #include "HeaderBlock.h" #include "SoapSerializer.h" #include "ComplexElement.h" #include "CharacterElement.h" #include "Namespace.h" #include "../common/AxisTrace.h" AXIS_CPP_NAMESPACE_START extern SoapEnvVersionsStruct gs_SoapEnvVersionsStruct[VERSION_LAST]; HeaderBlock:: HeaderBlock() { logEntryEngine("HeaderBlock::HeaderBlock") iNoOFChildren = 0; m_sPrefix = ""; logExit() } HeaderBlock:: HeaderBlock(const AxisChar *pachLocalName, const AxisChar *pachUri) { logEntryEngine("HeaderBlock::HeaderBlock") iNoOFChildren = 0; m_localname = pachLocalName; m_uri = pachUri; m_sPrefix = ""; logExit() } HeaderBlock:: HeaderBlock(const AxisChar *pachLocalName, const AxisChar *pachUri, const AxisChar *pachPrefix) { logEntryEngine("HeaderBlock::HeaderBlock") iNoOFChildren = 0; m_localname = pachLocalName; m_uri = pachUri; m_sPrefix = pachPrefix; logExit() } HeaderBlock:: HeaderBlock(const HeaderBlock& rCopy): IHeaderBlock(rCopy), iNoOFChildren(rCopy.iNoOFChildren), m_localname(rCopy.m_localname), m_sPrefix(rCopy.m_sPrefix), m_uri(rCopy.m_uri) { logEntryEngine("HeaderBlock::HeaderBlock") list<BasicNode*>::const_iterator itCurrChild= rCopy.m_children.begin(); while(itCurrChild != rCopy.m_children.end()) { this->m_children.push_back( (*itCurrChild)->clone() ); itCurrChild++; } list<Attribute*>::const_iterator itCurrAttribute= rCopy.m_attributes.begin(); while(itCurrAttribute != rCopy.m_attributes.end()) { this->m_attributes.push_back( (*itCurrAttribute)->clone() ); itCurrAttribute++; } /* TO DO: check whether we have to do this * list<Namespace*>::const_iterator itCurrNamespace= rCopy.m_namespaceDecls.begin(); while(itCurrNamespace != rCopy.m_namespaceDecls.end()) { this->m_namespaceDecls.push_back( (*itCurrNamespace)->clone() ); itCurrNamespace++; } */ logExit() } IHeaderBlock* HeaderBlock:: clone() { return new HeaderBlock(*this); } HeaderBlock:: ~HeaderBlock() { logEntryEngine("HeaderBlock::~HeaderBlock") // Clear the Attributes list<Attribute*>::iterator itCurrAttribute= m_attributes.begin(); while(itCurrAttribute != m_attributes.end()) { delete (*itCurrAttribute); itCurrAttribute++; } m_attributes.clear(); // Clear the Namespaces list<Namespace*>::iterator itCurrNamespace= m_namespaceDecls.begin(); while(itCurrNamespace != m_namespaceDecls.end()) { delete (*itCurrNamespace); itCurrNamespace++; } m_namespaceDecls.clear(); // Clear the children list<BasicNode*>::iterator itCurrChild= m_children.begin(); while(itCurrChild != m_children.end()) { delete (*itCurrChild); itCurrChild++; } m_children.clear(); logExit() } int HeaderBlock:: setLocalName(const AxisChar* localname) { logEntryEngine("HeaderBlock::setLocalName") int Status = AXIS_FAIL; if(localname) { m_localname=localname; Status = AXIS_SUCCESS; } logExitWithReturnCode(Status) return Status; } const AxisChar * HeaderBlock:: getLocalName() { return m_localname.c_str(); } int HeaderBlock:: setPrefix(const AxisChar* prefix) { logEntryEngine("HeaderBlock::setPrefix") if(prefix) m_sPrefix= prefix; else m_sPrefix=""; logExitWithReturnCode(AXIS_SUCCESS) return AXIS_SUCCESS; } int HeaderBlock:: setURI(const AxisChar* uri) { logEntryEngine("HeaderBlock::setURI") if(uri) m_uri= uri; else m_uri=""; logExitWithReturnCode(AXIS_SUCCESS) return AXIS_SUCCESS; } int HeaderBlock:: addAttribute(Attribute* pAttr) { logEntryEngine("HeaderBlock::addAttribute") int Status = AXIS_FAIL; if (pAttr) { m_attributes.push_back(pAttr); Status = AXIS_SUCCESS; } logExitWithReturnCode(Status) return Status; } int HeaderBlock:: serialize(SoapSerializer& pSZ) { logEntryEngine("HeaderBlock::serialize") /* *In the code we don't look whether the m_sPrefix is available or * not. Instead directly insert it. The reason is that the SOAP * 1.1 spec says that "All immediate child elements of the SOAP * Header element MUST be namespace-qualified". */ int iStatus= AXIS_SUCCESS; list<AxisChar*> lstTmpNameSpaceStack; bool blnIsNewNamespace = false; bool bResetPrefix = false; do { // TO DO: ReWrite the following logic to deal with name spaces pSZ.serialize("<", NULL); if(m_sPrefix.length() == 0) { m_sPrefix = pSZ.getNamespacePrefix(m_uri.c_str(), blnIsNewNamespace); if (blnIsNewNamespace) lstTmpNameSpaceStack.push_back((AxisChar*)m_uri.c_str()); bResetPrefix = true; } else { // new namespace and will be declared as a namespace declaration. blnIsNewNamespace = true; /* Adding to the Serializer namespace list because the child elements of this HeaderBlock might use this namespace, so that they can get the correct corresponding prefix from the Serializer. */ pSZ.addNamespaceToNamespaceList(m_uri.c_str(), m_sPrefix.c_str()); /* Adding this namespace to the temporary namespace list because we have to remove this namespace from the Serializer at the end of this HeaderBlock serialization. */ lstTmpNameSpaceStack.push_back((AxisChar*)m_uri.c_str()); } pSZ.serialize(m_sPrefix.c_str(), ":", m_localname.c_str(), NULL); if (blnIsNewNamespace) pSZ.serialize(" xmlns:", m_sPrefix.c_str(), "=", PLATFORM_DOUBLE_QUOTE_S, m_uri.c_str(), PLATFORM_DOUBLE_QUOTE_S, NULL); iStatus= attrSerialize(pSZ, lstTmpNameSpaceStack); if(iStatus==AXIS_FAIL) break; iStatus= serializeNamespaceDecl(pSZ, lstTmpNameSpaceStack); if(iStatus==AXIS_FAIL) break; pSZ.serialize(">", NULL); iStatus= serializeChildren(pSZ, lstTmpNameSpaceStack); if(iStatus==AXIS_FAIL) break; pSZ.serialize("</", m_sPrefix.c_str(), ":", m_localname.c_str(), ">", NULL); // Removing the namespace list of this headerblock from the stack. list<AxisChar*>::iterator itCurrentNamespace = lstTmpNameSpaceStack.begin(); while (itCurrentNamespace != lstTmpNameSpaceStack.end()) { pSZ.removeNamespacePrefix(*itCurrentNamespace); itCurrentNamespace++; } } while(0); if (bResetPrefix) m_sPrefix = ""; logExitWithReturnCode(iStatus) return iStatus; } int HeaderBlock:: attrSerialize(SoapSerializer& pSZ, list<AxisChar*>& lstTmpNameSpaceStack) { logEntryEngine("HeaderBlock::attrSerialize") int iStatus= AXIS_SUCCESS; list<Attribute*>::iterator itCurrAttribute= m_attributes.begin(); while(itCurrAttribute != m_attributes.end()) { // See if this prefix matches a namespace within this headerblock const AxisChar *uri = NULL; Attribute *attr = *itCurrAttribute; const AxisChar *attrPrefix = attr->getPrefix(); if (NULL != attrPrefix) { list<Namespace*>::iterator itNs = m_namespaceDecls.begin(); while (itNs != m_namespaceDecls.end()) { if (0 == strcmp((*itNs)->getPrefix(), attrPrefix)) { uri = (*itNs)->getURI(); break; } itNs++; } } iStatus= (*itCurrAttribute)->serialize(pSZ, lstTmpNameSpaceStack, uri); if(iStatus==AXIS_FAIL) { break; } itCurrAttribute++; } logExitWithReturnCode(iStatus) return iStatus; } bool HeaderBlock:: isSerializable() { logEntryEngine("HeaderBlock::isSerializable") bool bStatus= true; if(m_localname.length() == 0) bStatus= false; else { if(m_sPrefix.length() == 0) { if(m_uri.length() != 0) bStatus= false; } else { if(m_uri.length() == 0) bStatus= false; } } logExitWithBoolean(bStatus) return bStatus; } int HeaderBlock:: addChild(BasicNode *pBasicNode) { logEntryEngine("HeaderBlock::addChild") int iStatus = AXIS_FAIL; if (pBasicNode) { m_children.push_back(pBasicNode); iNoOFChildren++; iStatus = AXIS_SUCCESS; } logExitWithReturnCode(iStatus) return iStatus; } int HeaderBlock:: serializeChildren(SoapSerializer& pSZ, list<AxisChar *>& lstTmpNameSpaceStack) { logEntryEngine("HeaderBlock::serializeChildren") int iStatus = AXIS_SUCCESS; // SOAP serialiser does not have an == operator so can't check it list<BasicNode*>::iterator itCurrBasicNode = m_children.begin(); while( itCurrBasicNode != m_children.end() && iStatus == AXIS_SUCCESS) { if ((*itCurrBasicNode)->getNodeType() == ELEMENT_NODE) { // Processing for ELEMENT_NODE types iStatus = (*itCurrBasicNode)->serialize( pSZ, lstTmpNameSpaceStack); } else { // Processing for CHARACTER_NODE types iStatus = (*itCurrBasicNode)->serialize( pSZ); } itCurrBasicNode++; } logExitWithReturnCode(iStatus) return iStatus; } INamespace* HeaderBlock:: createNamespaceDecl( const AxisChar * pPrefix, const AxisChar * pURI) { logEntryEngine("HeaderBlock::createNamespaceDecl") INamespace* returnPtr = NULL; // Check that the prefix and uri are valid pointers and that the string is not empty. if( pPrefix != NULL && strlen( pPrefix) > 0 && pURI != NULL && strlen( pURI) > 0) { // Iterate through the namespaces checking that the prefix does not already exist. bool bNameFound = false; list<Namespace*>::iterator itCurrNamespaceDecl = m_namespaceDecls.begin(); while( itCurrNamespaceDecl != m_namespaceDecls.end() && !bNameFound) { if( !(bNameFound = !strcmp( (*itCurrNamespaceDecl)->getPrefix(), pPrefix))) itCurrNamespaceDecl++; } // If the prefix is found in the declared namespace list, then update the uri // for the prefix and return a pointer to that namespace. // If the prefix was not found, then create a new namespace for the prefix/uri // pair and return the pointer to the new namespace. if( bNameFound) { (*itCurrNamespaceDecl)->setURI( pURI); returnPtr = (INamespace *) *itCurrNamespaceDecl; } else { Namespace * pNamespace = new Namespace( pPrefix, pURI); m_namespaceDecls.push_back( pNamespace); returnPtr = (INamespace *) pNamespace; } } logExitWithPointer(returnPtr) return returnPtr; } int HeaderBlock:: serializeNamespaceDecl(SoapSerializer &pSZ, std::list<AxisChar*>& lstTmpNameSpaceStack) { logEntryEngine("HeaderBlock::serializeNamespaceDecl") list<Namespace*>::iterator itCurrNamespaceDecl= m_namespaceDecls.begin(); while(itCurrNamespaceDecl != m_namespaceDecls.end()) { (*itCurrNamespaceDecl)->serialize(pSZ, lstTmpNameSpaceStack); itCurrNamespaceDecl++; } logExitWithReturnCode(AXIS_SUCCESS) return AXIS_SUCCESS; } BasicNode* HeaderBlock:: getLastChild() { logEntryEngine("HeaderBlock::getLastChild") BasicNode* returnPtr = NULL; list<BasicNode*>::reverse_iterator ritCurrBasicNode= m_children.rbegin(); if (ritCurrBasicNode != m_children.rend()) returnPtr = *ritCurrBasicNode; logExitWithPointer(returnPtr) return returnPtr; } BasicNode* HeaderBlock:: getChild(int iChildPosition) { logEntryEngine("HeaderBlock::getChild") BasicNode* returnPtr = NULL; if ( (iChildPosition<=0) || (iChildPosition > iNoOFChildren) ) returnPtr = NULL; else { list<BasicNode*>::iterator itCurrBasicNode= m_children.begin(); // following is done since the previous line already takes the iterator one step forward iChildPosition--; /* Takes the iterator to the relavent positon */ for (int i=0; i<iChildPosition; i++) { itCurrBasicNode++; } if (itCurrBasicNode != m_children.end()) returnPtr = *itCurrBasicNode; } logExitWithPointer(returnPtr) return returnPtr; } BasicNode* HeaderBlock:: createChild(NODE_TYPE eNODE_TYPE) { logEntryEngine("HeaderBlock::createChild") BasicNode* pBasicNode = NULL; if(eNODE_TYPE==CHARACTER_NODE) pBasicNode = new CharacterElement(); else if (eNODE_TYPE==ELEMENT_NODE) pBasicNode = new ComplexElement(); logExitWithPointer(pBasicNode) return pBasicNode; } bool HeaderBlock:: operator ==( const HeaderBlock &objHeaderBlock) { /* * TODO : the logic */ return true; } BasicNode* HeaderBlock::createImmediateChild(NODE_TYPE eNODE_TYPE) { return createImmediateChild(eNODE_TYPE, "", "", "", ""); } /** * The localname must be specified, but all other input parameters are optional. */ IAttribute* HeaderBlock::createAttribute(const AxisChar *localname, const AxisChar *prefix, const AxisChar *value) { return createAttribute(localname, prefix, NULL, value); } /** * The localname must be specified, but all other input parameters are optional. */ IAttribute* HeaderBlock::createAttribute(const AxisChar * pLocalName, const AxisChar * pPrefix, const AxisChar * pURI, const AxisChar * pValue) { logEntryEngine("HeaderBlock::createAttribute") // Check that the contents of the passed parameters are valid. if( NULL == pLocalName || 0 == strlen( pLocalName)) { logExitWithPointer(NULL) return NULL; } if( !pPrefix) pPrefix = ""; if( !pURI) pURI = ""; if( !pValue) pValue = ""; // Check that the local name and prefix have not already been defined. If // they have, then return NULL indicating that the prefix/localname pair have // already been defined. list<Attribute*>::iterator itCurrAttribute= m_attributes.begin(); while( itCurrAttribute != m_attributes.end()) { if( (strcmp( (*itCurrAttribute)->getLocalName(), pLocalName) == 0) && (strcmp( (*itCurrAttribute)->getPrefix(), pPrefix) == 0)) { logExitWithPointer(NULL) return NULL; } else { itCurrAttribute++; } } // Check that the prefix has not already been defined in the namespace // declarations. If it has, then return NULL indicating that the // prefix/localname pair has already been defined and 'copy down' the // namespace decl into the attribute list as this will help in the // serialisation. list<Namespace*>::iterator itCurrNamespaceDecls = m_namespaceDecls.begin(); while( itCurrNamespaceDecls != m_namespaceDecls.end()) { if( !strcmp( (*itCurrNamespaceDecls)->getPrefix(), pPrefix)) { Attribute * pAttribute = new Attribute( m_attributes, pLocalName, pPrefix, (*itCurrNamespaceDecls)->getURI(), pValue); m_attributes.push_back( pAttribute); logExitWithPointer(pAttribute) return pAttribute; } else { itCurrNamespaceDecls++; } } // If the prefix/localname pair have not previously been defined, then create // and return the attribute. Attribute * pAttribute = new Attribute( m_attributes, pLocalName, pPrefix, pURI, pValue); m_attributes.push_back( pAttribute); logExitWithPointer(pAttribute) return pAttribute; } IAttribute* HeaderBlock:: createStdAttribute(HEADER_BLOCK_STD_ATTR_TYPE eStdAttrType, SOAP_VERSION eSOAP_VERSION) { logEntryEngine("HeaderBlock::createStdAttribute") Attribute* pAttribute = NULL; bool blnStatus = true; do { switch(eSOAP_VERSION) { case VERSION_LAST: blnStatus = false; break; case SOAP_VER_1_1: switch(eStdAttrType) { case ACTOR: pAttribute = new Attribute(m_attributes, "actor", gs_SoapEnvVersionsStruct[SOAP_VER_1_1].pchPrefix, "","http://schemas.xmlsoap.org/soap/actor/next"); break; case MUST_UNDERSTAND_TRUE: pAttribute = new Attribute(m_attributes, "mustUnderstand", gs_SoapEnvVersionsStruct [SOAP_VER_1_1].pchPrefix,"","1"); break; case MUST_UNDERSTAND_FALSE: pAttribute = new Attribute(m_attributes, "mustUnderstand", gs_SoapEnvVersionsStruct [SOAP_VER_1_1].pchPrefix,"","0"); break; default: blnStatus = false; break; } break; case SOAP_VER_1_2: switch(eStdAttrType) { case ROLE_NEXT: pAttribute = new Attribute(m_attributes, "role", gs_SoapEnvVersionsStruct[SOAP_VER_1_2].pchPrefix, "", "http://www.w3.org/2003/05/soap-envelope/role/next"); break; case ROLE_NONE: pAttribute = new Attribute(m_attributes, "role", gs_SoapEnvVersionsStruct[SOAP_VER_1_2].pchPrefix, "", "http://www.w3.org/2003/05/soap-envelope/role/none"); break; case ROLE_ULTIMATE_RECEIVER: pAttribute = new Attribute(m_attributes, "role", gs_SoapEnvVersionsStruct[SOAP_VER_1_2].pchPrefix, "", "http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver"); break; case MUST_UNDERSTAND_TRUE: pAttribute = new Attribute(m_attributes, "mustUnderstand", gs_SoapEnvVersionsStruct[SOAP_VER_1_2].pchPrefix, "","true"); break; case MUST_UNDERSTAND_FALSE: pAttribute = new Attribute(m_attributes, "mustUnderstand", gs_SoapEnvVersionsStruct[SOAP_VER_1_2].pchPrefix, "","false"); break; default: blnStatus = false; break; } break; default: blnStatus = false; break; } } while (0); if (blnStatus) { // got to check for duplicate attributes list<Attribute*>::iterator itAttr = m_attributes.begin(); while (itAttr != m_attributes.end()) { Attribute* pCurrentAttribute = *itAttr; if (!strcmp(pCurrentAttribute->getLocalName(),pAttribute->getLocalName() ) && !strcmp(pCurrentAttribute->getPrefix(), pAttribute->getPrefix() ) ) { // we have the attribute set already, so only change the value pCurrentAttribute->setValue( pAttribute->getValue() ); delete pAttribute; logExitWithPointer(pCurrentAttribute) return pCurrentAttribute; } itAttr++; } // we do not have the attribute set already, hence add it m_attributes.push_back(pAttribute); logExitWithPointer(pAttribute) return pAttribute; } else { logExitWithPointer(NULL) return NULL; } } const AxisChar* HeaderBlock:: getAttributeValue(const AxisChar *localname, const AxisChar *prefix) { logEntryEngine("HeaderBlock::getAttributeValue") const AxisChar* returnValue = NULL; if(!localname) localname=""; if(!prefix) prefix=""; list<Attribute*>::iterator itAttr = m_attributes.begin(); while (itAttr != m_attributes.end()) { Attribute* pAttribute = *itAttr; if (!strcmp(pAttribute->getLocalName(),localname) && !strcmp(pAttribute->getPrefix(),prefix)) { returnValue = pAttribute->getValue(); break; } itAttr++; } logExitWithString(returnValue) return returnValue; } const AxisChar * HeaderBlock:: getAttributeUri( const AxisChar * localname, const AxisChar * prefix) { logEntryEngine("HeaderBlock::getAttributeUri") const AxisChar* returnValue = NULL; list<Attribute*>::iterator itAttr = m_attributes.begin(); while( itAttr != m_attributes.end()) { Attribute * pAttribute = *itAttr; if( !strcmp( pAttribute->getLocalName(),localname) && !strcmp( pAttribute->getPrefix(),prefix)) { returnValue = pAttribute->getURI(); break; } if( strlen( localname) == 0 && !strcmp( pAttribute->getPrefix(), prefix)) { returnValue = pAttribute->getURI(); break; } itAttr++; } logExitWithString(returnValue) return returnValue; } BasicNode* HeaderBlock:: createImmediateChild(NODE_TYPE eNODE_TYPE, AxisChar *pachLocalName, AxisChar *pachPrefix, AxisChar *pachUri, AxisChar* pachValue) { logEntryEngine("HeaderBlock::createImmediateChild") BasicNode* pBasicNode = NULL; if(!pachLocalName) pachLocalName=""; if(!pachPrefix) pachPrefix=""; if(!pachUri) pachUri=""; if(!pachValue) pachValue=""; do { if(eNODE_TYPE==CHARACTER_NODE) pBasicNode = new CharacterElement(pachValue); else if (eNODE_TYPE==ELEMENT_NODE) { if ( (pachLocalName) && (pachUri) ) pBasicNode = new ComplexElement(pachLocalName, pachPrefix, pachUri); else break; } else break; if (pBasicNode) { m_children.push_back(pBasicNode); iNoOFChildren++; } } while (0); logExitWithPointer(pBasicNode) return pBasicNode; } BasicNode* HeaderBlock:: createChild(NODE_TYPE eNODE_TYPE, AxisChar *pachLocalName, AxisChar *pachPrefix, AxisChar *pachUri, AxisChar *pachValue) { logEntryEngine("HeaderBlock::createChild") BasicNode* pBasicNode = NULL; if(!pachLocalName) pachLocalName=""; if(!pachPrefix) pachPrefix=""; if(!pachUri) pachUri=""; if(!pachValue) pachValue=""; do { if(eNODE_TYPE==CHARACTER_NODE) pBasicNode = new CharacterElement(pachValue); else if (eNODE_TYPE==ELEMENT_NODE) pBasicNode = new ComplexElement(pachLocalName, pachPrefix, pachUri); else break; } while (0); logExitWithPointer(pBasicNode) return pBasicNode; } int HeaderBlock::getNoOfChildren() { return iNoOFChildren; } BasicNode* HeaderBlock:: getFirstChild() { logEntryEngine("HeaderBlock::getFirstChild") BasicNode* returnValue = NULL; list<BasicNode*>::iterator itCurrBasicNode= m_children.begin(); if (itCurrBasicNode != m_children.end()) { returnValue = (*itCurrBasicNode); } logExitWithPointer(returnValue) return returnValue; } AXIS_CPP_NAMESPACE_END