Merge branch 'master' of ../martinsarsale-support-for-repeats
[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
20 module Google
21   class APIClient
22     ##
23     # Provides a module which all other parsers should include.
24     module JSONParser
25       extend Parser
26       content_type 'application/json'
27
28       module Matcher
29         def conditions
30           @conditions ||= []
31         end
32
33         def matches_kind(kind)
34           self.matches_field_value(:kind, kind)
35         end
36
37         def matches_fields(fields)
38           self.conditions << [:fields, fields]
39         end
40
41         def matches_field_value(field, value)
42           self.conditions << [:field_value, field, value]
43         end
44       end
45
46       def self.parsers
47         @parsers ||= []
48       end
49
50       ##
51       # This method ensures that all parsers auto-register themselves.
52       def self.included(parser)
53         self.parsers << parser
54         parser.extend(Matcher)
55       end
56
57       def initialize(data)
58         @data = data.kind_of?(Hash) ? data : ::JSON.parse(data)
59       end
60
61       def [](key)
62         return self.json[key]
63       end
64
65       def json
66         if @data
67           data = @data
68         elsif self.respond_to?(:data)
69           data = self.data
70         else
71           raise TypeError, "Parser did not provide access to raw data."
72         end
73         return data
74       end
75
76       ##
77       # Matches a parser to the data.
78       def self.match(data)
79         for parser in self.parsers
80           conditions_met = true
81           for condition in (parser.conditions.sort_by { |c| c.size }).reverse
82             condition_type, *params = condition
83             case condition_type
84             when :fields
85               for field in params
86                 if !data.has_key?(field)
87                   conditions_met = false
88                   break
89                 end
90               end
91             when :field_values
92               field, value = params
93               if data[field] != value
94                 conditions_met = false
95                 break
96               end
97             else
98               raise ArgumentError, "Unknown condition type: #{condition_type}"
99             end
100             break if !conditions_met
101           end
102           if conditions_met
103             return parser
104           end
105         end
106         return nil
107       end
108
109       def self.parse(json)
110         data = json.kind_of?(Hash) ? json : ::JSON.parse(json)
111         parser = self.match(data)
112         if parser
113           return parser.new(data)
114         else
115           return data
116         end
117       end
118     end
119   end
120 end