| /* |
| * Copyright 2003-2004 The Apache Software Foundation. |
| * |
| * 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. |
| * |
| * @author Sanjaya Singharage |
| * @author Suasntha Kumara (skumara@virtusa.com, susantha@opensource.lk) |
| * |
| */ |
| |
| // !!! This include file must be first thing in file !!! |
| #include "../platforms/PlatformAutoSense.hpp" |
| |
| #include "WSDDDocument.h" |
| #include "WSDDKeywords.h" |
| #include "../engine/XMLParserFactory.h" |
| |
| #include "../common/AxisTrace.h" |
| |
| #define NAMESPACESEPARATOR 0x03 /* Heart */ |
| #define FILEBUFFSIZE 1024 |
| |
| AXIS_CPP_NAMESPACE_START |
| |
| WSDDDocument:: |
| WSDDDocument(map<AxisString, int>* pLibNameIdMap) |
| { |
| m_lev0 = WSDD_UNKNOWN; |
| m_lev1 = WSDD_UNKNOWN; |
| m_lev2 = WSDD_UNKNOWN; |
| m_CurTrType = APTHTTP1_1; /* default is HTTP */ |
| m_nLibId = 0; |
| m_pLibNameIdMap = pLibNameIdMap; |
| /* Get the maximum Lib Id from the entries in the map if available */ |
| for (map<AxisString, int>::iterator itr = m_pLibNameIdMap->begin(); |
| itr != m_pLibNameIdMap->end(); itr++) |
| { |
| if (m_nLibId < (*itr).second) m_nLibId = (*itr).second; |
| } |
| m_bFatalError = false; |
| m_bError = false; |
| } |
| |
| WSDDDocument:: |
| ~WSDDDocument() |
| { |
| |
| } |
| |
| int WSDDDocument:: |
| getDeployment(const AxisChar* pcWSDDFileName, WSDDDeployment* pDeployment) |
| { |
| m_pDeployment = pDeployment; |
| /* this enables the access to Deployment object while parsing */ |
| if (AXIS_SUCCESS != parseDocument(pcWSDDFileName)) |
| { |
| return AXIS_FAIL; |
| } |
| return AXIS_SUCCESS; |
| } |
| |
| /* This function is never called. */ |
| AXIS_TRANSPORT_STATUS WSDDDocument:: |
| WSDDFileInputStream::sendBytes(const char* pcSendBuffer, const void* pBufferid) |
| { |
| return TRANSPORT_FINISHED; |
| } |
| |
| AXIS_TRANSPORT_STATUS WSDDDocument::WSDDFileInputStream:: |
| getBytes(char* pcBuffer, int* piRetSize) |
| { |
| /* open in binary because on ebcdic platforms the data will get converted */ |
| if (!m_pFile) |
| m_pFile = fopen(m_pcWSDDFileName, "rb"); |
| |
| if (NULL == m_pFile) |
| return TRANSPORT_FAILED; |
| |
| if (feof(m_pFile)) |
| { |
| fclose(m_pFile); |
| pcBuffer[0]=0; /* put null */ |
| *piRetSize = 0; |
| return TRANSPORT_FINISHED; |
| } |
| |
| *piRetSize = fread(pcBuffer, 1, *piRetSize, m_pFile); |
| if (ferror(m_pFile)) |
| { |
| fclose(m_pFile); |
| pcBuffer[0]=0; /* put null */ |
| *piRetSize = 0; |
| return TRANSPORT_FAILED; |
| } |
| |
| return TRANSPORT_IN_PROGRESS; |
| } |
| |
| /* This function is never called. */ |
| AXIS_TRANSPORT_STATUS WSDDDocument:: |
| WSDDMemBufInputStream::sendBytes(const char* pcSendBuffer, const void* pBufferid) |
| { |
| return TRANSPORT_FINISHED; |
| } |
| |
| AXIS_TRANSPORT_STATUS WSDDDocument:: |
| WSDDMemBufInputStream::getBytes(char* pcBuffer, int* piRetSize) |
| { |
| if (!m_pcWSDDMemBuffer) |
| return TRANSPORT_FAILED; |
| |
| int nBufLen = strlen(m_pcWSDDMemBuffer); |
| if (0 == nBufLen) |
| { |
| pcBuffer[0]=0; /* put null */ |
| *piRetSize = 0; |
| return TRANSPORT_FINISHED; |
| } |
| |
| nBufLen = ((*piRetSize - 1) < nBufLen) ? (*piRetSize - 1) : nBufLen; |
| strncpy(pcBuffer, m_pcWSDDMemBuffer, nBufLen); |
| pcBuffer[nBufLen] = 0; |
| m_pcWSDDMemBuffer+=nBufLen; |
| *piRetSize = nBufLen; |
| return TRANSPORT_IN_PROGRESS; |
| } |
| |
| int WSDDDocument:: |
| parseDocument(const AxisChar* pcWSDDFileName) |
| { |
| if (!pcWSDDFileName) |
| return AXIS_FAIL; |
| |
| XMLParser* pParser = XMLParserFactory::getParserObject(); |
| if (!pParser) |
| { |
| return AXIS_FAIL; |
| } |
| |
| WSDDFileInputStream stream(pcWSDDFileName); |
| pParser->setInputStream(&stream); |
| const AnyElement* pNode; |
| |
| while(true) |
| { |
| /* We are lucky as long as there is no useful data as character data |
| * in wsdd. If there are any we are in trouble and we will not be able |
| * to use the same parser which is used to parse SOAP. Now we never |
| * ask for character data events. To support character data in a |
| * wsdd this entire file will have to be re-written in true |
| * XML PULL model |
| */ |
| pNode = pParser->next(); |
| if (AXIS_FAIL == pParser->getStatus()) |
| { |
| XMLParserFactory::destroyParserObject(pParser); |
| return AXIS_FAIL; |
| } |
| if (!pNode) break; |
| |
| switch(pNode->m_type) |
| { |
| case START_ELEMENT: |
| startElement(pNode); |
| break; |
| case CHARACTER_ELEMENT: |
| /* Not used at the moment */ |
| break; |
| case END_ELEMENT: |
| endElement(pNode); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| XMLParserFactory::destroyParserObject(pParser); |
| return AXIS_SUCCESS; |
| } |
| |
| int WSDDDocument:: |
| updateDeployment(const AxisChar* pcWSDDMemBuffer, WSDDDeployment* pDeployment) |
| { |
| m_pDeployment = pDeployment;/* this enables the access to Deployment |
| object while parsing */ |
| if (!pcWSDDMemBuffer) |
| return AXIS_FAIL; |
| |
| WSDDMemBufInputStream stream(pcWSDDMemBuffer); |
| |
| XMLParser* pParser = XMLParserFactory::getParserObject(); |
| if (!pParser) |
| return AXIS_FAIL; |
| |
| pParser->setInputStream(&stream); |
| const AnyElement* pNode; |
| |
| while(true) |
| { |
| /* We are lucky as long as there is no useful data as character data |
| * in wsdd. If there are any we are in trouble and we will not be able |
| * to use the same parser which is used to parse SOAP. Now we never |
| * ask for character data events. To support character data in a |
| * wsdd this entire file will have to be re-written in true |
| * XML PULL model |
| */ |
| pNode = pParser->next(); |
| if (AXIS_FAIL == pParser->getStatus()) |
| return AXIS_FAIL; |
| if (!pNode) |
| break; |
| |
| switch(pNode->m_type) |
| { |
| case START_ELEMENT: |
| startElement(pNode); |
| break; |
| case CHARACTER_ELEMENT: |
| /* Not used at the moment */ |
| break; |
| case END_ELEMENT: |
| endElement(pNode); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| XMLParserFactory::destroyParserObject(pParser); |
| return AXIS_SUCCESS; |
| } |
| |
| void WSDDDocument:: |
| endElement(const AnyElement* pEvent) |
| { |
| /* just neglect endElement of parameter */ |
| if (0 == strcmp(pEvent->m_pchNameOrValue, kw_param)) |
| return; |
| |
| if (m_lev1 == WSDD_UNKNOWN) |
| { |
| /* not inside a requestFlow or responseFlow elements */ |
| |
| switch(m_lev0) |
| { |
| case WSDD_DEPLOYMENT: |
| m_lev0 = WSDD_UNKNOWN; |
| break; |
| case WSDD_GLOBCONF: |
| m_lev0 = WSDD_DEPLOYMENT; |
| break; |
| case WSDD_SERVICE: |
| if (0 == strcmp(pEvent->m_pchNameOrValue, kw_srv)) |
| { |
| /* add service object to Deployment object */ |
| if (DT_DEPLOYMENT == m_pDeployment->getDeploymentType()) |
| m_pDeployment->addService(m_pService); |
| else |
| m_pDeployment->removeService(m_pService); |
| |
| m_pService = NULL; |
| m_lev0 = WSDD_DEPLOYMENT; |
| } |
| |
| break; |
| case WSDD_HANDLER: |
| /* just ignore the handlers defined outside ??? TODO */ |
| delete m_pHandler; |
| m_pHandler = NULL; |
| m_lev0 = WSDD_DEPLOYMENT; |
| break; |
| case WSDD_TRANSPORT: |
| m_CurTrType = APTHTTP1_1; /* default is HTTP */ |
| m_lev0 = WSDD_DEPLOYMENT; |
| break; |
| break; |
| |
| default: |
| ; |
| } |
| } |
| /* inside a requestFlow or responseFlow elements */ |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_hdl)) |
| { |
| m_lev2 = WSDD_UNKNOWN; |
| /* add handler in m_pHandler to the corresponding container. */ |
| switch (m_lev0) |
| { |
| case WSDD_GLOBCONF: |
| { |
| if (DT_DEPLOYMENT == m_pDeployment->getDeploymentType()) |
| m_pDeployment->addHandler(true,(m_lev1 == WSDD_REQFLOW), m_pHandler); |
| else |
| m_pDeployment->removeHandler(true,(m_lev1 == WSDD_REQFLOW), m_pHandler); |
| |
| m_pHandler = NULL; |
| break; |
| } |
| case WSDD_TRANSPORT: |
| { |
| if (DT_DEPLOYMENT == m_pDeployment->getDeploymentType()) |
| m_pDeployment->addHandler(false,(m_lev1 == WSDD_REQFLOW), m_pHandler, m_CurTrType); |
| else |
| m_pDeployment->removeHandler(false,(m_lev1 == WSDD_REQFLOW), m_pHandler, m_CurTrType); |
| |
| m_pHandler = NULL; |
| break; |
| } |
| case WSDD_SERVICE: |
| { |
| if (DT_DEPLOYMENT == m_pDeployment->getDeploymentType()) |
| m_pService->addHandler((m_lev1 == WSDD_REQFLOW), m_pHandler); |
| else |
| m_pService->removeHandler((m_lev1 == WSDD_REQFLOW) , m_pHandler); |
| |
| m_pHandler = NULL; |
| break; |
| } |
| default: ; /* this cannot happen ?? */ |
| } |
| } |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_rqf)) |
| m_lev1 = WSDD_UNKNOWN; |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_rsf)) |
| m_lev1 = WSDD_UNKNOWN; |
| } |
| |
| void WSDDDocument:: |
| processAttributes(WSDDLevels eElementType, const AnyElement* pEvent) |
| { |
| const XML_Ch* pcLocalname; |
| const XML_Ch* pcNamespace; |
| const XML_Ch* pcValue; |
| for (int i=0; pEvent->m_pchAttributes[i]; i+=3) |
| { |
| pcLocalname = pEvent->m_pchAttributes[i]; |
| pcNamespace = pEvent->m_pchAttributes[i+1]; |
| pcValue = pEvent->m_pchAttributes[i+2]; |
| |
| switch(eElementType) |
| { |
| case WSDD_SERVICE: |
| /* add this attribute to current service object */ |
| if (0 == strcmp(pcLocalname, kw_name)) |
| m_pService->setName(pcValue); |
| else if (0 == strcmp(pcLocalname, kw_prv)) |
| m_pService->setProvider(pcValue); |
| else if (0 == strcmp(pcLocalname, kw_desc)) |
| m_pService->setDescription(pcValue); |
| break; |
| case WSDD_HANDLER: |
| /* add this attribute to current handler object */ |
| if (0 == strcmp(pcLocalname, kw_name)) |
| m_pHandler->setName(pcValue); |
| else if (0 == strcmp(pcLocalname, kw_type)) |
| { |
| /* we get the libname for the handler here ??? */ |
| m_pHandler->setLibName(pcValue); |
| |
| /* add to map if libray name not already in the map */ |
| if (m_pLibNameIdMap->find(pcValue) == m_pLibNameIdMap->end()) |
| (*m_pLibNameIdMap)[pcValue] = ++m_nLibId; |
| |
| m_pHandler->setLibId((*m_pLibNameIdMap)[pcValue]); |
| } |
| else if (0 == strcmp(pcLocalname, kw_desc)) |
| m_pHandler->setDescription(pcValue); |
| break; |
| case WSDD_REQFLOW: |
| case WSDD_RESFLOW: |
| if (0 == strcmp(pcLocalname, kw_name)) |
| { |
| /* usefull ? ignore for now .. TODO */ |
| } |
| break; |
| case WSDD_TRANSPORT: |
| if (0 == strcmp(pcLocalname, kw_name)) |
| { |
| /* get tranport type */ |
| if (0 == strcmp(pcValue, kw_http)) |
| m_CurTrType = APTHTTP1_1; |
| else if (0 == strcmp(pcValue, kw_smtp)) |
| m_CurTrType = APTSMTP; |
| } |
| break; |
| default:; |
| } |
| } |
| } |
| |
| void WSDDDocument:: |
| getParameters(WSDDLevels eElementType, const AnyElement* pEvent) |
| { |
| const XML_Ch* pcLocalname; |
| const XML_Ch* pcNamespace; |
| const XML_Ch* pcValue = 0; |
| const XML_Ch* pcType; |
| const XML_Ch* pcName = 0; |
| for (int i=0; pEvent->m_pchAttributes[i]; i+=3) |
| { |
| pcLocalname = pEvent->m_pchAttributes[i]; |
| pcNamespace = pEvent->m_pchAttributes[i+1]; |
| pcValue = pEvent->m_pchAttributes[i+2]; |
| if (0 == strcmp(pcLocalname, kw_name)) |
| pcName = pcValue; |
| else if (0 == strcmp(pcLocalname, kw_type)) |
| pcType = pcValue; |
| } |
| |
| switch(eElementType) |
| { |
| case WSDD_GLOBCONF: /* parameters just inside globalConfiguration */ |
| /* TODO */ |
| break; |
| case WSDD_SERVICE: |
| if (0 == strcmp(pcName, kw_am)) |
| addAllowedMethodsToService(pcValue); |
| else if(0 == strcmp(pcName, kw_cn)) |
| { |
| m_pService->setLibName(pcValue); |
| |
| /* add to map if libray name not already in the map */ |
| if (m_pLibNameIdMap->find(pcValue) == m_pLibNameIdMap->end()) |
| (*m_pLibNameIdMap)[pcValue] = ++m_nLibId; |
| |
| m_pService->setLibId((*m_pLibNameIdMap)[pcValue]); |
| } |
| else if (0 == strcmp(pcName, kw_scope)) |
| m_pService->setScope(pcValue); |
| else if (0 == strcmp(pcName, kw_ar)) |
| addAllowedRolesToService(pcValue); |
| else |
| m_pService->addParameter(pcName, pcValue); |
| break; |
| case WSDD_HANDLER: |
| if (0 == strcmp(pcName, kw_scope)) |
| m_pHandler->setScope(pcValue); |
| else |
| m_pHandler->addParameter(pcName, pcValue); |
| break; |
| |
| default:; |
| } |
| } |
| |
| void WSDDDocument:: |
| addAllowedRolesToService(const AxisXMLCh* pcValue) |
| { |
| AxisString sValue = pcValue; |
| unsigned int prepos = 0, pos = 0; |
| if (sValue.find('*') == AxisString::npos) |
| { |
| do |
| { |
| pos = sValue.find(ROLENAME_SEPARATOR, prepos); |
| if (AxisString::npos == pos) |
| break; |
| m_pService->addAllowedRole(sValue.substr(prepos, pos-prepos).c_str()); |
| prepos = pos + 1; |
| } |
| while (true); |
| } |
| } |
| |
| void WSDDDocument:: |
| addAllowedMethodsToService(const AxisXMLCh* pcValue) |
| { |
| AxisString sValue = pcValue; |
| unsigned int prepos = 0, pos = 0; |
| if (sValue.find('*') == AxisString::npos) |
| { |
| do |
| { |
| pos = sValue.find(METHODNAME_SEPARATOR, prepos); |
| if (AxisString::npos == pos) // Handle the case of no trailing space in AllowedMethods |
| pos = sValue.size(); |
| if (pos <= prepos) |
| break; |
| m_pService->addAllowedMethod(sValue.substr(prepos, pos-prepos).c_str()); |
| prepos = pos + 1; |
| } |
| while (true); |
| } |
| else |
| m_pService->addAllowedMethod("*"); |
| } |
| |
| void WSDDDocument:: |
| startElement(const AnyElement* pEvent) |
| { |
| if (m_lev1 == WSDD_UNKNOWN) |
| /* not inside a requestFlow or responseFlow elements */ |
| { |
| switch(m_lev0) |
| { |
| case WSDD_UNKNOWN: |
| if(0 == strcmp(pEvent->m_pchNameOrValue, kw_depl)) |
| { |
| m_lev0 = WSDD_DEPLOYMENT; |
| m_pDeployment->setDeploymentType(DT_DEPLOYMENT); |
| } |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_undepl)) |
| { |
| m_lev0 = WSDD_DEPLOYMENT; |
| m_pDeployment->setDeploymentType(DT_UNDEPLOYMENT); |
| } |
| break; |
| case WSDD_DEPLOYMENT: |
| if(0 == strcmp(pEvent->m_pchNameOrValue, kw_glconf)) |
| m_lev0 = WSDD_GLOBCONF; |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_srv)) |
| { |
| /* get service name and provider if any */ |
| m_lev0 = WSDD_SERVICE; |
| m_pService = new WSDDService(); |
| processAttributes(WSDD_SERVICE, pEvent); |
| } |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_hdl)) |
| { |
| /* get handler name and type if any */ |
| m_lev0 = WSDD_HANDLER; |
| m_pHandler = new WSDDHandler(); |
| processAttributes(WSDD_HANDLER, pEvent); |
| } |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_tr)) |
| { |
| m_lev0 = WSDD_TRANSPORT; |
| processAttributes(WSDD_TRANSPORT, pEvent); |
| } |
| break; |
| case WSDD_GLOBCONF: |
| if(0 == strcmp(pEvent->m_pchNameOrValue, kw_param)) |
| getParameters(WSDD_GLOBCONF, pEvent); |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_rqf)) |
| { |
| m_lev1 = WSDD_REQFLOW; |
| processAttributes(WSDD_REQFLOW, pEvent); |
| } |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_rsf)) |
| { |
| m_lev1 = WSDD_RESFLOW; |
| processAttributes(WSDD_RESFLOW, pEvent); |
| } |
| break; |
| case WSDD_SERVICE: |
| if(0 == strcmp(pEvent->m_pchNameOrValue, kw_param)) |
| getParameters(WSDD_SERVICE, pEvent); |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_rqf)) |
| { |
| m_lev1 = WSDD_REQFLOW; |
| processAttributes(WSDD_REQFLOW, pEvent); |
| } |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_rsf)) |
| { |
| m_lev1 = WSDD_RESFLOW; |
| processAttributes(WSDD_RESFLOW, pEvent); |
| } |
| break; |
| case WSDD_HANDLER: |
| if(0 == strcmp(pEvent->m_pchNameOrValue, kw_param)) |
| getParameters(WSDD_HANDLER, pEvent); |
| |
| break; |
| case WSDD_TRANSPORT: |
| if(0 == strcmp(pEvent->m_pchNameOrValue, kw_rqf)) |
| { |
| m_lev1 = WSDD_REQFLOW; |
| processAttributes(WSDD_REQFLOW, pEvent); |
| } |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_rsf)) |
| { |
| m_lev1 = WSDD_RESFLOW; |
| processAttributes(WSDD_RESFLOW, pEvent); |
| } |
| break; |
| default:; |
| } |
| } |
| /* inside a requestFlow or responseFlow elements */ |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_param)) |
| { |
| /* must be parameters of a handler or a chain */ |
| getParameters(m_lev2, pEvent); |
| } |
| else if(0 == strcmp(pEvent->m_pchNameOrValue, kw_hdl)) |
| { |
| /* get handler name and type if any */ |
| m_lev2 = WSDD_HANDLER; |
| m_pHandler = new WSDDHandler(); |
| processAttributes(WSDD_HANDLER, pEvent); |
| } |
| } |
| |
| AXIS_CPP_NAMESPACE_END |
| |
| |