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.
- checksums.yaml +7 -0
- data/CHANGELOG +169 -0
- data/LICENCE +7 -0
- data/README.md +436 -0
- data/bin/wrest +4 -0
- data/bin/wrest_shell.rb +23 -0
- data/lib/wrest/async_request/event_machine_backend.rb +32 -0
- data/lib/wrest/async_request/thread_backend.rb +34 -0
- data/lib/wrest/async_request/thread_pool.rb +29 -0
- data/lib/wrest/async_request.rb +51 -0
- data/lib/wrest/cache_proxy.rb +119 -0
- data/lib/wrest/caching/memcached.rb +37 -0
- data/lib/wrest/caching/redis.rb +38 -0
- data/lib/wrest/caching.rb +57 -0
- data/lib/wrest/callback.rb +70 -0
- data/lib/wrest/components/container/alias_accessors.rb +70 -0
- data/lib/wrest/components/container/typecaster.rb +178 -0
- data/lib/wrest/components/container.rb +204 -0
- data/lib/wrest/components/mutators/base.rb +65 -0
- data/lib/wrest/components/mutators/camel_to_snake_case.rb +26 -0
- data/lib/wrest/components/mutators/xml_type_caster.rb +56 -0
- data/lib/wrest/components/mutators.rb +42 -0
- data/lib/wrest/components/translators/content_types.rb +25 -0
- data/lib/wrest/components/translators/json.rb +36 -0
- data/lib/wrest/components/translators/txt.rb +35 -0
- data/lib/wrest/components/translators/xml/conversions.rb +56 -0
- data/lib/wrest/components/translators/xml.rb +77 -0
- data/lib/wrest/components/translators.rb +30 -0
- data/lib/wrest/components.rb +22 -0
- data/lib/wrest/core_ext/hash/conversions.rb +45 -0
- data/lib/wrest/core_ext/hash.rb +7 -0
- data/lib/wrest/core_ext/string/conversions.rb +38 -0
- data/lib/wrest/core_ext/string.rb +7 -0
- data/lib/wrest/exceptions.rb +38 -0
- data/lib/wrest/hash_with_case_insensitive_access.rb +52 -0
- data/lib/wrest/hash_with_indifferent_access.rb +442 -0
- data/lib/wrest/http_codes.rb +83 -0
- data/lib/wrest/http_shared/headers.rb +345 -0
- data/lib/wrest/http_shared/standard_headers.rb +22 -0
- data/lib/wrest/http_shared/standard_tokens.rb +21 -0
- data/lib/wrest/http_shared.rb +25 -0
- data/lib/wrest/multipart.rb +84 -0
- data/lib/wrest/native/connection_factory.rb +28 -0
- data/lib/wrest/native/delete.rb +27 -0
- data/lib/wrest/native/get.rb +83 -0
- data/lib/wrest/native/options.rb +27 -0
- data/lib/wrest/native/patch.rb +27 -0
- data/lib/wrest/native/post.rb +27 -0
- data/lib/wrest/native/post_multipart.rb +36 -0
- data/lib/wrest/native/put.rb +27 -0
- data/lib/wrest/native/put_multipart.rb +36 -0
- data/lib/wrest/native/redirection.rb +39 -0
- data/lib/wrest/native/request.rb +161 -0
- data/lib/wrest/native/response.rb +278 -0
- data/lib/wrest/native/session.rb +66 -0
- data/lib/wrest/native.rb +36 -0
- data/lib/wrest/test/request_patches.rb +12 -0
- data/lib/wrest/test.rb +3 -0
- data/lib/wrest/uri/builders.rb +48 -0
- data/lib/wrest/uri.rb +312 -0
- data/lib/wrest/uri_template.rb +63 -0
- data/lib/wrest/utils.rb +129 -0
- data/lib/wrest/version.rb +14 -0
- data/lib/wrest.rb +77 -0
- data/lib/wrest_no_ext.rb +7 -0
- 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'
|