util/datamapper.lua
author Matthew Wild <mwild1@gmail.com>
Wed, 27 Mar 2024 15:35:15 +0000
branch0.12
changeset 13469 54a936345aaa
parent 12584 a9dbf657c894
child 12786 8815d3090928
permissions -rw-r--r--
prosodyctl check: Warn about invalid domain names in the config file This ensures that domain names of virtual hosts and components are valid in XMPP, and that they are encoded correctly.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12584
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
     1
-- This file is generated from teal-src/util/datamapper.lua
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
     2
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
local st = require("util.stanza");
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
     4
local pointer = require("util.jsonpointer");
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
11466
d1982b7eb00d util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents: 11465
diff changeset
     6
local schema_t = {}
d1982b7eb00d util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents: 11465
diff changeset
     7
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
local function toboolean(s)
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
	if s == "true" or s == "1" then
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
		return true
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
	elseif s == "false" or s == "0" then
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
		return false
11459
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    13
	elseif s then
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    14
		return true
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    15
	end
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    16
end
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    17
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    18
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
    19
	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
    20
		return nil
377a9eaf7bef util.datamapper: Fix error on attempt to coerce nil to something
Kim Alvefur <zash@zash.se>
parents: 11480
diff changeset
    21
	end
11459
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    22
	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
    23
		return 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 == "boolean" then
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    25
		return toboolean(s)
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
    26
	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
    27
		return tonumber(s)
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
	end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
11458
1d9c1893cc5e util.datamapper: Use enum instead of mutually exclusive booleans
Kim Alvefur <zash@zash.se>
parents: 11457
diff changeset
    31
local value_goes = {}
1d9c1893cc5e util.datamapper: Use enum instead of mutually exclusive booleans
Kim Alvefur <zash@zash.se>
parents: 11457
diff changeset
    32
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    33
local function resolve_schema(schema, root)
12584
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    34
	if type(schema) == "table" then
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    35
		if schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    36
			return pointer.resolve(root, schema["$ref"]:sub(2))
12137
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
	end
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    39
	return schema
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    40
end
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
    41
12584
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    42
local function guess_schema_type(schema)
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    43
	local schema_types = schema.type
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    44
	if type(schema_types) == "string" then
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    45
		return schema_types
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    46
	elseif schema_types ~= nil then
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    47
		error("schema has unsupported 'type' property")
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    48
	elseif schema.properties then
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    49
		return "object"
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    50
	elseif schema.items then
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    51
		return "array"
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    52
	end
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    53
	return "string"
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    54
end
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    55
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    56
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
    57
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    58
	local proptype = "string"
11470
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
    59
	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
    60
	local name = propname
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
    61
	local namespace
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    62
	local prefix
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    63
	local single_attribute
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    64
	local enums
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    65
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    66
	if type(propschema) == "table" then
12584
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    67
		proptype = guess_schema_type(propschema);
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    68
	elseif type(propschema) == "string" then
12584
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
    69
		error("schema as string is not supported: " .. propschema .. " {" .. current_ns .. "}" .. propname)
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    70
	end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    71
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    72
	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
    73
		value_where = "in_children"
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    74
	end
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    75
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    76
	if type(propschema) == "table" then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    77
		local xml = propschema.xml
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    78
		if xml then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    79
			if xml.name then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    80
				name = xml.name
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    81
			end
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
    82
			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
    83
				namespace = xml.namespace
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
			if xml.prefix then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    86
				prefix = xml.prefix
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    87
			end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    88
			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
    89
				value_where = "in_wrapper"
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
    90
			elseif xml.attribute then
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    91
				value_where = "in_attribute"
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    92
			elseif xml.text then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    93
				value_where = "in_text"
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    94
			elseif xml.x_name_is_value then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    95
				value_where = "in_tag_name"
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    96
			elseif xml.x_single_attribute then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    97
				single_attribute = xml.x_single_attribute
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    98
				value_where = "in_single_attribute"
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
    99
			end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   100
		end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   101
		if propschema["const"] then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   102
			enums = {propschema["const"]}
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   103
		elseif propschema["enum"] then
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   104
			enums = propschema["enum"]
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   105
		end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   106
	end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   107
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   108
	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
   109
end
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   110
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   111
local parse_object
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   112
local parse_array
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   113
11469
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   114
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
   115
	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
   116
		local c
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   117
		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
   118
			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
   119
		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
   120
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   121
			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
   122
				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
   123
				if c then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   124
					break
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   125
				end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   126
			end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   127
		else
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   128
			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
   129
		end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   130
		if c then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   131
			return c.name
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   132
		end
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_attribute" then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   134
		local attr = name
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   135
		if prefix then
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   136
			attr = prefix .. ":" .. name
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
   137
		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
   138
			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
   139
		end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   140
		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
   141
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   142
	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
   143
		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
   144
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   145
	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
   146
		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
   147
		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
   148
	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
   149
		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
   150
	end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   151
end
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   152
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   153
function parse_object(schema, s, root)
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   154
	local out = {}
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   155
	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
   156
	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
   157
		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
   158
			propschema = resolve_schema(propschema, root)
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   160
			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
   161
11469
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   162
			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
   163
				if proptype == "object" then
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   164
					local c = s:get_child(name, namespace)
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   165
					if c then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   166
						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
   167
					end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   168
				elseif proptype == "array" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   169
					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
   170
					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
   171
						out[prop] = a;
b2f9782497dd util.datamapper: Don't include empty unwrapped arrays
Kim Alvefur <zash@zash.se>
parents: 11483
diff changeset
   172
					end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   173
				else
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   174
					error("unreachable")
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
				end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   176
			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
   177
				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
   178
				if wrapper then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   179
					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
   180
				end
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   181
			else
11469
19a88b61ab4e util.datamapper: Factor out extraction of the XML part to use
Kim Alvefur <zash@zash.se>
parents: 11468
diff changeset
   182
				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
   183
11459
a5050e21ab08 util.datamapper: Separate extraction of xml from coercion to target type
Kim Alvefur <zash@zash.se>
parents: 11458
diff changeset
   184
				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
   185
			end
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   186
		end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   187
	end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   188
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   189
	return out
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   190
end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   191
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   192
function parse_array(schema, s, root)
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   193
	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
   194
	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
   195
	local attr_name
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
   196
	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
   197
		value_where = "in_attribute";
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
   198
		attr_name = single_attribute;
c098d07e6717 util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11469
diff changeset
   199
	end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   200
	local out = {}
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   201
11475
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   202
	if proptype == "object" then
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   203
		if type(itemschema) == "table" then
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   204
			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
   205
				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
   206
			end
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   207
		else
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   208
			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
   209
		end
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   210
	elseif proptype == "array" then
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   211
		if type(itemschema) == "table" then
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   212
			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
   213
				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
   214
			end
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   215
		end
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   216
	else
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   217
		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
   218
			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
   219
ab03de8e503e util.datamapper: Handle nested arrays or objects in arrays
Kim Alvefur <zash@zash.se>
parents: 11474
diff changeset
   220
			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
   221
		end
11461
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   222
	end
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   223
	return out
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   224
end
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   225
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   226
local function parse(schema, s)
12584
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
   227
	local s_type = guess_schema_type(schema)
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
   228
	if s_type == "object" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   229
		return parse_object(schema, s, schema)
12584
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
   230
	elseif s_type == "array" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   231
		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
   232
	else
6a51749af7f4 util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents: 11460
diff changeset
   233
		error("top-level scalars unsupported")
11439
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   234
	end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   235
end
a1fa6202fa13 util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   236
11479
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   237
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
   238
	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
   239
		return v
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   240
	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
   241
		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
   242
	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
   243
		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
   244
	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
   245
		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
   246
	end
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   247
end
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   248
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   249
local unparse
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   250
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   251
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
   252
	single_attribute, root)
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   253
11471
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   254
	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
   255
		local attr = name
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   256
		if prefix then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   257
			attr = prefix .. ":" .. name
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
   258
		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
   259
			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
   260
		end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   261
11479
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   262
		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
   263
	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
   264
		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
   265
	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
   266
		assert(single_attribute)
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   267
		local propattr = {}
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   268
11480
83e127eb91f9 util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents: 11479
diff changeset
   269
		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
   270
			propattr.xmlns = namespace
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   271
		end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   272
11479
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   273
		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
   274
		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
   275
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   276
	else
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   277
		local propattr
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   278
		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
   279
			propattr = {xmlns = namespace}
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   280
		end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   281
		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
   282
			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
   283
				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
   284
			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
   285
				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
   286
			end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   287
		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
   288
			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
   289
			if c then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   290
				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
   291
			end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   292
		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
   293
			if value_where == "in_wrapper" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   294
				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
   295
				if c then
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   296
					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
   297
				end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   298
			else
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   299
				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
   300
			end
11479
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   301
		else
9bd36e871f05 util.datamapper: Factor out conversion from any value to XML string
Kim Alvefur <zash@zash.se>
parents: 11475
diff changeset
   302
			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
   303
		end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   304
	end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   305
end
88792dd2bee9 util.datamapper: Factor out handling of object properties for array reuse
Kim Alvefur <zash@zash.se>
parents: 11470
diff changeset
   306
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   307
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
   308
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   309
	if root == nil then
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   310
		root = schema
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   311
	end
11440
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   312
11462
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   313
	if schema.xml then
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   314
		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
   315
			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
   316
		end
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   317
		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
   318
			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
   319
		end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   320
11462
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   321
	end
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   322
11466
d1982b7eb00d util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents: 11465
diff changeset
   323
	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
   324
12584
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
   325
	local s_type = guess_schema_type(schema)
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
   326
	if s_type == "object" then
11440
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   327
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   328
		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
   329
			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
   330
			local v = t[prop]
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
			if v ~= nil then
11460
4e376a43fe40 util.datamapper: Factor out common schema unpacking
Kim Alvefur <zash@zash.se>
parents: 11459
diff changeset
   333
				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
   334
				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
   335
			end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   336
		end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   337
		return out
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   338
12584
a9dbf657c894 util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents: 12137
diff changeset
   339
	elseif s_type == "array" then
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   340
		local itemschema = resolve_schema(schema.items, root)
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   341
		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
   342
		for _, item in ipairs(t) do
12137
11060c8919b6 util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents: 11485
diff changeset
   343
			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
   344
		end
0e00fa518688 util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents: 11461
diff changeset
   345
		return out
11440
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   346
	end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   347
end
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   348
5df9ffc25bb4 util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents: 11439
diff changeset
   349
return {parse = parse; unparse = unparse}