summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2009-09-11 15:51:32 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2009-09-11 15:51:32 +0000
commit8a7c0cbaa3260ab86b4cfe108fc2570d9ef666d7 (patch)
treea7a310d8716dba362f8aa66933e325de4acd4ec8
parent9a677fb7424600d1bfc386982e81bf080b40ff0f (diff)
XML: add an API to set namespace on a single instance of a LassoNode
* lasso/xml/xml.h lasso/xml/xml.c: add a new public API lasso_node_set_custom_namespace(node, prefix, href). It allows to set the precise namespace of a single object, all other instance of the same class continue to use the default namespace for the class. It should be used for difficult consumer of certain nodes (like wsse:Security) which only know certain namespace or do not use the namespace going with the specified version of a specification (like MSP not following ID-WSF 1.0 specification and using http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd instead of http://schemas.xmlsoap.org/ws/2003/06/secext. It also allows to share implementation of schema objects common to many version of the same specification (wsse:Security between ID-WSF 1.0 and ID-WSF 2.0), without creating too many child classes.
-rw-r--r--lasso/xml/xml.c73
-rw-r--r--lasso/xml/xml.h2
2 files changed, 74 insertions, 1 deletions
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
index e389eb9b..0f60fd19 100644
--- a/lasso/xml/xml.c
+++ b/lasso/xml/xml.c
@@ -743,6 +743,7 @@ lasso_node_cleanup_original_xmlnodes(LassoNode *node)
}
static GQuark original_xmlnode_quark;
+static GQuark custom_namespace_quark;
/**
* lasso_node_get_original_xmlnode:
@@ -797,6 +798,63 @@ lasso_node_set_original_xmlnode(LassoNode *node, xmlNode* xmlnode)
}
}
+struct _CustomNamespace {
+ char *prefix;
+ char *href;
+};
+
+static struct _CustomNamespace *
+_lasso_node_new_custom_namespace(char *prefix, char *href)
+{
+ struct _CustomNamespace *ret = g_new(struct _CustomNamespace, 1);
+ lasso_assign_string(ret->prefix, prefix);
+ lasso_assign_string(ret->href, href);
+ return ret;
+}
+
+static void
+_lasso_node_free_custom_namespace(struct _CustomNamespace *custom_namespace)
+{
+ lasso_release_string(custom_namespace->prefix);
+ lasso_release_string(custom_namespace->href);
+ lasso_release(custom_namespace);
+}
+
+/**
+ * _lasso_node_get_custom_namespace:
+ * @node: a #LassoNode object
+ *
+ * Return the eventually attached custom namespace object
+ *
+ * Return value: NULL or an #_CustomNamespace structure.
+ */
+static struct _CustomNamespace*
+_lasso_node_get_custom_namespace(LassoNode *node)
+{
+ if (! LASSO_NODE(node))
+ return NULL;
+ return g_object_get_qdata((GObject*)node, custom_namespace_quark);
+}
+
+/**
+ * lasso_node_set_custom_namespace:
+ * @node: a #LassoNode object
+ * @prefix: the prefix to use for the definition
+ * @href: the URI of the namespace
+ *
+ * Set a custom namespace for an object instance, use it with object existing a lot of revision of
+ * the nearly same namespace.
+ */
+void
+lasso_node_set_custom_namespace(LassoNode *node, char *prefix, char *href)
+{
+ if (! LASSO_IS_NODE(node) || ! prefix || ! href)
+ return;
+ g_object_set_qdata_full((GObject*)node, custom_namespace_quark,
+ _lasso_node_new_custom_namespace(prefix, href),
+ (GDestroyNotify)_lasso_node_free_custom_namespace);
+}
+
/*****************************************************************************/
/* implementation methods */
/*****************************************************************************/
@@ -1149,11 +1207,22 @@ lasso_node_impl_get_xmlNode(LassoNode *node, gboolean lasso_dump)
GList *list_ns = NULL, *list_classes = NULL, *t;
LassoNode *value_node;
struct XmlSnippet *version_snippet;
+ struct _CustomNamespace *custom_namespace;
if (class->node_data == NULL)
return NULL;
xmlnode = xmlNewNode(NULL, (xmlChar*)class->node_data->node_name);
+ /* set a custom namespace if one is found */
+ custom_namespace = _lasso_node_get_custom_namespace(node);
+ if (custom_namespace) {
+ xmlNewNs(xmlnode, (xmlChar*)custom_namespace->href,
+ (xmlChar*)custom_namespace->prefix);
+ /* skip the base class namespace, it is replaced by the custom one */
+ class = g_type_class_peek_parent(class);
+ }
+
+ /* collect namespaces in the order of ancestor classes, nearer first */
while (class && LASSO_IS_NODE_CLASS(class) && class->node_data) {
if (class->node_data->ns)
list_ns = g_list_append(list_ns, class->node_data->ns);
@@ -1161,6 +1230,7 @@ lasso_node_impl_get_xmlNode(LassoNode *node, gboolean lasso_dump)
class = g_type_class_peek_parent(class);
}
+ /* create the namespaces */
t = g_list_first(list_ns);
while (t) {
ns = t->data;
@@ -1168,7 +1238,7 @@ lasso_node_impl_get_xmlNode(LassoNode *node, gboolean lasso_dump)
t = g_list_next(t);
}
g_list_free(list_ns);
-
+ /* first NS defined is the namespace of the element */
xmlSetNs(xmlnode, xmlnode->nsDef);
t = g_list_last(list_classes);
@@ -1339,6 +1409,7 @@ class_init(LassoNodeClass *class)
gobject_class->finalize = lasso_node_finalize;
original_xmlnode_quark = g_quark_from_static_string("lasso_original_xmlnode");
+ custom_namespace_quark = g_quark_from_static_string("lasso_custom_namespace");
class->node_data = NULL;
}
diff --git a/lasso/xml/xml.h b/lasso/xml/xml.h
index 6eca78d9..60af9c6e 100644
--- a/lasso/xml/xml.h
+++ b/lasso/xml/xml.h
@@ -154,6 +154,8 @@ LASSO_EXPORT xmlNode* lasso_node_get_original_xmlnode(LassoNode *node);
LASSO_EXPORT void lasso_node_set_original_xmlnode(LassoNode *node, xmlNode* xmlNode);
+LASSO_EXPORT void lasso_node_set_custom_namespace(LassoNode *node, char *prefix, char *href);
+
LASSO_EXPORT LassoMessageFormat lasso_node_init_from_message(LassoNode *node, const char *message);
LASSO_EXPORT gboolean lasso_node_init_from_query(LassoNode *node, const char *query);