1 # -----------------------------------------------------------------------
2 # Copyright (C) 2007 Georgia Public Library Service
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 # -----------------------------------------------------------------------
16 JSON_PAYLOAD_KEY = '__p'
17 JSON_CLASS_KEY = '__c'
19 class osrfNetworkObject(object):
20 """Base class for serializable network objects."""
22 """Returns a dict of data contained by this object"""
26 class __unknown(osrfNetworkObject):
27 """Default class for un-registered network objects."""
28 def __init__(self, data=None):
31 setattr(__unknown,'__keys', [])
32 setattr(osrfNetworkObject,'__unknown', __unknown)
35 def osrfNetworkRegisterHint(hint, keys, type='hash'):
36 """Register a network hint.
38 This creates a new class at osrfNetworkObject.<hint> with
39 methods for accessing/mutating the object's data.
40 Method names will match the names found in the keys array
42 hint - The hint name to encode with the object
43 type - The data container type.
44 keys - An array of data keys. If type is an 'array', the order of
45 the keys will determine how the data is accessed
49 # XXX Surely there is a cleaner way to accomplish this via
53 estr = "class %s(osrfNetworkObject):\n" % hint
54 estr += "\tdef __init__(self, data=None):\n"
55 estr += "\t\tself.data = data\n"
56 estr += "\t\tif data:\n"
59 estr += "\t\t\tpass\n"
61 # we have to make sure the array is large enough
62 estr += "\t\t\twhile len(data) < %d:\n" % len(keys)
63 estr += "\t\t\t\tdata.append(None)\n"
68 estr += "\t\t\tself.data = []\n"
69 estr += "\t\t\tfor i in range(%s):\n" % len(keys)
70 estr += "\t\t\t\tself.data.append(None)\n"
71 for i in range(len(keys)):
72 estr += "\tdef %s(self, *args):\n"\
73 "\t\tif len(args) != 0:\n"\
74 "\t\t\tself.data[%s] = args[0]\n"\
75 "\t\treturn self.data[%s]\n" % (keys[i], i, i)
78 estr += "\t\t\tself.data = {}\n"
79 estr += "\t\t\tfor i in %s:\n" % str(keys)
80 estr += "\t\t\t\tself.data[i] = None\n"
82 estr += "\tdef %s(self, *args):\n"\
83 "\t\tif len(args) != 0:\n"\
84 "\t\t\tself.data['%s'] = args[0]\n"\
86 "\t\ttry: val = self.data['%s']\n"\
87 "\t\texcept: return None\n"\
88 "\t\treturn val\n" % (i, i, i)
90 estr += "setattr(osrfNetworkObject, '%s', %s)\n" % (hint,hint)
91 estr += "setattr(osrfNetworkObject.%s, '__keys', keys)" % hint
96 # -------------------------------------------------------------------
97 # Define the custom object parsing behavior
98 # -------------------------------------------------------------------
99 def parseNetObject(obj):
103 hint = obj[JSON_CLASS_KEY]
104 obj = obj[JSON_PAYLOAD_KEY]
106 if isinstance(obj,list):
108 for i in range(len(obj)):
109 obj[i] = parseNetObject(obj[i])
111 if isinstance(obj,dict):
112 for k,v in obj.iteritems():
113 obj[k] = parseNetObject(v)
115 if hint: # Now, "bless" the object into an osrfNetworkObject
116 estr = 'obj = osrfNetworkObject.%s(obj)' % hint
119 except AttributeError:
120 # this object has not been registered, shove it into the default container
121 obj = osrfNetworkObject.__unknown(obj)