119 lines
3.6 KiB
VimL
119 lines
3.6 KiB
VimL
|
" soap
|
||
|
" Last Change: 2010-09-10
|
||
|
" Maintainer: Yasuhiro Matsumoto <mattn.jp@gmail.com>
|
||
|
" License: This file is placed in the public domain.
|
||
|
" Reference:
|
||
|
" http://tools.ietf.org/rfc/rfc4743.txt
|
||
|
|
||
|
let s:save_cpo = &cpo
|
||
|
set cpo&vim
|
||
|
|
||
|
function! s:soap_call(url, func, ...)
|
||
|
let envelope = webapi#xml#createElement("soap:Envelope")
|
||
|
let envelope.attr["xmlns:soap"] = "http://schemas.xmlsoap.org/soap/envelope/"
|
||
|
let envelope.attr["xmlns:xsi"] = "http://www.w3.org/2001/XMLSchema-instance"
|
||
|
|
||
|
let body = webapi#xml#createElement("soap:Body")
|
||
|
call add(envelope.child, body)
|
||
|
let func = webapi#xml#createElement(a:func)
|
||
|
call add(body.child, func)
|
||
|
|
||
|
let n = 1
|
||
|
for a in a:000
|
||
|
let arg = webapi#xml#createElement("param".n)
|
||
|
let arg.attr["xsi:type"] = "xsd:string"
|
||
|
call arg.value(a)
|
||
|
call add(func.child, arg)
|
||
|
let n += 1
|
||
|
endfor
|
||
|
|
||
|
let str = '<?xml version="1.0" encoding="UTF-8"?>' . envelope.toString()
|
||
|
let res = webapi#http#post(a:url, str)
|
||
|
let dom = webapi#xml#parse(res.content)
|
||
|
return s:parse_return(dom.find("return"))
|
||
|
endfunction
|
||
|
|
||
|
function! s:parse_return(node)
|
||
|
if a:node.attr["xsi:type"] =~ ":Array$"
|
||
|
let arr = []
|
||
|
for item in a:node.child
|
||
|
call add(ret, s:parse_return(item.child)
|
||
|
endfor
|
||
|
let ret = arr
|
||
|
elseif a:node.attr["xsi:type"] =~ ":Map$"
|
||
|
let ret = {}
|
||
|
for item in a:node.childNodes("item")
|
||
|
let val = item.childNode("value")
|
||
|
if val.attr["xsi:type"] =~ ":Map$"
|
||
|
let ret[item.childNode("key").value()] = s:parse_return(val)
|
||
|
else
|
||
|
let ret[item.childNode("key").value()] = item.childNode("value").value()
|
||
|
endif
|
||
|
endfor
|
||
|
else
|
||
|
if len(a:node.child)
|
||
|
let arr = []
|
||
|
for item in a:node.child
|
||
|
call add(arr, s:parse_return(item)
|
||
|
endfor
|
||
|
let ret = arr
|
||
|
else
|
||
|
let ret = s:parse_return(a:node)
|
||
|
endif
|
||
|
endif
|
||
|
return ret
|
||
|
endfunction
|
||
|
|
||
|
function! s:get_convert_code(arg)
|
||
|
let code = ''
|
||
|
let arg = a:arg
|
||
|
if arg.type == "xsd:string"
|
||
|
let code .= "let ".arg.name." = a:".arg.name
|
||
|
elseif arg.type == "xsd:int"
|
||
|
let code .= "let ".arg.name." = 0+a:".arg.name
|
||
|
elseif arg.type == "xsd:boolean"
|
||
|
let code .= "let ".arg.name." = (0+a:".arg.name.") ? 'true' : 'false'"
|
||
|
elseif arg.type == "xsd:float"
|
||
|
let code .= "let ".arg.name." = nr2float(0+a:".arg.name.")"
|
||
|
elseif arg.type =~ ":Array$"
|
||
|
let code .= "let ".arg.name." = a:".arg.name
|
||
|
else
|
||
|
throw "unknown type:". arg.type
|
||
|
endif
|
||
|
return code
|
||
|
endfunction
|
||
|
|
||
|
function! webapi#soap#proxy(url)
|
||
|
let dom = webapi#xml#parseURL(a:url)
|
||
|
let l:api = {}
|
||
|
let action = dom.childNode("service").find("soap:address").attr["location"]
|
||
|
let operations = dom.childNode("portType").childNodes("operation")
|
||
|
for operation in operations
|
||
|
let name = operation.attr["name"]
|
||
|
let inp = substitute(operation.childNode("input").attr["message"], "^tns:", "", "")
|
||
|
let out = substitute(operation.childNode("output").attr["message"], "^tns:", "", "")
|
||
|
let message = dom.childNode("message", {"name": inp})
|
||
|
let args = []
|
||
|
for part in message.childNodes("part")
|
||
|
call add(args, {"name": part.attr["name"], "type": part.attr["type"]})
|
||
|
endfor
|
||
|
let argnames = []
|
||
|
let code = ""
|
||
|
for arg in args
|
||
|
call add(argnames, arg.name)
|
||
|
let code .= " ".s:get_convert_code(arg)."\n"
|
||
|
endfor
|
||
|
let code .= " return s:soap_call(".string(action).", ".string(name).", ".join(argnames, ",").")\n"
|
||
|
let source = "function! l:api.".name."(".join(argnames, ",").") dict\n"
|
||
|
let source .= code
|
||
|
let source .= "endfunction\n"
|
||
|
exe source
|
||
|
endfor
|
||
|
return api
|
||
|
endfunction
|
||
|
|
||
|
let &cpo = s:save_cpo
|
||
|
unlet s:save_cpo
|
||
|
|
||
|
" vim:set et:
|