Module: Google::APIClient::Schema Private

Defined in:
lib/google/api_client/discovery/schema.rb

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Class Method Summary collapse

Class Method Details

.parse(api, schema_data) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



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
# File 'lib/google/api_client/discovery/schema.rb', line 33

def self.parse(api, schema_data)
  # This method is super-long, but hard to break up due to the
  # unavoidable dependence on closures and execution context.
  schema_name = schema_data['id']

  # Due to an oversight, schema IDs may not be URI references.
  # TODO(bobaman): Remove this code once this has been resolved.
  schema_uri = (
    api.document_base +
    (schema_name[0..0] != '#' ? '#' + schema_name : schema_name)
  )

  # Due to an oversight, schema IDs may not be URI references.
  # TODO(bobaman): Remove this whole lambda once this has been resolved.
  reformat_references = lambda do |data|
    # This code is not particularly efficient due to recursive traversal
    # and excess object creation, but this hopefully shouldn't be an
    # issue since it should only be called only once per schema per
    # process.
    if data.kind_of?(Hash) &&
        data['$ref'] && !data['$ref'].kind_of?(Hash)
      if data['$ref'].respond_to?(:to_str)
        reference = data['$ref'].to_str
      else
        raise TypeError, "Expected String, got #{data['$ref'].class}"
      end
      reference = '#' + reference if reference[0..0] != '#'
      data.merge({
        '$ref' => reference
      })
    elsif data.kind_of?(Hash)
      data.inject({}) do |accu, (key, value)|
        if value.kind_of?(Hash)
          accu[key] = reformat_references.call(value)
        else
          accu[key] = value
        end
        accu
      end
    else
      data
    end
  end
  schema_data = reformat_references.call(schema_data)

  if schema_name
    api_name_string = ActiveSupport::Inflector.camelize(api.name)
    api_version_string = ActiveSupport::Inflector.camelize(api.version).gsub('.', '_')
    # This is for compatibility with Ruby 1.8.7.
    # TODO(bobaman) Remove this when we eventually stop supporting 1.8.7.
    args = []
    args << false if Class.method(:const_defined?).arity != 1
    if Google::APIClient::Schema.const_defined?(api_name_string, *args)
      api_name = Google::APIClient::Schema.const_get(
        api_name_string, *args
      )
    else
      api_name = Google::APIClient::Schema.const_set(
        api_name_string, Module.new
      )
    end
    if api_name.const_defined?(api_version_string, *args)
      api_version = api_name.const_get(api_version_string, *args)
    else
      api_version = api_name.const_set(api_version_string, Module.new)
    end
    if api_version.const_defined?(schema_name, *args)
      schema_class = api_version.const_get(schema_name, *args)
    end
  end

  # It's possible the schema has already been defined. If so, don't
  # redefine it. This means that reloading a schema which has already
  # been loaded into memory is not possible.
  unless schema_class
    schema_class = AutoParse.generate(schema_data, :uri => schema_uri)
    if schema_name
      api_version.const_set(schema_name, schema_class)
    end
  end
  return schema_class
end