wrest 4.0.0-universal-java-18

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.
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'