Basic SOAP client, reworked transport streams.
[shibboleth/xmltooling.git] / xmltooling / soap / impl / SOAPClient.cpp
diff --git a/xmltooling/soap/impl/SOAPClient.cpp b/xmltooling/soap/impl/SOAPClient.cpp
new file mode 100644 (file)
index 0000000..584c7d0
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *  Copyright 2001-2006 Internet2
+ * 
+ * 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.
+ */
+
+/**
+ * SOAPClient.cpp
+ * 
+ * Implements SOAP 1.1 messaging over a transport.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "soap/SOAP.h"
+#include "soap/SOAPClient.h"
+#include "util/XMLHelper.h"
+
+#include <sstream>
+
+using namespace soap11;
+using namespace xmltooling;
+using namespace std;
+
+SOAPClient::~SOAPClient()
+{
+    reset();
+}
+
+void SOAPClient::reset()
+{
+    delete m_transport;
+    m_transport=NULL;
+}
+
+void SOAPClient::send(const Envelope* env, const KeyInfoSource& peer, const char* endpoint)
+{
+    // Prepare a transport object.
+    const char* pch = strchr(endpoint,':');
+    if (!pch)
+        throw IOException("SOAP endpoint was not a URL.");
+    string scheme(endpoint, pch-endpoint);
+    m_transport = XMLToolingConfig::getConfig().SOAPTransportManager.newPlugin(scheme.c_str(), make_pair(&peer,endpoint));
+    prepareTransport(*m_transport);
+    
+    // Serialize envelope.
+    stringstream s;
+    XMLHelper::serialize(env->marshall(), s);
+    
+    // Send to peer.
+    m_transport->send(s);
+}
+
+Envelope* SOAPClient::receive()
+{
+    if (!m_transport)
+        throw IOException("No call is active.");
+    
+    // If we can get the stream, then the call is still active.
+    istream& out = m_transport->receive();
+    if (!out)
+        return NULL;    // nothing yet
+    
+    // Parse and bind the document into an XMLObject.
+    DOMDocument* doc = (m_validate ? XMLToolingConfig::getConfig().getValidatingParser()
+        : XMLToolingConfig::getConfig().getParser()).parse(out); 
+    XercesJanitor<DOMDocument> janitor(doc);
+    auto_ptr<XMLObject> xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
+    janitor.release();
+
+    Envelope* env = dynamic_cast<Envelope*>(xmlObject.get());
+    if (!env)
+        throw IOException("Response was not a SOAP 1.1 Envelope.");
+    reset();
+    xmlObject.release();
+    return env;
+}