Added default values.
[arvados.git] / lib / google / api_client / discovery / schema.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 'addressable/uri'
18 require 'addressable/template'
19
20 require 'google/inflection'
21 require 'google/api_client/errors'
22
23 module Google
24   class APIClient
25     class Schema
26       def initialize(api, api_name, api_version, discovery_document)
27         # This constructor is super-long, but hard to break up due to the
28         # unavoidable dependence on closures and execution context.
29         @api = api
30         @discovery_document = discovery_document
31         api_name_string =
32           Google::INFLECTOR.camelize(api_name)
33         api_version_string =
34           Google::INFLECTOR.camelize(api_version).gsub('.', '_')
35         @schema_name = @discovery_document['id']
36         if Google::APIClient::Schema.const_defined?(api_name_string)
37           @api_name = Google::APIClient::Schema.const_get(api_name_string)
38         else
39           @api_name = Google::APIClient::Schema.const_set(
40             api_name_string, Class.new
41           )
42         end
43         if @api_name.const_defined?(api_version_string)
44           @api_version = @api_name.const_get(api_version_string)
45         else
46           @api_version = @api_name.const_set(api_version_string, Class.new)
47         end
48         if @api_version.const_defined?(@schema_name)
49           @schema_class = @api_version.const_get(@schema_name)
50         else
51           @schema_class = @api_version.const_set(
52             @schema_name,
53             Class.new(APIObject) do |klass|
54               discovery_document['properties'].each do |(k, v)|
55                 property_name = Google::INFLECTOR.underscore(k)
56                 define_method(property_name + '_property') do
57                   v
58                 end
59                 case v['type']
60                 when 'string'
61                   define_method(property_name) do
62                     self[k] || v['default']
63                   end
64                   define_method(property_name + '=') do |value|
65                     if value.respond_to?(:to_str)
66                       self[k] = value.to_str
67                     elsif value.kind_of?(Symbol)
68                       self[k] = value.to_s
69                     else
70                       raise TypeError,
71                         "Expected String or Symbol, got #{value.class}."
72                     end
73                   end
74                 else
75                   # TODO(bobaman):
76                   # Implement the remainder of the types.
77
78                   # Don't know what this is, default to anything goes.
79                   define_method(property_name) do
80                     self[k] || v['default']
81                   end
82                   define_method(property_name + '=') do |value|
83                     self[k] = value
84                   end
85                 end
86               end
87             end
88           )
89         end
90       end
91
92       def schema_name
93         return @schema_name
94       end
95
96       def schema_class
97         return @schema_class
98       end
99
100       ##
101       # Returns a <code>String</code> representation of the resource's state.
102       #
103       # @return [String] The resource's state, as a <code>String</code>.
104       def inspect
105         sprintf(
106           "#<%s:%#0x CLASS:%s>",
107           self.class.to_s, self.object_id, self.schema_class.name
108         )
109       end
110     end
111
112     class APIObject
113       def initialize(data)
114         @data = data
115       end
116
117       def [](key)
118         return @data[key]
119       end
120
121       def []=(key, value)
122         return @data[key] = value
123       end
124     end
125   end
126 end