blob: 849b44405ba93cfa227ba49875b4f76d08da81eb [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# JSON data conversion functions
try:
import json
except:
from django.utils import simplejson as json
from StringIO import StringIO
from util import *
from elemutil import *
# Return true if a list represents a JS array
def isJSArray(l):
if isNil(l):
return True
v = car(l)
if isSymbol(v):
return False
if isList(v):
if not isNil(v) and isSymbol(car(v)):
return False
return True
# Converts JSON properties to values
def jsPropertiesToValues(propertiesSoFar, o, i):
if isNil(i):
return propertiesSoFar
p = car(i)
jsv = o[p]
v = jsValToValue(jsv)
if isinstance(p, basestring):
n = str(p)
if n[0:1] == "@":
return jsPropertiesToValues(cons((attribute, "'" + n[1:], v), propertiesSoFar), o, cdr(i))
if isList(v) and not isJSArray(v):
return jsPropertiesToValues(cons(cons(element, cons("'" + n, v)), propertiesSoFar), o, cdr(i))
return jsPropertiesToValues(cons((element, "'" + n, v), propertiesSoFar), o, cdr(i))
return jsPropertiesToValues(cons(v, propertiesSoFar), o, cdr(i))
# Converts a JSON val to a value
def jsValToValue(jsv):
if jsv is None:
return None
if isinstance(jsv, dict):
return jsPropertiesToValues((), jsv, tuple(jsv.keys()))
if isList(jsv):
return jsPropertiesToValues((), jsv, tuple(reversed(range(0, len(jsv)))))
if isinstance(jsv, basestring):
return str(jsv)
return jsv
# Return true if a list of strings contains a JSON document
def isJSON(l):
if isNil(l):
return False
s = car(l)[0:1]
return s == "[" or s == "{"
# Convert a list of strings representing a JSON document to a list of values
def readJSON(l):
s = StringIO()
writeStrings(l, s)
val = json.loads(s.getvalue())
return jsValToValue(val)
# Convert a list of values to JSON array elements
def valuesToJSElements(a, l, i):
if isNil(l):
return a
pv = valueToJSVal(car(l))
a[i] = pv
return valuesToJSElements(a, cdr(l), i + 1)
# Convert a value to a JSON value
def valueToJSVal(v):
if not isList(v):
return v
if isJSArray(v):
return valuesToJSElements(list(range(0, len(v))), v, 0)
return valuesToJSProperties({}, v)
# Convert a list of values to JSON properties
def valuesToJSProperties(o, l):
if isNil(l):
return o
token = car(l)
if isTaggedList(token, attribute):
pv = valueToJSVal(attributeValue(token))
o["@" + attributeName(token)[1:]] = pv
elif isTaggedList(token, element):
if elementHasValue(token):
pv = valueToJSVal(elementValue(token))
o[elementName(token)[1:]] = pv
else:
child = {}
o[elementName(token)[1:]] = child
valuesToJSProperties(child, elementChildren(token))
return valuesToJSProperties(o, cdr(l))
# Convert a list of values to a list of strings representing a JSON document
def writeJSON(l):
if isJSArray(l):
jsv = valuesToJSElements(list(range(0, len(l))), l, 0)
else:
jsv = valuesToJSProperties({}, l)
s = json.dumps(jsv, separators=(',',':'))
return (s,)
# Convert a list + params to a JSON-RPC request
def jsonRequest(id, func, params):
r = (("'id", id), ("'method", func), ("'params", params))
return writeJSON(valuesToElements(r))
# Convert a value to a JSON-RPC result
def jsonResult(id, val):
return writeJSON(valuesToElements((("'id", id), ("'result", val))))
# Convert a JSON-RPC result to a value
def jsonResultValue(s):
jsres = readJSON(s)
res = elementsToValues(jsres)
val = cadr(assoc("'result", res))
if isList(val) and not isJSArray(val):
return (val,)
return val
# Return a portable function name from a JSON-RPC function name
def funcName(f):
if f.startswith("."):
return f[1:]
if f.startswith("system."):
return f[7:]
if f.startswith("Service."):
return f[8:]
return f