From c65da59d55409db9e6fb166a0eabf666a1101785 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthony.minessale@gmail.com>
Date: Thu, 11 Feb 2010 17:32:22 +0000
Subject: [PATCH] add new api funcs to xml

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16605 d0543943-73ff-0310-b7d9-9358b9ac24b2
---
 src/include/switch_xml.h |  8 +++++
 src/switch_xml.c         | 67 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

diff --git a/src/include/switch_xml.h b/src/include/switch_xml.h
index e430952d4e..0443f96ba6 100644
--- a/src/include/switch_xml.h
+++ b/src/include/switch_xml.h
@@ -373,6 +373,14 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(_In_z_ const char *key,
 SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_in_domain(_In_z_ const char *user_name, _In_ switch_xml_t domain, _Out_ switch_xml_t *user,
 																 _Out_opt_ switch_xml_t *ingroup);
 
+
+SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_merged(const char *key, const char *user_name, const char *domain_name,
+															  const char *ip, switch_xml_t *user, switch_event_t *params);
+
+SWITCH_DECLARE(void) switch_xml_merge_user(switch_xml_t user, switch_xml_t domain, switch_xml_t group);
+
+SWITCH_DECLARE(switch_xml_t) switch_xml_dup(switch_xml_t xml);
+
 ///\brief open a config in the core registry
 ///\param file_path the name of the config section e.g. modules.conf
 ///\param node a pointer to point to the node if it is found
diff --git a/src/switch_xml.c b/src/switch_xml.c
index 818c75a6a7..234eaf0181 100644
--- a/src/switch_xml.c
+++ b/src/switch_xml.c
@@ -1747,6 +1747,73 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_in_domain(const char *use
 	return status;
 }
 
+
+SWITCH_DECLARE(switch_xml_t) switch_xml_dup(switch_xml_t xml)
+{
+	char *x = switch_xml_toxml(xml, SWITCH_FALSE);
+	return switch_xml_parse_str_dynamic(x, SWITCH_FALSE); 
+}
+
+
+static void do_merge(switch_xml_t in, switch_xml_t src, const char *container, const char *tag_name) 
+{
+	switch_xml_t itag, tag, param, iparam, iitag;
+
+	if (!(itag = switch_xml_child(in, container))) {
+		itag = switch_xml_add_child_d(in, container, 0);
+	}
+
+	if ((tag = switch_xml_child(src, container))) {
+		for (param = switch_xml_child(tag, tag_name); param; param = param->next) {
+			const char *var = switch_xml_attr(param, "name");
+			const char *val = switch_xml_attr(param, "value");
+			
+			int go = 1;
+
+			for (iparam = switch_xml_child(itag, tag_name); iparam; iparam = iparam->next) {
+				const char *ivar = switch_xml_attr(iparam, "name");
+				
+				if (var && ivar && !strcasecmp(var, ivar)) {
+					go = 0;
+					break;
+				}
+			}
+			
+			if (go) {
+				iitag = switch_xml_add_child_d(itag, tag_name, 0);
+				switch_xml_set_attr_d(iitag, var, val);
+			}
+		}
+	}
+	
+}
+
+
+SWITCH_DECLARE(void) switch_xml_merge_user(switch_xml_t user, switch_xml_t domain, switch_xml_t group)
+{
+
+	do_merge(user, group, "params", "param");
+	do_merge(user, group, "variables", "variable");
+	do_merge(user, domain, "params", "param");
+	do_merge(user, domain, "variables", "variable");
+}
+
+SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_merged(const char *key, const char *user_name, const char *domain_name,
+															  const char *ip, switch_xml_t *user, switch_event_t *params)
+{
+	switch_xml_t xml, domain, group, x_user, x_user_dup;
+	switch_status_t status = SWITCH_STATUS_FALSE;
+
+	if ((status = switch_xml_locate_user(key, user_name, domain_name, ip, &xml, &domain, &x_user, &group, params)) == SWITCH_STATUS_SUCCESS) {
+		x_user_dup = switch_xml_dup(x_user);
+		switch_xml_merge_user(x_user_dup, domain, group);
+		*user = x_user_dup;
+	}
+
+	return status;
+
+}
+
 SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
 													   const char *user_name,
 													   const char *domain_name,