Find file
Fetching contributors…
Cannot retrieve contributors at this time
178 lines (164 sloc) 5.46 KB
---------------------------------------------------------------------
-- LuaSoap implementation for Lua.
-- See Copyright Notice in license.html
-- $Id: soap.lua,v 1.5 2004/11/03 13:29:51 tomas Exp $
---------------------------------------------------------------------
require"lxp.lom"
local assert, ipairs, pairs, tostring, type = assert, ipairs, pairs, tostring, type
local getn, tconcat, tinsert, tremove = table.getn, table.concat, table.insert, table.remove
local format, strfind = string.format, string.find
local max = math.max
local parse = lxp.lom.parse
module (arg and arg[1])
_COPYRIGHT = "Copyright (C) 2004 Kepler Project"
_DESCRIPTION = "LuaSOAP provides a very simple API that convert Lua tables to and from XML documents"
_NAME = "LuaSOAP"
_VERSION = "1.0b"
local serialize
---------------------------------------------------------------------
-- Serialize the table of attributes.
-- @param a Table with the attributes of an element.
-- @return String representation of the object.
---------------------------------------------------------------------
local function attrs (a)
if not a then
return "" -- no attributes
else
local c = {}
if a[1] then
for i, v in ipairs (a) do
tinsert (c, format ("%s=%q", v, a[v]))
end
else
for i, v in pairs (a) do
tinsert (c, format ("%s=%q", i, v))
end
end
if getn (c) > 0 then
return " "..tconcat (c, " ")
else
return ""
end
end
end
---------------------------------------------------------------------
-- Serialize the children of an object.
-- @param obj Table with the object to be serialized.
-- @return String representation of the children.
---------------------------------------------------------------------
local function contents (obj)
if not obj[1] then
contents = ""
else
local c = {}
for i, v in ipairs (obj) do
c[i] = serialize (v)
end
return tconcat (c)
end
end
---------------------------------------------------------------------
-- Serialize an object.
-- @param obj Table with the object to be serialized.
-- @return String with representation of the object.
---------------------------------------------------------------------
serialize = function (obj)
local tt = type(obj)
if tt == "string" or tt == "number" then
return obj
elseif tt == "table" then
local t = obj.tag
assert (t, "Invalid table format (no `tag' field)")
return format ("<%s%s>%s</%s>", t, attrs(obj.attr), contents(obj), t)
else
return ""
end
end
---------------------------------------------------------------------
-- @param attr Table of object's attributes.
-- @return String with the value of the namespace ("xmlns") field.
---------------------------------------------------------------------
local function find_xmlns (attr)
for a, v in pairs (attr) do
if strfind (a, "xmlns", 1, 1) then
return v
end
end
end
---------------------------------------------------------------------
-- Add header element (if it exists) to object.
-- Cleans old header element anyway.
---------------------------------------------------------------------
local header_template = {
tag = "SOAP-ENV:Header",
}
local function insert_header (obj, header)
-- removes old header
if obj[2] then
tremove (obj, 1)
end
if header then
header_template[1] = header
tinsert (obj, 1, header_template)
end
end
local envelope_template = {
tag = "SOAP-ENV:Envelope",
attr = { "xmlns:SOAP-ENV", "SOAP-ENV:encodingStyle",
["xmlns:SOAP-ENV"] = "http://schemas.xmlsoap.org/soap/envelope/",
["SOAP-ENV:encodingStyle"] = "http://schemas.xmlsoap.org/soap/encoding/",
},
{
tag = "SOAP-ENV:Body",
[1] = {
tag = nil, -- must be filled
attr = {}, -- must be filled
},
}
}
---------------------------------------------------------------------
-- Converts a LuaExpat table into a SOAP message.
-- @param namespace String with the namespace of the elements.
-- @param method String with the method's name.
-- @param entries Table of SOAP elements (LuaExpat's format).
-- @param header Table describing the header of the SOAP-ENV (optional).
-- @return String with SOAP-ENV element.
---------------------------------------------------------------------
function encode (namespace, method, entries, header)
-- Cleans old header and insert a new one (if it exists).
insert_header (envelope_template, header)
-- Sets new body contents (and erase old content).
local body = (envelope_template[2] and envelope_template[2][1]) or envelope_template[1][1]
for i = 1, max (getn(body), getn(entries)) do
body[i] = entries[i]
end
-- Sets method (actually, the table's tag) and namespace.
body.tag = (namespace and "m:" or "")..method
body.attr["xmlns:m"] = namespace
return serialize (envelope_template)
end
---------------------------------------------------------------------
-- Converts a SOAP message into Lua objects.
-- @param doc String with SOAP document.
-- @return String with namespace, String with method's name and
-- Table with SOAP elements (LuaExpat's format).
---------------------------------------------------------------------
function decode (doc)
local obj = assert (parse (doc))
assert (obj.tag == "SOAP-ENV:Envelope", "Not a SOAP Envelope: "..
tostring(obj.tag))
local namespace = find_xmlns (obj.attr)
if obj[1].tag == "SOAP-ENV:Body" then
obj = obj[1]
elseif obj[2].tag == "SOAP-ENV:Body" then
obj = obj[2]
else
error ("Couldn't find SOAP Body!")
end
local _, _, method = strfind (obj[1].tag, "^.*:(.*)$")
local entries = {}
for i, el in ipairs (obj[1]) do
entries[i] = el
end
return namespace, method, entries
end