From 724a04cd5cd63c0b61e15a78f12d95eb477fa235 Mon Sep 17 00:00:00 2001 From: erickson Date: Fri, 18 May 2007 16:55:51 +0000 Subject: [PATCH] broke network-object logic out of the JSON parsing code git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@899 9efc2488-bf62-4759-914b-345cdb29e865 --- src/python/osrf/json.py | 212 +++++++++++++++++++------------------ src/python/osrf/net_obj.py | 127 ++++++++++++++++++++++ src/python/osrf/ses.py | 1 + 3 files changed, 235 insertions(+), 105 deletions(-) create mode 100644 src/python/osrf/net_obj.py diff --git a/src/python/osrf/json.py b/src/python/osrf/json.py index 615b0fd..1b73e37 100644 --- a/src/python/osrf/json.py +++ b/src/python/osrf/json.py @@ -14,116 +14,118 @@ # ----------------------------------------------------------------------- -import simplejson, types +import simplejson, types +from osrf.net_obj import * JSON_PAYLOAD_KEY = '__p' JSON_CLASS_KEY = '__c' -class osrfNetworkObject(object): - """Base class for serializable network objects.""" - def getData(self): - """Returns a dict of data contained by this object""" - return self.data - - -class __unknown(osrfNetworkObject): - """Default class for un-registered network objects.""" - def __init__(self, data=None): - self.data = data - -setattr(__unknown,'__keys', []) -setattr(osrfNetworkObject,'__unknown', __unknown) - - -def osrfNetworkRegisterHint(hint, keys, type='hash'): - """Register a network hint. - - This creates a new class at osrfNetworkObject. with - methods for accessing/mutating the object's data. - Method names will match the names found in the keys array - - hint - The hint name to encode with the object - type - The data container type. - keys - An array of data keys. If type is an 'array', the order of - the keys will determine how the data is accessed - """ - - estr = "class %s(osrfNetworkObject):\n" % hint - estr += "\tdef __init__(self, data=None):\n" - estr += "\t\tself.data = data\n" - estr += "\t\tif data:\n" - - if type == 'hash': - estr += "\t\t\tpass\n" - else: - # we have to make sure the array is large enough - estr += "\t\t\twhile len(data) < %d:\n" % len(keys) - estr += "\t\t\t\tdata.append(None)\n" - - estr += "\t\telse:\n" - - if type == 'array': - estr += "\t\t\tself.data = []\n" - estr += "\t\t\tfor i in range(%s):\n" % len(keys) - estr += "\t\t\t\tself.data.append(None)\n" - for i in range(len(keys)): - estr += "\tdef %s(self, *args):\n"\ - "\t\tif len(args) != 0:\n"\ - "\t\t\tself.data[%s] = args[0]\n"\ - "\t\treturn self.data[%s]\n" % (keys[i], i, i) - - if type == 'hash': - estr += "\t\t\tself.data = {}\n" - estr += "\t\t\tfor i in %s:\n" % str(keys) - estr += "\t\t\t\tself.data[i] = None\n" - for i in keys: - estr += "\tdef %s(self, *args):\n"\ - "\t\tif len(args) != 0:\n"\ - "\t\t\tself.data['%s'] = args[0]\n"\ - "\t\tval = None\n"\ - "\t\ttry: val = self.data['%s']\n"\ - "\t\texcept: return None\n"\ - "\t\treturn val\n" % (i, i, i) - - estr += "setattr(osrfNetworkObject, '%s', %s)\n" % (hint,hint) - estr += "setattr(osrfNetworkObject.%s, '__keys', keys)" % hint - exec(estr) - - - -# ------------------------------------------------------------------- -# Define the custom object parsing behavior -# ------------------------------------------------------------------- -def __parseNetObject(obj): - hint = None - islist = False - try: - hint = obj[JSON_CLASS_KEY] - obj = obj[JSON_PAYLOAD_KEY] - except: pass - if isinstance(obj,list): - islist = True - for i in range(len(obj)): - obj[i] = __parseNetObject(obj[i]) - else: - if isinstance(obj,dict): - for k,v in obj.iteritems(): - obj[k] = __parseNetObject(v) - - if hint: # Now, "bless" the object into an osrfNetworkObject - estr = 'obj = osrfNetworkObject.%s(obj)' % hint - try: - exec(estr) - except AttributeError: - # this object has not been registered, shove it into the default container - obj = osrfNetworkObject.__unknown(obj) - - return obj; - - -# ------------------------------------------------------------------- +#class osrfNetworkObject(object): +# """Base class for serializable network objects.""" +# def getData(self): +# """Returns a dict of data contained by this object""" +# return self.data +# +# +#class __unknown(osrfNetworkObject): +# """Default class for un-registered network objects.""" +# def __init__(self, data=None): +# self.data = data +# +#setattr(__unknown,'__keys', []) +#setattr(osrfNetworkObject,'__unknown', __unknown) +# +# +#def osrfNetworkRegisterHint(hint, keys, type='hash'): +# """Register a network hint. +# +# This creates a new class at osrfNetworkObject. with +# methods for accessing/mutating the object's data. +# Method names will match the names found in the keys array +# +# hint - The hint name to encode with the object +# type - The data container type. +# keys - An array of data keys. If type is an 'array', the order of +# the keys will determine how the data is accessed +# """ +# +# estr = "class %s(osrfNetworkObject):\n" % hint +# estr += "\tdef __init__(self, data=None):\n" +# estr += "\t\tself.data = data\n" +# estr += "\t\tif data:\n" +# +# if type == 'hash': +# estr += "\t\t\tpass\n" +# else: +# # we have to make sure the array is large enough +# estr += "\t\t\twhile len(data) < %d:\n" % len(keys) +# estr += "\t\t\t\tdata.append(None)\n" +# +# estr += "\t\telse:\n" +# +# if type == 'array': +# estr += "\t\t\tself.data = []\n" +# estr += "\t\t\tfor i in range(%s):\n" % len(keys) +# estr += "\t\t\t\tself.data.append(None)\n" +# for i in range(len(keys)): +# estr += "\tdef %s(self, *args):\n"\ +# "\t\tif len(args) != 0:\n"\ +# "\t\t\tself.data[%s] = args[0]\n"\ +# "\t\treturn self.data[%s]\n" % (keys[i], i, i) +# +# if type == 'hash': +# estr += "\t\t\tself.data = {}\n" +# estr += "\t\t\tfor i in %s:\n" % str(keys) +# estr += "\t\t\t\tself.data[i] = None\n" +# for i in keys: +# estr += "\tdef %s(self, *args):\n"\ +# "\t\tif len(args) != 0:\n"\ +# "\t\t\tself.data['%s'] = args[0]\n"\ +# "\t\tval = None\n"\ +# "\t\ttry: val = self.data['%s']\n"\ +# "\t\texcept: return None\n"\ +# "\t\treturn val\n" % (i, i, i) +# +# estr += "setattr(osrfNetworkObject, '%s', %s)\n" % (hint,hint) +# estr += "setattr(osrfNetworkObject.%s, '__keys', keys)" % hint +# exec(estr) +# +# +# +## ------------------------------------------------------------------- +## Define the custom object parsing behavior +## ------------------------------------------------------------------- +#def __parseNetObject(obj): +# hint = None +# islist = False +# try: +# hint = obj[JSON_CLASS_KEY] +# obj = obj[JSON_PAYLOAD_KEY] +# except: pass +# if isinstance(obj,list): +# islist = True +# for i in range(len(obj)): +# obj[i] = __parseNetObject(obj[i]) +# else: +# if isinstance(obj,dict): +# for k,v in obj.iteritems(): +# obj[k] = __parseNetObject(v) +# +# if hint: # Now, "bless" the object into an osrfNetworkObject +# estr = 'obj = osrfNetworkObject.%s(obj)' % hint +# try: +# exec(estr) +# except AttributeError: +# # this object has not been registered, shove it into the default container +# obj = osrfNetworkObject.__unknown(obj) +# +# return obj; +# +# +## ------------------------------------------------------------------- # Define the custom object encoding behavior # ------------------------------------------------------------------- + class osrfJSONNetworkEncoder(simplejson.JSONEncoder): def default(self, obj): if isinstance(obj, osrfNetworkObject): @@ -142,7 +144,7 @@ def osrfObjectToJSON(obj): def osrfJSONToObject(json): """Turns a JSON string into python objects""" obj = simplejson.loads(json) - return __parseNetObject(obj) + return parseNetObject(obj) def osrfParseJSONRaw(json): """Parses JSON the old fashioned way.""" diff --git a/src/python/osrf/net_obj.py b/src/python/osrf/net_obj.py new file mode 100644 index 0000000..1dafa1e --- /dev/null +++ b/src/python/osrf/net_obj.py @@ -0,0 +1,127 @@ +# ----------------------------------------------------------------------- +# Copyright (C) 2007 Georgia Public Library Service +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# ----------------------------------------------------------------------- + + +JSON_PAYLOAD_KEY = '__p' +JSON_CLASS_KEY = '__c' + +class osrfNetworkObject(object): + """Base class for serializable network objects.""" + def getData(self): + """Returns a dict of data contained by this object""" + return self.data + + +class __unknown(osrfNetworkObject): + """Default class for un-registered network objects.""" + def __init__(self, data=None): + self.data = data + +setattr(__unknown,'__keys', []) +setattr(osrfNetworkObject,'__unknown', __unknown) + + +def osrfNetworkRegisterHint(hint, keys, type='hash'): + """Register a network hint. + + This creates a new class at osrfNetworkObject. with + methods for accessing/mutating the object's data. + Method names will match the names found in the keys array + + hint - The hint name to encode with the object + type - The data container type. + keys - An array of data keys. If type is an 'array', the order of + the keys will determine how the data is accessed + """ + + # + # XXX Surely there is a cleaner way to accomplish this via + # the PythonAPI + # + + estr = "class %s(osrfNetworkObject):\n" % hint + estr += "\tdef __init__(self, data=None):\n" + estr += "\t\tself.data = data\n" + estr += "\t\tif data:\n" + + if type == 'hash': + estr += "\t\t\tpass\n" + else: + # we have to make sure the array is large enough + estr += "\t\t\twhile len(data) < %d:\n" % len(keys) + estr += "\t\t\t\tdata.append(None)\n" + + estr += "\t\telse:\n" + + if type == 'array': + estr += "\t\t\tself.data = []\n" + estr += "\t\t\tfor i in range(%s):\n" % len(keys) + estr += "\t\t\t\tself.data.append(None)\n" + for i in range(len(keys)): + estr += "\tdef %s(self, *args):\n"\ + "\t\tif len(args) != 0:\n"\ + "\t\t\tself.data[%s] = args[0]\n"\ + "\t\treturn self.data[%s]\n" % (keys[i], i, i) + + if type == 'hash': + estr += "\t\t\tself.data = {}\n" + estr += "\t\t\tfor i in %s:\n" % str(keys) + estr += "\t\t\t\tself.data[i] = None\n" + for i in keys: + estr += "\tdef %s(self, *args):\n"\ + "\t\tif len(args) != 0:\n"\ + "\t\t\tself.data['%s'] = args[0]\n"\ + "\t\tval = None\n"\ + "\t\ttry: val = self.data['%s']\n"\ + "\t\texcept: return None\n"\ + "\t\treturn val\n" % (i, i, i) + + estr += "setattr(osrfNetworkObject, '%s', %s)\n" % (hint,hint) + estr += "setattr(osrfNetworkObject.%s, '__keys', keys)" % hint + exec(estr) + + + +# ------------------------------------------------------------------- +# Define the custom object parsing behavior +# ------------------------------------------------------------------- +def parseNetObject(obj): + hint = None + islist = False + try: + hint = obj[JSON_CLASS_KEY] + obj = obj[JSON_PAYLOAD_KEY] + except: pass + if isinstance(obj,list): + islist = True + for i in range(len(obj)): + obj[i] = parseNetObject(obj[i]) + else: + if isinstance(obj,dict): + for k,v in obj.iteritems(): + obj[k] = parseNetObject(v) + + if hint: # Now, "bless" the object into an osrfNetworkObject + estr = 'obj = osrfNetworkObject.%s(obj)' % hint + try: + exec(estr) + except AttributeError: + # this object has not been registered, shove it into the default container + obj = osrfNetworkObject.__unknown(obj) + + return obj; + + + + diff --git a/src/python/osrf/ses.py b/src/python/osrf/ses.py index 2fbb502..f1c6c38 100644 --- a/src/python/osrf/ses.py +++ b/src/python/osrf/ses.py @@ -14,6 +14,7 @@ # ----------------------------------------------------------------------- from osrf.json import * +from osrf.net_obj import * from osrf.conf import osrfConfigValue from osrf.net import osrfNetworkMessage, osrfGetNetworkHandle from osrf.log import * -- 2.43.2