From 57476f9763b66186bfb7a38ea4d892a0eabc5e3f Mon Sep 17 00:00:00 2001 From: Hendrik Buschmeier <hbuschme@uni-bielefeld.de> Date: Thu, 18 Dec 2014 09:35:37 +0100 Subject: [PATCH] Added proxy objects for complex (i.e., JSON) payload types. --- ipaacalib/python/src/ipaaca/__init__.py | 129 ++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/ipaacalib/python/src/ipaaca/__init__.py b/ipaacalib/python/src/ipaaca/__init__.py index c117a5d..8196d2d 100755 --- a/ipaacalib/python/src/ipaaca/__init__.py +++ b/ipaacalib/python/src/ipaaca/__init__.py @@ -212,6 +212,15 @@ class Payload(dict): self._batch_update_lock.release() return r + def __getitem__(self, k): + value = dict.__getitem__(self, k) + if isinstance(value, dict): + return PayloadItemDictProxy(value, self, k) + elif isinstance(value, list): + return PayloadItemListProxy(value, self, k) + else: + return value + def __setitem__(self, k, v, writer_name=None): self._batch_update_lock.acquire(True) #if not self._batch_update_lock.acquire(False): @@ -287,6 +296,126 @@ class Payload(dict): current_time = time.time() raise IUPayloadLockTimeoutError(self.iu) +class PayloadItemProxy(object): + + def __init__(self, content, payload, identifier_in_payload): + self.payload = payload + self.content = content + self.identifier_in_payload = identifier_in_payload + + def _notify_payload(self): + self.payload[self.identifier_in_payload] = self.content + + def _create_proxy(self, obj, identifier_in_payload): + if isinstance(obj, dict): + return PayloadItemDictProxy(obj, self.payload, identifier_in_payload) + elif isinstance(obj, list): + return PayloadItemListProxy(obj, self.payload, identifier_in_payload) + else: + return obj + + def __setitem__(self, k, v): + self.content.__setitem__(k,v) + self._notify_payload() + + def __getitem__(self, k): + item = self.content.__getitem__(k) + return self._create_proxy(item, k) + + def __delitem__(self, k): + self.content.__delitem__(k) + self._notify_payload() + + +class PayloadItemDictProxy(PayloadItemProxy, dict): + + def __init__(self, content, payload, identifier_in_payload): + dict.__init__(self, content) + PayloadItemProxy.__init__(self, content, payload, identifier_in_payload) + + def clear(self): + self.content.clear() + self._notify_payload() + + def get(self, key, default=None): + value = self.content.get(key, default) + return self._create_proxy(value, key) + + def items(self): + return [(key, value) for key, value in self.iteritems()] + + def iteritems(self): + for key, value in self.content.iteritems(): + yield key, self._create_proxy(value, key) + + def values(self): + return [value for value in self.itervalues()] + + def itervalues(self): + for key, value in self.content.iteritems(): + yield self._create_proxy(value, key) + + def pop(self, key, *args): + x = self.content.pop(key, *args) + self._notify_payload() + return x + + def popitem(self): + x = self.content.popitem() + self._notify_payload() + return x + + def setdefault(self, key, default=None): + notification_necessary = not key in self.content + x = self.content.setdefault(key, default) + if notification_necessary: + self._notify_payload() + return x + + def update(self, *args, **kwargs): + self.content.update(*args, **kwargs) + self._notify_payload() + + +class PayloadItemListProxy(PayloadItemProxy, list): + + def __init__(self, content, payload, identifier_in_payload): + list.__init__(self, content) + PayloadItemProxy.__init__(self, content, payload, identifier_in_payload) + + def __iter__(self): + for index, item in enumerate(self.content): + yield self._create_proxy(item, index) + + def append(self, x): + self.content.append(x) + self._notify_payload() + + def extend(self, l): + self.content.extend(l) + self._notify_payload() + + def insert(self, i, x): + self.content.insert(i, x) + self._notify_payload() + + def remove(self, x): + self.content.remove(x) + self._notify_payload() + + def pop(self, *args, **kwargs): + x = self.content.pop(*args, **kwargs) + self._notify_payload() + return x + + def sort(self, cmp=None, key=None, reverse=False): + self.content.sort(cmp, key, reverse) + self._notify_payload() + + def reverse(self): + self.content.reverse() + self._notify_payload() + class IUInterface(object): #{{{ -- GitLab