wrest 0.0.9-java → 0.1.0-java
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/CHANGELOG +34 -0
- data/README.rdoc +16 -10
- data/Rakefile +362 -124
- data/VERSION.yml +2 -2
- data/examples/delicious.rb +17 -7
- data/examples/facebook.rb +101 -0
- data/examples/keep_alive.rb +37 -0
- data/examples/twitter.rb +3 -3
- data/examples/twitter_public_timeline.rb +11 -4
- data/examples/wow_realm_status.rb +8 -2
- data/{spec/functional/sample_rails_app/public/favicon.ico → init.rb} +0 -0
- data/lib/wrest/components/{attributes_container → container}/alias_accessors.rb +4 -4
- data/lib/wrest/components/{attributes_container → container}/typecaster.rb +1 -1
- data/lib/wrest/components/{attributes_container.rb → container.rb} +46 -16
- data/lib/wrest/components/mutators.rb +4 -4
- data/lib/wrest/components/translators/json.rb +2 -2
- data/lib/wrest/components/translators/xml.rb +3 -2
- data/lib/wrest/components/translators.rb +3 -3
- data/lib/wrest/components.rb +3 -3
- data/lib/wrest/core_ext/hash.rb +1 -1
- data/lib/wrest/core_ext/string.rb +1 -1
- data/lib/wrest/curl/delete.rb +23 -0
- data/lib/wrest/curl/get.rb +23 -0
- data/lib/wrest/curl/options.rb +16 -0
- data/lib/wrest/curl/post.rb +23 -0
- data/lib/wrest/curl/put.rb +23 -0
- data/lib/wrest/curl/request.rb +95 -0
- data/lib/wrest/curl/response.rb +63 -0
- data/lib/wrest/curl/session.rb +57 -0
- data/lib/wrest/curl.rb +49 -0
- data/lib/wrest/exceptions.rb +16 -1
- data/lib/wrest/http_shared/headers.rb +350 -0
- data/lib/wrest/http_shared/standard_headers.rb +21 -0
- data/lib/wrest/http_shared/standard_tokens.rb +18 -0
- data/lib/wrest/http_shared.rb +24 -0
- data/lib/wrest/native/connection_factory.rb +23 -0
- data/lib/wrest/{http → native}/delete.rb +1 -1
- data/lib/wrest/{http → native}/get.rb +1 -1
- data/lib/wrest/{http → native}/options.rb +1 -1
- data/lib/wrest/{http → native}/post.rb +1 -1
- data/lib/wrest/{http → native}/put.rb +1 -1
- data/lib/wrest/{http → native}/redirection.rb +4 -1
- data/lib/wrest/{http → native}/request.rb +32 -20
- data/lib/wrest/{http → native}/response.rb +12 -4
- data/lib/wrest/native/session.rb +57 -0
- data/lib/wrest/native.rb +32 -0
- data/lib/wrest/resource/base.rb +1 -1
- data/lib/wrest/resource.rb +1 -1
- data/lib/wrest/test/request_patches.rb +5 -0
- data/lib/wrest/test.rb +1 -0
- data/lib/wrest/uri.rb +31 -3
- data/lib/wrest/version.rb +2 -2
- data/lib/wrest.rb +52 -16
- data/spec/unit/spec_helper.rb +12 -3
- data/spec/unit/wrest/components/attributes_container/alias_accessors_spec.rb +2 -2
- data/spec/unit/wrest/components/attributes_container/typecaster_spec.rb +6 -6
- data/spec/unit/wrest/components/attributes_container_spec.rb +44 -12
- data/spec/unit/wrest/components/translators/xml_spec.rb +7 -3
- data/spec/unit/wrest/curl/request_spec.rb +19 -0
- data/spec/unit/wrest/curl/response_spec.rb +16 -0
- data/spec/unit/wrest/http/response_spec.rb +17 -38
- data/spec/unit/wrest/{http → native}/redirection_spec.rb +5 -5
- data/spec/unit/wrest/{http → native}/request_spec.rb +15 -14
- data/spec/unit/wrest/native/response_spec.rb +72 -0
- data/spec/unit/wrest/native/session_spec.rb +74 -0
- data/spec/unit/wrest/resource/base_spec.rb +2 -2
- data/spec/unit/wrest/uri_spec.rb +51 -11
- data/wrest.gemspec +168 -0
- metadata +60 -164
- data/lib/wrest/http.rb +0 -25
- data/spec/functional/sample_rails_app/README +0 -3
- data/spec/functional/sample_rails_app/Rakefile +0 -10
- data/spec/functional/sample_rails_app/app/controllers/application_controller.rb +0 -10
- data/spec/functional/sample_rails_app/app/controllers/lead_bottles_controller.rb +0 -7
- data/spec/functional/sample_rails_app/app/helpers/application_helper.rb +0 -3
- data/spec/functional/sample_rails_app/app/models/bottle.rb +0 -3
- data/spec/functional/sample_rails_app/app/models/glass_bottle.rb +0 -3
- data/spec/functional/sample_rails_app/app/models/lead_bottle.rb +0 -3
- data/spec/functional/sample_rails_app/config/boot.rb +0 -110
- data/spec/functional/sample_rails_app/config/database.yml +0 -16
- data/spec/functional/sample_rails_app/config/environment.rb +0 -42
- data/spec/functional/sample_rails_app/config/environments/development.rb +0 -17
- data/spec/functional/sample_rails_app/config/environments/production.rb +0 -28
- data/spec/functional/sample_rails_app/config/environments/test.rb +0 -28
- data/spec/functional/sample_rails_app/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/functional/sample_rails_app/config/initializers/inflections.rb +0 -10
- data/spec/functional/sample_rails_app/config/initializers/mime_types.rb +0 -5
- data/spec/functional/sample_rails_app/config/initializers/new_rails_defaults.rb +0 -19
- data/spec/functional/sample_rails_app/config/initializers/session_store.rb +0 -15
- data/spec/functional/sample_rails_app/config/locales/en.yml +0 -5
- data/spec/functional/sample_rails_app/config/routes.rb +0 -3
- data/spec/functional/sample_rails_app/db/development.sqlite3 +0 -0
- data/spec/functional/sample_rails_app/db/migrate/20090319115628_create_bottle.rb +0 -13
- data/spec/functional/sample_rails_app/db/schema.rb +0 -20
- data/spec/functional/sample_rails_app/db/test.sqlite3 +0 -0
- data/spec/functional/sample_rails_app/log/development.log +0 -1
- data/spec/functional/sample_rails_app/public/404.html +0 -30
- data/spec/functional/sample_rails_app/public/422.html +0 -30
- data/spec/functional/sample_rails_app/public/500.html +0 -30
- data/spec/functional/sample_rails_app/public/images/rails.png +0 -0
- data/spec/functional/sample_rails_app/public/index.html +0 -275
- data/spec/functional/sample_rails_app/public/robots.txt +0 -5
- data/spec/functional/sample_rails_app/script/about +0 -4
- data/spec/functional/sample_rails_app/script/autospec +0 -6
- data/spec/functional/sample_rails_app/script/console +0 -3
- data/spec/functional/sample_rails_app/script/dbconsole +0 -3
- data/spec/functional/sample_rails_app/script/destroy +0 -3
- data/spec/functional/sample_rails_app/script/generate +0 -3
- data/spec/functional/sample_rails_app/script/performance/benchmarker +0 -3
- data/spec/functional/sample_rails_app/script/performance/profiler +0 -3
- data/spec/functional/sample_rails_app/script/plugin +0 -3
- data/spec/functional/sample_rails_app/script/runner +0 -3
- data/spec/functional/sample_rails_app/script/server +0 -3
- data/spec/functional/sample_rails_app/script/spec +0 -10
- data/spec/functional/sample_rails_app/script/spec_server +0 -9
- data/spec/functional/sample_rails_app/test/performance/browsing_test.rb +0 -9
- data/spec/functional/sample_rails_app/test/test_helper.rb +0 -38
- data/spec/functional/sample_rails_app/tmtags +0 -2559
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/MIT-LICENSE +0 -20
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/README.rdoc +0 -100
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/Rakefile +0 -18
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/init.rb +0 -5
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/install.rb +0 -1
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/base.rb +0 -140
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/resources.rb +0 -16
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/resources_controller.rb +0 -26
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/routes_controller.rb +0 -16
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/api.rb +0 -26
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/exception.rb +0 -23
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/from_json.rb +0 -15
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/dispatch.rb +0 -235
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/models/resourced_route.rb +0 -84
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/query.rb +0 -337
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/html.rb +0 -50
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/json.rb +0 -75
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/xml.rb +0 -65
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render.rb +0 -63
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/retrieve.rb +0 -74
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/version.rb +0 -9
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full.rb +0 -14
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/base_spec.rb +0 -88
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/controllers/resources_spec.rb +0 -29
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/dispatch_spec.rb +0 -262
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/models/resourced_route_spec.rb +0 -62
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/query/parameter_spec.rb +0 -57
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/query_spec.rb +0 -462
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/html_spec.rb +0 -4
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/json_spec.rb +0 -107
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/xml_spec.rb +0 -98
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render_spec.rb +0 -5
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/retrieve_spec.rb +0 -173
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/spec_helper.rb +0 -98
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/uninstall.rb +0 -1
- data/spec/functional/spec_helper.rb +0 -0
data/CHANGELOG
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Features under the section marked 'In Progress' are currently in the process of being implemented. They are to be considered unstable and not ready for use.
|
|
2
|
+
|
|
3
|
+
Features under the section marked 'Current' are completed but pending release as a gem. If you need any of these, you'll need to use the latest source from the git repository.
|
|
4
|
+
|
|
5
|
+
Features under a numbered section are complete and available in the Wrest gem.
|
|
6
|
+
|
|
7
|
+
== Coming soon
|
|
8
|
+
* Cookie support
|
|
9
|
+
* Proxy support
|
|
10
|
+
|
|
11
|
+
== In progress
|
|
12
|
+
* 304/ETag response caching
|
|
13
|
+
* Keep-alive support for libcurl
|
|
14
|
+
|
|
15
|
+
== 0.1.0
|
|
16
|
+
* Added Nokogiri as a fallback for LibXML Ruby before we give up and use REXML. (Nokogiri is available on JRuby, unlike LibXML-ruby)
|
|
17
|
+
* Added code to attempt to load JREXML (for what it's worth) when using REXML on JRuby
|
|
18
|
+
* Ensure that Wrest throws an exception when an actual request is made in a test environment in Rails (RAILS_ENV == 'test')
|
|
19
|
+
* Support for keep-alive connections via Wrest::Http::Session and Wrest::Http::Response#connection_closed?
|
|
20
|
+
* Create two convenience Post methods on Uri - one for application/x-www-form-urlencoded and the other normal
|
|
21
|
+
* Optional libcurl implementations of the Request/Response classes (for those on MRI who need better performance). See examples/delicious.rb, examples/facebook.rb. Note that while there is a great deal of API compatibility, everything may not behave exactly the same under libcurl. Please do report inconsistencies.
|
|
22
|
+
* Added live functional tests to codebase (rake spec:functional, needs spec/functional/sample_rails_app running on port 3000)
|
|
23
|
+
|
|
24
|
+
== 0.0.9
|
|
25
|
+
* Added redirect follow support for GET requests (see examples/redirection.rb)
|
|
26
|
+
* Auto redirection limit
|
|
27
|
+
* Request timeout limit config
|
|
28
|
+
* Added an alias_accessor macro to allow alternative names for attribute accessors (see examples/wow_realm_status.rb)
|
|
29
|
+
* Removed the need to explicitly include AttributesContainer::Typecaster or to use the enable_typecasting_support macro. The call to typecast now does this for us. See AttributesContainer#typecast and AttributesContainer::Typecaster#typecast
|
|
30
|
+
|
|
31
|
+
== 0.0.8
|
|
32
|
+
* Added URI extension using the [] method (see examples/delicious.rb)
|
|
33
|
+
* Refactored out Request as the first step to adding Response caching
|
|
34
|
+
|
data/README.rdoc
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
= Wrest 0.0
|
|
1
|
+
= Wrest 0.1.0
|
|
2
2
|
|
|
3
3
|
(c) Copyright 2009 {Sidu Ponnappa}[http://blog.sidu.in]. All Rights Reserved.
|
|
4
4
|
|
|
5
|
-
Wrest is a ruby REST client library which
|
|
5
|
+
Wrest is a ruby REST client library which
|
|
6
|
+
* allows allows you to quickly build object oriented wrappers around any web service
|
|
7
|
+
* is spec driven, strongly favours immutable objects and avoids class methods and setters making it better suited for use as a library, especially in multi-threaded environments
|
|
8
|
+
* runs on Ruby 1.8, 1.9 and JRuby, with MacRuy and IronRuby support on the way
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
To receive notifications whenever new features are added to Wrest, please subscribe to my {twitter feed}[http://twitter.com/ponnappa].
|
|
11
|
+
|
|
12
|
+
(If you were wondering why the words 'demon', 'chi' and 'fu-puppies' show up in nearly every example and spec, it's because they're all references to {Roger Zelazny's}[http://en.wikipedia.org/wiki/Roger_Zelazny] last book, 'Lord Demon.')
|
|
8
13
|
|
|
9
14
|
== Wrest Core: Features
|
|
10
15
|
|
|
11
|
-
* Provides convenient HTTP wrappers, redirect handling, serialisation and deserialisation with response caching in the works
|
|
16
|
+
* Provides convenient HTTP wrappers, redirect handling, serialisation and deserialisation with response caching in the works
|
|
17
|
+
* Supports using either Net::HTTP or libcurl as the underlying HTTP library
|
|
12
18
|
* Designed to be used as a library, not just a command line REST client (fewer class/static methods, more object oriented)
|
|
13
19
|
* Isn't coupled to Rails (usable in a pure Ruby application to consume any HTTP/REST api)
|
|
14
20
|
* Can be used both stand alone as well as to build object oriented abstractions around resources and web services (Wrest::Resource is an example of the latter)
|
|
15
21
|
|
|
16
22
|
== Examples
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
For Facebook, Twitter, Delicious, GitHub and other API examples, see http://github.com/kaiwren/wrest/tree/master/examples
|
|
19
25
|
|
|
20
26
|
== Installation
|
|
21
27
|
|
|
@@ -23,7 +29,7 @@ The source is available at git://github.com/kaiwren/wrest.git
|
|
|
23
29
|
|
|
24
30
|
To install as a Rails plugin, do <tt>script/plugin install git://github.com/kaiwren/wrest.git</tt>
|
|
25
31
|
|
|
26
|
-
To install the Wrest gem, do <tt>(sudo) gem install wrest</tt>.
|
|
32
|
+
To install the Wrest gem, do <tt>(sudo) gem install wrest</tt>.
|
|
27
33
|
|
|
28
34
|
Wrest is also available as a gem for JRuby; you can install it by running <tt>(sudo) jruby -S gem install wrest</tt>.
|
|
29
35
|
|
|
@@ -31,7 +37,7 @@ Wrest is also available as a gem for JRuby; you can install it by running <tt>(s
|
|
|
31
37
|
|
|
32
38
|
You can launch the interactive Wrest shell by running bin/wrest if you have the source or invoking <tt>wrest</tt> from your prompt if you've installed the gem.
|
|
33
39
|
$ wrest
|
|
34
|
-
>> y 'http://twitter.com/statuses/public_timeline.json'.to_uri.get.deserialise
|
|
40
|
+
>> y 'http://twitter.com/statuses/public_timeline.json'.to_uri(:timeout => 5).get.deserialise
|
|
35
41
|
|
|
36
42
|
=== Usage: Library
|
|
37
43
|
|
|
@@ -131,7 +137,7 @@ Wrest::Resource is an alternative to Rails' ActiveResource. It targets Rails RES
|
|
|
131
137
|
If you're looking for help doing this on Rails on the server side, take a look at {resource_full}[http://github.com/bguthrie/resource_full], a Rails plugin that makes RESTful Rails a whole order of magnitude easier. resource_full is a stable project and is currently in use in production.
|
|
132
138
|
|
|
133
139
|
|
|
134
|
-
* No more pretending that REST resources are the same as records in a database (yeah, no more freaking ActiveResource::Connection)
|
|
140
|
+
* No more pretending that REST resources are the same as records in a database (yeah, no more freaking ActiveResource::Connection that pretends it's a DB connection)
|
|
135
141
|
* Treat put as 'create or update,' not just 'update'
|
|
136
142
|
* Response codes result in user defined state transitions; favours state transitions based on response code over arbitrary ones
|
|
137
143
|
* Supports moving toward hypermedia links as opposed to client server collusion through URI templates
|
|
@@ -156,10 +162,10 @@ If you're looking for help doing this on Rails on the server side, take a look a
|
|
|
156
162
|
* gems
|
|
157
163
|
* json (json-jruby on JRuby)
|
|
158
164
|
* active_support
|
|
159
|
-
* ruby-libxml (
|
|
165
|
+
* ruby-libxml or Nokogiri (Wrest tries ruby-libxml first, then nokogiri, and will finally fall back on REXML; be aware that Wrest uses ActiveSupport::XmlMini, so if you're using Wrest as a plugin in a Rails application, all xml parsing across the application will switch to using libxml if it's available. You're free to change this by hand by using the ActiveSupport::XmlMini.backend= method.)
|
|
160
166
|
|
|
161
167
|
=== Build
|
|
162
|
-
|
|
168
|
+
|
|
163
169
|
* rspec
|
|
164
170
|
* rcov (unsupported on JRuby)
|
|
165
171
|
* jeweler
|
data/Rakefile
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
9
|
|
|
10
|
+
# Note that some optional libraries/gems that the build (not Wrest itself) uses may not be available on all implementations of Ruby.
|
|
10
11
|
puts "Building on Ruby #{RUBY_VERSION}, #{RUBY_RELEASE_DATE}, #{RUBY_PLATFORM}"
|
|
11
|
-
puts "Note that some optional libraries/gems that the build (not Wrest itself) uses may not be available on all implementations of Ruby."
|
|
12
12
|
|
|
13
13
|
if Object.const_defined?('RAILS_ROOT')
|
|
14
14
|
require File.dirname(__FILE__) + '/../../../config/environment'
|
|
@@ -18,7 +18,7 @@ else
|
|
|
18
18
|
require 'rake'
|
|
19
19
|
require 'spec'
|
|
20
20
|
require 'spec/rake/spectask'
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
begin
|
|
23
23
|
require 'metric_fu'
|
|
24
24
|
rescue LoadError
|
|
@@ -27,12 +27,20 @@ else
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
desc 'Default: run spec tests.'
|
|
30
|
-
task :default => :
|
|
30
|
+
task :default => 'spec:unit'
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
namespace :spec do
|
|
33
|
+
desc "Run all unit specs"
|
|
34
|
+
Spec::Rake::SpecTask.new(:unit) do |task|
|
|
35
|
+
task.spec_files = FileList['spec/unit/wrest/**/*_spec.rb']
|
|
36
|
+
task.spec_opts = ['--options', 'spec/spec.opts']
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
desc "Run unit all specs"
|
|
40
|
+
Spec::Rake::SpecTask.new(:functional) do |task|
|
|
41
|
+
task.spec_files = FileList['spec/functional/wrest/**/*_spec.rb']
|
|
42
|
+
task.spec_opts = ['--options', 'spec/spec.opts']
|
|
43
|
+
end
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
begin
|
|
@@ -70,9 +78,10 @@ end
|
|
|
70
78
|
begin
|
|
71
79
|
require 'jeweler'
|
|
72
80
|
Jeweler::Tasks.new do |gemspec|
|
|
81
|
+
# p Rake::FileList['spec/functional/**/*']
|
|
73
82
|
gemspec.name = "wrest"
|
|
74
83
|
gemspec.summary = "REST client library for Ruby."
|
|
75
|
-
gemspec.description = "Wrest is a REST client library which allows you to quickly build object oriented wrappers around any web service.
|
|
84
|
+
gemspec.description = "Wrest is a HTTP and REST client library which allows you to quickly build well encapsulated, object oriented wrappers around any web service."
|
|
76
85
|
gemspec.authors = ["Sidu Ponnappa"]
|
|
77
86
|
gemspec.email = "ckponnappa@gmail.com"
|
|
78
87
|
gemspec.homepage = "http://github.com/kaiwren/wrest"
|
|
@@ -80,12 +89,13 @@ begin
|
|
|
80
89
|
gemspec.rubyforge_project = 'wrest'
|
|
81
90
|
gemspec.executables = ['wrest', 'jwrest']
|
|
82
91
|
gemspec.require_path = "lib"
|
|
83
|
-
gemspec.files.exclude 'spec/
|
|
84
|
-
gemspec.test_files.exclude 'spec/
|
|
85
|
-
gemspec.add_dependency('activesupport', '>= 2.3.
|
|
92
|
+
gemspec.files.exclude *['.gitignore', 'spec/functional']
|
|
93
|
+
gemspec.test_files.exclude *['.gitignore', 'spec/functional', 'examples']
|
|
94
|
+
gemspec.add_dependency('activesupport', '>= 2.3.5')
|
|
86
95
|
case RUBY_PLATFORM
|
|
87
96
|
when /java/
|
|
88
97
|
gemspec.add_dependency('json-jruby', '>= 1.1.3')
|
|
98
|
+
gemspec.add_dependency('nokogiri', '>= 1.3.3')
|
|
89
99
|
gemspec.platform = 'java'
|
|
90
100
|
else
|
|
91
101
|
gemspec.add_dependency('json', '>= 1.1.3')
|
|
@@ -120,7 +130,7 @@ begin
|
|
|
120
130
|
end
|
|
121
131
|
end
|
|
122
132
|
rescue LoadError
|
|
123
|
-
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured.
|
|
133
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
|
124
134
|
end
|
|
125
135
|
|
|
126
136
|
|
|
@@ -128,132 +138,360 @@ namespace (:benchmark) do
|
|
|
128
138
|
desc "Create classes to be used in Wrest::Resource vs. ActiveResource"
|
|
129
139
|
task :setup_test_classes do
|
|
130
140
|
require 'active_resource'
|
|
131
|
-
require 'wrest'
|
|
141
|
+
require 'lib/wrest'
|
|
132
142
|
|
|
133
|
-
class Ooga < Wrest::
|
|
134
|
-
|
|
143
|
+
class Ooga < Wrest::Resource::Base
|
|
144
|
+
end
|
|
145
|
+
class Booga < ActiveResource::Base
|
|
146
|
+
self.site=''
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
desc "Benchmark when objects are created each time before getting data; i.e there are few queries per instantiation"
|
|
151
|
+
task :create_and_get => :setup_test_classes do |t|
|
|
152
|
+
|
|
153
|
+
n = 10000
|
|
154
|
+
puts "Running #{n} times per report"
|
|
155
|
+
Benchmark.bmbm(10) do |rpt|
|
|
156
|
+
rpt.report("Wrest::Resource") do
|
|
157
|
+
n.times {
|
|
158
|
+
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
159
|
+
ooga.profession
|
|
160
|
+
ooga.profession?
|
|
161
|
+
ooga.enhanced_by
|
|
162
|
+
ooga.enhanced_by?
|
|
163
|
+
}
|
|
135
164
|
end
|
|
136
165
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
146
|
-
ooga.profession
|
|
147
|
-
ooga.profession?
|
|
148
|
-
ooga.enhanced_by
|
|
149
|
-
ooga.enhanced_by?
|
|
150
|
-
}
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
rpt.report("ActiveResource") do
|
|
154
|
-
n.times {
|
|
155
|
-
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
156
|
-
booga.profession
|
|
157
|
-
booga.profession?
|
|
158
|
-
booga.enhanced_by
|
|
159
|
-
booga.enhanced_by?
|
|
160
|
-
}
|
|
161
|
-
end
|
|
162
|
-
end
|
|
166
|
+
rpt.report("ActiveResource") do
|
|
167
|
+
n.times {
|
|
168
|
+
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
169
|
+
booga.profession
|
|
170
|
+
booga.profession?
|
|
171
|
+
booga.enhanced_by
|
|
172
|
+
booga.enhanced_by?
|
|
173
|
+
}
|
|
163
174
|
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
164
177
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
rpt.report("ActiveResource") do
|
|
184
|
-
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
185
|
-
|
|
186
|
-
n.times {
|
|
187
|
-
booga.profession
|
|
188
|
-
booga.profession?
|
|
189
|
-
booga.enhanced_by
|
|
190
|
-
booga.enhanced_by?
|
|
191
|
-
}
|
|
192
|
-
end
|
|
193
|
-
end
|
|
178
|
+
desc "Benchmark when objects are created beforehand; i.e there are many queries per instantiation"
|
|
179
|
+
task :create_once_and_get => :setup_test_classes do |t|
|
|
180
|
+
|
|
181
|
+
n = 10000
|
|
182
|
+
puts "Running #{n} times per report"
|
|
183
|
+
|
|
184
|
+
Benchmark.bmbm(10) do |rpt|
|
|
185
|
+
rpt.report("Wrest::Resource") do
|
|
186
|
+
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
187
|
+
|
|
188
|
+
n.times {
|
|
189
|
+
ooga.profession
|
|
190
|
+
ooga.profession?
|
|
191
|
+
ooga.enhanced_by
|
|
192
|
+
ooga.enhanced_by?
|
|
193
|
+
}
|
|
194
194
|
end
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
rpt.report("ActiveResource") do
|
|
197
|
+
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
198
198
|
|
|
199
|
-
n
|
|
200
|
-
|
|
199
|
+
n.times {
|
|
200
|
+
booga.profession
|
|
201
|
+
booga.profession?
|
|
202
|
+
booga.enhanced_by
|
|
203
|
+
booga.enhanced_by?
|
|
204
|
+
}
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
201
208
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
209
|
+
desc "Benchmark objects respond_to? performance without invocation"
|
|
210
|
+
task :responds_to_before => :setup_test_classes do |t|
|
|
205
211
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
ooga.respond_to?(:profession?)
|
|
209
|
-
ooga.respond_to?(:profession=)
|
|
210
|
-
}
|
|
211
|
-
end
|
|
212
|
+
n = 10000
|
|
213
|
+
puts "Running #{n} times per report"
|
|
212
214
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
+
Benchmark.bmbm(10) do |rpt|
|
|
216
|
+
rpt.report("Wrest::Resource") do
|
|
217
|
+
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
215
218
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
end
|
|
222
|
-
end
|
|
219
|
+
n.times {
|
|
220
|
+
ooga.respond_to?(:profession)
|
|
221
|
+
ooga.respond_to?(:profession?)
|
|
222
|
+
ooga.respond_to?(:profession=)
|
|
223
|
+
}
|
|
223
224
|
end
|
|
224
225
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
n
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
226
|
+
rpt.report("ActiveResource") do
|
|
227
|
+
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
228
|
+
|
|
229
|
+
n.times {
|
|
230
|
+
booga.respond_to?(:profession)
|
|
231
|
+
booga.respond_to?(:profession?)
|
|
232
|
+
booga.respond_to?(:profession=)
|
|
233
|
+
}
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
desc "Benchmark objects respond_to? performance after invocation"
|
|
239
|
+
task :responds_to_after => :setup_test_classes do |t|
|
|
240
|
+
|
|
241
|
+
n = 10000
|
|
242
|
+
puts "Running #{n} times per report"
|
|
243
|
+
|
|
244
|
+
Benchmark.bmbm(10) do |rpt|
|
|
245
|
+
rpt.report("Wrest::Resource") do
|
|
246
|
+
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
247
|
+
ooga.profession
|
|
248
|
+
ooga.profession?
|
|
249
|
+
ooga.profession = ''
|
|
250
|
+
|
|
251
|
+
n.times {
|
|
252
|
+
ooga.respond_to?(:profession)
|
|
253
|
+
ooga.respond_to?(:profession?)
|
|
254
|
+
ooga.respond_to?(:profession=)
|
|
255
|
+
}
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
rpt.report("ActiveResource") do
|
|
259
|
+
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
|
260
|
+
booga.profession
|
|
261
|
+
booga.profession?
|
|
262
|
+
booga.profession = ''
|
|
263
|
+
|
|
264
|
+
n.times {
|
|
265
|
+
booga.respond_to?(:profession)
|
|
266
|
+
booga.respond_to?(:profession?)
|
|
267
|
+
booga.respond_to?(:profession=)
|
|
268
|
+
}
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
desc "Benchmark keepalive connections (needs functional/sample_rails_app running with class-caching on and keep-alive enabled)"
|
|
274
|
+
task :keep_alive => :setup_test_classes do
|
|
275
|
+
n = 20
|
|
276
|
+
Wrest.logger = Logger.new(File.open("log/benchmark.log", 'a'))
|
|
277
|
+
Benchmark.bmbm(10) do |rpt|
|
|
278
|
+
rpt.report("Fresh connections (Connection: Close)") do
|
|
279
|
+
n.times {
|
|
280
|
+
'http://localhost:3000/headers'.to_uri.get
|
|
281
|
+
'http://localhost:3000/lead_bottles.xml?owner=Kai&type=bottle'.to_uri.get
|
|
282
|
+
}
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
rpt.report("Keep-alive connection (Connection: Keep-Alive)") do
|
|
286
|
+
Wrest::Native::Session.new('http://localhost:3000'.to_uri) do |session|
|
|
287
|
+
n.times {
|
|
288
|
+
session.get '/headers'
|
|
289
|
+
session.get '/lead_bottles.xml'
|
|
290
|
+
}
|
|
257
291
|
end
|
|
258
292
|
end
|
|
259
293
|
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
desc "Benchmark xml deserialisation"
|
|
297
|
+
task :deserialise_xml => :setup_test_classes do |t|
|
|
298
|
+
n = 100
|
|
299
|
+
puts "Deserialising using #{ActiveSupport::XmlMini.backend}"
|
|
300
|
+
|
|
301
|
+
Benchmark.bmbm(10) do |rpt|
|
|
302
|
+
rpt.report("Hash.from_xml") do
|
|
303
|
+
n.times {
|
|
304
|
+
Hash.from_xml(serialised_data)
|
|
305
|
+
}
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def serialised_data
|
|
311
|
+
<<-EOXML
|
|
312
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
313
|
+
<business-units type="array">
|
|
314
|
+
<business-unit>
|
|
315
|
+
<company>OogaInc</company>
|
|
316
|
+
<created-at type="datetime">2008-08-27T16:21:33Z</created-at>
|
|
317
|
+
<department>FooMeh</department>
|
|
318
|
+
<id type="integer">1</id>
|
|
319
|
+
<client-number>0001</client-number>
|
|
320
|
+
<updated-at type="datetime">2008-08-27T16:21:33Z</updated-at>
|
|
321
|
+
<accounts type="array">
|
|
322
|
+
<account>
|
|
323
|
+
<account-number>1</account-number>
|
|
324
|
+
<created-at type="datetime">2008-08-27T16:21:33Z</created-at>
|
|
325
|
+
<id type="integer">1</id>
|
|
326
|
+
<client-id type="integer">1</client-id>
|
|
327
|
+
<updated-at type="datetime">2008-08-27T16:21:33Z</updated-at>
|
|
328
|
+
<client-number>0001</client-number>
|
|
329
|
+
</account>
|
|
330
|
+
</accounts>
|
|
331
|
+
</business-unit>
|
|
332
|
+
<business-unit>
|
|
333
|
+
<company>OogaInc</company>
|
|
334
|
+
<created-at type="datetime">2008-08-27T18:35:22Z</created-at>
|
|
335
|
+
<department>BoogaBooga</department>
|
|
336
|
+
<id type="integer">32479</id>
|
|
337
|
+
<client-number>0002</client-number>
|
|
338
|
+
<updated-at type="datetime">2008-08-27T18:35:37Z</updated-at>
|
|
339
|
+
<accounts type="array">
|
|
340
|
+
<account>
|
|
341
|
+
<account-number>0</account-number>
|
|
342
|
+
<created-at type="datetime">2008-08-27T18:36:07Z</created-at>
|
|
343
|
+
<id type="integer">32479</id>
|
|
344
|
+
<client-id type="integer">32479</client-id>
|
|
345
|
+
<updated-at type="datetime">2008-08-27T18:36:12Z</updated-at>
|
|
346
|
+
<client-number>0002</client-number>
|
|
347
|
+
</account>
|
|
348
|
+
</accounts>
|
|
349
|
+
</business-unit>
|
|
350
|
+
<business-unit>
|
|
351
|
+
<company>OogaInc</company>
|
|
352
|
+
<created-at type="datetime">2008-08-27T16:21:33Z</created-at>
|
|
353
|
+
<department>Engineering</department>
|
|
354
|
+
<id type="integer">2</id>
|
|
355
|
+
<client-number>000101</client-number>
|
|
356
|
+
<updated-at type="datetime">2008-08-27T16:21:33Z</updated-at>
|
|
357
|
+
<accounts type="array">
|
|
358
|
+
<account>
|
|
359
|
+
<account-number>101</account-number>
|
|
360
|
+
<created-at type="datetime">2008-08-27T16:21:33Z</created-at>
|
|
361
|
+
<id type="integer">2</id>
|
|
362
|
+
<client-id type="integer">2</client-id>
|
|
363
|
+
<updated-at type="datetime">2008-08-27T16:21:33Z</updated-at>
|
|
364
|
+
<client-number>000101</client-number>
|
|
365
|
+
</account>
|
|
366
|
+
</accounts>
|
|
367
|
+
</business-unit>
|
|
368
|
+
<business-unit>
|
|
369
|
+
<company>OogaInc</company>
|
|
370
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
371
|
+
<department></department>
|
|
372
|
+
<id type="integer">3</id>
|
|
373
|
+
<client-number>0001000</client-number>
|
|
374
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
375
|
+
<accounts type="array">
|
|
376
|
+
<account>
|
|
377
|
+
<account-number>31974</account-number>
|
|
378
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
379
|
+
<id type="integer">3</id>
|
|
380
|
+
<client-id type="integer">3</client-id>
|
|
381
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
382
|
+
<client-number>0001000</client-number>
|
|
383
|
+
</account>
|
|
384
|
+
</accounts>
|
|
385
|
+
</business-unit>
|
|
386
|
+
<business-unit>
|
|
387
|
+
<company>OogaInc</company>
|
|
388
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
389
|
+
<department></department>
|
|
390
|
+
<id type="integer">4</id>
|
|
391
|
+
<client-number>0001001</client-number>
|
|
392
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
393
|
+
<accounts type="array">
|
|
394
|
+
<account>
|
|
395
|
+
<account-number>656064</account-number>
|
|
396
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
397
|
+
<id type="integer">4</id>
|
|
398
|
+
<client-id type="integer">4</client-id>
|
|
399
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
400
|
+
<client-number>0001001</client-number>
|
|
401
|
+
</account>
|
|
402
|
+
</accounts>
|
|
403
|
+
</business-unit>
|
|
404
|
+
<business-unit>
|
|
405
|
+
<company>OogaInc</company>
|
|
406
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
407
|
+
<department></department>
|
|
408
|
+
<id type="integer">5</id>
|
|
409
|
+
<client-number>0001002</client-number>
|
|
410
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
411
|
+
<accounts type="array">
|
|
412
|
+
<account>
|
|
413
|
+
<account-number>619842</account-number>
|
|
414
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
415
|
+
<id type="integer">5</id>
|
|
416
|
+
<client-id type="integer">5</client-id>
|
|
417
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
418
|
+
<client-number>0001002</client-number>
|
|
419
|
+
</account>
|
|
420
|
+
</accounts>
|
|
421
|
+
</business-unit>
|
|
422
|
+
<business-unit>
|
|
423
|
+
<company>OogaInc</company>
|
|
424
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
425
|
+
<department></department>
|
|
426
|
+
<id type="integer">6</id>
|
|
427
|
+
<client-number>0001003</client-number>
|
|
428
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
429
|
+
<accounts type="array">
|
|
430
|
+
<account>
|
|
431
|
+
<account-number>694370</account-number>
|
|
432
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
433
|
+
<id type="integer">6</id>
|
|
434
|
+
<client-id type="integer">6</client-id>
|
|
435
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
436
|
+
<client-number>0001003</client-number>
|
|
437
|
+
</account>
|
|
438
|
+
</accounts>
|
|
439
|
+
</business-unit>
|
|
440
|
+
<business-unit>
|
|
441
|
+
<company>OogaInc</company>
|
|
442
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
443
|
+
<department></department>
|
|
444
|
+
<id type="integer">7</id>
|
|
445
|
+
<client-number>0001004</client-number>
|
|
446
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
447
|
+
<accounts type="array">
|
|
448
|
+
<account>
|
|
449
|
+
<account-number>29284</account-number>
|
|
450
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
451
|
+
<id type="integer">7</id>
|
|
452
|
+
<client-id type="integer">7</client-id>
|
|
453
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
454
|
+
<client-number>0001004</client-number>
|
|
455
|
+
</account>
|
|
456
|
+
</accounts>
|
|
457
|
+
</business-unit>
|
|
458
|
+
<business-unit>
|
|
459
|
+
<company>OogaInc</company>
|
|
460
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
461
|
+
<department></department>
|
|
462
|
+
<id type="integer">8</id>
|
|
463
|
+
<client-number>0001005</client-number>
|
|
464
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
465
|
+
<accounts type="array">
|
|
466
|
+
<account>
|
|
467
|
+
<account-number>21285</account-number>
|
|
468
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
469
|
+
<id type="integer">8</id>
|
|
470
|
+
<client-id type="integer">8</client-id>
|
|
471
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
472
|
+
<client-number>0001005</client-number>
|
|
473
|
+
</account>
|
|
474
|
+
</accounts>
|
|
475
|
+
</business-unit>
|
|
476
|
+
<business-unit>
|
|
477
|
+
<company>OogaInc</company>
|
|
478
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
479
|
+
<department></department>
|
|
480
|
+
<id type="integer">9</id>
|
|
481
|
+
<client-number>0001006</client-number>
|
|
482
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
483
|
+
<accounts type="array">
|
|
484
|
+
<account>
|
|
485
|
+
<account-number>638772</account-number>
|
|
486
|
+
<created-at type="datetime">2008-08-27T16:21:34Z</created-at>
|
|
487
|
+
<id type="integer">9</id>
|
|
488
|
+
<client-id type="integer">9</client-id>
|
|
489
|
+
<updated-at type="datetime">2008-08-27T16:21:34Z</updated-at>
|
|
490
|
+
<client-number>0001006</client-number>
|
|
491
|
+
</account>
|
|
492
|
+
</accounts>
|
|
493
|
+
</business-unit>
|
|
494
|
+
</business-units>
|
|
495
|
+
EOXML
|
|
496
|
+
end
|
|
497
|
+
end
|