From 654dea5b85815951a6ff90933f827b26c23a94fd Mon Sep 17 00:00:00 2001
From: Pavel Zuna <pzuna@redhat.com>
Date: Tue, 10 Aug 2010 16:40:00 -0400
Subject: [PATCH 1/6] Improve serialization to JSON.

- Make it recursive.
- Make Param classes serializable.
- Take python native data types into account.
---
 ipalib/parameters.py       |   14 ++++++++++++++
 ipalib/plugins/baseldap.py |    3 ++-
 ipalib/util.py             |   12 +++++++++++-
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index c86db75..7d89f4e 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -852,6 +852,20 @@ class Param(ReadOnly):
                     pass
         return self.default
 
+    def __json__(self):
+        json_dict = {}
+        for (a, k, d) in self.kwargs:
+            if k in (callable, DefaultFrom):
+                continue
+            elif isinstance(getattr(self, a), frozenset):
+                json_dict[a] = [k for k in getattr(self, a, [])]
+            else:
+                json_dict[a] = getattr(self, a, '')
+        json_dict['class'] = self.__class__.__name__
+        json_dict['name'] = self.name
+        json_dict['type'] = self.type.__name__
+        return json_dict
+
 
 class Bool(Param):
     """
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 7e2fd4f..f3e5b0f 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -137,7 +137,8 @@ class LDAPObject(Object):
         json_dict = dict(
             (a, getattr(self, a)) for a in self.json_friendly_attributes
         )
-        json_dict['primary_key'] = self.primary_key.name
+        if self.primary_key:
+            json_dict['primary_key'] = self.primary_key.name
         json_dict['methods'] = [m for m in self.methods]
         return json_dict
 
diff --git a/ipalib/util.py b/ipalib/util.py
index ba111d4..4aff88f 100644
--- a/ipalib/util.py
+++ b/ipalib/util.py
@@ -27,15 +27,25 @@ import logging
 import time
 import krbV
 import socket
+from types import NoneType
+
 from ipalib import errors
 from ipapython import dnsclient
 
 
 def json_serialize(obj):
+    if isinstance(obj, (list, tuple)):
+        return [json_serialize(o) for o in obj]
+    if isinstance(obj, dict):
+        return dict((k, json_serialize(v)) for (k, v) in obj.iteritems())
+    if isinstance(obj, (bool, float, int, unicode, NoneType)):
+        return obj
+    if isinstance(obj, str):
+        return obj.decode('utf-8')
     if not callable(getattr(obj, '__json__', None)):
         # raise TypeError('%r is not JSON serializable')
         return ''
-    return obj.__json__()
+    return json_serialize(obj.__json__())
 
 def get_current_principal():
     try:
-- 
1.7.1.1

