util/datamapper.lua
author Jonas Schäfer <jonas@wielicki.name>
Sat, 15 Jan 2022 15:40:29 +0100
changeset 12193 82c8e855c850
parent 12137 11060c8919b6
child 12584 a9dbf657c894
permissions -rw-r--r--
mod_storage_xep0227: treat roster metadata pseudo-entry correctly The roster version is stored in a pseudo-item which has the key `false`. The if condition in the touched code attempts to guard against this, but it does not take into account that the jid prepping returns nil instead of false. By moving the jid prepping into the if, we can check for the metadata entry safely.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
local st = require("util.stanza");
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
     2
local pointer = require("util.jsonpointer");
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
11466
d1982b7eb00d util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents: 11465
diff changeset
     4
local schema_t = {}
d1982b7eb00d util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents: 11465
diff changeset
     5
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
local function toboolean(s)
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
	if s == "true" or s == "1" then
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
		return true
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
	elseif s == "false" or s == "0" then
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
		return false
11459
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    11
	elseif s then
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    12
		return true
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    13
	end
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    14
end
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    15
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    16
local function totype(t, s)
11483
377a9eaf7bef util.datamapper: Fix error on attempt to coerce nil to something
Kim Alvefur <zash@zash.se>
parents: 11480
diff changeset
    17
	if not s then
377a9eaf7bef util.datamapper: Fix error on attempt to coerce nil to something
Kim Alvefur <zash@zash.se>
parents: 11480
diff changeset
    18
		return nil
377a9eaf7bef util.datamapper: Fix error on attempt to coerce nil to something
Kim Alvefur <zash@zash.se>
parents: 11480
diff changeset
    19
	end
11459
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    20
	if t == "string" then
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    21
		return s
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    22
	elseif t == "boolean" then
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    23
		return toboolean(s)
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    24
	elseif t == "number" or t == "integer" then
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    25
		return tonumber(s)
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
	end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
11458
1d9c1893cc5e util.datamapper: Use enum instead of mutually exclusive booleans
Kim Alvefur <zash@zash.se>
parents: 11457
diff changeset
    29
local value_goes = {}
1d9c1893cc5e util.datamapper: Use enum instead of mutually exclusive booleans
Kim Alvefur <zash@zash.se>
parents: 11457
diff changeset
    30
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    31
local function resolve_schema(schema, root)
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    32
	if type(schema) == "table" and schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    33
		local referenced = pointer.resolve(root, schema["$ref"]:sub(2));
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    34
		if referenced ~= nil then
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    35
			return referenced
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    36
		end
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    37
	end
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    38
	return schema
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    39
end
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    40
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    41
local function unpack_propschema(propschema, propname, current_ns)
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    42
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    43
	local proptype = "string"
11470
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
    44
	local value_where = propname and "in_text_tag" or "in_text"
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    45
	local name = propname
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
    46
	local namespace
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    47
	local prefix
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    48
	local single_attribute
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    49
	local enums
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    50
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    51
	if type(propschema) == "table" then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    52
		proptype = propschema.type
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    53
	elseif type(propschema) == "string" then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    54
		proptype = propschema
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    55
	end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    56
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    57
	if proptype == "object" or proptype == "array" then
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    58
		value_where = "in_children"
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    59
	end
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    60
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    61
	if type(propschema) == "table" then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    62
		local xml = propschema.xml
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    63
		if xml then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    64
			if xml.name then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    65
				name = xml.name
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    66
			end
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
    67
			if xml.namespace and xml.namespace ~= current_ns then
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    68
				namespace = xml.namespace
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    69
			end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    70
			if xml.prefix then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    71
				prefix = xml.prefix
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    72
			end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    73
			if proptype == "array" and xml.wrapped then
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    74
				value_where = "in_wrapper"
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    75
			elseif xml.attribute then
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    76
				value_where = "in_attribute"
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    77
			elseif xml.text then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    78
				value_where = "in_text"
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    79
			elseif xml.x_name_is_value then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    80
				value_where = "in_tag_name"
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    81
			elseif xml.x_single_attribute then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    82
				single_attribute = xml.x_single_attribute
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    83
				value_where = "in_single_attribute"
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    84
			end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    85
		end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    86
		if propschema["const"] then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    87
			enums = {propschema["const"]}
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    88
		elseif propschema["enum"] then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    89
			enums = propschema["enum"]
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    90
		end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    91
	end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    92
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    93
	return proptype, value_where, name, namespace, prefix, single_attribute, enums
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    94
end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    95
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    96
local parse_object
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    97
local parse_array
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    98
11469
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
    99
local function extract_value(s, value_where, proptype, name, namespace, prefix, single_attribute, enums)
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   100
	if value_where == "in_tag_name" then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   101
		local c
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   102
		if proptype == "boolean" then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   103
			c = s:get_child(name, namespace);
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   104
		elseif enums and proptype == "string" then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   105
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   106
			for i = 1, #enums do
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   107
				c = s:get_child(enums[i], namespace);
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   108
				if c then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   109
					break
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   110
				end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   111
			end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   112
		else
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   113
			c = s:get_child(nil, namespace);
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   114
		end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   115
		if c then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   116
			return c.name
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   117
		end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   118
	elseif value_where == "in_attribute" then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   119
		local attr = name
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   120
		if prefix then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   121
			attr = prefix .. ":" .. name
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
   122
		elseif namespace and namespace ~= s.attr.xmlns then
11469
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   123
			attr = namespace .. "\1" .. name
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   124
		end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   125
		return s.attr[attr]
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   126
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   127
	elseif value_where == "in_text" then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   128
		return s:get_text()
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   129
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   130
	elseif value_where == "in_single_attribute" then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   131
		local c = s:get_child(name, namespace)
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   132
		return c and c.attr[single_attribute]
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   133
	elseif value_where == "in_text_tag" then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   134
		return s:get_child_text(name, namespace)
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   135
	end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   136
end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   137
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   138
function parse_object(schema, s, root)
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
	local out = {}
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   140
	schema = resolve_schema(schema, root)
11465
766b0eddd12c util.datamapper: Deal with type name changes in util.jsonschema
Kim Alvefur <zash@zash.se>
parents: 11462
diff changeset
   141
	if type(schema) == "table" and schema.properties then
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   142
		for prop, propschema in pairs(schema.properties) do
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   143
			propschema = resolve_schema(propschema, root)
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   144
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   145
			local proptype, value_where, name, namespace, prefix, single_attribute, enums = unpack_propschema(propschema, prop, s.attr.xmlns)
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   146
11469
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   147
			if value_where == "in_children" and type(propschema) == "table" then
11459
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
   148
				if proptype == "object" then
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   149
					local c = s:get_child(name, namespace)
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   150
					if c then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   151
						out[prop] = parse_object(propschema, c, root);
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   152
					end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   153
				elseif proptype == "array" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   154
					local a = parse_array(propschema, s, root);
11485
b2f9782497dd util.datamapper: Don't include empty unwrapped arrays
Kim Alvefur <zash@zash.se>
parents: 11483
diff changeset
   155
					if a and a[1] ~= nil then
b2f9782497dd util.datamapper: Don't include empty unwrapped arrays
Kim Alvefur <zash@zash.se>
parents: 11483
diff changeset
   156
						out[prop] = a;
b2f9782497dd util.datamapper: Don't include empty unwrapped arrays
Kim Alvefur <zash@zash.se>
parents: 11483
diff changeset
   157
					end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   158
				else
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   159
					error("unreachable")
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
				end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   161
			elseif value_where == "in_wrapper" and type(propschema) == "table" and proptype == "array" then
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   162
				local wrapper = s:get_child(name, namespace);
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   163
				if wrapper then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   164
					out[prop] = parse_array(propschema, wrapper, root);
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   165
				end
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   166
			else
11469
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   167
				local value = extract_value(s, value_where, proptype, name, namespace, prefix, single_attribute, enums)
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   168
11459
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
   169
				out[prop] = totype(proptype, value)
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
   170
			end
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   171
		end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   172
	end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   173
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   174
	return out
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   176
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   177
function parse_array(schema, s, root)
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   178
	local itemschema = resolve_schema(schema.items, root);
11475
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   179
	local proptype, value_where, child_name, namespace, prefix, single_attribute, enums = unpack_propschema(itemschema, nil, s.attr.xmlns)
11470
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
   180
	local attr_name
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
   181
	if value_where == "in_single_attribute" then
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
   182
		value_where = "in_attribute";
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
   183
		attr_name = single_attribute;
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
   184
	end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   185
	local out = {}
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   186
11475
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   187
	if proptype == "object" then
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   188
		if type(itemschema) == "table" then
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   189
			for c in s:childtags(child_name, namespace) do
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   190
				table.insert(out, parse_object(itemschema, c, root));
11475
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   191
			end
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   192
		else
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   193
			error("array items must be schema object")
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   194
		end
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   195
	elseif proptype == "array" then
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   196
		if type(itemschema) == "table" then
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   197
			for c in s:childtags(child_name, namespace) do
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   198
				table.insert(out, parse_array(itemschema, c, root));
11475
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   199
			end
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   200
		end
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   201
	else
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   202
		for c in s:childtags(child_name, namespace) do
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   203
			local value = extract_value(c, value_where, proptype, attr_name or child_name, namespace, prefix, single_attribute, enums)
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   204
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   205
			table.insert(out, totype(proptype, value));
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   206
		end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   207
	end
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   208
	return out
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   209
end
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   210
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   211
local function parse(schema, s)
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
	if schema.type == "object" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   213
		return parse_object(schema, s, schema)
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   214
	elseif schema.type == "array" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   215
		return parse_array(schema, s, schema)
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   216
	else
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   217
		error("top-level scalars unsupported")
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   218
	end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   219
end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   220
11479
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   221
local function toxmlstring(proptype, v)
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   222
	if proptype == "string" and type(v) == "string" then
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   223
		return v
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   224
	elseif proptype == "number" and type(v) == "number" then
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   225
		return string.format("%g", v)
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   226
	elseif proptype == "integer" and type(v) == "number" then
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   227
		return string.format("%d", v)
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   228
	elseif proptype == "boolean" then
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   229
		return v and "1" or "0"
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   230
	end
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   231
end
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   232
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   233
local unparse
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   234
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   235
local function unparse_property(out, v, proptype, propschema, value_where, name, namespace, current_ns, prefix,
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   236
	single_attribute, root)
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   237
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   238
	if value_where == "in_attribute" then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   239
		local attr = name
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   240
		if prefix then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   241
			attr = prefix .. ":" .. name
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
   242
		elseif namespace and namespace ~= current_ns then
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   243
			attr = namespace .. "\1" .. name
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   244
		end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   245
11479
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   246
		out.attr[attr] = toxmlstring(proptype, v)
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   247
	elseif value_where == "in_text" then
11479
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   248
		out:text(toxmlstring(proptype, v))
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   249
	elseif value_where == "in_single_attribute" then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   250
		assert(single_attribute)
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   251
		local propattr = {}
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   252
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
   253
		if namespace and namespace ~= current_ns then
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   254
			propattr.xmlns = namespace
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   255
		end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   256
11479
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   257
		propattr[single_attribute] = toxmlstring(proptype, v)
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   258
		out:tag(name, propattr):up();
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   259
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   260
	else
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   261
		local propattr
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   262
		if namespace ~= current_ns then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   263
			propattr = {xmlns = namespace}
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   264
		end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   265
		if value_where == "in_tag_name" then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   266
			if proptype == "string" and type(v) == "string" then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   267
				out:tag(v, propattr):up();
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   268
			elseif proptype == "boolean" and v == true then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   269
				out:tag(name, propattr):up();
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   270
			end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   271
		elseif proptype == "object" and type(propschema) == "table" and type(v) == "table" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   272
			local c = unparse(propschema, v, name, namespace, nil, root);
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   273
			if c then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   274
				out:add_direct_child(c);
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   275
			end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   276
		elseif proptype == "array" and type(propschema) == "table" and type(v) == "table" then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   277
			if value_where == "in_wrapper" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   278
				local c = unparse(propschema, v, name, namespace, nil, root);
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   279
				if c then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   280
					out:add_direct_child(c);
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   281
				end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   282
			else
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   283
				unparse(propschema, v, name, namespace, out, root);
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   284
			end
11479
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   285
		else
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   286
			out:text_tag(name, toxmlstring(proptype, v), propattr)
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   287
		end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   288
	end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   289
end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   290
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   291
function unparse(schema, t, current_name, current_ns, ctx, root)
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   292
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   293
	if root == nil then
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   294
		root = schema
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   295
	end
11440
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   296
11462
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   297
	if schema.xml then
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   298
		if schema.xml.name then
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   299
			current_name = schema.xml.name
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   300
		end
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   301
		if schema.xml.namespace then
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   302
			current_ns = schema.xml.namespace
11440
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   303
		end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   304
11462
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   305
	end
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   306
11466
d1982b7eb00d util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents: 11465
diff changeset
   307
	local out = ctx or st.stanza(current_name, {xmlns = current_ns})
11462
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   308
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   309
	if schema.type == "object" then
11440
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   310
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   311
		for prop, propschema in pairs(schema.properties) do
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   312
			propschema = resolve_schema(propschema, root)
11440
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   313
			local v = t[prop]
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   314
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   315
			if v ~= nil then
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   316
				local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(propschema, prop, current_ns)
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   317
				unparse_property(out, v, proptype, propschema, value_where, name, namespace, current_ns, prefix, single_attribute, root)
11440
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   318
			end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   319
		end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   320
		return out
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   321
11462
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   322
	elseif schema.type == "array" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   323
		local itemschema = resolve_schema(schema.items, root)
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   324
		local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(itemschema, current_name, current_ns)
11472
348b191cd850 util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents: 11471
diff changeset
   325
		for _, item in ipairs(t) do
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   326
			unparse_property(out, item, proptype, itemschema, value_where, name, namespace, current_ns, prefix, single_attribute, root)
11462
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   327
		end
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   328
		return out
11440
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   329
	end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   330
end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   331
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   332
return {parse = parse; unparse = unparse}