Skip to content

Instantly share code, notes, and snippets.

@tobias
Created October 6, 2010 17:53
Show Gist options
  • Save tobias/613776 to your computer and use it in GitHub Desktop.
Save tobias/613776 to your computer and use it in GitHub Desktop.
# Convert XML response to defined Ruby Class
def xml_to_class(c, item)
obj = c.new
# Set default attributes
obj.id = item['id']
api = self
c.instance_eval do
define_method :client do
api
end
end
obj.uri = item['href']
logger = @logger
logger << "[DC] Creating class #{obj.class.name}\n"
obj.instance_eval do
# Declare methods for all attributes in object
item.xpath('./*').each do |attribute|
# If attribute is a link to another object then
# create a method which request this object from API
if api.entry_points.keys.include?(:"#{attribute.name}s")
c.instance_eval do
define_method :"#{attribute.name.sanitize}" do
client.send(:"#{attribute.name}", attribute['id'] )
end
logger << "[DC] Added #{attribute.name} to class #{obj.class.name}\n"
end
else
# Define methods for other attributes
c.instance_eval do
case attribute.name
# When response cointains 'link' block, declare
# methods to call links inside. This is used for instance
# to dynamicaly create .stop!, .start! methods
when "actions":
actions = []
attribute.xpath('link').each do |link|
actions << [link['rel'], link[:href]]
puts actions.inspect
define_method :"#{link['rel'].sanitize}!" do
puts link['href']
# client.request(:"#{link['method']}", link['href'], {}, {})
@current_state = client.send(:"#{item.name}", item['id']).state
obj.instance_eval do |o|
def state
@current_state
end
end
end
end
define_method :actions do
actions.collect { |a| a.first }
end
define_method :actions_urls do
urls = {}
actions.each { |a| urls[a.first] = a.last }
urls
end
# Property attribute is handled differently
when "property":
attr_accessor :"#{attribute['name'].sanitize}"
if attribute['value'] =~ /^(\d+)$/
obj.send(:"#{attribute['name'].sanitize}=",
DeltaCloud::HWP::FloatProperty.new(attribute, attribute['name']))
else
obj.send(:"#{attribute['name'].sanitize}=",
DeltaCloud::HWP::Property.new(attribute, attribute['name']))
end
# Public and private addresses are returned as Array
when "public_addresses", "private_addresses":
attr_accessor :"#{attribute.name.sanitize}"
obj.send(:"#{attribute.name.sanitize}=",
attribute.xpath('address').collect { |address| address.text })
# Value for other attributes are just returned using
# method with same name as attribute (eg. .owner_id, .state)
else
attr_accessor :"#{attribute.name.sanitize}"
obj.send(:"#{attribute.name.sanitize}=", attribute.text.convert)
logger << "[DC] Added method #{attribute.name}[#{attribute.text}] to #{obj.class.name}\n"
end
end
end
end
end
return obj
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment