ff828bf33223fd6ebc121d01bab597e69f692605
[arvados.git] / lib / google / api_client / parsers / json_parser.rb
1 # Copyright 2010 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15
16 require 'json'
17 require 'google/api_client/parser'
18
19 module Google
20   class APIClient
21     ##
22     # Provides a module which all other parsers should include.
23     module JSONParser
24       extend Parser
25       content_type 'application/json'
26
27       module Matcher
28         def conditions
29           @conditions ||= []
30         end
31
32         def matches_kind(kind)
33           self.matches_field_value(:kind, kind)
34         end
35
36         def matches_fields(fields)
37           self.conditions << [:fields, fields]
38         end
39
40         def matches_field_value(field, value)
41           self.conditions << [:field_value, field, value]
42         end
43       end
44
45       def self.parsers
46         @parsers ||= []
47       end
48
49       ##
50       # This method ensures that all parsers auto-register themselves.
51       def self.included(parser)
52         self.parsers << parser
53         parser.extend(Matcher)
54       end
55
56       def initialize(data)
57         @data = data.kind_of?(Hash) ? data : ::JSON.parse(data)
58       end
59
60       def [](key)
61         return self.json[key]
62       end
63
64       def json
65         if @data
66           data = @data
67         elsif self.respond_to?(:data)
68           data = self.data
69         else
70           raise TypeError, "Parser did not provide access to raw data."
71         end
72         return data
73       end
74
75       ##
76       # Matches a parser to the data.
77       def self.match(data)
78         for parser in self.parsers
79           conditions_met = true
80           for condition in (parser.conditions.sort_by { |c| c.size }).reverse
81             condition_type, *params = condition
82             case condition_type
83             when :fields
84               for field in params
85                 if !data.has_key?(field)
86                   conditions_met = false
87                   break
88                 end
89               end
90             when :field_values
91               field, value = params
92               if data[field] != value
93                 conditions_met = false
94                 break
95               end
96             else
97               raise ArgumentError, "Unknown condition type: #{condition_type}"
98             end
99             break if !conditions_met
100           end
101           if conditions_met
102             return parser
103           end
104         end
105         return nil
106       end
107
108       def self.parse(json)
109         data = json.kind_of?(Hash) ? json : ::JSON.parse(json)
110         parser = self.match(data)
111         if parser
112           return parser.new(data)
113         else
114           return data
115         end
116       end
117     end
118   end
119 end