diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-23 05:48:11 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-23 05:48:11 +0000 |
commit | 1c2df9a2458897ff6c2393913b2723457e42a0da (patch) | |
tree | 69652a0305830b4472f39c55ad1168522d8301f1 /sca-cpp/trunk/contrib/runtime/core/src/tuscany/sca/model/WSDLDefinition.cpp | |
parent | e5d978186780787e8dad6681cca139486df93643 (diff) |
Simplified the automake build using configure options instead of environment variables and cleaned up some of the makefile.am files. Adjusted build instructions. Moved directories that don't yet build or work out of the main build dir and obsolete docs to a contrib dir.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@883254 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp/trunk/contrib/runtime/core/src/tuscany/sca/model/WSDLDefinition.cpp')
-rw-r--r-- | sca-cpp/trunk/contrib/runtime/core/src/tuscany/sca/model/WSDLDefinition.cpp | 633 |
1 files changed, 633 insertions, 0 deletions
diff --git a/sca-cpp/trunk/contrib/runtime/core/src/tuscany/sca/model/WSDLDefinition.cpp b/sca-cpp/trunk/contrib/runtime/core/src/tuscany/sca/model/WSDLDefinition.cpp new file mode 100644 index 0000000000..53971b5a17 --- /dev/null +++ b/sca-cpp/trunk/contrib/runtime/core/src/tuscany/sca/model/WSDLDefinition.cpp @@ -0,0 +1,633 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +/* $Rev$ $Date$ */ + +#include <sstream> +#include <set> + +#include "tuscany/sca/model/WSDLDefinition.h" +#include "tuscany/sca/model/WSDLOperation.h" +#include "tuscany/sca/util/Logging.h" +#include "tuscany/sca/util/Utils.h" +#include "tuscany/sca/core/Exceptions.h" + +using namespace std; +using namespace commonj::sdo; +using namespace tuscany::sca::util; + +namespace tuscany +{ + namespace sca + { + namespace model + { + + // Constructor + WSDLDefinition::WSDLDefinition(DataObjectPtr wsdlModel) + { + logentry(); + + wsdlModels.insert(wsdlModels.end(), wsdlModel); + mapOperations( wsdlModel ); + } + + WSDLDefinition::~WSDLDefinition() + { + logentry(); + } + + /// + /// The namespace of the service and other definitions defined in this wsdl definition + string WSDLDefinition::getNamespace() + { + logentry(); + return wsdlModels[0]->getCString("targetNamespace"); + } + + void WSDLDefinition::addWSDLModel(DataObjectPtr wsdlModel) + { + logentry(); + wsdlModels.insert(wsdlModels.end(), wsdlModel); + mapOperations( wsdlModel ); + } + + /// + /// Find the operation defined in this wsdl + /// + const WSDLOperation& WSDLDefinition::findOperation(const string& serviceName, + const string& portName, + const string& operationName) + { + logentry(); + + string operationKey = serviceName+"#"+portName; + STR_OPERATION_MAP::const_iterator spIter = servicePortMap.find(operationKey); + if( spIter == servicePortMap.end() ) + { + stringstream errMessage; + errMessage + << "Unable to find Service and Port: \"" + << serviceName << "," << portName + << "\" in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + + OPERATION_MAP::const_iterator opIter = spIter->second.find(operationName); + + if (opIter != spIter->second.end()) + { + return opIter->second; + } + else + { + stringstream errMessage; + errMessage + << "Unable to find operation \"" + << serviceName << ":" << portName << ":" << operationName + << "\" in the WSDL definition"; + + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + } + + /// + /// Find the operation defined in this wsdl + /// + const WSDLOperation& WSDLDefinition::findOperation(const string& portTypeName, + const string& operationName) + { + logentry(); + + STR_OPERATION_MAP::const_iterator ptIter = portTypeMap.find(portTypeName); + if( ptIter == portTypeMap.end() ) + { + stringstream errMessage; + errMessage + << "Unable to find PortType: \"" + << portTypeName + << "\" in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + + OPERATION_MAP::const_iterator opIter = ptIter->second.find(operationName); + + if (opIter != ptIter->second.end()) + { + return opIter->second; + } + else + { + stringstream errMessage; + errMessage + << "Unable to find Operation \"" + << portTypeName << ":" << operationName + << "\" in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + } + + std::list<std::string> WSDLDefinition::getPortTypes() + { + logentry(); + + std::list<std::string> ptList; + STR_OPERATION_MAP::const_iterator ptIter = portTypeMap.begin(); + STR_OPERATION_MAP::const_iterator ptIterEnd = portTypeMap.end(); + + for( ; ptIter != ptIterEnd; ++ptIter ) + { + ptList.push_back( ptIter->first ); + } + + return ptList; + } + + std::list<std::string> WSDLDefinition::getOperations( const std::string &portTypeName ) + { + logentry(); + + std::list<std::string> ptOpList; + STR_OPERATION_MAP::const_iterator ptIter = portTypeMap.find( portTypeName ); + + if( ptIter == portTypeMap.end() ) + { + stringstream errMessage; + errMessage + << "Unable to find PortType: \"" + << portTypeName + << "\" in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + + OPERATION_MAP::const_iterator opIter = ptIter->second.begin(); + OPERATION_MAP::const_iterator opIterEnd = ptIter->second.end(); + + for( ; opIter != opIterEnd; ++opIter ) + { + ptOpList.push_back( opIter->first ); + } + + return ptOpList; + } + + /// + /// Find a service + /// + DataObjectPtr WSDLDefinition::findService(const string& serviceName) + { + logentry(); + + DataObjectPtr service = 0; + + // Find the binding + for (unsigned int m = 0; m < wsdlModels.size(); m++) + { + DataObjectList& serviceList = wsdlModels[m]->getList("service"); + for (unsigned int i=0; i<serviceList.size(); i++) + { + string name(serviceList[i]->getCString("name")); + + if (name.compare(serviceName) == 0) + { + return serviceList[i]; + } + } + } + + return service; + } + + + /// + /// Find a named binding + /// + DataObjectPtr WSDLDefinition::findBinding(const string& bindingName) + { + logentry(); + + DataObjectPtr binding = 0; + string uri; + string name; + + Utils::rTokeniseString("#", bindingName, uri, name); + + // Find the binding + for (unsigned int m = 0; m < wsdlModels.size(); m++) + { + DataObjectList& bindingList = wsdlModels[m]->getList("binding"); + for (unsigned int i=0; i<bindingList.size(); i++) + { + string nameBinding(bindingList[i]->getCString("name")); + + if (nameBinding.compare(name) == 0) + { + return bindingList[i]; + } + } + } + + return binding; + } + + /// + /// Find a named portType + /// + DataObjectPtr WSDLDefinition::findPortType(const string& portTypeName) + { + logentry(); + + DataObjectPtr portType = 0; + string uri; + string name; + + Utils::rTokeniseString("#", portTypeName, uri, name); + + // Find the binding + for (unsigned int m = 0; m < wsdlModels.size(); m++) + { + DataObjectList& portTypeList = wsdlModels[m]->getList("portType"); + for (unsigned int i=0; i<portTypeList.size(); i++) + { + string namePortType(portTypeList[i]->getCString("name")); + + if (namePortType.compare(name) == 0) + { + return portTypeList[i]; + } + } + } + + return portType; + } + + /// + /// Find a named message + /// + DataObjectPtr WSDLDefinition::findMessage(const string& messageName) + { + logentry(); + + DataObjectPtr message = 0; + string uri; + string name; + + Utils::rTokeniseString("#", messageName, uri, name); + + // Find the binding + for (unsigned int m = 0; m < wsdlModels.size(); m++) + { + DataObjectList& messageList = wsdlModels[m]->getList("message"); + for (unsigned int i=0; i<messageList.size(); i++) + { + string nameMessage(messageList[i]->getCString("name")); + + if (nameMessage.compare(name) == 0) + { + return messageList[i]; + } + } + } + + return message; + } + + /// + /// Traverse the WSDL SDO and insert operations into the operationMap + /// + void WSDLDefinition::mapOperations( DataObjectPtr wsdlModel ) + { + logentry(); + + // check for duplicate message/binding/PortType/Service + // with equal name attributes. This cant be enforced by + // the schema, so it has to be enforced at the app level + checkForDuplicates( wsdlModel ); + + DataObjectList& serviceList = wsdlModel->getList("service"); + + // Iterate through the WSDL services + for (unsigned int i=0; i < serviceList.size(); i++) + { + string serviceName( serviceList[i]->getCString("name") ); + + // Iterate through the WSDL service ports + DataObjectList& portList = serviceList[i]->getList("port"); + for (unsigned int j=0; j < portList.size();j++) + { + string portName( portList[j]->getCString("name") ); + string wsBindingName(portList[j]->getCString("binding")); + + // There can only be one soap address and the check must be made + // at the application level since it cant be specified in the xsd +/* + DataObjectList& soapAddressList = portList[j]->getList("address"); + if( soapAddressList.size() != 1 ) + { + // Invalid WSDL + stringstream errMessage; + errMessage + << "service/port/address: \"" + << portName + << "\" cannot be duplicated in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } +*/ + + string targetAddress(portList[j]->getCString("address/location")); + + // get the binding specified in the WSDL service port + DataObjectPtr wsBinding = findBinding(wsBindingName); + if (!wsBinding) + { + // Invalid WSDL + stringstream errMessage; + errMessage + << "Unable to find binding \"" + << wsBindingName + << "\" in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + + // Check if its a SOAP binding, if not go on to the next binding + // doing a find like this will work for SOAP11 and SOAP12 + DataObjectPtr wsBindingSubBinding = wsBinding->getDataObject("binding"); + string bindingURI(wsBindingSubBinding->getType().getURI()); + if (bindingURI.find("http://schemas.xmlsoap.org/wsdl/soap") == string::npos) + { + loginfo("Discarding non-SOAP Binding %s", wsBindingName.c_str() ); + continue; + } + + // Get the port type specified the WSDL binding + string wsBindingPortTypeName(wsBinding->getCString("type")); + DataObjectPtr portType = findPortType(wsBindingPortTypeName); + if (!portType) + { + // Invalid WSDL + stringstream errMessage; + errMessage + << "Unable to find PortType \"" + << wsBindingPortTypeName + << "\" in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + string portTypeName( portType->getCString("name") ); + + // Fill in this map with operation names to WSDLOperations + // then after iterating through the operations, add the map + // to the portTypeMap, keyed off of the portTypeName + OPERATION_MAP operationMap; + + // For each binding and portType operation: + // - get the soap action, style, and use from the binding + // - get the input and/or output message types + // its ok if not all of the PortType operations are not defined in the binding + DataObjectList& bindingOperationList = wsBinding->getList("operation"); + DataObjectList& portTypeOperationList = portType->getList("operation"); + for (unsigned int k=0; k < bindingOperationList.size(); k++) + { + DataObjectPtr bindingOp = bindingOperationList[k]; + string operationName = bindingOp->getCString("name"); + + // Get the corresponding PortType operation + // I know this may not be very efficient, but its a necessary evil + bool foundPortType = false; + DataObjectPtr portTypeOp; + for (unsigned int l=0; + (!foundPortType && l < portTypeOperationList.size()); + l++) + { + //portTypeOp = portTypeOperationList[l]->getDataObject("operation"); + portTypeOp = portTypeOperationList[l]; + if (operationName == portTypeOp->getCString("name") ) + { + foundPortType = true; + } + } + + if( !foundPortType ) + { + // Invalid WSDL + stringstream errMessage; + errMessage + << "Unable to find PortType operation for binding operation: \"" + << operationName + << "\" in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + + string soapAction = ""; + bool documentStyle = true; + bool wrappedStyle = true; + bool useEncodedInput = false; + bool useEncodedOutput = false; + WSDLOperation::soapVersion soapVer = WSDLOperation::SOAP11; + + string opType = bindingOp->getType().getURI(); + if (opType == "http://schemas.xmlsoap.org/wsdl/soap12/") + { + soapVer = WSDLOperation::SOAP12; + } + + // Get the soapAction + soapAction = bindingOp->getCString("operation/soapAction"); + + // Get the style + string style = bindingOp->getCString("operation/style"); + if (style == "") + { + style = wsBinding->getCString("binding/style"); + } + if (style != "document") + { + documentStyle = false; + wrappedStyle = false; + } + + // get the use + string use = bindingOp->getCString("input/body/use"); + if (use == "encoded") + { + useEncodedInput = true; + } + + use = bindingOp->getCString("output/body/use"); + if (use == "encoded") + { + useEncodedOutput = true; + } + + // Get the request message type from the PortType + DataObjectPtr wsMessageIn = + findMessage(portTypeOp->getCString("input/message")); + if (!wsMessageIn) + { + stringstream errMessage; + errMessage + << "unable to find PortType input message \"" + << portTypeOp->getCString("input/message") + << "\" in the wsdl definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + string inputMessageType( wsMessageIn->getCString("name") ); + // If it doesnt have a namespace prefix, add the target namespace + if (inputMessageType.find("#") == string::npos) + { + inputMessageType.insert(0, (getNamespace() + "#") ); + } + + // Get the response message type from the PortType + DataObjectPtr wsMessageOut = + findMessage(portTypeOp->getCString("output/message")); + if (!wsMessageOut) + { + // TODO this is ok for one way operations, right? + stringstream errMessage; + errMessage + << "unable to find PortType output message \"" + << portTypeOp->getCString("output/message") + << "\" in the wsdl definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + string outputMessageType( wsMessageOut->getCString("name") ); + // If it doesnt have a namespace prefix, add the target namespace + if (outputMessageType.find("#") == string::npos) + { + outputMessageType.insert(0, (getNamespace() + "#") ); + } + + WSDLOperation wsdlOp; + wsdlOp.setOperationName(operationName); + wsdlOp.setSoapAction(soapAction); + wsdlOp.setEndpoint(targetAddress); + wsdlOp.setSoapVersion(soapVer); + wsdlOp.setDocumentStyle(documentStyle); + wsdlOp.setWrappedStyle(wrappedStyle); + wsdlOp.setInputEncoded(useEncodedInput); + wsdlOp.setOutputEncoded(useEncodedOutput); + wsdlOp.setInputMessageType(inputMessageType); + wsdlOp.setOutputMessageType(outputMessageType); + wsdlOp.setInputMessage(wsMessageIn); + wsdlOp.setOutputMessage(wsMessageOut); + + operationMap[ operationName ] = wsdlOp; + + } // end bindingOperationList + + portTypeMap[portTypeName] = operationMap; + servicePortMap[(serviceName+"#"+portName)] = operationMap; + + } // end portTypeList + } // end serviceList + } // end method mapOperations + + void WSDLDefinition::checkForDuplicates( DataObjectPtr wsdlModel ) + { + logentry(); + + // check for duplicate message/binding/PortType/service + // with equal name attributes. This cant be enforced by + // the schema, so it has to be enforced at the app level + + std::set<string> namesSet; + + DataObjectList &messageList = wsdlModel->getList("message"); + for( unsigned int i = 0; i < messageList.size(); i++ ) + { + if( namesSet.find( messageList[i]->getCString("name") ) == namesSet.end() ) + { + namesSet.insert( messageList[i]->getCString("name") ); + } + else + { + // Invalid WSDL + stringstream errMessage; + errMessage + << "message/name: \"" + << messageList[i]->getCString("name") + << "\" cannot be duplicated in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + } + + namesSet.clear(); + DataObjectList &bindingList = wsdlModel->getList("binding"); + for( unsigned int i = 0; i < bindingList.size(); i++ ) + { + if( namesSet.find( bindingList[i]->getCString("name") ) == namesSet.end() ) + { + namesSet.insert( bindingList[i]->getCString("name") ); + } + else + { + // Invalid WSDL + stringstream errMessage; + errMessage + << "binding/name: \"" + << bindingList[i]->getCString("name") + << "\" cannot be duplicated in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + } + + namesSet.clear(); + DataObjectList &portTypeList = wsdlModel->getList("portType"); + for( unsigned int i = 0; i < portTypeList.size(); i++ ) + { + if( namesSet.find( portTypeList[i]->getCString("name") ) == namesSet.end() ) + { + namesSet.insert( portTypeList[i]->getCString("name") ); + } + else + { + // Invalid WSDL + stringstream errMessage; + errMessage + << "portType/name: \"" + << portTypeList[i]->getCString("name") + << "\" cannot be duplicated in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + } + + namesSet.clear(); + DataObjectList &serviceList = wsdlModel->getList("service"); + for( unsigned int i = 0; i < serviceList.size(); i++ ) + { + if( namesSet.find( serviceList[i]->getCString("name") ) == namesSet.end() ) + { + namesSet.insert( serviceList[i]->getCString("name") ); + } + else + { + // Invalid WSDL + stringstream errMessage; + errMessage + << "service/name: \"" + << serviceList[i]->getCString("name") + << "\" cannot be duplicated in the WSDL definition"; + throwException(SystemConfigurationException, errMessage.str().c_str()); + } + } + } + + } // end namespace model + } // end namespace sca +} // End namespace tuscany |