restfulie 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +10 -5
- data/Rakefile +5 -2
- data/lib/restfulie.rb +10 -5
- data/lib/restfulie/client.rb +13 -9
- data/lib/restfulie/client/base.rb +24 -65
- data/lib/restfulie/client/configuration.rb +62 -64
- data/lib/restfulie/client/entry_point.rb +36 -0
- data/lib/restfulie/client/ext/atom_ext.rb +12 -0
- data/lib/restfulie/client/ext/http_ext.rb +22 -0
- data/lib/restfulie/client/ext/json_ext.rb +12 -0
- data/lib/restfulie/client/ext/xml_ext.rb +4 -0
- data/lib/restfulie/client/http.rb +25 -13
- data/lib/restfulie/client/http/cache.rb +22 -22
- data/lib/restfulie/client/http/error.rb +70 -70
- data/lib/restfulie/client/http/link_request_builder.rb +15 -0
- data/lib/restfulie/client/http/request_adapter.rb +209 -0
- data/lib/restfulie/client/http/request_builder.rb +107 -0
- data/lib/restfulie/client/http/request_builder_executor.rb +24 -0
- data/lib/restfulie/client/http/request_executor.rb +17 -0
- data/lib/restfulie/client/http/request_follow.rb +42 -0
- data/lib/restfulie/client/http/request_follow_executor.rb +10 -0
- data/lib/restfulie/client/http/request_history.rb +69 -0
- data/lib/restfulie/client/http/request_history_executor.rb +10 -0
- data/lib/restfulie/client/http/request_marshaller.rb +127 -0
- data/lib/restfulie/client/http/request_marshaller_executor.rb +10 -0
- data/lib/restfulie/client/http/response.rb +23 -0
- data/lib/restfulie/client/http/response_handler.rb +67 -0
- data/lib/restfulie/client/http/response_holder.rb +9 -0
- data/lib/restfulie/client/mikyung.rb +17 -14
- data/lib/restfulie/client/mikyung/concatenator.rb +15 -12
- data/lib/restfulie/client/mikyung/core.rb +65 -39
- data/lib/restfulie/client/mikyung/languages.rb +8 -26
- data/lib/restfulie/client/mikyung/languages/german.rb +24 -0
- data/lib/restfulie/client/mikyung/languages/portuguese.rb +23 -0
- data/lib/restfulie/client/mikyung/rest_process_model.rb +184 -107
- data/lib/restfulie/client/mikyung/steady_state_walker.rb +34 -28
- data/lib/restfulie/client/mikyung/then_condition.rb +33 -27
- data/lib/restfulie/client/mikyung/when_condition.rb +53 -49
- data/lib/restfulie/common.rb +7 -12
- data/lib/restfulie/common/converter.rb +20 -9
- data/lib/restfulie/common/converter/atom.rb +8 -83
- data/lib/restfulie/common/converter/atom/base.rb +89 -0
- data/lib/restfulie/common/converter/atom/builder.rb +101 -99
- data/lib/restfulie/common/converter/atom/helpers.rb +16 -8
- data/lib/restfulie/common/converter/json.rb +12 -0
- data/lib/restfulie/common/converter/json/base.rb +84 -0
- data/lib/restfulie/common/converter/json/builder.rb +102 -0
- data/lib/restfulie/common/converter/json/helpers.rb +17 -0
- data/lib/restfulie/common/converter/values.rb +30 -26
- data/lib/restfulie/common/converter/xml.rb +14 -0
- data/lib/restfulie/common/converter/xml/base.rb +61 -0
- data/lib/restfulie/common/converter/xml/builder.rb +112 -0
- data/lib/restfulie/common/converter/xml/helpers.rb +17 -0
- data/lib/restfulie/common/converter/xml/link.rb +25 -0
- data/lib/restfulie/common/converter/xml/links.rb +25 -0
- data/lib/restfulie/common/core_ext.rb +1 -5
- data/lib/restfulie/common/core_ext/hash.rb +12 -0
- data/lib/restfulie/common/error.rb +19 -0
- data/lib/restfulie/common/logger.rb +17 -9
- data/lib/restfulie/common/representation.rb +9 -10
- data/lib/restfulie/common/representation/atom.rb +15 -47
- data/lib/restfulie/common/representation/atom/base.rb +122 -365
- data/lib/restfulie/common/representation/atom/category.rb +41 -0
- data/lib/restfulie/common/representation/atom/entry.rb +52 -100
- data/lib/restfulie/common/representation/atom/factory.rb +43 -0
- data/lib/restfulie/common/representation/atom/feed.rb +103 -99
- data/lib/restfulie/common/representation/atom/link.rb +68 -0
- data/lib/restfulie/common/representation/atom/person.rb +48 -0
- data/lib/restfulie/common/representation/atom/source.rb +59 -0
- data/lib/restfulie/common/representation/atom/tag_collection.rb +38 -0
- data/lib/restfulie/common/representation/atom/xml.rb +95 -0
- data/lib/restfulie/common/representation/generic.rb +30 -29
- data/lib/restfulie/common/representation/json.rb +10 -22
- data/lib/restfulie/common/representation/json/base.rb +27 -0
- data/lib/restfulie/common/representation/json/keys_as_methods.rb +72 -0
- data/lib/restfulie/common/representation/json/link.rb +29 -0
- data/lib/restfulie/common/representation/json/link_collection.rb +23 -0
- data/lib/restfulie/common/representation/xml.rb +18 -227
- data/lib/restfulie/server.rb +9 -10
- data/lib/restfulie/server/action_controller.rb +10 -12
- data/lib/restfulie/server/action_controller/base.rb +18 -15
- data/lib/restfulie/server/action_controller/{routing/patch.rb → patch.rb} +0 -0
- data/lib/restfulie/server/action_controller/restful_responder.rb +43 -35
- data/lib/restfulie/server/action_view.rb +8 -6
- data/lib/restfulie/server/action_view/helpers.rb +47 -41
- data/lib/restfulie/server/action_view/template_handlers.rb +24 -12
- data/lib/restfulie/server/action_view/template_handlers/tokamak.rb +17 -12
- data/lib/restfulie/server/configuration.rb +22 -19
- data/lib/restfulie/server/{restfulie_controller.rb → controller.rb} +1 -10
- data/lib/restfulie/server/core_ext.rb +1 -1
- data/lib/restfulie/version.rb +14 -0
- metadata +52 -16
- data/lib/restfulie/client/http/adapter.rb +0 -502
- data/lib/restfulie/client/http/atom_ext.rb +0 -4
- data/lib/restfulie/client/http/core_ext.rb +0 -6
- data/lib/restfulie/client/http/core_ext/http.rb +0 -19
- data/lib/restfulie/client/http/marshal.rb +0 -145
- data/lib/restfulie/client/http/xml_ext.rb +0 -7
- data/lib/restfulie/common/core_ext/proc.rb +0 -48
- data/lib/restfulie/common/errors.rb +0 -15
- data/lib/restfulie/server/action_controller/routing.rb +0 -12
- data/lib/restfulie/server/action_controller/routing/restful_route.rb +0 -14
@@ -1,32 +1,38 @@
|
|
1
1
|
# A steady walker that tries 3 times each step
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
2
|
+
module Restfulie
|
3
|
+
module Client
|
4
|
+
module Mikyung
|
5
|
+
class SteadyStateWalker
|
6
|
+
def move(goal, current, mikyung)
|
7
|
+
step = goal.next_step(current, mikyung)
|
8
|
+
raise UnableToAchieveGoalError, "No step was found for #{current}" unless step
|
9
|
+
Common::Logger.logger.debug "Mikyung > next step will be #{step}"
|
10
|
+
step = step.new if step.kind_of? Class
|
11
|
+
try_to_execute(step, current, 3, mikyung)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def try_to_execute(step, current, max_attempts, mikyung)
|
17
|
+
raise "Unable to proceed when trying to #{step}" if max_attempts == 0
|
18
|
+
|
19
|
+
resource = step
|
20
|
+
raise "Step returned 'give up'" if resource.nil?
|
21
|
+
|
22
|
+
if step.respond_to?(:execute)
|
23
|
+
resource = step.execute(current, mikyung)
|
24
|
+
end
|
19
25
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
# TODO: should it really retry if it is not 200? Or only if it is on the 50x family?
|
27
|
+
# for instance the result could be a 302 redirection
|
28
|
+
unless resource.response.code == 200
|
29
|
+
try_to_execute(step, current, max_attempts-1, mikyung)
|
30
|
+
else
|
31
|
+
Common::Logger.logger.debug resource.response.body
|
32
|
+
resource
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
29
36
|
end
|
30
37
|
end
|
31
|
-
|
32
|
-
end
|
38
|
+
end
|
@@ -1,33 +1,39 @@
|
|
1
1
|
# A conclusion to a step.
|
2
2
|
#
|
3
3
|
# Whenever a step rule matches, there are a series of conditions to be executed.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
4
|
+
module Restfulie
|
5
|
+
module Client
|
6
|
+
module Mikyung
|
7
|
+
class ThenCondition
|
8
|
+
attr_reader :description
|
9
|
+
|
10
|
+
# creates a new result, based on this description
|
11
|
+
def initialize(description)
|
12
|
+
@description = description
|
13
|
+
end
|
14
|
+
|
15
|
+
# finds the rule for this result and executes it
|
16
|
+
def execute(resource, goal, mikyung)
|
17
|
+
goal.then_rules.each do |rule|
|
18
|
+
if (matches = Regexp.new(rule[0]).match(@description))
|
19
|
+
return invoke_rule(rule[1], resource, matches, mikyung)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def invoke_rule(rule, resource, matches, mikyung)
|
27
|
+
case rule.arity
|
28
|
+
when 1
|
29
|
+
rule.call(resource)
|
30
|
+
when 2
|
31
|
+
rule.call(resource, matches)
|
32
|
+
else
|
33
|
+
rule.call(resource, matches, mikyung)
|
34
|
+
end
|
35
|
+
end
|
18
36
|
end
|
19
37
|
end
|
20
|
-
nil
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
def invoke_rule(rule, resource, matches, mikyung)
|
25
|
-
if rule.arity==1
|
26
|
-
rule.call(resource)
|
27
|
-
elsif rule.arity==2
|
28
|
-
rule.call(resource, matches)
|
29
|
-
else
|
30
|
-
rule.call(resource, matches, mikyung)
|
31
|
-
end
|
32
38
|
end
|
33
|
-
end
|
39
|
+
end
|
@@ -1,53 +1,57 @@
|
|
1
1
|
# Checks whether one or more rule holds and is capable of executing results.
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
2
|
+
module Restfulie
|
3
|
+
module Client
|
4
|
+
module Mikyung
|
5
|
+
# Creates a conditional execution based on a description.
|
6
|
+
# Its rule is an array where its first element represents a rule name and second a lambda that returns true or false
|
7
|
+
# Its params are extra params that might be passed to the rule
|
8
|
+
# Example
|
9
|
+
# WhenCondition.new("when running", ["", lambda { |resource| resource.human.state=='running' }], "")
|
10
|
+
class WhenCondition
|
11
|
+
def initialize(description, rule, params)
|
12
|
+
@description = description
|
13
|
+
@results = []
|
14
|
+
@extra = []
|
15
|
+
@rule = rule
|
16
|
+
@params = params
|
17
|
+
end
|
18
|
+
|
19
|
+
# will execute the first attached result
|
20
|
+
def execute(resource, goal, mikyung)
|
21
|
+
@results.each do |result|
|
22
|
+
Restfulie::Common::Logger.logger.info("will '#{result.description}'")
|
23
|
+
return result.execute(resource, goal, mikyung)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# checks whether this step should execute for a specific resource
|
28
|
+
def should_run_for(resource, goal)
|
29
|
+
if @rule[1].arity == 2
|
30
|
+
rule_accepts = @rule[1].call(resource, @params)
|
31
|
+
else
|
32
|
+
rule_accepts = @rule[1].call(resource)
|
33
|
+
end
|
34
|
+
return false unless rule_accepts
|
35
|
+
!@extra.find do |condition|
|
36
|
+
!condition.should_run_for(resource, goal)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# adds an extra condition to this step
|
41
|
+
def and(condition)
|
42
|
+
@extra << condition
|
43
|
+
end
|
44
|
+
|
45
|
+
# adds an extra condition to this step
|
46
|
+
def but(condition)
|
47
|
+
@extra << condition
|
48
|
+
end
|
49
|
+
|
50
|
+
# adds an extra result to this step
|
51
|
+
def results_on(result)
|
52
|
+
@results << result
|
53
|
+
end
|
54
|
+
end
|
35
55
|
end
|
36
56
|
end
|
37
|
-
|
38
|
-
# adds an extra condition to this step
|
39
|
-
def and(condition)
|
40
|
-
@extra << condition
|
41
|
-
end
|
42
|
-
|
43
|
-
# adds an extra condition to this step
|
44
|
-
def but(condition)
|
45
|
-
@extra << condition
|
46
|
-
end
|
47
|
-
|
48
|
-
# adds an extra result to this step
|
49
|
-
def results_on(result)
|
50
|
-
@results << result
|
51
|
-
end
|
52
|
-
|
53
57
|
end
|
data/lib/restfulie/common.rb
CHANGED
@@ -4,19 +4,14 @@ require 'uri'
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'active_support'
|
6
6
|
require 'action_controller'
|
7
|
+
require 'restfulie/common/core_ext'
|
7
8
|
|
8
9
|
module Restfulie
|
9
|
-
module Common
|
10
|
+
module Common
|
11
|
+
autoload :Error, 'restfulie/common/error'
|
12
|
+
autoload :Logger, 'restfulie/common/logger'
|
13
|
+
autoload :Representation, 'restfulie/common/representation'
|
14
|
+
autoload :Converter, 'restfulie/common/converter'
|
15
|
+
end
|
10
16
|
end
|
11
17
|
|
12
|
-
%w(
|
13
|
-
errors
|
14
|
-
logger
|
15
|
-
core_ext
|
16
|
-
representation
|
17
|
-
converter
|
18
|
-
).each do |file|
|
19
|
-
require "restfulie/common/#{file}"
|
20
|
-
end
|
21
|
-
|
22
|
-
include ActiveSupport::CoreExtensions::Hash
|
@@ -1,11 +1,22 @@
|
|
1
|
-
|
2
|
-
module
|
1
|
+
module Restfulie
|
2
|
+
module Common
|
3
|
+
module Converter
|
4
|
+
autoload :Values, 'restfulie/common/converter/values'
|
5
|
+
autoload :Atom, 'restfulie/common/converter/atom'
|
6
|
+
autoload :Json, 'restfulie/common/converter/json'
|
7
|
+
autoload :Xml, 'restfulie/common/converter/xml'
|
3
8
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
).
|
10
|
-
|
9
|
+
# Returns the default root element name for an item or collection
|
10
|
+
def self.root_element_for(obj)
|
11
|
+
if obj.kind_of?(Hash) && obj.size==1
|
12
|
+
obj.keys.first.to_s
|
13
|
+
elsif obj.kind_of?(Array) && !obj.empty?
|
14
|
+
root_element_for(obj.first).to_s.underscore.pluralize
|
15
|
+
else
|
16
|
+
obj.class.to_s.underscore
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
11
21
|
end
|
22
|
+
|
@@ -1,87 +1,12 @@
|
|
1
|
-
module Restfulie
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@@headers = {
|
10
|
-
:get => { 'Accept' => media_type_name },
|
11
|
-
:post => { 'Content-Type' => media_type_name }
|
12
|
-
}
|
13
|
-
|
14
|
-
mattr_reader :recipes
|
15
|
-
@@recipes = {}
|
16
|
-
|
17
|
-
class << self
|
18
|
-
|
19
|
-
def helper
|
20
|
-
Restfulie::Common::Converter::Atom::Helpers
|
1
|
+
module Restfulie
|
2
|
+
module Common
|
3
|
+
module Converter
|
4
|
+
module Atom
|
5
|
+
autoload :Base, 'restfulie/common/converter/atom/base'
|
6
|
+
autoload :Builder, 'restfulie/common/converter/atom/builder'
|
7
|
+
autoload :Helpers, 'restfulie/common/converter/atom/helpers'
|
8
|
+
extend Base::ClassMethods
|
21
9
|
end
|
22
|
-
|
23
|
-
def describe_recipe(recipe_name, options={}, &block)
|
24
|
-
raise 'Undefined recipe' unless block_given?
|
25
|
-
raise 'Undefined recipe_name' unless recipe_name
|
26
|
-
@@recipes[recipe_name] = block
|
27
|
-
end
|
28
|
-
|
29
|
-
def to_atom(obj = nil, options = {}, &block)
|
30
|
-
# just instantiate the string with the atom factory
|
31
|
-
return Restfulie::Common::Representation::Atom::Factory.create(obj) if obj.kind_of?(String)
|
32
|
-
|
33
|
-
if block_given?
|
34
|
-
recipe = block
|
35
|
-
elsif options[:recipe]
|
36
|
-
recipe = @@recipes[options[:recipe]]
|
37
|
-
else
|
38
|
-
return obj if obj.respond_to?(:atom_type) && (obj.atom_type == "feed" || obj.atom_type == "entry")
|
39
|
-
raise Restfulie::Common::Error::ConverterError.new("Recipe required")
|
40
|
-
end
|
41
|
-
|
42
|
-
# execute with the builder if a recipe is set (even if the obj is an atom)
|
43
|
-
options[:atom_type] ||= obj.respond_to?(:each) ? :feed : :entry
|
44
|
-
raise Restfulie::Common::Error::ConverterError.new("Undefined atom type #{options[:atom_type]}") unless [:entry,:feed].include?(options[:atom_type])
|
45
|
-
|
46
|
-
# Create representation and proxy
|
47
|
-
builder = Builder.new(options[:atom_type], obj)
|
48
|
-
|
49
|
-
# Check recipe arity size before calling it
|
50
|
-
recipe.call(*[builder, obj, options][0,recipe.arity])
|
51
|
-
|
52
|
-
builder.representation
|
53
|
-
end
|
54
|
-
|
55
|
-
alias_method :unmarshal, :to_atom
|
56
|
-
|
57
|
-
def to_hash(obj)
|
58
|
-
return obj if obj.kind_of?(Hash)
|
59
|
-
|
60
|
-
xml = nil
|
61
|
-
|
62
|
-
if obj.kind_of?(::String)
|
63
|
-
xml = obj
|
64
|
-
elsif obj.respond_to?(:to_xml)
|
65
|
-
xml = obj.to_xml
|
66
|
-
end
|
67
|
-
|
68
|
-
Hash.from_xml(xml).with_indifferent_access unless xml.nil?
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
def to_s(obj)
|
73
|
-
return obj if obj.kind_of?(String)
|
74
|
-
if obj.respond_to?(:to_xml)
|
75
|
-
obj.to_xml.to_s
|
76
|
-
else
|
77
|
-
obj.to_s
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def marshal(obj, options = nil)
|
82
|
-
to_atom(obj, options).to_xml
|
83
|
-
end
|
84
|
-
|
85
10
|
end
|
86
11
|
end
|
87
12
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Restfulie
|
2
|
+
module Common
|
3
|
+
module Converter
|
4
|
+
module Atom
|
5
|
+
module Base
|
6
|
+
module ClassMethods
|
7
|
+
mattr_reader :media_type_name
|
8
|
+
@@media_type_name = 'application/atom+xml'
|
9
|
+
|
10
|
+
mattr_reader :headers
|
11
|
+
@@headers = {
|
12
|
+
:get => { 'Accept' => media_type_name },
|
13
|
+
:post => { 'Content-Type' => media_type_name }
|
14
|
+
}
|
15
|
+
|
16
|
+
mattr_reader :recipes
|
17
|
+
@@recipes = {}
|
18
|
+
|
19
|
+
def helper
|
20
|
+
Restfulie::Common::Converter::Atom::Helpers
|
21
|
+
end
|
22
|
+
|
23
|
+
def describe_recipe(recipe_name, options={}, &block)
|
24
|
+
raise 'Undefined recipe' unless block_given?
|
25
|
+
raise 'Undefined recipe_name' unless recipe_name
|
26
|
+
@@recipes[recipe_name] = block
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_atom(obj = nil, options = {}, &block)
|
30
|
+
# just instantiate the string with the atom factory
|
31
|
+
return Restfulie::Common::Representation::Atom::Factory.create(obj) if obj.kind_of?(String)
|
32
|
+
|
33
|
+
if block_given?
|
34
|
+
recipe = block
|
35
|
+
elsif options[:recipe]
|
36
|
+
recipe = @@recipes[options[:recipe]]
|
37
|
+
else
|
38
|
+
return obj if obj.respond_to?(:atom_type) && (obj.atom_type == "feed" || obj.atom_type == "entry")
|
39
|
+
raise Restfulie::Common::Error::ConverterError.new("Recipe required")
|
40
|
+
end
|
41
|
+
|
42
|
+
# execute with the builder if a recipe is set (even if the obj is an atom)
|
43
|
+
options[:atom_type] ||= obj.respond_to?(:each) ? :feed : :entry
|
44
|
+
raise Restfulie::Common::Error::ConverterError.new("Undefined atom type #{options[:atom_type]}") unless [:entry,:feed].include?(options[:atom_type])
|
45
|
+
|
46
|
+
# Create representation and proxy
|
47
|
+
builder = Builder.new(options[:atom_type], obj)
|
48
|
+
|
49
|
+
# Check recipe arity size before calling it
|
50
|
+
recipe.call(*[builder, obj, options][0,recipe.arity])
|
51
|
+
|
52
|
+
builder.representation
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :unmarshal, :to_atom
|
56
|
+
|
57
|
+
def to_hash(obj)
|
58
|
+
return obj if obj.kind_of?(Hash)
|
59
|
+
|
60
|
+
xml = nil
|
61
|
+
|
62
|
+
if obj.kind_of?(::String)
|
63
|
+
xml = obj
|
64
|
+
elsif obj.respond_to?(:to_xml)
|
65
|
+
xml = obj.to_xml
|
66
|
+
end
|
67
|
+
|
68
|
+
Hash.from_xml(xml).with_indifferent_access unless xml.nil?
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def to_s(obj)
|
73
|
+
return obj if obj.kind_of?(String)
|
74
|
+
if obj.respond_to?(:to_xml)
|
75
|
+
obj.to_xml.to_s
|
76
|
+
else
|
77
|
+
obj.to_s
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def marshal(obj, options = nil)
|
82
|
+
to_atom(obj, options).to_xml
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|