summaryrefslogtreecommitdiffstats
path: root/sca-cpp/tags/cpp-stable-20060304/sca/runtime/core/src/tuscany/sca/ws/SDOStub.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/tags/cpp-stable-20060304/sca/runtime/core/src/tuscany/sca/ws/SDOStub.cpp')
-rw-r--r--sca-cpp/tags/cpp-stable-20060304/sca/runtime/core/src/tuscany/sca/ws/SDOStub.cpp476
1 files changed, 476 insertions, 0 deletions
diff --git a/sca-cpp/tags/cpp-stable-20060304/sca/runtime/core/src/tuscany/sca/ws/SDOStub.cpp b/sca-cpp/tags/cpp-stable-20060304/sca/runtime/core/src/tuscany/sca/ws/SDOStub.cpp
new file mode 100644
index 0000000000..0b9a4fbd28
--- /dev/null
+++ b/sca-cpp/tags/cpp-stable-20060304/sca/runtime/core/src/tuscany/sca/ws/SDOStub.cpp
@@ -0,0 +1,476 @@
+/*
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.
+ */
+
+/* $Rev$ $Date: 2005/12/22 11:33:21 $ */
+
+#include "SDOStub.h"
+#include "commonj/sdo/HelperProvider.h"
+#include "osoa/sca/export.h"
+#include "tuscany/sca/util/Logging.h"
+#include "tuscany/sca/util/Exceptions.h"
+#include "tuscany/sca/util/Utils.h"
+
+
+// For Axis stub code
+#include <axis/AxisWrapperAPI.hpp>
+#include <axis/client/Stub.hpp>
+#include <axis/OtherFaultException.hpp>
+#include <axis/ISoapFault.hpp>
+
+using namespace std;
+
+AXIS_CPP_NAMESPACE_USE
+
+using namespace commonj::sdo;
+using namespace tuscany::sca;
+
+
+namespace tuscany
+{
+namespace sca
+{
+ namespace ws
+ {
+ /** Construct an SDOStub using the default HTTP 1.1 transport.
+ */
+ SDOStub::SDOStub()
+ : Stub(" ", APTHTTP1_1),
+ m_strEndpoint(""),
+ m_strTargetNamespace(""),
+ m_strOperationName(""),
+ m_strOperationResponseName(""),
+ m_strSoapAction("")
+ {
+ }
+
+
+ /** Construct an SDOStub using the default HTTP 1.1 transport
+ * and set the web service endpoint URI.
+ * @param endpoint - web service endpoint URI
+ */
+ SDOStub::SDOStub(const char* endpoint)
+ : Stub(endpoint, APTHTTP1_1),
+ m_strEndpoint(endpoint),
+ m_strTargetNamespace(""),
+ m_strOperationName(""),
+ m_strOperationResponseName(""),
+ m_strSoapAction("")
+ {
+ }
+
+
+ /** Destruct the SDOStub
+ */
+ SDOStub::~SDOStub()
+ {
+ }
+
+ /** Set the web service endpoint URI.
+ * The endpoint is the value of the soap:address element in the WSDL.
+ * @param endpoint - web service endpoint URI.
+ */
+ void SDOStub::setEndpoint(const char* endpoint)
+ {
+ m_strEndpoint = endpoint;
+ // Stub::setEndPoint
+ setEndPoint(endpoint);
+ }
+
+ /** Get the web service endpoint URI.
+ * @return web service endpoint URI.
+ */
+ const char* SDOStub::getEndpoint()
+ {
+ return m_strEndpoint.c_str();
+ }
+
+ /** Set the target namespace for elements and operations.
+ * @param targetNamespace - the target namespace.
+ */
+ void SDOStub::setTargetNamespace(const char* targetNamespace)
+ {
+ m_strTargetNamespace = targetNamespace;
+ }
+
+ /** Get the target namespace.
+ * @return - target namespace.
+ */
+ const char* SDOStub::getTargetNamesapce()
+ {
+ return m_strTargetNamespace.c_str();
+ }
+
+ /** Set the name of the operation to invoke.
+ * @param operationName - operation name
+ */
+ void SDOStub::setOperationName(const char* operationName)
+ {
+ m_strOperationName = operationName;
+ }
+
+ /** Get the operation name.
+ * @return operation name.
+ */
+ const char* SDOStub::getOperationName()
+ {
+ return m_strOperationName.c_str();
+ }
+
+ /** Set the name of the element that is returned as the result of a soap method.
+ * @param operationResponseName - name of the response element.
+ */
+ void SDOStub::setOperationResponseName(const char* operationResponseName)
+ {
+ m_strOperationResponseName = operationResponseName;
+ }
+
+ /** Get the name of the element that is returned as the result of a soap method.
+ * @return operation response name.
+ */
+ const char* SDOStub::getOperationResponseName()
+ {
+ return m_strOperationResponseName.c_str();
+ }
+
+ /** Set the SOAPAction header.
+ * @param soapAction - the soap action.
+ */
+ void SDOStub::setSoapAction(const char* soapAction)
+ {
+ m_strSoapAction = soapAction;
+ }
+
+ /** Get the SoapAction header.
+ * @return soap action.
+ */
+ const char* SDOStub::getSoapAction()
+ {
+ return m_strSoapAction.c_str();
+ }
+
+ /** Invoke the operation on the web service.
+ * @param requestDO - SDO containing the input parameters for the operation.
+ * @param dataFactory - DataFactory for de/serialzing the SDOs.
+ * @return DataObjectPtr - SDO containg the response from the web service.
+ */
+ DataObjectPtr SDOStub::invoke(DataObjectPtr requestDO, DataFactoryPtr dataFactory)
+ {
+ // SDO return object
+ DataObjectPtr pReturn;
+
+ // For faults
+ //const char* pcCmplxFaultName = NULL;
+
+ // Get an XMLHelper
+ XMLHelperPtr xmlHelper = HelperProvider::getXMLHelper(dataFactory);
+
+
+ try
+ {
+ // Initialize the call structure for Doc Literal request/response.
+ if (AXIS_SUCCESS != m_pCall->initialize(CPP_DOC_PROVIDER))
+ {
+ return pReturn; // Return if there is a failure
+ }
+
+ // Set the SoapAction if it is not already set.
+ if (NULL == m_pCall->getTransportProperty("SOAPAction",false))
+ {
+ m_pCall->setTransportProperty(SOAPACTION_HEADER , m_strSoapAction.c_str());
+ }
+
+ // Set the Soap Version.
+ m_pCall->setSOAPVersion(SOAP_VER_1_1);
+
+ // Set the Operation (operationName and targetNamespace)
+ m_pCall->setOperation(m_strOperationName.c_str(), m_strTargetNamespace.c_str());
+
+ //includeSecure();
+ //applyUserPreferences();
+
+ //
+ // Serialize the DataObject.
+ //
+
+ // DEBUG
+ XMLDocumentPtr requestDoc =
+ xmlHelper->createDocument(requestDO,
+ m_strTargetNamespace.c_str(),
+ m_strOperationName.c_str());
+ requestDoc->setXMLDeclaration(false);
+ char *requestXML = xmlHelper->save(requestDoc);
+ cout << "SDOStub::invoke: Request XML= " << endl;
+ cout << requestXML << endl;
+ cout << endl;
+ // DEBUG
+
+ // Loop through the top level data object, serializing individual properties.
+ // We cannot simply serialize the request DataObject to an XML string and add
+ // the XML as an AnyType parameter because Axis will wrap the request with an
+ // element named for the operationName (Doc Literal/Wrapped), duplicating the
+ // top-level element.
+ PropertyList properties = requestDO->getInstanceProperties();
+ for (int i=0; i < properties.size() ; i++)
+ {
+ Property& property = properties[i];
+ const char *propertyName = property.getName();
+
+ // If the property is not set, don't bother adding it as a parameter.
+ if (!requestDO->isValid(property)) continue;
+
+ switch (property.getTypeEnum())
+ {
+ // Simple string property - add it as an XSD_STRING parameter.
+ case Type::StringType:
+ {
+ if (!property.isMany())
+ {
+ string strPrefixAndParamName;
+ const char *namespacePrefix =
+ m_pCall->getNamespacePrefix(m_strTargetNamespace.c_str());
+ strPrefixAndParamName.append(namespacePrefix);
+ strPrefixAndParamName.append(":");
+ strPrefixAndParamName.append(propertyName);
+ const char *paramValue = requestDO->getCString(i);
+ m_pCall->addParameter((void *)paramValue,
+ strPrefixAndParamName.c_str(),
+ XSD_STRING);
+ }
+ }
+ break;
+
+ // DataObject property.
+ case Type::DataObjectType:
+ {
+ const char *dobXML = NULL;
+ if (property.isMany())
+ {
+ // Many valued property - get the list.
+ DataObjectList& dobList = requestDO->getList(property);
+ for (int j=0; j< dobList.size(); j++)
+ {
+ DataObjectPtr dob = dobList[j];
+ if (dob != 0)
+ {
+ // Create an XML string from the DataObject.
+ XMLDocumentPtr doc =
+ xmlHelper->createDocument(dob,
+ m_strTargetNamespace.c_str(),
+ propertyName);
+ doc->setXMLDeclaration(false);
+ dobXML = xmlHelper->save(doc);
+
+ // DEBUG
+ cout << "SDOStub::invoke: DataObject \"" << propertyName << "\" as XML:" << endl;
+ cout << dobXML << endl;
+ cout << endl;
+ // DEBUG
+
+ // Add the XML to the call as an AnyType.
+ AnyType* pAny = new AnyType();
+ pAny->_size = 1;
+ pAny->_array = new char*[1];
+ pAny->_array[0] = strdup(dobXML);
+ m_pCall->addAnyObject(pAny);
+ }
+ }
+ } // if isMany
+ else
+ {
+ // Single valued property.
+ DataObjectPtr dob = requestDO->getDataObject(property);
+ if (dob != 0)
+ {
+ // Create an XML string from the DataObject.
+ XMLDocumentPtr doc =
+ xmlHelper->createDocument(dob,
+ m_strTargetNamespace.c_str(),
+ propertyName);
+ doc->setXMLDeclaration(false);
+ dobXML = xmlHelper->save(doc);
+
+ // DEBUG
+ cout << "SDOStub::invoke: DataObject \"" << propertyName << "\" as XML:" << endl;
+ cout << dobXML << endl;
+ cout << endl;
+ // DEBUG
+
+ // Add the XML to the call as an AnyType.
+ AnyType* pAny = new AnyType();
+ pAny->_size = 1;
+ pAny->_array = new char*[1];
+ pAny->_array[0] = strdup(dobXML);
+ m_pCall->addAnyObject(pAny);
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Invoke the operation.
+ if (AXIS_SUCCESS == m_pCall->invoke())
+ {
+ // Make sure the response element is what we expect; ie that the element matches
+ // the operation response name set on the stub and its targetNamespace matches
+ // the targetNamespace set on the stub.
+ if (AXIS_SUCCESS == m_pCall->checkMessage(m_strOperationResponseName.c_str(),
+ m_strTargetNamespace.c_str()))
+ {
+ cout << "SDOStub::invoke: Successful call..." << endl;
+
+ // Deserialize the soap response.
+ string strResponse = getSoapResponse();
+
+ // DEBUG
+ cout << "SDOStub::invoke: Response XML= " << endl;
+ cout << strResponse.c_str() << endl;
+ cout << endl;
+ // DEBUG
+
+ // Create an XMLDocument from the soap reponse
+ XMLDocumentPtr returnDoc =
+ xmlHelper->load(strResponse.c_str(), m_strTargetNamespace.c_str());
+ // Get the root DataObject to return as the result.
+ pReturn = returnDoc->getRootDataObject();
+ // DEBUG
+ cout << "SDOStub::invoke: Response DataObject= " << endl;
+ Utils::printDO(pReturn);
+ cout << endl;
+ // DEBUG
+ }
+ }
+ else
+ {
+ cout << "SDOStub::invoke: checkMessage failed:" << endl;
+ cout << "SDOStub::invoke: Expected \'"
+ << m_strOperationResponseName.c_str()
+ << "\' element with namespace \'"
+ << m_strTargetNamespace.c_str()
+ << "\'."
+ << endl;
+ }
+
+
+ // Invoked the operation successfully - uninitialize the Call object.
+ m_pCall->unInitialize();
+
+ }
+ catch (AxisException& e)
+ {
+ // Get the exception code.
+ int iExceptionCode = e.getExceptionCode();
+
+ if (AXISC_NODE_VALUE_MISMATCH_EXCEPTION != iExceptionCode)
+ {
+ m_pCall->unInitialize();
+ throw ServiceRuntimeException("AxisException", ServiceRuntimeException::Error, e.what());
+ }
+
+ // Get the details of the SoapFault.
+ ISoapFault* pSoapFault = (ISoapFault*) m_pCall->checkFault("Fault", m_strEndpoint.c_str());
+
+ if (pSoapFault)
+ {
+ const char *detail = pSoapFault->getSimpleFaultDetail();
+ bool deleteDetail=false;
+
+ if (NULL==detail || 0==strlen(detail))
+ {
+ detail=m_pCall->getFaultAsXMLString();
+
+
+ if (NULL==detail)
+ {
+ detail="";
+ }
+ else
+ {
+ deleteDetail=true;
+ }
+ }
+
+ OtherFaultException ofe(pSoapFault->getFaultcode(),
+ pSoapFault->getFaultstring(),
+ pSoapFault->getFaultactor(),
+ detail, iExceptionCode);
+
+ if (deleteDetail && NULL!=detail)
+ {
+ delete [] const_cast<char*>(detail);
+ }
+
+ m_pCall->unInitialize();
+ throw ofe;
+ }
+ else
+ {
+ m_pCall->unInitialize();
+ throw ServiceRuntimeException("AxisException", ServiceRuntimeException::Error, e.what());
+ }
+ }
+ catch(SDORuntimeException sdoE)
+ {
+ cout << "SDOStub::invoke: SDORuntimeException: " << endl;
+ sdoE.PrintSelf(cout);
+ }
+
+
+ return pReturn;
+
+ }
+
+ // Deserialize the soap response from the web service.
+ string SDOStub::getSoapResponse()
+ {
+ // Get the response as an XML string.
+ AnyType* soapAny = m_pCall->getAnyObject();
+
+ // The Doc Literal response does not include the top level
+ // response element if we use getAnyObject - we need to wrap
+ // the response with the response element.
+ string strResponse("<");
+ strResponse.append(m_strOperationResponseName);
+ strResponse.append(" xmlns=\"");
+ strResponse.append(m_strTargetNamespace);
+ strResponse.append("\">");
+
+ for (int j=0; j < soapAny->_size ; j++)
+ {
+ // DEBUG
+ cout << "SDOStub::getSoapResponse: soapAny->_array[" << j << "]=" << endl;
+ cout << soapAny->_array[j] << endl;
+ cout << endl;
+ // DEBUG
+
+ strResponse.append(soapAny->_array[j]);
+ }
+
+ strResponse.append("</");
+ strResponse.append(m_strOperationResponseName);
+ strResponse.append(">");
+
+ return strResponse;
+ }
+
+ } // end namespace ws
+} // end namespace sca
+} // end namespace tuscany
+