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

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

# coding=utf-8 

# 

# Copyright (C) 2010-2012 Platform Computing 

# 

# This library is free software; you can redistribute it and/or 

# modify it under the terms of the GNU Lesser General Public 

# License as published by the Free Software Foundation; either 

# version 2.1 of the License, or (at your option) any later version. 

# 

# This library 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 

# Lesser General Public License for more details. 

# 

# You should have received a copy of the GNU Lesser General Public 

# License along with this library; if not, write to the Free Software 

# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA 

# 

 

''' 

JSON based rendering. 

 

Created on 01.02.2012 

 

@author: tmetsch 

''' 

 

# L8R: check if this can be move partly to occi_rendering (once standardized) 

# and rename to a parser class. 

 

# disabling 'Method is abstract' pylint check (currently only support GETs!) 

# pylint: disable=W0223 

 

from occi.core_model import Resource 

from occi.handlers import CONTENT_TYPE 

from occi.protocol.rendering import Rendering 

import json 

 

 

def _from_category(category): 

    ''' 

    Create a JSON struct for a category. 

    ''' 

    data = {'term': category.term, 'scheme': category.scheme} 

    if hasattr(category, 'title') and category.title is not '': 

        data['title'] = category.title 

    if hasattr(category, 'related') and len(category.related) > 0: 

        rel_list = [] 

        for item in category.related: 

            rel_list.append(str(item)) 

        data['related'] = rel_list 

    if hasattr(category, 'location') and category.location is not None: 

        data['location'] = category.location 

    if hasattr(category, 'attributes') and len(category.attributes) >= 1: 

        attr_list = {} 

        for item in category.attributes: 

            if category.attributes[item] == 'required': 

                attr_list[item] = 'required' 

            elif category.attributes[item] == 'immutable': 

                attr_list[item] = 'immutable' 

            else: 

                attr_list[item] = 'muttable' 

        data['attributes'] = attr_list 

    if hasattr(category, 'actions') and len(category.actions) > 0: 

        action_list = [] 

        for item in category.actions: 

            action_list.append(str(item)) 

        data['actions'] = action_list 

    return data 

 

 

def _from_entity(entity): 

    ''' 

    Create a JSON struct for an entity. 

    ''' 

    data = {'kind': _from_category(entity.kind)} 

    # kind 

 

    # mixins 

    mixins = [] 

    for mixin in entity.mixins: 

        tmp = _from_category(mixin) 

        mixins.append(tmp) 

    data['mixins'] = mixins 

 

    # actions 

    actions = [] 

    for action in entity.actions: 

        tmp = {'kind': _from_category(action), 'link': entity.identifier + 

               '?action=' + action.term} 

        actions.append(tmp) 

    data['actions'] = actions 

 

    # links 

    if isinstance(entity, Resource): 

        links = [] 

        for link in entity.links: 

            tmp = _from_entity(link) 

            tmp['source'] = link.source.identifier 

            tmp['target'] = link.target.identifier 

            links.append(tmp) 

        data['links'] = links 

 

    # attributes 

    attr = {} 

    for attribute in entity.attributes: 

        attr[attribute] = entity.attributes[attribute] 

    data['attributes'] = attr 

 

    return data 

 

 

class JsonRendering(Rendering): 

    ''' 

    This is a rendering which will use the HTTP header to place the information 

    in an syntax and semantics as defined in the OCCI specification. 

    ''' 

 

    mime_type = 'application/occi+json' 

 

    def from_entity(self, entity): 

        data = _from_entity(entity) 

 

        body = json.dumps(data, sort_keys=True, indent=2) 

        return {CONTENT_TYPE: self.mime_type}, body 

 

    def from_entities(self, entities, key): 

        data = [] 

        for item in entities: 

            data.append(_from_entity(item)) 

 

        body = json.dumps(data, sort_keys=True, indent=2) 

        return {CONTENT_TYPE: self.mime_type}, body 

 

    def from_categories(self, categories): 

        data = [] 

        for item in categories: 

            data.append(_from_category(item)) 

 

        body = json.dumps(data, sort_keys=True, indent=2) 

        return {CONTENT_TYPE: self.mime_type}, body