ib_ruby_proxy 0.0.1
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/.circleci/config.yml +77 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.rubocop.yml +143 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +74 -0
- data/LICENSE.txt +21 -0
- data/README.md +130 -0
- data/Rakefile +12 -0
- data/bin/console +14 -0
- data/bin/generate_ruby_classes +13 -0
- data/bin/ibproxy +32 -0
- data/bin/setup +8 -0
- data/docs/diagrams.key +0 -0
- data/docs/images/architecture.png +0 -0
- data/examples/common.rb +14 -0
- data/examples/plain_req_historical_ticks.rb +19 -0
- data/examples/req_contract_details.rb +9 -0
- data/examples/req_historical_bars_data.rb +10 -0
- data/examples/req_historical_ticks.rb +10 -0
- data/examples/req_tick_by_tick_data.rb +9 -0
- data/ib_ruby_proxy.gemspec +43 -0
- data/lib/ib_ruby_proxy.rb +35 -0
- data/lib/ib_ruby_proxy/client/callbacks_response_handler.rb +135 -0
- data/lib/ib_ruby_proxy/client/client.rb +69 -0
- data/lib/ib_ruby_proxy/client/ib/bar.rb +36 -0
- data/lib/ib_ruby_proxy/client/ib/combo_leg.rb +36 -0
- data/lib/ib_ruby_proxy/client/ib/contract.rb +56 -0
- data/lib/ib_ruby_proxy/client/ib/contract_details.rb +100 -0
- data/lib/ib_ruby_proxy/client/ib/delta_neutral_contract.rb +26 -0
- data/lib/ib_ruby_proxy/client/ib/historical_tick.rb +26 -0
- data/lib/ib_ruby_proxy/client/ib/historical_tick_bid_ask.rb +32 -0
- data/lib/ib_ruby_proxy/client/ib/historical_tick_last.rb +32 -0
- data/lib/ib_ruby_proxy/client/ib/order.rb +262 -0
- data/lib/ib_ruby_proxy/client/ib/tick_attrib_bid_ask.rb +24 -0
- data/lib/ib_ruby_proxy/client/ib/tick_attrib_last.rb +24 -0
- data/lib/ib_ruby_proxy/client/ib_callbacks_observer.rb +25 -0
- data/lib/ib_ruby_proxy/config.yml +43 -0
- data/lib/ib_ruby_proxy/server/ext/array.rb +22 -0
- data/lib/ib_ruby_proxy/server/ext/enum.rb +20 -0
- data/lib/ib_ruby_proxy/server/ext/idempotent_types.rb +23 -0
- data/lib/ib_ruby_proxy/server/ib/bar.rb +21 -0
- data/lib/ib_ruby_proxy/server/ib/combo_leg.rb +21 -0
- data/lib/ib_ruby_proxy/server/ib/contract.rb +31 -0
- data/lib/ib_ruby_proxy/server/ib/contract_details.rb +53 -0
- data/lib/ib_ruby_proxy/server/ib/delta_neutral_contract.rb +16 -0
- data/lib/ib_ruby_proxy/server/ib/historical_tick.rb +16 -0
- data/lib/ib_ruby_proxy/server/ib/historical_tick_bid_ask.rb +19 -0
- data/lib/ib_ruby_proxy/server/ib/historical_tick_last.rb +19 -0
- data/lib/ib_ruby_proxy/server/ib/order.rb +134 -0
- data/lib/ib_ruby_proxy/server/ib/tick_attrib_bid_ask.rb +15 -0
- data/lib/ib_ruby_proxy/server/ib/tick_attrib_last.rb +15 -0
- data/lib/ib_ruby_proxy/server/ib_client_adapter.rb +51 -0
- data/lib/ib_ruby_proxy/server/ib_proxy_service.rb +85 -0
- data/lib/ib_ruby_proxy/server/ib_ruby_class_files_generator.rb +77 -0
- data/lib/ib_ruby_proxy/server/ib_ruby_class_source_generator.rb +155 -0
- data/lib/ib_ruby_proxy/server/ib_wrapper_adapter.rb +47 -0
- data/lib/ib_ruby_proxy/server/reflection/ib_class.rb +62 -0
- data/lib/ib_ruby_proxy/server/reflection/ib_field.rb +60 -0
- data/lib/ib_ruby_proxy/util/has_logger.rb +10 -0
- data/lib/ib_ruby_proxy/util/string_utils.rb +29 -0
- data/lib/ib_ruby_proxy/version.rb +3 -0
- data/lib/server.rb +4 -0
- data/sandbox/drb_performance/client.rb +46 -0
- data/sandbox/drb_performance/server.rb +26 -0
- data/vendor/TwsApi.jar +0 -0
- metadata +226 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# ---------------------------------------------
|
2
|
+
# File generated automatically by ib_ruby_proxy
|
3
|
+
# ---------------------------------------------
|
4
|
+
|
5
|
+
java_import "com.ib.client.TickAttribBidAsk"
|
6
|
+
|
7
|
+
class Java::ComIbClient::TickAttribBidAsk
|
8
|
+
def to_ruby
|
9
|
+
ruby_object = IbRubyProxy::Client::Ib::TickAttribBidAsk.new
|
10
|
+
ruby_object.bid_past_low = bidPastLow().to_ruby
|
11
|
+
ruby_object.ask_past_high = askPastHigh().to_ruby
|
12
|
+
|
13
|
+
ruby_object
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# ---------------------------------------------
|
2
|
+
# File generated automatically by ib_ruby_proxy
|
3
|
+
# ---------------------------------------------
|
4
|
+
|
5
|
+
java_import "com.ib.client.TickAttribLast"
|
6
|
+
|
7
|
+
class Java::ComIbClient::TickAttribLast
|
8
|
+
def to_ruby
|
9
|
+
ruby_object = IbRubyProxy::Client::Ib::TickAttribLast.new
|
10
|
+
ruby_object.past_limit = pastLimit().to_ruby
|
11
|
+
ruby_object.unreported = unreported().to_ruby
|
12
|
+
|
13
|
+
ruby_object
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
java_import 'com.ib.client.EClient'
|
2
|
+
|
3
|
+
module IbRubyProxy
|
4
|
+
module Server
|
5
|
+
# This is the Ruby representation of the IB Java +EClient+ class. It adapts ruby invocations
|
6
|
+
# and arguments to invoke the corresponding Java API methods.
|
7
|
+
#
|
8
|
+
# It is the object DRb clients get when connecting to the {IbProxyService proxy service}.
|
9
|
+
#
|
10
|
+
# Mimicking how the Java API works, it collaborates with an {IbWrapperAdapter} that
|
11
|
+
# corresponds with an +EWrapper+ in the Java world. It works by observing callbacks
|
12
|
+
# in this wrapper.
|
13
|
+
#
|
14
|
+
# The usage of observers as a communication mechanism is because it is supported
|
15
|
+
# by DRb and, being DRb a standard implemented in JRuby, enables communicating Ruby and JRuby.
|
16
|
+
# If supporting other rubies was not required this level of indirection would be unnecessary.
|
17
|
+
class IbClientAdapter
|
18
|
+
extend IbRubyProxy::Util::StringUtils
|
19
|
+
|
20
|
+
attr_reader :ib_client, :ib_wrapper_adapter
|
21
|
+
|
22
|
+
# @param [com.ib.client.EClient] ib_client IB +EClient+ object
|
23
|
+
# @param [IbWrapperAdapter] ib_wrapper_adapter
|
24
|
+
def initialize(ib_client, ib_wrapper_adapter)
|
25
|
+
@ib_client = ib_client
|
26
|
+
@ib_wrapper_adapter = ib_wrapper_adapter
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param [IbRubyProxy::Client::IbCallbacksObserver] ib_callbacks_observer
|
30
|
+
def add_ib_callbacks_observer(ib_callbacks_observer)
|
31
|
+
ib_wrapper_adapter.add_observer(ib_callbacks_observer)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @private
|
35
|
+
def self.define_ruby_method_for(java_method)
|
36
|
+
ruby_method_name = to_underscore(java_method.name)
|
37
|
+
|
38
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
39
|
+
def #{ruby_method_name}(*arguments)
|
40
|
+
ib_arguments = arguments.collect(&:to_ib)
|
41
|
+
@ib_client.#{java_method.name} *ib_arguments
|
42
|
+
end
|
43
|
+
RUBY
|
44
|
+
end
|
45
|
+
|
46
|
+
EClient.java_class.declared_instance_methods.each do |java_method|
|
47
|
+
define_ruby_method_for(java_method)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'ib_ruby_proxy/version'
|
2
|
+
require_relative 'ib_wrapper_adapter'
|
3
|
+
require_relative 'ib_client_adapter'
|
4
|
+
require 'drb'
|
5
|
+
|
6
|
+
java_import 'com.ib.client.EClientSocket'
|
7
|
+
java_import 'com.ib.client.EJavaSignal'
|
8
|
+
java_import 'com.ib.client.EClientSocket'
|
9
|
+
java_import 'com.ib.client.EReader'
|
10
|
+
|
11
|
+
module IbRubyProxy
|
12
|
+
module Server
|
13
|
+
# Proxy service for invoking IB api through
|
14
|
+
# {https://ruby-doc.org/stdlib-2.6.1/libdoc/drb/rdoc/DRb.html DRb}
|
15
|
+
#
|
16
|
+
# The proxy does essentially 2 things:
|
17
|
+
#
|
18
|
+
# * Starts a DRb process you can connect to invoke the IB api. This will expose an {IbClientAdapter}
|
19
|
+
# object to its clients
|
20
|
+
# * Starts an IB message-processing thread that will dispatch messages sent to IB client app (
|
21
|
+
# gateway or TWS)
|
22
|
+
class IbProxyService
|
23
|
+
DEFAULT_IB_GATEWAY_PORT = 4002
|
24
|
+
DEFAULT_DRB_PORT = 1992
|
25
|
+
|
26
|
+
# @param [String] ib_host Hostname for the IB client app (gateway or TWS). Default +localhost+
|
27
|
+
# @param [Integer] ib_port Port for hte IB client app (gateway or TWS). Default +4002+ (gateway)
|
28
|
+
# @param [String] drb_host Hostname for the DRB process. Default +localhost+
|
29
|
+
# @param [Integer] drb_port Port for the . Default +1992+
|
30
|
+
def initialize(ib_host: 'localhost', ib_port: DEFAULT_IB_GATEWAY_PORT,
|
31
|
+
drb_host: 'localhost', drb_port: DEFAULT_DRB_PORT)
|
32
|
+
@ib_host = ib_host
|
33
|
+
@ib_port = ib_port
|
34
|
+
@drb_host = drb_host
|
35
|
+
@drb_port = drb_port
|
36
|
+
|
37
|
+
@wrapper = IbRubyProxy::Server::IbWrapperAdapter.new
|
38
|
+
@client = wrapper.client
|
39
|
+
@signal = wrapper.signal
|
40
|
+
|
41
|
+
connect
|
42
|
+
end
|
43
|
+
|
44
|
+
# Connects to IB and starts the DRb process
|
45
|
+
#
|
46
|
+
# Clients of the DRb service will get an {IbClientAdapter} object to interact with the IB api
|
47
|
+
# @return [void]
|
48
|
+
def start
|
49
|
+
DRb.start_service("druby://#{drb_host}:#{drb_port}", ib_client_adapter, verbose: true)
|
50
|
+
start_ib_message_processing_thread
|
51
|
+
puts "Ib proxy server started at druby://#{drb_host}:#{drb_port}. Connected to IB at"\
|
52
|
+
" #{ib_host}:#{ib_port}"
|
53
|
+
DRb.thread.join
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
attr_reader :wrapper, :client, :signal, :ib_host, :ib_port, :drb_host, :drb_port
|
59
|
+
|
60
|
+
def start_ib_message_processing_thread
|
61
|
+
reader = EReader.new(client, signal)
|
62
|
+
reader.start
|
63
|
+
|
64
|
+
Thread.new do
|
65
|
+
while client.isConnected
|
66
|
+
signal.waitForSignal
|
67
|
+
begin
|
68
|
+
reader.processMsgs
|
69
|
+
rescue StandardError => e
|
70
|
+
puts "Error while processing ib message: #{e}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def connect
|
77
|
+
client.eConnect(ib_host, ib_port, 2)
|
78
|
+
end
|
79
|
+
|
80
|
+
def ib_client_adapter
|
81
|
+
@ib_client_adapter ||= IbRubyProxy::Server::IbClientAdapter.new(client, wrapper)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module IbRubyProxy
|
2
|
+
module Server
|
3
|
+
# Source code generator that interacts with {IbRubyClassSourceGenerator} and writes down the
|
4
|
+
# actual files with the source for both Ruby classes representing IB classes and Ruby extensions
|
5
|
+
# for these.
|
6
|
+
class IbRubyClassFilesGenerator
|
7
|
+
attr_reader :client_code_dir, :server_code_dir
|
8
|
+
|
9
|
+
# @param [String] client_code_dir
|
10
|
+
# @param [String] server_code_dir
|
11
|
+
def initialize(client_code_dir:, server_code_dir:)
|
12
|
+
@client_code_dir = client_code_dir
|
13
|
+
@server_code_dir = server_code_dir
|
14
|
+
|
15
|
+
import_ruby_classes
|
16
|
+
end
|
17
|
+
|
18
|
+
# Generate client files and server class extensions
|
19
|
+
#
|
20
|
+
# It will format the generated code with {https://github.com/ruby-formatter/rufo Rufo}.
|
21
|
+
#
|
22
|
+
# @see IbRubyClassSourceGenerator#ruby_class_source
|
23
|
+
# @see IbRubyClassSourceGenerator#ib_class_extension_source
|
24
|
+
def generate_all
|
25
|
+
do_generate_all
|
26
|
+
format_code
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def import_ruby_classes
|
32
|
+
ruby_classes.each do |class_name|
|
33
|
+
java_import "com.ib.client.#{class_name}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def ruby_classes
|
38
|
+
@ruby_classes ||= IbRubyProxy.config['classes']
|
39
|
+
end
|
40
|
+
|
41
|
+
def do_generate_all
|
42
|
+
ruby_classes.each do |class_name|
|
43
|
+
generate_files class_name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_files(class_name)
|
48
|
+
ib_class = Java::ComIbClient.const_get(class_name)
|
49
|
+
generator = IbRubyClassSourceGenerator.new(ib_class,
|
50
|
+
namespace: 'IbRubyProxy::Client::Ib')
|
51
|
+
|
52
|
+
file_name = "#{IbRubyProxy::Util::StringUtils.to_underscore(class_name)}.rb"
|
53
|
+
generate_client_file(generator, file_name)
|
54
|
+
generate_server_file(generator, file_name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def generate_client_file(generator, file_name)
|
58
|
+
target_file = File.join(client_code_dir, file_name)
|
59
|
+
puts "Generating client file: #{target_file}..."
|
60
|
+
File.open(target_file, 'w') { |file| file.write(generator.ruby_class_source) }
|
61
|
+
end
|
62
|
+
|
63
|
+
def generate_server_file(generator, file_name)
|
64
|
+
target_file = File.join(server_code_dir, file_name)
|
65
|
+
puts "Generating server file: #{target_file}..."
|
66
|
+
File.open(target_file, 'w') { |file| file.write(generator.ib_class_extension_source) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def format_code
|
70
|
+
[server_code_dir, client_code_dir].each do |dir|
|
71
|
+
puts "Formatting #{dir}..."
|
72
|
+
system "rufo #{dir}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
module IbRubyProxy
|
2
|
+
module Server
|
3
|
+
# Given a value object class from Interactive Broker API, this generator can build Ruby source
|
4
|
+
# code for:
|
5
|
+
#
|
6
|
+
# * A ruby class to manipulate the same class in Ruby
|
7
|
+
# * An extension to the original Java class for converting instances into Ruby
|
8
|
+
class IbRubyClassSourceGenerator
|
9
|
+
include IbRubyProxy::Util::StringUtils
|
10
|
+
|
11
|
+
attr_reader :ib_class, :namespace_list
|
12
|
+
|
13
|
+
# @param [Class] ib_class Class from IB broker to mimic in Ruby. It is meant to be used with
|
14
|
+
# value objects, as only properties are translated. That is the case for classes that
|
15
|
+
# represent either arguments or returned values (via callbacks) in the API.
|
16
|
+
# @param [String] namespace The namespace to generate the classes in. Default
|
17
|
+
# +IbRubyProxy::Client::Ib+
|
18
|
+
def initialize(ib_class, namespace: 'IbRubyProxy::Client::Ib')
|
19
|
+
@ib_class = Reflection::IbClass.new(ib_class)
|
20
|
+
@namespace_list = namespace.split('::')
|
21
|
+
end
|
22
|
+
|
23
|
+
# Source for a ruby class translates into Ruby the Java properties of the target
|
24
|
+
# ib class.
|
25
|
+
#
|
26
|
+
# It generates a {Struct} with the list of properties, that admits a keyword-based
|
27
|
+
# constructor, and that includes a +to_ib+ method for converting the ruby back into its
|
28
|
+
# original Java counterpart.
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
def ruby_class_source
|
32
|
+
<<-RUBY
|
33
|
+
#{header}
|
34
|
+
|
35
|
+
#{generate_ruby_class}
|
36
|
+
RUBY
|
37
|
+
end
|
38
|
+
|
39
|
+
# Source for a ruby class that extends the original IB Java class with a +to_ruby+ method,
|
40
|
+
# to convert Java Ib objects into their Ruby counterparts generated in {#ruby_class_source}
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
def ib_class_extension_source
|
44
|
+
<<-RUBY
|
45
|
+
#{header}
|
46
|
+
|
47
|
+
#{generate_ib_class_extension}
|
48
|
+
RUBY
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def header
|
54
|
+
<<-RUBY
|
55
|
+
# ---------------------------------------------
|
56
|
+
# File generated automatically by ib_ruby_proxy
|
57
|
+
# ---------------------------------------------
|
58
|
+
RUBY
|
59
|
+
end
|
60
|
+
|
61
|
+
def generate_ib_class_extension
|
62
|
+
<<-RUBY
|
63
|
+
java_import "com.ib.client.#{ib_class.name}"
|
64
|
+
|
65
|
+
class #{ib_class.full_name}
|
66
|
+
#{generate_to_ruby_method}
|
67
|
+
end
|
68
|
+
RUBY
|
69
|
+
end
|
70
|
+
|
71
|
+
def generate_ruby_class
|
72
|
+
<<-RUBY
|
73
|
+
#{generate_namespace_open}
|
74
|
+
|
75
|
+
#{generate_class_declaration}
|
76
|
+
#{generate_constructor}
|
77
|
+
#{generate_to_ib_method}
|
78
|
+
end
|
79
|
+
|
80
|
+
#{generate_namespace_close}
|
81
|
+
RUBY
|
82
|
+
end
|
83
|
+
|
84
|
+
def generate_namespace_open
|
85
|
+
namespace_list.collect { |namespace| "module #{namespace}" }.join("\n")
|
86
|
+
end
|
87
|
+
|
88
|
+
def generate_namespace_close
|
89
|
+
namespace_list.length.times.collect { 'end' }.join("\n")
|
90
|
+
end
|
91
|
+
|
92
|
+
def generate_class_declaration
|
93
|
+
struct_init_properties = ib_class.ruby_property_names.collect { |property| ":#{property}" }
|
94
|
+
.join(', ')
|
95
|
+
struct_init_properties << ', keyword_init: true'
|
96
|
+
|
97
|
+
<<-RUBY
|
98
|
+
#{ib_class.name} = Struct.new(#{struct_init_properties}) do
|
99
|
+
RUBY
|
100
|
+
end
|
101
|
+
|
102
|
+
def generate_constructor
|
103
|
+
constructor_declarations = ib_class.zipped_ruby_and_java_properties
|
104
|
+
.collect do |ruby_property, java_field|
|
105
|
+
"#{ruby_property}: #{java_field.default_value_as_string}"
|
106
|
+
end
|
107
|
+
|
108
|
+
assignment_statements = ib_class.ruby_property_names.collect do |ruby_property|
|
109
|
+
<<-RUBY
|
110
|
+
self.#{ruby_property} = #{ruby_property}
|
111
|
+
RUBY
|
112
|
+
end
|
113
|
+
<<-RUBY
|
114
|
+
def initialize(#{constructor_declarations.join(', ')})
|
115
|
+
#{assignment_statements.join('')}
|
116
|
+
end
|
117
|
+
RUBY
|
118
|
+
end
|
119
|
+
|
120
|
+
def generate_to_ib_method
|
121
|
+
property_copy_sentences = ib_class.zipped_ruby_and_java_properties
|
122
|
+
.collect do |ruby_property, java_field|
|
123
|
+
<<-RUBY
|
124
|
+
ib_object.#{java_field.name}(#{ruby_property}).to_java
|
125
|
+
RUBY
|
126
|
+
end
|
127
|
+
|
128
|
+
<<-RUBY
|
129
|
+
def to_ib
|
130
|
+
ib_object = #{ib_class.klass.name}.new
|
131
|
+
#{property_copy_sentences.join('')}
|
132
|
+
ib_object
|
133
|
+
end
|
134
|
+
RUBY
|
135
|
+
end
|
136
|
+
|
137
|
+
def generate_to_ruby_method
|
138
|
+
property_copy_sentences = ib_class.zipped_ruby_and_java_properties
|
139
|
+
.collect do |ruby_property, java_field|
|
140
|
+
<<-RUBY
|
141
|
+
ruby_object.#{ruby_property} = #{java_field.name}().to_ruby
|
142
|
+
RUBY
|
143
|
+
end
|
144
|
+
|
145
|
+
<<-RUBY
|
146
|
+
def to_ruby
|
147
|
+
ruby_object = #{namespace_list.join('::')}::#{ib_class.name}.new
|
148
|
+
#{property_copy_sentences.join('')}
|
149
|
+
ruby_object
|
150
|
+
end
|
151
|
+
RUBY
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
java_import 'com.ib.client.EWrapper'
|
2
|
+
require 'drb/observer'
|
3
|
+
|
4
|
+
module IbRubyProxy
|
5
|
+
module Server
|
6
|
+
# Ruby representation of the IB +EWrapper+ class. It delegates received callbacks by
|
7
|
+
# triggering an observer notification. It will translate the name of the java method to
|
8
|
+
# Ruby (underscore), as well as translate the parameters from IB to the Ruby world.
|
9
|
+
#
|
10
|
+
# @see IbClientAdapter
|
11
|
+
class IbWrapperAdapter
|
12
|
+
# include DRb::DRbObservable
|
13
|
+
include EWrapper
|
14
|
+
include DRb::DRbObservable
|
15
|
+
include IbRubyProxy::Util::HasLogger
|
16
|
+
extend IbRubyProxy::Util::StringUtils
|
17
|
+
|
18
|
+
attr_reader :signal, :client
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@signal = EJavaSignal.new
|
22
|
+
@client = EClientSocket.new(self, @signal)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @private
|
26
|
+
def self.define_ruby_method_for(java_method)
|
27
|
+
ruby_method_name = to_underscore(java_method.name)
|
28
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
29
|
+
def #{java_method.name}(*arguments)
|
30
|
+
ruby_arguments = arguments.collect(&:to_ruby)
|
31
|
+
if count_observers > 0
|
32
|
+
changed
|
33
|
+
notify_observers *(["#{ruby_method_name}"] + ruby_arguments)
|
34
|
+
else
|
35
|
+
logger.debug "Received #{ruby_method_name}"
|
36
|
+
logger.debug ruby_arguments.inspect
|
37
|
+
end
|
38
|
+
end
|
39
|
+
RUBY
|
40
|
+
end
|
41
|
+
|
42
|
+
EWrapper.java_class.declared_instance_methods.each do |java_method|
|
43
|
+
define_ruby_method_for(java_method)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|