Class: RestKat::IosMapping

Inherits:
Object
  • Object
show all
Defined in:
lib/rest_kat.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_schema) ⇒ IosMapping

Returns a new instance of IosMapping.



147
148
149
150
# File 'lib/rest_kat.rb', line 147

def initialize api_schema
    raise "#{api_schema} does not exist" unless File.exist?(api_schema)
    @schema_file = api_schema
end

Class Method Details

.obj_c_type_for_property(parent_node, property_name) ⇒ Object



215
216
217
218
# File 'lib/rest_kat.rb', line 215

def self.obj_c_type_for_property parent_node, property_name
  parent_type = parent_node[:name].gsub /MSRest/, ''
  "MSRest#{parent_type.camelize}#{property_name.camelize}"
end

Instance Method Details

#classesObject



161
162
163
# File 'lib/rest_kat.rb', line 161

def classes
  @classes ||= []
end

#find_processed_class(node) ⇒ Object



220
221
222
# File 'lib/rest_kat.rb', line 220

def find_processed_class node
  classes.find{|c| c.type == node[:name]}
end

#generate_objective_c_classesObject

Generate the required objective c class AST’s for th name resource in the correct order so they can be written to code in the correct order in the templates



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/rest_kat.rb', line 185

def generate_objective_c_classes
  @classes = []
  resources_from_schema.collect do |resource_hash|
    Resource.new(resource_hash).tap do |resource|
      # Generate the query classes first
      resource.queries.each do |query|
        to_objective_c_class query["type"]
      end
      # Generate the resource classes next
      klass = to_objective_c_class resource.hash[:type]
      # Mark this class as being a REST resource
      klass.resource = resource
    end
  end
end

#h_templateObject



174
175
176
# File 'lib/rest_kat.rb', line 174

def h_template
  template "model.h.erb"
end

#m_templateObject



178
179
180
# File 'lib/rest_kat.rb', line 178

def m_template
  template "model.m.erb"
end

#resourcesObject



165
166
167
# File 'lib/rest_kat.rb', line 165

def resources
  @resources ||= []
end

#resources_from_schemaObject



152
153
154
# File 'lib/rest_kat.rb', line 152

def resources_from_schema
  schema[:resources]
end

#schemaObject



156
157
158
159
# File 'lib/rest_kat.rb', line 156

def schema
  require 'kwalify'
  @schema ||= HashWithIndifferentAccess.new Kwalify::Yaml.load_file(@schema_file)
end

#template(name) ⇒ Object



169
170
171
172
# File 'lib/rest_kat.rb', line 169

def template name
  require 'erb'
  ERB.new File.read(File.expand_path(File.join("..", name), __FILE__)), 0, '<>'
end

#to_h(name) ⇒ Object

Generate the objective C header for name resource



202
203
204
205
# File 'lib/rest_kat.rb', line 202

def to_h name
  @resources = generate_objective_c_classes
  h_template.result binding
end

#to_m(name) ⇒ Object

Generate the objective C implementation file for name resource



208
209
210
211
212
213
# File 'lib/rest_kat.rb', line 208

def to_m name
  @resources = generate_objective_c_classes
  #TODO below 'header' must change
  header = (File.basename name, ".*") + ".h"
  m_template.result binding
end

#to_objective_c_class(node) ⇒ Object

Perform a depth first traversal of the type tree. The resulting classes array will have the top level class last in the array. In the code generation phase this classes will be injected last into the code making sure the dependencies are define in the correct order.

Raises:

  • (Exception)


229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/rest_kat.rb', line 229

def to_objective_c_class node
  unless node
    raise Exception.new("node is nil for name '#{name}'")
  end

  case node[:type]
  when "map"

    unless klass = find_processed_class(node)
      klass = ObjCClass.new(node[:name], node[:type], node)

      klass.properties = node[:mapping].collect do |property_name, property_node|
        if property_node[:type] == "map"
          property_node[:name] ||= IosMapping.obj_c_type_for_property(node, property_name)
        end
        ObjCProperty.new(to_objective_c_class(property_node), property_name)
      end

      self.classes << klass
    end

  when "seq"
    klass = ObjCClass.new(node[:name] || "NSArray", node[:type], node)
    if node[:sequence].length != 1
      raise "Only support sequence of map with one map type"
    end
    sequence_node = node[:sequence].first
    if sequence_node["type"] == "map"
      if not sequence_node["name"]
        raise Exception.new ("sequence of map nodes must have a :name to generate the objective C types")
      end
      klass.sequence_of = to_objective_c_class sequence_node
    end
  when "str", "text"
    klass = ObjCClass.new(node[:name] || "NSString", node[:type], node)
  when "int"
    klass = ObjCClass.new(node[:name] || "NSNumber", node[:type], node)
  when "float"
    klass = ObjCClass.new(node[:name] || "NSNumber", node[:type], node)
  when "bool"
    klass = ObjCClass.new(node[:name] || "NSNumber", node[:type], node)
  when "any"
    klass = ObjCClass.new(node[:name] || "NSObject", node[:type], node)
  else
    raise Exception.new("Unhandled type '#{node[:type]} for node with name #{node[:name]}")
  end

  raise Exception.new("klass cannot be nil") unless klass

  klass

end