Better way to handle automatic parsing using the schemas in the discovery document.
This commit is contained in:
		
							parent
							
								
									b4745890f5
								
							
						
					
					
						commit
						1fa3fb25d9
					
				|  | @ -16,3 +16,4 @@ | |||
| require 'google/api_client/discovery/api' | ||||
| require 'google/api_client/discovery/resource' | ||||
| require 'google/api_client/discovery/method' | ||||
| require 'google/api_client/discovery/schema' | ||||
|  |  | |||
|  | @ -135,15 +135,32 @@ module Google | |||
|         end | ||||
|       end | ||||
| 
 | ||||
|       ## | ||||
|       # A list of schemas available for this version of the API. | ||||
|       # | ||||
|       # @return [Hash] A list of {Google::APIClient::Schema} objects. | ||||
|       def schemas | ||||
|         return @schemas ||= ( | ||||
|           (@discovery_document['schemas'] || []).inject({}) do |accu, (k, v)| | ||||
|             accu[k] = Google::APIClient::Schema.new( | ||||
|               self, self.name, self.version, v | ||||
|             ) | ||||
|             accu | ||||
|           end | ||||
|         ) | ||||
|       end | ||||
| 
 | ||||
|       ## | ||||
|       # A list of resources available at the root level of this version of the | ||||
|       # service. | ||||
|       # API. | ||||
|       # | ||||
|       # @return [Array] A list of {Google::APIClient::Resource} objects. | ||||
|       def resources | ||||
|         return @resources ||= ( | ||||
|           (@discovery_document['resources'] || []).inject([]) do |accu, (k, v)| | ||||
|             accu << Google::APIClient::Resource.new(self.method_base, k, v) | ||||
|             accu << Google::APIClient::Resource.new( | ||||
|               self, self.method_base, k, v | ||||
|             ) | ||||
|             accu | ||||
|           end | ||||
|         ) | ||||
|  | @ -151,13 +168,13 @@ module Google | |||
| 
 | ||||
|       ## | ||||
|       # A list of methods available at the root level of this version of the | ||||
|       # service. | ||||
|       # API. | ||||
|       # | ||||
|       # @return [Array] A list of {Google::APIClient::Method} objects. | ||||
|       def methods | ||||
|         return @methods ||= ( | ||||
|           (@discovery_document['methods'] || []).inject([]) do |accu, (k, v)| | ||||
|             accu << Google::APIClient::Method.new(self.method_base, k, v) | ||||
|             accu << Google::APIClient::Method.new(self, self.method_base, k, v) | ||||
|             accu | ||||
|           end | ||||
|         ) | ||||
|  |  | |||
|  | @ -35,7 +35,8 @@ module Google | |||
|       #   The section of the discovery document that applies to this method. | ||||
|       # | ||||
|       # @return [Google::APIClient::Method] The constructed method object. | ||||
|       def initialize(method_base, method_name, discovery_document) | ||||
|       def initialize(api, method_base, method_name, discovery_document) | ||||
|         @api = api | ||||
|         @method_base = method_base | ||||
|         @name = method_name | ||||
|         @discovery_document = discovery_document | ||||
|  | @ -102,6 +103,32 @@ module Google | |||
|         ) | ||||
|       end | ||||
| 
 | ||||
|       ## | ||||
|       # Returns the Schema object for the method's request, if any. | ||||
|       # | ||||
|       # @return [Google::APIClient::Schema] The request schema. | ||||
|       def request_schema | ||||
|         if @discovery_document['request'] | ||||
|           schema_name = @discovery_document['request']['$ref'] | ||||
|           return @api.schemas[schema_name] | ||||
|         else | ||||
|           return nil | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       ## | ||||
|       # Returns the Schema object for the method's response, if any. | ||||
|       # | ||||
|       # @return [Google::APIClient::Schema] The response schema. | ||||
|       def response_schema | ||||
|         if @discovery_document['response'] | ||||
|           schema_name = @discovery_document['response']['$ref'] | ||||
|           return @api.schemas[schema_name] | ||||
|         else | ||||
|           return nil | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       ## | ||||
|       # Normalizes parameters, converting to the appropriate types. | ||||
|       # | ||||
|  |  | |||
|  | @ -35,7 +35,8 @@ module Google | |||
|       #   The section of the discovery document that applies to this resource. | ||||
|       # | ||||
|       # @return [Google::APIClient::Resource] The constructed resource object. | ||||
|       def initialize(method_base, resource_name, discovery_document) | ||||
|       def initialize(api, method_base, resource_name, discovery_document) | ||||
|         @api = api | ||||
|         @method_base = method_base | ||||
|         @name = resource_name | ||||
|         @discovery_document = discovery_document | ||||
|  | @ -95,7 +96,9 @@ module Google | |||
|       def resources | ||||
|         return @resources ||= ( | ||||
|           (@discovery_document['resources'] || []).inject([]) do |accu, (k, v)| | ||||
|             accu << Google::APIClient::Resource.new(self.method_base, k, v) | ||||
|             accu << Google::APIClient::Resource.new( | ||||
|               @api, self.method_base, k, v | ||||
|             ) | ||||
|             accu | ||||
|           end | ||||
|         ) | ||||
|  | @ -108,7 +111,7 @@ module Google | |||
|       def methods | ||||
|         return @methods ||= ( | ||||
|           (@discovery_document['methods'] || []).inject([]) do |accu, (k, v)| | ||||
|             accu << Google::APIClient::Method.new(self.method_base, k, v) | ||||
|             accu << Google::APIClient::Method.new(@api, self.method_base, k, v) | ||||
|             accu | ||||
|           end | ||||
|         ) | ||||
|  |  | |||
|  | @ -0,0 +1,126 @@ | |||
| # Copyright 2010 Google Inc. | ||||
| # | ||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #      http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software | ||||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | ||||
| 
 | ||||
| 
 | ||||
| require 'json' | ||||
| require 'addressable/uri' | ||||
| require 'addressable/template' | ||||
| 
 | ||||
| require 'google/inflection' | ||||
| require 'google/api_client/errors' | ||||
| 
 | ||||
| module Google | ||||
|   class APIClient | ||||
|     class Schema | ||||
|       def initialize(api, api_name, api_version, discovery_document) | ||||
|         # This constructor is super-long, but hard to break up due to the | ||||
|         # unavoidable dependence on closures and execution context. | ||||
|         @api = api | ||||
|         @discovery_document = discovery_document | ||||
|         api_name_string = | ||||
|           Google::INFLECTOR.camelize(api_name) | ||||
|         api_version_string = | ||||
|           Google::INFLECTOR.camelize(api_version).gsub('.', '_') | ||||
|         @schema_name = @discovery_document['id'] | ||||
|         if Google::APIClient::Schema.const_defined?(api_name_string) | ||||
|           @api_name = Google::APIClient::Schema.const_get(api_name_string) | ||||
|         else | ||||
|           @api_name = Google::APIClient::Schema.const_set( | ||||
|             api_name_string, Class.new | ||||
|           ) | ||||
|         end | ||||
|         if @api_name.const_defined?(api_version_string) | ||||
|           @api_version = @api_name.const_get(api_version_string) | ||||
|         else | ||||
|           @api_version = @api_name.const_set(api_version_string, Class.new) | ||||
|         end | ||||
|         if @api_version.const_defined?(@schema_name) | ||||
|           @schema_class = @api_version.const_get(@schema_name) | ||||
|         else | ||||
|           @schema_class = @api_version.const_set( | ||||
|             @schema_name, | ||||
|             Class.new(APIObject) do |klass| | ||||
|               discovery_document['properties'].each do |(k, v)| | ||||
|                 property_name = Google::INFLECTOR.underscore(k) | ||||
|                 define_method(property_name + '_property') do | ||||
|                   v | ||||
|                 end | ||||
|                 case v['type'] | ||||
|                 when 'string' | ||||
|                   define_method(property_name) do | ||||
|                     self[k] | ||||
|                   end | ||||
|                   define_method(property_name + '=') do |value| | ||||
|                     if value.respond_to?(:to_str) | ||||
|                       self[k] = value.to_str | ||||
|                     elsif value.kind_of?(Symbol) | ||||
|                       self[k] = value.to_s | ||||
|                     else | ||||
|                       raise TypeError, | ||||
|                         "Expected String or Symbol, got #{value.class}." | ||||
|                     end | ||||
|                   end | ||||
|                 else | ||||
|                   # TODO(bobaman): | ||||
|                   # Implement the remainder of the types. | ||||
| 
 | ||||
|                   # Don't know what this is, default to anything goes. | ||||
|                   define_method(property_name) do | ||||
|                     self[k] | ||||
|                   end | ||||
|                   define_method(property_name + '=') do |value| | ||||
|                     self[k] = value | ||||
|                   end | ||||
|                 end | ||||
|               end | ||||
|             end | ||||
|           ) | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       def schema_name | ||||
|         return @schema_name | ||||
|       end | ||||
| 
 | ||||
|       def schema_class | ||||
|         return @schema_class | ||||
|       end | ||||
| 
 | ||||
|       ## | ||||
|       # Returns a <code>String</code> representation of the resource's state. | ||||
|       # | ||||
|       # @return [String] The resource's state, as a <code>String</code>. | ||||
|       def inspect | ||||
|         sprintf( | ||||
|           "#<%s:%#0x CLASS:%s>", | ||||
|           self.class.to_s, self.object_id, self.schema_class.name | ||||
|         ) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     class APIObject | ||||
|       def initialize(data) | ||||
|         @data = data | ||||
|       end | ||||
| 
 | ||||
|       def [](key) | ||||
|         return @data[key] | ||||
|       end | ||||
| 
 | ||||
|       def []=(key, value) | ||||
|         return @data[key] = value | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
		Loading…
	
		Reference in New Issue