jubilee 1.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.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +5 -0
  4. data/CHANGELOG +32 -0
  5. data/Gemfile +35 -0
  6. data/Gemfile.lock +244 -0
  7. data/Guardfile +24 -0
  8. data/KNOWN_ISSUES +6 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +147 -0
  11. data/ROADMAP +5 -0
  12. data/Rakefile +98 -0
  13. data/bin/jubilee +6 -0
  14. data/bin/jubilee_d +13 -0
  15. data/examples/chatapp/Gemfile +5 -0
  16. data/examples/chatapp/Gemfile.lock +27 -0
  17. data/examples/chatapp/README.md +17 -0
  18. data/examples/chatapp/app.rb +57 -0
  19. data/examples/chatapp/config.ru +3 -0
  20. data/examples/chatapp/public/assets/javascripts/application.js +67 -0
  21. data/examples/chatapp/public/assets/javascripts/jquery.js +5 -0
  22. data/examples/chatapp/public/assets/javascripts/sockjs-0.3.4.min.js +27 -0
  23. data/examples/chatapp/public/assets/javascripts/vertxbus.js +216 -0
  24. data/examples/chatapp/public/assets/stylesheets/application.css +29 -0
  25. data/examples/client/sockjs-0.3.4.min.js +27 -0
  26. data/examples/client/vertxbus.js +216 -0
  27. data/examples/jubilee.conf.rb +12 -0
  28. data/examples/jubilee/keystore.jks +0 -0
  29. data/examples/jubilee/server-keystore.jks +0 -0
  30. data/jars/hazelcast-2.6.3.jar +0 -0
  31. data/jars/jackson-annotations-2.2.2.jar +0 -0
  32. data/jars/jackson-core-2.2.2.jar +0 -0
  33. data/jars/jackson-databind-2.2.2.jar +0 -0
  34. data/jars/netty-all-4.0.13.Final.jar +0 -0
  35. data/jars/vertx-core-2.1M3-SNAPSHOT.jar +0 -0
  36. data/jars/vertx-hazelcast-2.1M3-SNAPSHOT.jar +0 -0
  37. data/java/src/jubilee/JubileeService.java +20 -0
  38. data/java/src/org/jruby/jubilee/Const.java +32 -0
  39. data/java/src/org/jruby/jubilee/RackApplication.java +103 -0
  40. data/java/src/org/jruby/jubilee/RackEnvironment.java +150 -0
  41. data/java/src/org/jruby/jubilee/RackEnvironmentHash.java +449 -0
  42. data/java/src/org/jruby/jubilee/RackInput.java +62 -0
  43. data/java/src/org/jruby/jubilee/RackResponse.java +11 -0
  44. data/java/src/org/jruby/jubilee/RubyHttpServerResponse.java +88 -0
  45. data/java/src/org/jruby/jubilee/RubyServer.java +171 -0
  46. data/java/src/org/jruby/jubilee/deploy/Starter.java +26 -0
  47. data/java/src/org/jruby/jubilee/impl/RubyIORackInput.java +201 -0
  48. data/java/src/org/jruby/jubilee/impl/RubyNullIO.java +107 -0
  49. data/java/src/org/jruby/jubilee/utils/RubyHelper.java +37 -0
  50. data/java/src/org/jruby/jubilee/vertx/JubileeVertx.java +38 -0
  51. data/jubilee.gemspec +201 -0
  52. data/lib/jubilee.rb +17 -0
  53. data/lib/jubilee/application.rb +13 -0
  54. data/lib/jubilee/cli.rb +127 -0
  55. data/lib/jubilee/configuration.rb +177 -0
  56. data/lib/jubilee/const.rb +40 -0
  57. data/lib/jubilee/jubilee.jar +0 -0
  58. data/lib/jubilee/response.rb +69 -0
  59. data/lib/jubilee/server.rb +12 -0
  60. data/lib/jubilee/version.rb +10 -0
  61. data/lib/rack/chunked.rb +38 -0
  62. data/lib/rack/handler/jubilee.rb +44 -0
  63. data/lib/vertx.rb +26 -0
  64. data/lib/vertx/README.md +7 -0
  65. data/lib/vertx/buffer.rb +251 -0
  66. data/lib/vertx/event_bus.rb +206 -0
  67. data/lib/vertx/shared_data.rb +214 -0
  68. data/spec/apps/rack/basic/config.ru +50 -0
  69. data/spec/apps/rails4/basic/.gitignore +16 -0
  70. data/spec/apps/rails4/basic/Gemfile +41 -0
  71. data/spec/apps/rails4/basic/Gemfile.lock +127 -0
  72. data/spec/apps/rails4/basic/README.rdoc +28 -0
  73. data/spec/apps/rails4/basic/Rakefile +6 -0
  74. data/spec/apps/rails4/basic/app/assets/images/.keep +0 -0
  75. data/spec/apps/rails4/basic/app/assets/images/rails.png +0 -0
  76. data/spec/apps/rails4/basic/app/assets/javascripts/application.js +12 -0
  77. data/spec/apps/rails4/basic/app/assets/stylesheets/application.css +13 -0
  78. data/spec/apps/rails4/basic/app/controllers/application_controller.rb +5 -0
  79. data/spec/apps/rails4/basic/app/controllers/concerns/.keep +0 -0
  80. data/spec/apps/rails4/basic/app/controllers/reloader_controller.rb +11 -0
  81. data/spec/apps/rails4/basic/app/controllers/reloader_controller.rb.erb +11 -0
  82. data/spec/apps/rails4/basic/app/controllers/root_controller.rb +14 -0
  83. data/spec/apps/rails4/basic/app/helpers/application_helper.rb +2 -0
  84. data/spec/apps/rails4/basic/app/mailers/.keep +0 -0
  85. data/spec/apps/rails4/basic/app/models/.keep +0 -0
  86. data/spec/apps/rails4/basic/app/models/concerns/.keep +0 -0
  87. data/spec/apps/rails4/basic/app/views/layouts/application.html.erb +14 -0
  88. data/spec/apps/rails4/basic/app/views/reloader/index.html.erb +1 -0
  89. data/spec/apps/rails4/basic/app/views/root/index.html.erb +8 -0
  90. data/spec/apps/rails4/basic/app/views/root/streaming.html.erb +6 -0
  91. data/spec/apps/rails4/basic/bin/bundle +3 -0
  92. data/spec/apps/rails4/basic/bin/rails +4 -0
  93. data/spec/apps/rails4/basic/bin/rake +4 -0
  94. data/spec/apps/rails4/basic/config.ru +4 -0
  95. data/spec/apps/rails4/basic/config/application.rb +23 -0
  96. data/spec/apps/rails4/basic/config/boot.rb +4 -0
  97. data/spec/apps/rails4/basic/config/database.yml +20 -0
  98. data/spec/apps/rails4/basic/config/environment.rb +5 -0
  99. data/spec/apps/rails4/basic/config/environments/development.rb +29 -0
  100. data/spec/apps/rails4/basic/config/environments/production.rb +80 -0
  101. data/spec/apps/rails4/basic/config/environments/test.rb +36 -0
  102. data/spec/apps/rails4/basic/config/initializers/backtrace_silencers.rb +7 -0
  103. data/spec/apps/rails4/basic/config/initializers/filter_parameter_logging.rb +4 -0
  104. data/spec/apps/rails4/basic/config/initializers/inflections.rb +16 -0
  105. data/spec/apps/rails4/basic/config/initializers/mime_types.rb +5 -0
  106. data/spec/apps/rails4/basic/config/initializers/secret_token.rb +12 -0
  107. data/spec/apps/rails4/basic/config/initializers/session_store.rb +2 -0
  108. data/spec/apps/rails4/basic/config/initializers/wrap_parameters.rb +14 -0
  109. data/spec/apps/rails4/basic/config/locales/en.yml +23 -0
  110. data/spec/apps/rails4/basic/config/routes.rb +5 -0
  111. data/spec/apps/rails4/basic/db/seeds.rb +7 -0
  112. data/spec/apps/rails4/basic/lib/assets/.keep +0 -0
  113. data/spec/apps/rails4/basic/lib/tasks/.keep +0 -0
  114. data/spec/apps/rails4/basic/public/404.html +58 -0
  115. data/spec/apps/rails4/basic/public/422.html +58 -0
  116. data/spec/apps/rails4/basic/public/500.html +57 -0
  117. data/spec/apps/rails4/basic/public/favicon.ico +0 -0
  118. data/spec/apps/rails4/basic/public/robots.txt +5 -0
  119. data/spec/apps/rails4/basic/public/some_page.html +7 -0
  120. data/spec/apps/rails4/basic/test/controllers/.keep +0 -0
  121. data/spec/apps/rails4/basic/test/fixtures/.keep +0 -0
  122. data/spec/apps/rails4/basic/test/helpers/.keep +0 -0
  123. data/spec/apps/rails4/basic/test/integration/.keep +0 -0
  124. data/spec/apps/rails4/basic/test/mailers/.keep +0 -0
  125. data/spec/apps/rails4/basic/test/models/.keep +0 -0
  126. data/spec/apps/rails4/basic/test/test_helper.rb +15 -0
  127. data/spec/apps/rails4/basic/vendor/assets/javascripts/.keep +0 -0
  128. data/spec/apps/rails4/basic/vendor/assets/stylesheets/.keep +0 -0
  129. data/spec/apps/sinatra/basic/Gemfile +4 -0
  130. data/spec/apps/sinatra/basic/Gemfile.lock +20 -0
  131. data/spec/apps/sinatra/basic/basic.rb +27 -0
  132. data/spec/apps/sinatra/basic/config.ru +7 -0
  133. data/spec/apps/sinatra/basic/public/some_page.html +7 -0
  134. data/spec/apps/sinatra/basic/views/index.erb +4 -0
  135. data/spec/apps/sinatra/basic/views/posted.haml +2 -0
  136. data/spec/apps/sinatra/basic/views/poster.haml +4 -0
  137. data/spec/apps/sinatra/basic/views/request_mapping.haml +4 -0
  138. data/spec/integration/basic_rack_spec.rb +89 -0
  139. data/spec/integration/basic_rails4_spec.rb +64 -0
  140. data/spec/integration/basic_sinatra_spec.rb +80 -0
  141. data/spec/spec_helper.rb +13 -0
  142. data/test/.ruby-version +1 -0
  143. data/test/config/app.rb +5 -0
  144. data/test/jubilee/test_cli.rb +11 -0
  145. data/test/jubilee/test_configuration.rb +31 -0
  146. data/test/jubilee/test_rack_server.rb +137 -0
  147. data/test/jubilee/test_response.rb +272 -0
  148. data/test/jubilee/test_server.rb +72 -0
  149. data/test/jubilee/test_upload.rb +301 -0
  150. data/test/sinatra_app/app.rb +31 -0
  151. data/test/sinatra_app/config.ru +6 -0
  152. data/test/sinatra_app/public/test.html +10 -0
  153. data/test/sinatra_app/unicorn.conf.rb +29 -0
  154. data/test/test_helper.rb +93 -0
  155. metadata +242 -0
@@ -0,0 +1,206 @@
1
+ # Copyright 2011 the original author or authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'rubygems'
16
+ require 'json'
17
+
18
+ module Vertx
19
+
20
+ # This class represents a distributed lightweight event bus which can encompass multiple vert.x instances.
21
+ # It is very useful for otherwise isolated vert.x application instances to communicate with each other.
22
+ #
23
+ # The event bus implements both publish / subscribe network and point to point messaging.
24
+ #
25
+ # For publish / subscribe, messages can be published to an address using one of the publish methods. An
26
+ # address is a simple String instance. Handlers are registered against an address. There can be multiple handlers
27
+ # registered against each address, and a particular handler can be registered against multiple addresses.
28
+ # The event bus will route a sent message to all handlers which are registered against that address.
29
+
30
+ # For point to point messaging, messages can be sent to an address using the send method.
31
+ # The messages will be delivered to a single handler, if one is registered on that address. If more than one
32
+ # handler is registered on the same address, Vert.x will choose one and deliver the message to that. Vert.x will
33
+ # aim to fairly distribute messages in a round-robin way, but does not guarantee strict round-robin under all
34
+ # circumstances.
35
+ #
36
+ # All messages sent over the bus are transient. On event of failure of all or part of the event bus messages
37
+ # may be lost. Applications should be coded to cope with lost messages, e.g. by resending them,
38
+ # and making application services idempotent.
39
+ #
40
+ # The order of messages received by any specific handler from a specific sender should match the order of messages
41
+ # sent from that sender.
42
+ #
43
+ # When sending a message, a reply handler can be provided. If so, it will be called when the reply from the receiver
44
+ # has been received. Reply messages can also be replied to, etc, ad infinitum.
45
+ #
46
+ # Different event bus instances can be clustered together over a network, to give a single logical event bus.
47
+ #
48
+ # When receiving a message in a handler the received object is an instance of EventBus::Message - this contains
49
+ # the actual message plus a reply method which can be used to reply to it.
50
+ #
51
+ # @author {http://tfox.org Tim Fox}
52
+ class EventBus
53
+
54
+ @@handler_map = {}
55
+
56
+ @@j_eventbus = org.jruby.jubilee.vertx.JubileeVertx.vertx().eventBus()
57
+
58
+ # Send a message on the event bus
59
+ # @param message [Hash] The message to send
60
+ # @param reply_handler [Block] An optional reply handler.
61
+ # It will be called when the reply from a receiver is received.
62
+ def EventBus.send(address, message, &reply_handler)
63
+ EventBus.send_or_pub(true, address, message, reply_handler)
64
+ self
65
+ end
66
+
67
+ # Publish a message on the event bus
68
+ # @param message [Hash] The message to publish
69
+ def EventBus.publish(address, message)
70
+ EventBus.send_or_pub(false, address, message)
71
+ self
72
+ end
73
+
74
+ # @private
75
+ def EventBus.send_or_pub(send, address, message, reply_handler = nil)
76
+ raise "An address must be specified" if !address
77
+ raise "A message must be specified" if message == nil
78
+ message = convert_msg(message)
79
+ if send
80
+ if reply_handler != nil
81
+ @@j_eventbus.send(address, message, InternalHandler.new(reply_handler))
82
+ else
83
+ @@j_eventbus.send(address, message)
84
+ end
85
+ else
86
+ @@j_eventbus.publish(address, message)
87
+ end
88
+ self
89
+ end
90
+
91
+ # Register a handler.
92
+ # @param address [String] The address to register for. Messages sent to that address will be
93
+ # received by the handler. A single handler can be registered against many addresses.
94
+ # @param local_only [Boolean] If true then handler won't be propagated across cluster
95
+ # @param message_hndlr [Block] The handler
96
+ # @return [FixNum] id of the handler which can be used in {EventBus.unregister_handler}
97
+ def EventBus.register_handler(address, local_only = false, &message_hndlr)
98
+ raise "An address must be specified" if !address
99
+ raise "A message handler must be specified" if !message_hndlr
100
+ internal = InternalHandler.new(message_hndlr)
101
+ if local_only
102
+ @@j_eventbus.registerLocalHandler(address, internal)
103
+ else
104
+ @@j_eventbus.registerHandler(address, internal)
105
+ end
106
+ id = java.util.UUID.randomUUID.toString
107
+ @@handler_map[id] = [address, internal]
108
+ id
109
+ end
110
+
111
+ # Registers a handler against a uniquely generated address, the address is returned as the id
112
+ # received by the handler. A single handler can be registered against many addresses.
113
+ # @param local_only [Boolean] If true then handler won't be propagated across cluster
114
+ # @param message_hndlr [Block] The handler
115
+ # @return [FixNum] id of the handler which can be used in {EventBus.unregister_handler}
116
+ def EventBus.register_simple_handler(local_only = false, &message_hndlr)
117
+ raise "A message handler must be specified" if !message_hndlr
118
+ internal = InternalHandler.new(message_hndlr)
119
+ id = java.util.UUID.randomUUID.toString
120
+ if local_only
121
+ @@j_eventbus.registerLocalHandler(id, internal)
122
+ else
123
+ @@j_eventbus.registerHandler(id, internal)
124
+ end
125
+ @@handler_map[id] = [id, internal]
126
+ id
127
+ end
128
+
129
+ # Unregisters a handler
130
+ # @param handler_id [FixNum] The id of the handler to unregister. Returned from {EventBus.register_handler}
131
+ def EventBus.unregister_handler(handler_id)
132
+ raise "A handler_id must be specified" if !handler_id
133
+ tuple = @@handler_map.delete(handler_id)
134
+ raise "Cannot find handler for id #{handler_id}" if !tuple
135
+ @@j_eventbus.unregisterHandler(tuple.first, tuple.last)
136
+ self
137
+ end
138
+
139
+ # @private
140
+ def EventBus.convert_msg(message)
141
+ if message.is_a? Hash
142
+ message = org.vertx.java.core.json.JsonObject.new(JSON.generate(message))
143
+ elsif message.is_a? Buffer
144
+ message = message._to_java_buffer
145
+ elsif message.is_a? Fixnum
146
+ message = java.lang.Long.new(message)
147
+ elsif message.is_a? Float
148
+ message = java.lang.Double.new(message)
149
+ end
150
+ message
151
+ end
152
+
153
+ end
154
+
155
+ # @private
156
+ class InternalHandler
157
+ include org.vertx.java.core.Handler
158
+
159
+ def initialize(hndlr)
160
+ @hndlr = hndlr
161
+ end
162
+
163
+ def handle(message)
164
+ @hndlr.call(Message.new(message))
165
+ end
166
+ end
167
+
168
+ # Represents a message received from the event bus
169
+ # @author {http://tfox.org Tim Fox}
170
+ class Message
171
+
172
+ attr_reader :body
173
+
174
+ # @private
175
+ def initialize(message)
176
+
177
+ @j_del = message
178
+ if message.body.is_a? org.vertx.java.core.json.JsonObject
179
+ @body = JSON.parse(message.body.encode)
180
+ elsif message.body.is_a? org.vertx.java.core.buffer.Buffer
181
+ @body = Buffer.new(message.body)
182
+ else
183
+ @body = message.body
184
+ end
185
+ end
186
+
187
+ # Reply to this message. If the message was sent specifying a receipt handler, that handler will be
188
+ # called when it has received a reply. If the message wasn't sent specifying a receipt handler
189
+ # this method does nothing.
190
+ # Replying to a message this way is equivalent to sending a message to an address which is the same as the message id
191
+ # of the original message.
192
+ # @param [Hash] Message send as reply
193
+ def reply(reply, &reply_handler)
194
+ raise "A reply message must be specified" if reply == nil
195
+ reply = EventBus.convert_msg(reply)
196
+ if reply_handler != nil
197
+ @j_del.reply(reply, InternalHandler.new(reply_handler))
198
+ else
199
+ @j_del.reply(reply)
200
+ end
201
+ end
202
+
203
+ end
204
+
205
+ end
206
+
@@ -0,0 +1,214 @@
1
+ # Copyright 2011 the original author or authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'delegate'
16
+
17
+ module Vertx
18
+
19
+ # Sometimes it is desirable to share immutable data between different event loops, for example to implement a
20
+ # cache of data.
21
+ #
22
+ # This class allows data structures to be looked up and used from different event loops.
23
+ # The data structures themselves will only allow certain data types to be stored into them. This shields the
24
+ # user from worrying about any thread safety issues might occur if mutable objects were shared between event loops.
25
+ #
26
+ # The following types can be stored in a shareddata data structure:
27
+ #
28
+ # String
29
+ # FixNum
30
+ # Float
31
+ # {Buffer} this will be automatically copied, and the copy will be stored in the structure.
32
+ #
33
+ # @author {http://tfox.org Tim Fox}
34
+ class SharedData
35
+
36
+ @@j_sd = org.jruby.jubilee.vertx.JubileeVertx.vertx().sharedData()
37
+
38
+ # Return a Hash with the specific name. All invocations of this method with the same value of name
39
+ # are guaranteed to return the same Hash instance.
40
+ # @param [String] key. Get the hash with the key.
41
+ # @return [Hash] the hash.
42
+ def SharedData.get_hash(key)
43
+ map = @@j_sd.getMap(key)
44
+ SharedHash.new(map)
45
+ end
46
+
47
+ # Return a Set with the specific name. All invocations of this method with the same value of name
48
+ # are guaranteed to return the same Set instance.
49
+ # @param [String] key. Get the set with the key.
50
+ # @return [SharedSet] the set.
51
+ def SharedData.get_set(key)
52
+ set = @@j_sd.getSet(key)
53
+ SharedSet.new(set)
54
+ end
55
+
56
+ # Remove the hash
57
+ # @param [String] key. The key of the hash.
58
+ def SharedData.remove_hash(key)
59
+ @@j_sd.removeMap(key)
60
+ end
61
+
62
+ # Remove the set
63
+ # @param [String] key. The key of the set.
64
+ def SharedData.remove_set(key)
65
+ @@j_sd.removeSet(key)
66
+ end
67
+
68
+ # Convert to corresponding Java objects
69
+ # And make copies where appropriate (the underlying java map will also make copies for some data types too)
70
+ # @private
71
+ def SharedData.check_obj(obj)
72
+ if obj.is_a?(Buffer)
73
+ obj = obj._to_java_buffer
74
+ end
75
+ obj
76
+ end
77
+
78
+ # @private
79
+ class SharedHash < DelegateClass(Hash)
80
+
81
+ def initialize(hash)
82
+ @hash = hash
83
+ # Pass the object to be delegated to the superclass.
84
+ super(@hash)
85
+ end
86
+
87
+ def []=(key, val)
88
+ key = SharedData.check_obj(key)
89
+ val = SharedData.check_obj(val)
90
+ super(key, val)
91
+ end
92
+
93
+ alias store []=
94
+
95
+ def [](key)
96
+ # We call the java class directly
97
+ obj = @hash.get(key)
98
+ obj = Buffer.new(obj) if obj.is_a? org.vertx.java.core.buffer.Buffer
99
+ obj
100
+ end
101
+
102
+ def ==(other)
103
+ if other.is_a?(SharedHash)
104
+ @hash.equal?(other._to_java_map)
105
+ else
106
+ false
107
+ end
108
+ end
109
+
110
+ def _to_java_map
111
+ @hash
112
+ end
113
+
114
+ end
115
+
116
+ #
117
+ # @private
118
+ class SharedSet
119
+
120
+ # @private
121
+ def initialize(j_set)
122
+ @j_set = j_set
123
+ end
124
+
125
+ def ==(other)
126
+ if other.is_a?(SharedSet)
127
+ @j_set.equal?(other._to_java_set)
128
+ else
129
+ false
130
+ end
131
+ end
132
+
133
+ # Add an object to the set
134
+ # @param [Object] obj. The object to add
135
+ # @return [SharedSet} self
136
+ def add(obj)
137
+ obj = SharedData.check_obj(obj)
138
+ @j_set.add(obj)
139
+ self
140
+ end
141
+
142
+ # Add an object to the set
143
+ # @param [Object] obj. The object to add
144
+ # @return [SharedSet] self if the object is not already in the set, otherwise nil
145
+ def add?(obj)
146
+ obj = SharedData.check_obj(obj)
147
+ if !@j_set.contains(obj)
148
+ @j_set.add(obj)
149
+ self
150
+ else
151
+ nil
152
+ end
153
+ end
154
+
155
+ # Clear the set
156
+ def clear
157
+ @j_set.clear
158
+ end
159
+
160
+ # Delete an object from the set
161
+ # @param [Object] obj. The object to delete
162
+ def delete(obj)
163
+ @j_set.remove(obj)
164
+ end
165
+
166
+ # Delete an object from the set
167
+ # @param [Object] obj. The object to delete
168
+ # @return [SharedSet] self if the object was in the set before the remove, nil otherwise.
169
+ def delete?(obj)
170
+ if @j_set.contains(obj)
171
+ @j_set.remove(obj)
172
+ self
173
+ else
174
+ nil
175
+ end
176
+ end
177
+
178
+ # Call the block for every element of the set
179
+ # @param [Blovk] block. The block to call.
180
+ def each(&block)
181
+ iter = @j_set.iterator
182
+ while iter.hasNext do
183
+ obj = iter.next
184
+ obj = Buffer.new(obj) if obj.is_a? org.vertx.java.core.buffer.Buffer
185
+ block.call(obj)
186
+ end
187
+ end
188
+
189
+ # @return [Boolean] true if the set is empty
190
+ def empty?
191
+ @j_set.isEmpty
192
+ end
193
+
194
+ # Does the set contain an element?
195
+ # @param [Object] obj, the object to check if the set contains
196
+ # @return [Boolean] true if the object is contained in the set
197
+ def include?(obj)
198
+ obj = obj._to_java_buffer if obj.is_a? Buffer
199
+ @j_set.contains(obj)
200
+ end
201
+
202
+ # @return [FixNum] The number of elements in the set
203
+ def size
204
+ @j_set.size
205
+ end
206
+
207
+ # @private
208
+ def _to_java_set
209
+ @j_set
210
+ end
211
+
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,50 @@
1
+ require 'rack'
2
+
3
+ class BasicMiddleware
4
+ def initialize(app, options={})
5
+ @app = app
6
+ end
7
+ def call(env)
8
+ # We had a bug triggered at one point by trying to access any HTTP
9
+ # header with a key less than 10 bytes long
10
+ env['HTTP_foo']
11
+ # Save off the accept header before Rack::Lint messes with it
12
+ env['tb.accept_header'] = env['HTTP_ACCEPT']
13
+ @app.call(env)
14
+ end
15
+ end
16
+
17
+ use BasicMiddleware
18
+ use Rack::Lint
19
+
20
+ app = lambda { |env|
21
+ body = <<-EOF
22
+ <div id='success' class='basic-rack'>it worked</div>
23
+ <div id='ruby-version'>#{RUBY_VERSION}</div>
24
+ <div id='path'>#{__FILE__}</div>
25
+ <div id='script_name'>#{env['SCRIPT_NAME']}</div>
26
+ <div id='path_info'>#{env['PATH_INFO']}</div>
27
+ <div id='request_uri'>#{env['REQUEST_URI']}</div>
28
+ <div id='accept_header'>#{env['tb.accept_header']}</div>
29
+ EOF
30
+ if env['REQUEST_METHOD'] == 'POST'
31
+ input = env['rack.input']
32
+ if env['PATH_INFO'] == '/basic-rack/gets'
33
+ posted = ''
34
+ posted_line = input.gets
35
+ while posted_line != nil
36
+ posted << posted_line
37
+ posted_line = input.gets
38
+ end
39
+ elsif env['PATH_INFO'] == '/basic-rack/read'
40
+ posted = input.read(2)
41
+ posted << input.read
42
+ elsif env['PATH_INFO'] == '/basic-rack/each'
43
+ posted = ""
44
+ input.each { |str| posted << str}
45
+ end
46
+ body << "<div id='posted'>#{posted}</div>"
47
+ end
48
+ [200, { 'Content-Type' => 'text/html' }, [body]]
49
+ }
50
+ run app