aboutsummaryrefslogtreecommitdiff
blob: e051596509e3b276b49278479f0572dda1347aa5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
    serialization.py
    ~~~~~~~~~~~~~~~~
    
    json serialization
    
    :copyright: (c) 2013 by Jauhien Piatlicki
    :license: GPL-2, see LICENSE for more details.
"""

import json
import importlib


class JSONSerializer(json.JSONEncoder):
    """
    Custom JSON encoder.

    Each serializable class should have a method serialize
    that returns JSON serializable value. If class addfitionally
    has a classmethod deserialize that it can be deserialized
    and additional metainformation is added to the resulting JSON.
    """
    def default(self, obj):
        if hasattr(obj, "serialize"):
            if hasattr(obj, "deserialize"):
                module = obj.__class__.__module__
                name = obj.__class__.__name__
                value = obj.serialize()
                return {"python_module" : module,
                        "python_class" : name,
                        "value" : value}
            else:
                return obj.serialize()
        return json.JSONEncoder.default(self, obj)


def deserializeHook(json_object):
    """
    Custom JSON decoder.

    Each class that can be deserialized should have classmethod deserialize
    that takes value (previously returned by serialize method) and transforms
    it into class instance.
    """
    if "python_class" in json_object:
        module = importlib.import_module(json_object["python_module"])
        cls = getattr(module, json_object["python_class"])
        return cls.deserialize(json_object["value"])
    return json_object