added a bunch of initialization parameters.
authorRodrigo Moya <rodrigo@ximian.com>
Mon, 17 Nov 2003 23:14:32 +0000 (23:14 +0000)
committerRodrigo Moya <rodrigo@src.gnome.org>
Mon, 17 Nov 2003 23:14:32 +0000 (23:14 +0000)
2003-11-17  Rodrigo Moya <rodrigo@ximian.com>

* libsoup/soup-soap-message.[ch] (soup_soap_message_new,
soup_soap_message_new_from_uri): added a bunch of initialization
parameters.
(soup_soap_message_get_xml_doc, soup_soap_message_start_envelope,
soup_soap_message_end_envelope, soup_soap_message_start_body,
soup_soap_message_end_body, soup_soap_message_start_element,
soup_soap_message_end_element):
new functions.

* configure.in: depend on libxml-2.0 for the SOAP code.

* libsoup/Makefile.am: use XML CFLAGS and LIBS.

ChangeLog
configure.in
libsoup/Makefile.am
libsoup/soup-soap-message.c
libsoup/soup-soap-message.h

index eed14a2..7bca122 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2003-11-17  Rodrigo Moya <rodrigo@ximian.com>
+
+       * libsoup/soup-soap-message.[ch] (soup_soap_message_new,
+       soup_soap_message_new_from_uri): added a bunch of initialization
+       parameters.
+       (soup_soap_message_get_xml_doc, soup_soap_message_start_envelope,
+       soup_soap_message_end_envelope, soup_soap_message_start_body,
+       soup_soap_message_end_body, soup_soap_message_start_element,
+       soup_soap_message_end_element):
+       new functions.
+
+       * configure.in: depend on libxml-2.0 for the SOAP code.
+
+       * libsoup/Makefile.am: use XML CFLAGS and LIBS.
+
 2003-11-17  Joe Shaw  <joe@ximian.com>
 
        * configure.in: Add in the --enable-libgpg-error flag from the 2.0
index c8a530c..c7ca988 100644 (file)
@@ -74,6 +74,10 @@ dnl ***********************
 
 AM_PATH_GLIB_2_0(2.0.0,,,gobject)
 
+PKG_CHECK_MODULES(XML, libxml-2.0)
+AC_SUBST(XML_CFLAGS)
+AC_SUBST(XML_LIBS)
+
 dnl *********************************
 dnl *** Networking library checks ***
 dnl *********************************
index 9a8e08e..e3f8560 100644 (file)
@@ -7,6 +7,7 @@ INCLUDES =                              \
        -I$(top_srcdir)                 \
        $(SOUP_DEBUG_FLAGS)             \
        $(GLIB_CFLAGS)                  \
+       $(XML_CFLAGS)                   \
        $(GNUTLS_CFLAGS)
 
 MARSHAL_GENERATED = soup-marshal.c soup-marshal.h
@@ -52,6 +53,7 @@ libsoup_2_2_la_LDFLAGS =      \
 
 libsoup_2_2_la_LIBADD =                \
        $(GLIB_LIBS)            \
+       $(XML_LIBS)             \
        $(GNUTLS_LIBS)
 
 libsoup_2_2_la_SOURCES =               \
index c803d5b..d8e5ab2 100644 (file)
@@ -9,6 +9,15 @@
 #define PARENT_TYPE SOUP_TYPE_MESSAGE
 
 struct _SoupSoapMessagePrivate {
+       /* Serialization fields */
+       xmlDocPtr doc;
+       xmlNodePtr last_node;
+       xmlNsPtr soap_ns;
+       xmlNsPtr xsi_ns;
+       gchar *env_prefix;
+       gchar *env_uri;
+       gboolean body_started;
+       gchar *action;
 };
 
 static GObjectClass *parent_class = NULL;
@@ -40,10 +49,30 @@ static void
 init (SoupSoapMessage *msg, SoupSoapMessageClass *klass)
 {
        msg->priv = g_new0 (SoupSoapMessagePrivate, 1);
+
+       /* initialize XML structures */
+       msg->priv->doc = xmlNewDoc ("1.0");
+       msg->priv->doc->standalone = FALSE;
+       msg->priv->doc->encoding = g_strdup ("UTF-8");
 }
 
 SOUP_MAKE_TYPE (soup_soap_message, SoupSoapMessage, class_init, init, PARENT_TYPE)
 
+static xmlNsPtr
+fetch_ns (SoupSoapMessage *msg, const char *prefix, const char *ns_uri)
+{
+        xmlNsPtr ns = NULL;
+                                                                                
+        if (prefix && ns_uri)
+                ns = xmlNewNs (msg->priv->last_node, ns_uri, prefix);
+        else if (prefix && !ns_uri) {
+                ns = xmlSearchNs (msg->priv->doc, msg->priv->last_node, prefix);
+                if (!ns) ns = xmlNewNs (msg->priv->last_node, "", prefix);
+        }
+                                                                                
+        return ns;
+}
+
 /**
  * soup_soap_message_new:
  * @method: the HTTP method for the created request.
@@ -55,7 +84,9 @@ SOUP_MAKE_TYPE (soup_soap_message, SoupSoapMessage, class_init, init, PARENT_TYP
  * parsed).
  */
 SoupSoapMessage *
-soup_soap_message_new (const char *method, const char *uri_string)
+soup_soap_message_new (const char *method, const char *uri_string,
+                      gboolean standalone, const char *xml_encoding,
+                      const char *env_prefix, const char *env_uri)
 {
        SoupSoapMessage *msg;
        SoupUri *uri;
@@ -64,9 +95,8 @@ soup_soap_message_new (const char *method, const char *uri_string)
        if (!uri)
                return NULL;
 
-       msg = g_object_new (SOUP_TYPE_SOAP_MESSAGE, NULL);
-       SOUP_MESSAGE (msg)->method = method ? method : SOUP_METHOD_GET;
-       soup_message_set_uri (SOUP_MESSAGE (msg), (const SoupUri *) uri);
+       msg = soup_soap_message_new_from_uri (method, uri, standalone,
+                                             xml_encoding, env_prefix, env_uri);
 
        soup_uri_free (uri);
 
@@ -83,13 +113,180 @@ soup_soap_message_new (const char *method, const char *uri_string)
  * Returns: the new #SoupSoapMessage
  */
 SoupSoapMessage *
-soup_soap_message_new_from_uri (const char *method, const SoupUri *uri)
+soup_soap_message_new_from_uri (const char *method, const SoupUri *uri,
+                               gboolean standalone, const char *xml_encoding,
+                               const char *env_prefix, const char *env_uri)
 {
        SoupSoapMessage *msg;
 
        msg = g_object_new (SOUP_TYPE_SOAP_MESSAGE, NULL);
        SOUP_MESSAGE (msg)->method = method ? method : SOUP_METHOD_GET;
-       soup_message_set_uri (SOUP_MESSAGE (msg), uri);
+       soup_message_set_uri (SOUP_MESSAGE (msg), (const SoupUri *) uri);
+
+       msg->priv->doc->standalone = standalone;
+
+       if (xml_encoding) {
+               g_free ((char *) msg->priv->doc->encoding);
+               msg->priv->doc->encoding = g_strdup (xml_encoding);
+       }
+
+       if (env_prefix || env_uri) {
+               msg->priv->env_prefix = g_strdup (env_prefix);
+               msg->priv->env_uri = g_strdup (env_uri);
+       }
 
        return msg;
 }
+
+/**
+ * soup_soap_message_start_envelope:
+ * @msg: the %SoupSoapMessage.
+ *
+ * Starts the top level SOAP Envelope element.
+ */
+void
+soup_soap_message_start_envelope (SoupSoapMessage *msg)
+{
+       g_return_if_fail (SOUP_IS_SOAP_MESSAGE (msg));
+
+       msg->priv->last_node = msg->priv->doc->xmlRootNode =
+               xmlNewDocNode (msg->priv->doc, NULL, "Envelope", NULL);
+
+       msg->priv->soap_ns = xmlNewNs (msg->priv->doc->xmlRootNode,
+                                      msg->priv->env_uri ? msg->priv->env_uri :
+                                      "http://schemas.xmlsoap.org/soap/envelope/",
+                                      msg->priv->env_prefix ? msg->priv->env_prefix : "SOAP-ENV");
+       if (msg->priv->env_uri) {
+               g_free (msg->priv->env_uri);
+               msg->priv->env_uri = NULL;
+       }
+       if (msg->priv->env_prefix) {
+               g_free (msg->priv->env_prefix);
+               msg->priv->env_prefix = NULL;
+       }
+
+       xmlSetNs (msg->priv->doc->xmlRootNode, msg->priv->soap_ns);
+
+       xmlNewNs (msg->priv->doc->xmlRootNode,
+                 "http://schemas.xmlsoap.org/soap/encoding/",
+                  "SOAP-ENC");
+       xmlNewNs (msg->priv->doc->xmlRootNode,
+                  "http://www.w3.org/1999/XMLSchema",
+                  "xsd");
+       msg->priv->xsi_ns = xmlNewNs (msg->priv->doc->xmlRootNode,
+                                     "http://www.w3.org/1999/XMLSchema-instance",
+                                     "xsi");
+}
+
+/**
+ * soup_soap_message_end_envelope:
+ * @msg: the %SoupSoapMessage.
+ *
+ * Closes the top level SOAP Envelope element.
+ */
+void
+soup_soap_message_end_envelope (SoupSoapMessage *msg)
+{
+       soup_soap_message_end_element (msg);
+}
+
+/**
+ * soup_soap_message_start_body:
+ * @msg: the %SoupSoapMessage.
+ *
+ * Starts the SOAP Body element.
+ */
+void
+soup_soap_message_start_body (SoupSoapMessage *msg)
+{
+       g_return_if_fail (SOUP_IS_SOAP_MESSAGE (msg));
+
+       if (msg->priv->body_started)
+               return;
+
+       msg->priv->last_node = xmlNewChild (msg->priv->last_node,
+                                           msg->priv->soap_ns,
+                                           "Body", NULL);
+
+       msg->priv->body_started = TRUE;
+}
+
+/**
+ * soup_soap_end_body:
+ * @msg: the %SoupSoapMessage.
+ *
+ * Closes the SOAP Body element.
+ */
+void
+soup_soap_message_end_body (SoupSoapMessage *msg)
+{
+       soup_soap_message_end_element (msg);
+}
+
+/**
+ * soup_soap_message_start_element:
+ * @msg: the %SoupSoapMessage.
+ * @name: the element name.
+ * @prefix: the namespace prefix
+ * @ns_uri: the namespace URI
+ *
+ * Starts a new arbitrary message element, with @name as the element name,
+ * @prefix as the XML Namespace prefix, and @ns_uri as the XML Namespace uri for * the created element.
+ *
+ * Passing @prefix with no @ns_uri will cause a recursive search for an
+ * existing namespace with the same prefix. Failing that a new ns will be
+ * created with an empty uri.
+ *
+ * Passing both @prefix and @ns_uri always causes new namespace attribute
+ * creation.
+ *
+ * Passing NULL for both @prefix and @ns_uri causes no prefix to be used, and
+ * the element will be in the default namespace.
+ */
+void
+soup_soap_message_start_element (SoupSoapMessage *msg,
+                                const char *name,
+                                const char *prefix,
+                                const char *ns_uri)
+{
+       g_return_if_fail (SOUP_IS_SOAP_MESSAGE (msg));
+
+       msg->priv->last_node = xmlNewChild (msg->priv->last_node, NULL, name, NULL);
+
+       xmlSetNs (msg->priv->last_node, fetch_ns (msg, prefix, ns_uri));
+
+       if (msg->priv->body_started && !msg->priv->action)
+               msg->priv->action = g_strconcat (ns_uri ? ns_uri : "",
+                                                "#", name, NULL);
+}
+
+/**
+ * soup_soap_message_end_element:
+ * @msg: the %SoupSoapMessage.
+ *
+ * Closes the current message element.
+ */
+void
+soup_soap_message_end_element (SoupSoapMessage *msg)
+{
+       g_return_if_fail (SOUP_IS_SOAP_MESSAGE (msg));
+
+       msg->priv->last_node = msg->priv->last_node->parent;
+}
+
+/**
+ * soup_soap_message_get_xml_doc:
+ * @msg: the %SoupSoapMessage.
+ *
+ * Returns the internal XML representation tree of the %SoupSoapMessage pointed
+ * to by @msg.
+ *
+ * Return value: the xmlDocPtr representing the SOAP message.
+ */
+xmlDocPtr
+soup_soap_message_get_xml_doc (SoupSoapMessage *msg)
+{
+       g_return_val_if_fail (SOUP_IS_SOAP_MESSAGE (msg), NULL);
+
+       return msg->priv->doc;
+}
index f14ea72..b508acc 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef SOUP_SOAP_MESSAGE_H
 #define SOUP_SOAP_MESSAGE_H 1
 
+#include <libxml/tree.h>
 #include <libsoup/soup-message.h>
 
 #define SOUP_TYPE_SOAP_MESSAGE            (soup_soap_message_get_type ())
@@ -28,7 +29,23 @@ typedef struct {
 
 GType            soup_soap_message_get_type (void);
 
-SoupSoapMessage *soup_soap_message_new (const char *method, const char *uri_string);
-SoupSoapMessage *soup_soap_message_new_from_uri (const char *method, const SoupUri *uri);
+SoupSoapMessage *soup_soap_message_new (const char *method, const char *uri_string,
+                                       gboolean standalone, const char *xml_encoding,
+                                       const char *env_prefix, const char *env_uri);
+SoupSoapMessage *soup_soap_message_new_from_uri (const char *method, const SoupUri *uri,
+                                                gboolean standalone, const char *xml_encoding,
+                                                const char *env_prefix, const char *env_uri);
+
+void             soup_soap_message_start_envelope (SoupSoapMessage *msg);
+void             soup_soap_message_end_envelope (SoupSoapMessage *msg);
+void             soup_soap_message_start_body (SoupSoapMessage *msg);
+void             soup_soap_message_end_body (SoupSoapMessage *msg);
+void             soup_soap_message_start_element (SoupSoapMessage *msg,
+                                                 const char *name,
+                                                 const char *prefix,
+                                                 const char *ns_uri);
+void             soup_soap_message_end_element (SoupSoapMessage *msg);
+
+xmlDocPtr        soup_soap_message_get_xml_doc (SoupSoapMessage *msg);
 
 #endif