wrest 4.0.0-universal-java-18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +169 -0
  3. data/LICENCE +7 -0
  4. data/README.md +436 -0
  5. data/bin/wrest +4 -0
  6. data/bin/wrest_shell.rb +23 -0
  7. data/lib/wrest/async_request/event_machine_backend.rb +32 -0
  8. data/lib/wrest/async_request/thread_backend.rb +34 -0
  9. data/lib/wrest/async_request/thread_pool.rb +29 -0
  10. data/lib/wrest/async_request.rb +51 -0
  11. data/lib/wrest/cache_proxy.rb +119 -0
  12. data/lib/wrest/caching/memcached.rb +37 -0
  13. data/lib/wrest/caching/redis.rb +38 -0
  14. data/lib/wrest/caching.rb +57 -0
  15. data/lib/wrest/callback.rb +70 -0
  16. data/lib/wrest/components/container/alias_accessors.rb +70 -0
  17. data/lib/wrest/components/container/typecaster.rb +178 -0
  18. data/lib/wrest/components/container.rb +204 -0
  19. data/lib/wrest/components/mutators/base.rb +65 -0
  20. data/lib/wrest/components/mutators/camel_to_snake_case.rb +26 -0
  21. data/lib/wrest/components/mutators/xml_type_caster.rb +56 -0
  22. data/lib/wrest/components/mutators.rb +42 -0
  23. data/lib/wrest/components/translators/content_types.rb +25 -0
  24. data/lib/wrest/components/translators/json.rb +36 -0
  25. data/lib/wrest/components/translators/txt.rb +35 -0
  26. data/lib/wrest/components/translators/xml/conversions.rb +56 -0
  27. data/lib/wrest/components/translators/xml.rb +77 -0
  28. data/lib/wrest/components/translators.rb +30 -0
  29. data/lib/wrest/components.rb +22 -0
  30. data/lib/wrest/core_ext/hash/conversions.rb +45 -0
  31. data/lib/wrest/core_ext/hash.rb +7 -0
  32. data/lib/wrest/core_ext/string/conversions.rb +38 -0
  33. data/lib/wrest/core_ext/string.rb +7 -0
  34. data/lib/wrest/exceptions.rb +38 -0
  35. data/lib/wrest/hash_with_case_insensitive_access.rb +52 -0
  36. data/lib/wrest/hash_with_indifferent_access.rb +442 -0
  37. data/lib/wrest/http_codes.rb +83 -0
  38. data/lib/wrest/http_shared/headers.rb +345 -0
  39. data/lib/wrest/http_shared/standard_headers.rb +22 -0
  40. data/lib/wrest/http_shared/standard_tokens.rb +21 -0
  41. data/lib/wrest/http_shared.rb +25 -0
  42. data/lib/wrest/multipart.rb +84 -0
  43. data/lib/wrest/native/connection_factory.rb +28 -0
  44. data/lib/wrest/native/delete.rb +27 -0
  45. data/lib/wrest/native/get.rb +83 -0
  46. data/lib/wrest/native/options.rb +27 -0
  47. data/lib/wrest/native/patch.rb +27 -0
  48. data/lib/wrest/native/post.rb +27 -0
  49. data/lib/wrest/native/post_multipart.rb +36 -0
  50. data/lib/wrest/native/put.rb +27 -0
  51. data/lib/wrest/native/put_multipart.rb +36 -0
  52. data/lib/wrest/native/redirection.rb +39 -0
  53. data/lib/wrest/native/request.rb +161 -0
  54. data/lib/wrest/native/response.rb +278 -0
  55. data/lib/wrest/native/session.rb +66 -0
  56. data/lib/wrest/native.rb +36 -0
  57. data/lib/wrest/test/request_patches.rb +12 -0
  58. data/lib/wrest/test.rb +3 -0
  59. data/lib/wrest/uri/builders.rb +48 -0
  60. data/lib/wrest/uri.rb +312 -0
  61. data/lib/wrest/uri_template.rb +63 -0
  62. data/lib/wrest/utils.rb +129 -0
  63. data/lib/wrest/version.rb +14 -0
  64. data/lib/wrest.rb +77 -0
  65. data/lib/wrest_no_ext.rb +7 -0
  66. metadata +286 -0
@@ -0,0 +1,204 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ module Wrest
13
+ module Components
14
+ module Container
15
+ end
16
+ end
17
+ end
18
+
19
+ require 'wrest/components/container/typecaster'
20
+ require 'wrest/components/container/alias_accessors'
21
+
22
+ module Wrest
23
+ module Components
24
+ # Adds behaviour allowing a class to
25
+ # contain attributes and providing support
26
+ # for dynamic getters, setters and query methods.
27
+ # These methods are added at runtime, on the first
28
+ # invocation and on a per instance basis.
29
+ # <tt>respond_to?</tt> however will respond as though
30
+ # they are all already present.
31
+ # This means that two different instances of the same
32
+ # Container could well have different attribute
33
+ # getters/setters/query methods.
34
+ #
35
+ # Note that the first call to a particular getter/setter/query
36
+ # method will be slower because the method is defined
37
+ # at that point; subsequent calls will be much faster.
38
+ #
39
+ # Also keep in mind that attribute getter/setter/query methods
40
+ # will _not_ override any existing methods on the class.
41
+ #
42
+ # In situations where this is a problem, such as a client consuming Rails
43
+ # REST services where <tt>id</tt> is a common attribute and clashes with
44
+ # Object#id, it is recommended to create getter/setter/query methods
45
+ # on the class (which affects all instances) using the +always_has+ macro.
46
+ #
47
+ # If you're implementing your own initialize method
48
+ # remember to delegate to the default initialize
49
+ # of Container by invoking <tt>super(attributes)</tt>
50
+ #
51
+ # Example:
52
+ # class ShenCoin
53
+ # include Wrest::Components::Container
54
+ # include Wrest::Components::Container::Typecaster
55
+ #
56
+ # always_has :id
57
+ # typecast :id => as_integer
58
+ # end
59
+ # coin = ShenCoin.new(:id => '5', :chi_count => 500, :owner => 'Kai Wren')
60
+ # coin.id # => 5
61
+ # coin.owner # => 'Kai Wren'
62
+ module Container
63
+ def self.included(klass) # :nodoc:
64
+ klass.extend Container::ClassMethods
65
+ klass.extend Container::Typecaster::Helpers
66
+ klass.class_eval do
67
+ include Container::InstanceMethods
68
+ include Container::AliasAccessors
69
+ end
70
+ end
71
+
72
+ def self.build_attribute_getter(attribute_name) # :nodoc:
73
+ "def #{attribute_name};@attributes[:#{attribute_name}];end;"
74
+ end
75
+
76
+ def self.build_attribute_setter(attribute_name) # :nodoc:
77
+ "def #{attribute_name}=(value);@attributes[:#{attribute_name}] = value;end;"
78
+ end
79
+
80
+ def self.build_attribute_queryer(attribute_name) # :nodoc:
81
+ "def #{attribute_name}?;not @attributes[:#{attribute_name}].nil?;end;"
82
+ end
83
+
84
+ module ClassMethods
85
+ # This macro explicitly creates getter, setter and query methods on
86
+ # an Container, overriding any existing methods with the same names.
87
+ # This can be used when attribute names clash with existing method names;
88
+ # an example would be Rails REST resources which frequently make use
89
+ # an attribute named <tt>id</tt> which clashes with Object#id. Also,
90
+ # this can be used as a performance optimisation if the incoming
91
+ # attributes are known beforehand.
92
+ def always_has(*attribute_names)
93
+ attribute_names.each do |attribute_name|
94
+ class_eval(
95
+ Container.build_attribute_getter(attribute_name) +
96
+ Container.build_attribute_setter(attribute_name) +
97
+ Container.build_attribute_queryer(attribute_name)
98
+ )
99
+ end
100
+ end
101
+
102
+ # This is a convenience macro which includes
103
+ # Wrest::Components::Container::Typecaster into
104
+ # the class (effectively overwriting this method) before delegating to
105
+ # the actual typecast method that is a part of that module.
106
+ # This saves us the effort of explicitly doing the include. Easy to use API is king.
107
+ #
108
+ # Remember that using typecast carries a performance penalty.
109
+ # See Wrest::Components::Container::Typecaster for the actual docs.
110
+ def typecast(cast_map)
111
+ class_eval { include Wrest::Components::Container::Typecaster }
112
+ typecast cast_map
113
+ end
114
+
115
+ # This is the name of the class in snake-case, with any parent
116
+ # module names removed.
117
+ #
118
+ # The class will use as the root element when
119
+ # serialised to xml after replacing underscores with hyphens.
120
+ #
121
+ # This method can be overidden should you need a different name.
122
+ def element_name
123
+ @element_name ||= Utils.string_underscore(Utils.string_demodulize(name))
124
+ end
125
+ end
126
+
127
+ module InstanceMethods
128
+ # Sets up any class to act like
129
+ # an attributes container by creating
130
+ # two variables, @attributes and @interface.
131
+ # Remember not to use these two variable names
132
+ # when using Container in your own class.
133
+ def initialize(attributes = {})
134
+ @attributes = HashWithIndifferentAccess.new(attributes)
135
+ end
136
+
137
+ # A translator is a anything that knows how to serialise a
138
+ # Hash. It must needs have a method named 'serialise' that
139
+ # accepts a hash and configuration options, and returns the serialised
140
+ # result (leaving the hash unchanged, of course).
141
+ #
142
+ # Examples for JSON and XML can be found under Wrest::Components::Translators.
143
+ # These serialised output of these translators will work out of the box for Rails
144
+ # applications; you may need to roll your own for anything else.
145
+ #
146
+ # Note: When serilising to XML, if you want the name of the class as the name of the root node
147
+ # then you should use the Container#to_xml helper.
148
+ def serialise_using(translator, options = {})
149
+ payload = {
150
+ self.class.element_name => @attributes.dup
151
+ }
152
+ translator.serialise(payload, options)
153
+ end
154
+
155
+ def to_xml(options = {})
156
+ serialise_using(Wrest::Components::Translators::Xml, { root: self.class.element_name }.merge(options))
157
+ end
158
+
159
+ def [](key)
160
+ @attributes[key.to_sym]
161
+ end
162
+
163
+ def []=(key, value)
164
+ @attributes[key.to_sym] = value
165
+ end
166
+
167
+ def respond_to_missing?(method_name, *)
168
+ if super.respond_to?(method_name)
169
+ true
170
+ else
171
+ @attributes.include?(method_name.to_s.gsub(/(\?$)|(=$)/,
172
+ '').to_sym)
173
+ end
174
+ end
175
+
176
+ # Creates getter, setter and query methods for
177
+ # attributes on the first call.
178
+ def method_missing(method_sym, *arguments)
179
+ method_name = method_sym.to_s
180
+ attribute_name = method_name.gsub(/(\?$)|(=$)/, '')
181
+ if @attributes.include?(attribute_name.to_sym) || method_name[-1] == '=' || method_name[-1] == '?'
182
+ generate_methods!(attribute_name, method_name)
183
+ send(method_sym, *arguments)
184
+ else
185
+ super(method_sym, *arguments)
186
+ end
187
+ end
188
+
189
+ private
190
+
191
+ def generate_methods!(attribute_name, method_name)
192
+ case method_name[-1]
193
+ when '='
194
+ instance_eval Container.build_attribute_setter(attribute_name)
195
+ when '?'
196
+ instance_eval Container.build_attribute_queryer(attribute_name)
197
+ else
198
+ instance_eval Container.build_attribute_getter(attribute_name)
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ module Wrest
13
+ module Components
14
+ # This is a base implementation of a
15
+ # hash mutator that ensures that the <tt>mutate</tt> method
16
+ # will chain to the next mutator by using a
17
+ # template method.
18
+ module Mutators
19
+ class Base
20
+ attr_reader :next_mutator
21
+
22
+ # Registers all subclasses of Mutators::Base in
23
+ # Mutators::REGISTRY making it easy to reference
24
+ # and chain them later.
25
+ #
26
+ # See Mutators#chain for more information.
27
+ def self.inherited(subklass)
28
+ super
29
+ return if Utils.string_blank?(subklass.name)
30
+
31
+ key = Utils.string_underscore(Utils.string_demodulize(subklass.name)).to_sym
32
+ Wrest::Components::Mutators.registry[key] = subklass
33
+ end
34
+
35
+ def initialize(next_mutator = nil)
36
+ @next_mutator = next_mutator
37
+ end
38
+
39
+ # This is a template method which operates on a tuple (well, pair)
40
+ # from a hash map and guarantees mutator chaining.
41
+ #
42
+ # Iterating over any hash using <tt>each</tt> injects
43
+ # each key/value pair from the hash in the
44
+ # form of an array.
45
+ # This method expects of this form as an argument, i.e.
46
+ # an array with the structure [:key, :value]
47
+ #
48
+ # The implementation of the mutation is achieved by
49
+ # overriding the <tt>do_mutate</tt> method in a subclass.
50
+ # Note that failing to do so will result in an exception
51
+ # at runtime.
52
+ def mutate(tuple)
53
+ out_tuple = do_mutate(tuple)
54
+ next_mutator ? next_mutator.mutate(out_tuple) : out_tuple
55
+ end
56
+
57
+ protected
58
+
59
+ def do_mutate(_tuple)
60
+ raise Wrest::Exceptions::MethodNotOverridden
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ module Wrest
13
+ module Components
14
+ # Converts the key to snake case
15
+ #
16
+ # Example:
17
+ # Mutators::CamelToSnakeCase.new.mutate(['Spirit-Sword', 'true']) # => ['spirit_sword', 'true']**
18
+ module Mutators
19
+ class CamelToSnakeCase < Mutators::Base
20
+ def do_mutate(tuple)
21
+ [Utils.string_underscore(tuple.first), tuple.last]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ module Wrest
13
+ module Components
14
+ # This mutator undertands how do type casting
15
+ # using the type data embedded in a hash
16
+ # created by deserialising an xml using
17
+ # ActiveSupport::XmlMini
18
+ module Mutators
19
+ class XmlTypeCaster < Mutators::Base
20
+ def do_mutate(tuple)
21
+ out_key, in_value = tuple
22
+
23
+ out_value = case in_value
24
+ when Hash
25
+ process_hash_value(in_value)
26
+ when Array
27
+ in_value.collect { |hash| hash.mutate_using(self) }
28
+ else
29
+ in_value
30
+ end
31
+
32
+ [out_key, out_value]
33
+ end
34
+
35
+ private
36
+
37
+ def process_hash_value(in_value)
38
+ if in_value['nil'] == 'true'
39
+ nil
40
+ elsif in_value.key?('type')
41
+ typecast_value(in_value)
42
+ elsif in_value.key?('__content__')
43
+ in_value['__content__']
44
+ else
45
+ in_value.mutate_using(self)
46
+ end
47
+ end
48
+
49
+ def typecast_value(in_value)
50
+ caster = Container::Typecaster::PARSING[in_value['type']]
51
+ caster ? caster.call(in_value['__content__']) : in_value
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ module Wrest
13
+ module Components
14
+ # A mutator understands how to transform
15
+ # one tuple(key/value pair) from a hash
16
+ # into another
17
+ module Mutators
18
+ # All sublasses of Mutators::Base are automatically
19
+ # registered here by underscored, symbolised class name.
20
+ def self.registry
21
+ @registry ||= {}
22
+ end
23
+
24
+ # Makes referencing and chaining mutators easy.
25
+ #
26
+ # Example:
27
+ # Mutators.chain(:xml_type_caster, :camel_to_snake_case)
28
+ # is equivalent to
29
+ # Wrest::Components::Mutators::XmlTypeCaster.new(Wrest::Components::Mutators::CamelToSnakeCase.new)
30
+ def self.chain(*mutator_keys)
31
+ mutator_key = mutator_keys.pop
32
+ mutator_keys.reverse.inject(registry[mutator_key].new) do |next_instance, next_key|
33
+ registry[next_key].new(next_instance)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ require 'wrest/core_ext/hash'
40
+ require 'wrest/components/mutators/base'
41
+ require 'wrest/components/mutators/xml_type_caster'
42
+ require 'wrest/components/mutators/camel_to_snake_case'
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ module Wrest
13
+ module Components
14
+ module Translators
15
+ # Maps content types to deserialisers
16
+ CONTENT_TYPES = {
17
+ 'application/xml' => Wrest::Components::Translators::Xml,
18
+ 'text/xml' => Wrest::Components::Translators::Xml,
19
+ 'application/json' => Wrest::Components::Translators::Json,
20
+ 'text/javascript' => Wrest::Components::Translators::Json,
21
+ 'text/plain' => Wrest::Components::Translators::Txt
22
+ }.freeze
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ module Wrest
13
+ module Components
14
+ module Translators
15
+ module Json
16
+ module_function
17
+
18
+ def deserialise(response, _options = {})
19
+ JSON.parse(response.body)
20
+ end
21
+
22
+ def deserialize(response, options = {})
23
+ deserialise(response, options)
24
+ end
25
+
26
+ def serialise(hash, options = {})
27
+ hash.to_json(options)
28
+ end
29
+
30
+ def serialize(hash, options = {})
31
+ serialise(hash, options)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+ module Wrest
12
+ module Components
13
+ module Translators
14
+ module Txt
15
+ module_function
16
+
17
+ def deserialise(response, _options = {})
18
+ response.body
19
+ end
20
+
21
+ def deserialize(response, options = {})
22
+ deserialise(response, options)
23
+ end
24
+
25
+ def serialise(hash, _options = {})
26
+ hash.inspect
27
+ end
28
+
29
+ def serialize(hash, options = {})
30
+ serialise(hash, options)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wrest
4
+ module Components
5
+ module Translators
6
+ module Xml
7
+ module Conversions # :nodoc:
8
+ module Document # :nodoc:
9
+ def to_hash
10
+ root.to_hash
11
+ end
12
+ end
13
+
14
+ module Node # :nodoc:
15
+ CONTENT_ROOT = '__content__'
16
+
17
+ # Convert XML document to hash.
18
+ #
19
+ # hash::
20
+ # Hash to merge the converted element into.
21
+ def to_hash(hash = {})
22
+ node_hash = {}
23
+
24
+ # Insert node hash into parent hash correctly.
25
+ case hash[name]
26
+ when Array then hash[name] << node_hash
27
+ when Hash then hash[name] = [hash[name], node_hash]
28
+ when nil then hash[name] = node_hash
29
+ end
30
+
31
+ # Handle child elements
32
+ children.each do |c|
33
+ if c.element?
34
+ c.to_hash(node_hash)
35
+ elsif c.text? || c.cdata?
36
+ node_hash[CONTENT_ROOT] ||= +''
37
+ node_hash[CONTENT_ROOT] << c.content
38
+ end
39
+ end
40
+
41
+ # Remove content node if it is blank and there are child tags
42
+ node_hash.delete(CONTENT_ROOT) if node_hash.length > 1 && Utils.object_blank?(node_hash[CONTENT_ROOT])
43
+
44
+ # Handle attributes
45
+ attribute_nodes.each { |a| node_hash[a.node_name] = a.value }
46
+
47
+ hash
48
+ end
49
+ end
50
+ end
51
+ Nokogiri::XML::Document.include(Conversions::Document)
52
+ Nokogiri::XML::Node.include(Conversions::Node)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ require_relative 'xml/conversions'
13
+
14
+ module Wrest
15
+ module Components
16
+ module Translators
17
+ module Xml
18
+ module_function
19
+
20
+ def deserialise(response, options = {})
21
+ data = response.body
22
+ data = StringIO.new(data || '') unless data.respond_to?(:read)
23
+ return {} if data.eof?
24
+
25
+ if options[:xpath].nil?
26
+ parse(data)
27
+ else
28
+ search(data, options[:xpath])
29
+ end
30
+ end
31
+
32
+ def deserialize(response, options = {})
33
+ deserialise(response, options)
34
+ end
35
+
36
+ def serialise(hash, _options = {})
37
+ to_xml(hash)
38
+ end
39
+
40
+ def serialize(hash, options = {})
41
+ serialise(hash, options)
42
+ end
43
+
44
+ def to_xml(hash, builder = nil)
45
+ builder ||= Nokogiri::XML::Builder.new
46
+ hash.each_with_object(builder) do |(key, value), inner_builder|
47
+ if value.is_a?(Hash)
48
+ inner_builder.send(key.to_s) do |child_builder|
49
+ to_xml(value, child_builder)
50
+ end
51
+ else
52
+ inner_builder.send(key.to_s, value.to_s)
53
+ end
54
+ end.to_xml
55
+ end
56
+
57
+ # Parse an XML Document string or IO into a simple hash using libxml / nokogiri.
58
+ # data::
59
+ # XML Document string or IO to parse
60
+ def parse(data)
61
+ build_nokogiri_doc(data).to_hash
62
+ end
63
+
64
+ def search(data, xpath)
65
+ build_nokogiri_doc(data).xpath(xpath)
66
+ end
67
+
68
+ def build_nokogiri_doc(data)
69
+ doc = Nokogiri::XML(data)
70
+ raise doc.errors.join("\n") if doc.errors.length.positive?
71
+
72
+ doc
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ module Wrest
13
+ module Components
14
+ # Contains strategies/lambdas which know how to deserialise
15
+ # different content types.
16
+ module Translators
17
+ # Loads the appropriate desirialisation strategy based on
18
+ # the content type
19
+ def self.lookup(content_type)
20
+ translator = CONTENT_TYPES[content_type]
21
+ translator || (raise Wrest::Exceptions::UnsupportedContentType, "Unsupported content type #{content_type}")
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ require 'wrest/components/translators/txt'
28
+ require 'wrest/components/translators/xml'
29
+ require 'wrest/components/translators/json'
30
+ require 'wrest/components/translators/content_types'
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2009 Sidu Ponnappa
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
9
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and limitations under the License.
11
+
12
+ module Wrest
13
+ # A component is a building block that can
14
+ # be used while building an object oriented wrapper
15
+ # around a REST service
16
+ module Components
17
+ end
18
+ end
19
+
20
+ require 'wrest/components/container'
21
+ require 'wrest/components/mutators'
22
+ require 'wrest/components/translators'