dotfiles/vim/bundle/webapi-vim/autoload/webapi/xmlrpc.vim

260 lines
7.9 KiB
VimL
Raw Normal View History

2013-07-07 21:25:47 +00:00
" xmlrpc
" Last Change: 2010-11-05
" Maintainer: Yasuhiro Matsumoto <mattn.jp@gmail.com>
" License: This file is placed in the public domain.
" Reference:
" http://tools.ietf.org/rfc/rfc3529.txt
let s:save_cpo = &cpo
set cpo&vim
let s:system = function(get(g:, 'webapi#system_function', 'system'))
function! webapi#xmlrpc#nil()
return 0
endfunction
function! webapi#xmlrpc#true()
return 1
endfunction
function! webapi#xmlrpc#false()
return 0
endfunction
function! s:get_childNode(node)
let child = a:node.childNode('value').childNode()
if empty(child)
let child = a:node.childNode('value')
endif
return child
endfunction
function! s:from_value(value)
let value = a:value
if value.name == 'methodResponse'
let param = value.childNode('params').childNodes('param')
if len(param) == 1
return s:from_value(s:get_childNode(param[0]))
else
let ret = []
for v in param
call add(ret, s:from_value(s:get_childNode(v)))
endfor
return ret
endif
elseif value.name == 'string'
return value.value()
elseif value.name == 'base64'
return value.value()
elseif value.name == 'dateTime.iso8601'
return value.value()
elseif value.name == 'boolean'
return 0+substitute(value.value(), "[ \n\r]", '', 'g')
elseif value.name == 'int'
return 0+substitute(value.value(), "[ \n\r]", '', 'g')
elseif value.name == 'i4'
return 0+substitute(value.value(), "[ \n\r]", '', 'g')
elseif value.name == 'double'
return str2float(substitute(value.value(), "[ \n\r]", '', 'g'))
elseif value.name == 'struct'
let ret = {}
for member in value.childNodes('member')
let ret[member.childNode('name').value()] = s:from_value(s:get_childNode(member))
endfor
return ret
elseif value.name == 'array'
let ret = []
for v in value.childNode('data').childNodes('value')
let child = v.childNode()
if !empty(child)
call add(ret, s:from_value(child))
else
call add(ret, v.value())
endif
endfor
return ret
elseif value.name == 'nil'
if get(g:, 'webapi#xmlrpc#allow_nil', 0) != 0
return function('webapi#xmlrpc#nil')
endif
return 0
elseif value.name == 'value'
return value.value()
else
throw "unknown type: ".value.name
endif
endfunction
function! s:to_value(content)
if type(a:content) == 4
if has_key(a:content, 'bits')
let struct = webapi#xml#createElement("struct")
let member = webapi#xml#createElement("member")
call add(struct.child, member)
let name = webapi#xml#createElement("name")
call add(member.child, name)
call name.value("name")
let value = webapi#xml#createElement("value")
call add(member.child, value)
call add(value.child, s:to_value(a:content["name"]))
let member = webapi#xml#createElement("member")
call add(struct.child, member)
let name = webapi#xml#createElement("name")
call name.value("bits")
call add(member.child, name)
let value = webapi#xml#createElement("value")
call add(member.child, value)
let base64 = webapi#xml#createElement("base64")
call add(value.child, base64)
if has_key(a:content, "bits") && len(a:content["bits"])
call base64.value(a:content["bits"])
elseif has_key(a:content, "path")
let quote = &shellxquote == '"' ? "'" : '"'
let bits = substitute(s:system("xxd -ps ".quote.a:content["path"].quote), "[ \n\r]", '', 'g')
call base64.value(webapi#base64#b64encodebin(bits))
endif
return struct
else
let struct = webapi#xml#createElement("struct")
for key in keys(a:content)
let member = webapi#xml#createElement("member")
let name = webapi#xml#createElement("name")
call name.value(key)
call add(member.child, name)
let value = webapi#xml#createElement("value")
call add(value.child, s:to_value(a:content[key]))
call add(member.child, value)
call add(struct.child, member)
endfor
return struct
endif
elseif type(a:content) == 3
let array = webapi#xml#createElement("array")
let data = webapi#xml#createElement("data")
for item in a:content
let value = webapi#xml#createElement("value")
call add(value.child, s:to_value(item))
call add(data.child, value)
endfor
call add(array.child, data)
return array
elseif type(a:content) == 2
if a:content == function('webapi#xmlrpc#true')
let true = webapi#xml#createElement("boolean")
call true.value('true')
return true
elseif a:content == function('webapi#xmlrpc#false')
let false = webapi#xml#createElement("boolean")
call false.value('false')
return false
else
return webapi#xml#createElement("nil")
endif
elseif type(a:content) <= 1 || type(a:content) == 5
if type(a:content) == 0
let int = webapi#xml#createElement("int")
call int.value(a:content)
return int
elseif type(a:content) == 1
let str = webapi#xml#createElement("string")
call str.value(a:content)
return str
elseif type(a:content) == 5
let double = webapi#xml#createElement("double")
call double.value(a:content)
return double
endif
endif
return {}
endfunction
function! s:to_fault(dom)
let struct = a:dom.find('struct')
let faultCode = ""
let faultString = ""
for member in struct.childNodes('member')
if member.childNode('name').value() == "faultCode"
let faultCode = member.childNode('value').value()
elseif member.childNode('name').value() == "faultString"
let faultString = member.childNode('value').value()
endif
endfor
return faultCode.":".faultString
endfunction
"add_node_params
"Add list of args on the xml tree.
"input: list of args
"output: none
function! s:add_node_params(args)
let params = webapi#xml#createElement("params")
for Arg in a:args
let param = webapi#xml#createElement("param")
let value = webapi#xml#createElement("value")
call value.value(s:to_value(Arg))
call add(param.child, value)
call add(params.child, param)
unlet Arg
endfor
return params
endfunction
function! webapi#xmlrpc#call(uri, func, args)
let methodCall = webapi#xml#createElement("methodCall")
let methodName = webapi#xml#createElement("methodName")
call methodName.value(a:func)
call add(methodCall.child, methodName)
if !empty(a:args)
call add(methodCall.child, s:add_node_params(a:args))
endif
let xml = '<?xml version="1.0" encoding="utf-8"?>'
let xml .= iconv(methodCall.toString(), &encoding, "utf-8")
let res = webapi#http#post(a:uri, xml, {"Content-Type": "text/xml"})
let dom = webapi#xml#parse(res.content)
if len(dom.find('fault'))
throw s:to_fault(dom)
else
return s:from_value(dom)
endif
endfunction
function! webapi#xmlrpc#wrap(contexts)
let api = {}
for context in a:contexts
let target = api
let namespaces = split(context.name, '\.')[:-2]
if len(namespaces) > 0
for ns in namespaces
if !has_key(target, ns)
let target[ns] = {".uri": context.uri}
endif
let target = target[ns]
let api['.uri'] = target['.uri']
endfor
endif
if len(context.argnames) && context.argnames[-1] == '...'
let arglist = '[' . join(map(copy(context.argnames[:-2]),'"a:".v:val'),',') . ']+a:000'
else
let arglist = '[' . join(map(copy(context.argnames),'"a:".v:val'),',') . ']'
endif
if has_key(context, 'alias')
exe "function api.".context.alias."(".join(context.argnames,",").") dict\n"
\. " return webapi#xmlrpc#call(self['.uri'], '".context.name."', ".arglist.")\n"
\. "endfunction\n"
else
exe "function api.".context.name."(".join(context.argnames,",").") dict\n"
\. " return webapi#xmlrpc#call('".context.uri."', '".context.name."', ".arglist.")\n"
\. "endfunction\n"
endif
endfor
return api
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo
" vim:set et: