activeldap 1.2.4 → 3.1.0
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/Gemfile +18 -0
- data/LICENSE +2 -1
- data/README.textile +137 -0
- data/doc/text/development.textile +50 -0
- data/{CHANGES → doc/text/news.textile} +256 -237
- data/doc/text/rails.textile +144 -0
- data/doc/text/tutorial.textile +1005 -0
- data/lib/active_ldap/adapter/base.rb +5 -3
- data/lib/active_ldap/adapter/net_ldap_ext.rb +1 -1
- data/lib/active_ldap/associations.rb +6 -2
- data/lib/active_ldap/base.rb +16 -71
- data/lib/active_ldap/callbacks.rb +52 -33
- data/lib/active_ldap/configuration.rb +2 -2
- data/lib/active_ldap/get_text/parser.rb +2 -2
- data/lib/active_ldap/human_readable.rb +5 -4
- data/lib/active_ldap/log_subscriber.rb +50 -0
- data/lib/active_ldap/persistence.rb +65 -0
- data/lib/active_ldap/railtie.rb +40 -0
- data/lib/active_ldap/railties/controller_runtime.rb +48 -0
- data/lib/active_ldap/user_password.rb +1 -0
- data/lib/active_ldap/validations.rb +34 -72
- data/lib/active_ldap.rb +13 -912
- data/{rails_generators/model_active_ldap → lib/rails/generators/active_ldap/model}/USAGE +2 -1
- data/lib/rails/generators/active_ldap/model/model_generator.rb +47 -0
- data/{rails_generators/model_active_ldap → lib/rails/generators/active_ldap/model}/templates/model_active_ldap.rb +0 -0
- data/lib/rails/generators/active_ldap/scaffold/scaffold_generator.rb +14 -0
- data/{rails_generators/scaffold_active_ldap → lib/rails/generators/active_ldap/scaffold}/templates/ldap.yml +1 -0
- data/test/test_base.rb +9 -0
- data/test/test_callback.rb +2 -6
- data/test/test_connection.rb +2 -2
- data/test/test_user.rb +2 -2
- data/test/test_validation.rb +11 -11
- metadata +165 -106
- data/README +0 -155
- data/Rakefile +0 -133
- data/rails/README +0 -54
- data/rails/init.rb +0 -33
- data/rails_generators/model_active_ldap/model_active_ldap_generator.rb +0 -69
- data/rails_generators/model_active_ldap/templates/unit_test.rb +0 -8
- data/rails_generators/scaffold_active_ldap/scaffold_active_ldap_generator.rb +0 -7
- data/test/al-test-utils.rb +0 -439
- data/test/command.rb +0 -112
- data/test/config.yaml.sample +0 -6
- data/test/fixtures/lower_case_object_class_schema.rb +0 -802
- data/test/run-test.rb +0 -44
data/test/al-test-utils.rb
DELETED
@@ -1,439 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
require 'erb'
|
4
|
-
require 'yaml'
|
5
|
-
require 'socket'
|
6
|
-
require 'rbconfig'
|
7
|
-
require 'tempfile'
|
8
|
-
|
9
|
-
require 'active_ldap'
|
10
|
-
|
11
|
-
require File.join(File.expand_path(File.dirname(__FILE__)), "command")
|
12
|
-
|
13
|
-
LDAP_ENV = "test" unless defined?(LDAP_ENV)
|
14
|
-
|
15
|
-
module AlTestUtils
|
16
|
-
def self.included(base)
|
17
|
-
base.class_eval do
|
18
|
-
include ActiveLdap::GetTextSupport
|
19
|
-
include Utilities
|
20
|
-
include Assertions
|
21
|
-
include Config
|
22
|
-
include Connection
|
23
|
-
include Populate
|
24
|
-
include TemporaryEntry
|
25
|
-
include CommandSupport
|
26
|
-
include MockLogger
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
module Utilities
|
31
|
-
def dn(string)
|
32
|
-
ActiveLdap::DN.parse(string)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
module Assertions
|
37
|
-
def assert_true(actual, *args)
|
38
|
-
assert_equal(true, actual, *args)
|
39
|
-
end
|
40
|
-
|
41
|
-
def assert_false(actual, *args)
|
42
|
-
assert_equal(false, actual, *args)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
module Config
|
47
|
-
def setup
|
48
|
-
super
|
49
|
-
@base_dir = File.expand_path(File.dirname(__FILE__))
|
50
|
-
@top_dir = File.expand_path(File.join(@base_dir, ".."))
|
51
|
-
@example_dir = File.join(@top_dir, "examples")
|
52
|
-
@fixtures_dir = File.join(@base_dir, "fixtures")
|
53
|
-
@config_file = File.join(@base_dir, "config.yaml")
|
54
|
-
ActiveLdap::Base.configurations = read_config
|
55
|
-
end
|
56
|
-
|
57
|
-
def teardown
|
58
|
-
super
|
59
|
-
end
|
60
|
-
|
61
|
-
def current_configuration
|
62
|
-
ActiveLdap::Base.configurations[LDAP_ENV]
|
63
|
-
end
|
64
|
-
|
65
|
-
def read_config
|
66
|
-
unless File.exist?(@config_file)
|
67
|
-
raise "config file for testing doesn't exist: #{@config_file}"
|
68
|
-
end
|
69
|
-
erb = ERB.new(File.read(@config_file))
|
70
|
-
erb.filename = @config_file
|
71
|
-
config = YAML.load(erb.result)
|
72
|
-
_adapter = adapter
|
73
|
-
config.each do |key, value|
|
74
|
-
value[:adapter] = _adapter if _adapter
|
75
|
-
end
|
76
|
-
config
|
77
|
-
end
|
78
|
-
|
79
|
-
def adapter
|
80
|
-
ENV["ACTIVE_LDAP_TEST_ADAPTER"]
|
81
|
-
end
|
82
|
-
|
83
|
-
def fixture(*components)
|
84
|
-
File.join(@fixtures_dir, *components)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
module ExampleFile
|
89
|
-
def certificate_path
|
90
|
-
File.join(@example_dir, 'example.der')
|
91
|
-
end
|
92
|
-
|
93
|
-
@@certificate = nil
|
94
|
-
def certificate
|
95
|
-
return @@certificate if @@certificate
|
96
|
-
if File.exists?(certificate_path)
|
97
|
-
@@certificate = read_binary_file(certificate_path)
|
98
|
-
return @@certificate
|
99
|
-
end
|
100
|
-
|
101
|
-
require 'openssl'
|
102
|
-
rsa = OpenSSL::PKey::RSA.new(512)
|
103
|
-
comment = "Generated by Ruby/OpenSSL"
|
104
|
-
|
105
|
-
cert = OpenSSL::X509::Certificate.new
|
106
|
-
cert.version = 3
|
107
|
-
cert.serial = 0
|
108
|
-
subject = [["OU", "test"],
|
109
|
-
["CN", Socket.gethostname]]
|
110
|
-
name = OpenSSL::X509::Name.new(subject)
|
111
|
-
cert.subject = name
|
112
|
-
cert.issuer = name
|
113
|
-
cert.not_before = Time.now
|
114
|
-
cert.not_after = Time.now + (365*24*60*60)
|
115
|
-
cert.public_key = rsa.public_key
|
116
|
-
|
117
|
-
ef = OpenSSL::X509::ExtensionFactory.new(nil, cert)
|
118
|
-
ef.issuer_certificate = cert
|
119
|
-
cert.extensions = [
|
120
|
-
ef.create_extension("basicConstraints","CA:FALSE"),
|
121
|
-
ef.create_extension("keyUsage", "keyEncipherment"),
|
122
|
-
ef.create_extension("subjectKeyIdentifier", "hash"),
|
123
|
-
ef.create_extension("extendedKeyUsage", "serverAuth"),
|
124
|
-
ef.create_extension("nsComment", comment),
|
125
|
-
]
|
126
|
-
aki = ef.create_extension("authorityKeyIdentifier",
|
127
|
-
"keyid:always,issuer:always")
|
128
|
-
cert.add_extension(aki)
|
129
|
-
cert.sign(rsa, OpenSSL::Digest::SHA1.new)
|
130
|
-
|
131
|
-
@@certificate = cert.to_der
|
132
|
-
@@certificate
|
133
|
-
end
|
134
|
-
|
135
|
-
def jpeg_photo_path
|
136
|
-
File.join(@example_dir, 'example.jpg')
|
137
|
-
end
|
138
|
-
|
139
|
-
def jpeg_photo
|
140
|
-
read_binary_file(jpeg_photo_path)
|
141
|
-
end
|
142
|
-
|
143
|
-
def read_binary_file(path)
|
144
|
-
File.open(path, "rb") do |input|
|
145
|
-
input.set_encoding("ascii-8bit") if input.respond_to?(:set_encoding)
|
146
|
-
input.read
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
module Connection
|
152
|
-
def setup
|
153
|
-
super
|
154
|
-
ActiveLdap::Base.setup_connection
|
155
|
-
end
|
156
|
-
|
157
|
-
def teardown
|
158
|
-
ActiveLdap::Base.remove_active_connections!
|
159
|
-
super
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
module Populate
|
164
|
-
def setup
|
165
|
-
@dumped_data = nil
|
166
|
-
super
|
167
|
-
begin
|
168
|
-
@dumped_data = ActiveLdap::Base.dump(:scope => :sub)
|
169
|
-
rescue ActiveLdap::ConnectionError
|
170
|
-
end
|
171
|
-
ActiveLdap::Base.delete_all(nil, :scope => :sub)
|
172
|
-
populate
|
173
|
-
end
|
174
|
-
|
175
|
-
def teardown
|
176
|
-
if @dumped_data
|
177
|
-
ActiveLdap::Base.setup_connection
|
178
|
-
ActiveLdap::Base.delete_all(nil, :scope => :sub)
|
179
|
-
ActiveLdap::Base.load(@dumped_data)
|
180
|
-
end
|
181
|
-
super
|
182
|
-
end
|
183
|
-
|
184
|
-
def populate
|
185
|
-
populate_base
|
186
|
-
populate_ou
|
187
|
-
populate_user_class
|
188
|
-
populate_group_class
|
189
|
-
populate_associations
|
190
|
-
populate_get_text_fix
|
191
|
-
end
|
192
|
-
|
193
|
-
def populate_base
|
194
|
-
ActiveLdap::Populate.ensure_base
|
195
|
-
end
|
196
|
-
|
197
|
-
def ou_class(prefix="")
|
198
|
-
ou_class = Class.new(ActiveLdap::Base)
|
199
|
-
ou_class.ldap_mapping(:dn_attribute => "ou",
|
200
|
-
:prefix => prefix,
|
201
|
-
:classes => ["top", "organizationalUnit"])
|
202
|
-
ou_class
|
203
|
-
end
|
204
|
-
|
205
|
-
def dc_class(prefix="")
|
206
|
-
dc_class = Class.new(ActiveLdap::Base)
|
207
|
-
dc_class.ldap_mapping(:dn_attribute => "dc",
|
208
|
-
:prefix => prefix,
|
209
|
-
:classes => ["top", "dcObject", "organization"])
|
210
|
-
dc_class
|
211
|
-
end
|
212
|
-
|
213
|
-
def entry_class(prefix="")
|
214
|
-
entry_class = Class.new(ActiveLdap::Base)
|
215
|
-
entry_class.ldap_mapping(:prefix => prefix,
|
216
|
-
:scope => :sub,
|
217
|
-
:classes => ["top"])
|
218
|
-
entry_class.dn_attribute = nil
|
219
|
-
entry_class
|
220
|
-
end
|
221
|
-
|
222
|
-
def populate_ou
|
223
|
-
%w(Users Groups).each do |name|
|
224
|
-
make_ou(name)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
def make_ou(name)
|
229
|
-
ActiveLdap::Populate.ensure_ou(name)
|
230
|
-
end
|
231
|
-
|
232
|
-
def make_dc(name)
|
233
|
-
ActiveLdap::Populate.ensure_dc(name)
|
234
|
-
end
|
235
|
-
|
236
|
-
def populate_user_class
|
237
|
-
@user_class = Class.new(ActiveLdap::Base)
|
238
|
-
@user_class_classes = ["posixAccount", "person"]
|
239
|
-
@user_class.ldap_mapping :dn_attribute => "uid",
|
240
|
-
:prefix => "ou=Users",
|
241
|
-
:scope => :sub,
|
242
|
-
:classes => @user_class_classes
|
243
|
-
end
|
244
|
-
|
245
|
-
def populate_group_class
|
246
|
-
@group_class = Class.new(ActiveLdap::Base)
|
247
|
-
@group_class.ldap_mapping :prefix => "ou=Groups",
|
248
|
-
:scope => :sub,
|
249
|
-
:classes => ["posixGroup"]
|
250
|
-
end
|
251
|
-
|
252
|
-
def populate_associations
|
253
|
-
@user_class.belongs_to :groups, :many => "memberUid"
|
254
|
-
@user_class.belongs_to :primary_group,
|
255
|
-
:foreign_key => "gidNumber",
|
256
|
-
:primary_key => "gidNumber"
|
257
|
-
@group_class.has_many :members, :wrap => "memberUid"
|
258
|
-
@group_class.has_many :primary_members,
|
259
|
-
:foreign_key => "gidNumber",
|
260
|
-
:primary_key => "gidNumber"
|
261
|
-
@user_class.set_associated_class(:groups, @group_class)
|
262
|
-
@user_class.set_associated_class(:primary_group, @group_class)
|
263
|
-
@group_class.set_associated_class(:members, @user_class)
|
264
|
-
@group_class.set_associated_class(:primary_members, @user_class)
|
265
|
-
end
|
266
|
-
|
267
|
-
def populate_get_text_fix
|
268
|
-
return if ActiveLdap.get_text_supported?
|
269
|
-
|
270
|
-
def @user_class.name
|
271
|
-
"User"
|
272
|
-
end
|
273
|
-
|
274
|
-
def @group_class.name
|
275
|
-
"Group"
|
276
|
-
end
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
module TemporaryEntry
|
281
|
-
include ExampleFile
|
282
|
-
|
283
|
-
def setup
|
284
|
-
super
|
285
|
-
@user_index = 0
|
286
|
-
@group_index = 0
|
287
|
-
end
|
288
|
-
|
289
|
-
def make_temporary_user(config={})
|
290
|
-
@user_index += 1
|
291
|
-
uid = config[:uid] || "temp-user#{@user_index}"
|
292
|
-
ensure_delete_user(uid) do
|
293
|
-
password = config[:password] || "password#{@user_index}"
|
294
|
-
uid_number = config[:uid_number] || default_uid
|
295
|
-
gid_number = config[:gid_number] || default_gid
|
296
|
-
home_directory = config[:home_directory] || "/nonexistent"
|
297
|
-
see_also = config[:see_also]
|
298
|
-
_wrap_assertion do
|
299
|
-
assert(!@user_class.exists?(uid))
|
300
|
-
assert_raise(ActiveLdap::EntryNotFound) do
|
301
|
-
@user_class.find(uid).dn
|
302
|
-
end
|
303
|
-
user = @user_class.new(uid)
|
304
|
-
assert(user.new_entry?)
|
305
|
-
user.cn = user.uid
|
306
|
-
user.sn = user.uid
|
307
|
-
user.uid_number = uid_number
|
308
|
-
user.gid_number = gid_number
|
309
|
-
user.home_directory = home_directory
|
310
|
-
user.user_password = ActiveLdap::UserPassword.ssha(password)
|
311
|
-
user.see_also = see_also
|
312
|
-
unless config[:simple]
|
313
|
-
user.add_class('shadowAccount', 'inetOrgPerson',
|
314
|
-
'organizationalPerson')
|
315
|
-
user.user_certificate = certificate
|
316
|
-
user.jpeg_photo = jpeg_photo
|
317
|
-
end
|
318
|
-
user.save
|
319
|
-
assert(!user.new_entry?)
|
320
|
-
yield(@user_class.find(user.uid), password)
|
321
|
-
end
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
def make_temporary_group(config={})
|
326
|
-
@group_index += 1
|
327
|
-
cn = config[:cn] || "temp-group#{@group_index}"
|
328
|
-
ensure_delete_group(cn) do
|
329
|
-
gid_number = config[:gid_number] || default_gid
|
330
|
-
_wrap_assertion do
|
331
|
-
assert(!@group_class.exists?(cn))
|
332
|
-
assert_raise(ActiveLdap::EntryNotFound) do
|
333
|
-
@group_class.find(cn)
|
334
|
-
end
|
335
|
-
group = @group_class.new(cn)
|
336
|
-
assert(group.new_entry?)
|
337
|
-
group.gid_number = gid_number
|
338
|
-
assert(group.save)
|
339
|
-
assert(!group.new_entry?)
|
340
|
-
yield(@group_class.find(group.cn))
|
341
|
-
end
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
def ensure_delete_user(uid)
|
346
|
-
yield(uid)
|
347
|
-
ensure
|
348
|
-
if @user_class.exists?(uid)
|
349
|
-
@user_class.search(:value => uid) do |dn, attribute|
|
350
|
-
@user_class.remove_connection(dn)
|
351
|
-
@user_class.delete(dn)
|
352
|
-
end
|
353
|
-
end
|
354
|
-
end
|
355
|
-
|
356
|
-
def ensure_delete_group(cn)
|
357
|
-
yield(cn)
|
358
|
-
ensure
|
359
|
-
@group_class.delete(cn) if @group_class.exists?(cn)
|
360
|
-
end
|
361
|
-
|
362
|
-
def default_uid
|
363
|
-
"10000#{@user_index}"
|
364
|
-
end
|
365
|
-
|
366
|
-
def default_gid
|
367
|
-
"10000#{@group_index}"
|
368
|
-
end
|
369
|
-
end
|
370
|
-
|
371
|
-
module CommandSupport
|
372
|
-
def setup
|
373
|
-
super
|
374
|
-
@fakeroot = "fakeroot"
|
375
|
-
@ruby = File.join(::Config::CONFIG["bindir"],
|
376
|
-
::Config::CONFIG["RUBY_INSTALL_NAME"])
|
377
|
-
@top_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
378
|
-
@examples_dir = File.join(@top_dir, "examples")
|
379
|
-
@lib_dir = File.join(@top_dir, "lib")
|
380
|
-
@ruby_args = [
|
381
|
-
"-I", @examples_dir,
|
382
|
-
"-I", @lib_dir,
|
383
|
-
]
|
384
|
-
end
|
385
|
-
|
386
|
-
def run_command(*args, &block)
|
387
|
-
file = Tempfile.new("al-command-support")
|
388
|
-
file.open
|
389
|
-
file.puts(ActiveLdap::Base.configurations["test"].to_yaml)
|
390
|
-
file.close
|
391
|
-
run_ruby(*[@command, "--config", file.path, *args], &block)
|
392
|
-
end
|
393
|
-
|
394
|
-
def run_ruby(*ruby_args, &block)
|
395
|
-
args = [@ruby, *@ruby_args]
|
396
|
-
args.concat(ruby_args)
|
397
|
-
Command.run(*args, &block)
|
398
|
-
end
|
399
|
-
|
400
|
-
def run_ruby_with_fakeroot(*ruby_args, &block)
|
401
|
-
args = [@fakeroot, @ruby, *@ruby_args]
|
402
|
-
args.concat(ruby_args)
|
403
|
-
Command.run(*args, &block)
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
module MockLogger
|
408
|
-
def make_mock_logger
|
409
|
-
logger = Object.new
|
410
|
-
class << logger
|
411
|
-
def messages(type)
|
412
|
-
@messages ||= {}
|
413
|
-
@messages[type] ||= []
|
414
|
-
@messages[type]
|
415
|
-
end
|
416
|
-
|
417
|
-
def info(content=nil)
|
418
|
-
messages(:info) << (block_given? ? yield : content)
|
419
|
-
end
|
420
|
-
def warn(content=nil)
|
421
|
-
messages(:warn) << (block_given? ? yield : content)
|
422
|
-
end
|
423
|
-
def error(content=nil)
|
424
|
-
messages(:error) << (block_given? ? yield : content)
|
425
|
-
end
|
426
|
-
end
|
427
|
-
logger
|
428
|
-
end
|
429
|
-
|
430
|
-
def with_mock_logger
|
431
|
-
original_logger = ActiveLdap::Base.logger
|
432
|
-
mock_logger = make_mock_logger
|
433
|
-
ActiveLdap::Base.logger = mock_logger
|
434
|
-
yield(mock_logger)
|
435
|
-
ensure
|
436
|
-
ActiveLdap::Base.logger = original_logger
|
437
|
-
end
|
438
|
-
end
|
439
|
-
end
|
data/test/command.rb
DELETED
@@ -1,112 +0,0 @@
|
|
1
|
-
require "thread"
|
2
|
-
require "socket"
|
3
|
-
require "shellwords"
|
4
|
-
|
5
|
-
module Command
|
6
|
-
class Error < StandardError
|
7
|
-
attr_reader :command, :result
|
8
|
-
def initialize(command, result)
|
9
|
-
@command = command
|
10
|
-
@result = result
|
11
|
-
super("#{command}: #{result}")
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
module_function
|
16
|
-
def detach_io
|
17
|
-
require 'fcntl'
|
18
|
-
[TCPSocket, ::File].each do |c|
|
19
|
-
ObjectSpace.each_object(c) do |io|
|
20
|
-
begin
|
21
|
-
unless io.closed?
|
22
|
-
io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
23
|
-
end
|
24
|
-
rescue SystemCallError,IOError => e
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def run(cmd, *args, &block)
|
31
|
-
raise ArgumentError, "command isn't specified" if cmd.nil?
|
32
|
-
if args.any? {|x| x.nil?}
|
33
|
-
raise ArgumentError, "args has nil: #{args.inspect}"
|
34
|
-
end
|
35
|
-
return java_run(cmd, *args, &block) if Object.respond_to?(:java)
|
36
|
-
in_r, in_w = IO.pipe
|
37
|
-
out_r, out_w = IO.pipe
|
38
|
-
pid = exit_status = nil
|
39
|
-
Thread.exclusive do
|
40
|
-
verbose = $VERBOSE
|
41
|
-
# ruby(>=1.8)'s fork terminates other threads with warning messages
|
42
|
-
$VERBOSE = nil
|
43
|
-
pid = fork do
|
44
|
-
$VERBOSE = verbose
|
45
|
-
detach_io
|
46
|
-
out = STDERR.dup
|
47
|
-
STDIN.reopen(in_r)
|
48
|
-
in_r.close
|
49
|
-
STDOUT.reopen(out_w)
|
50
|
-
STDERR.reopen(out_w)
|
51
|
-
out_w.close
|
52
|
-
exec(cmd, *args.collect {|arg| arg.to_s})
|
53
|
-
exit!(-1)
|
54
|
-
end
|
55
|
-
$VERBOSE = verbose
|
56
|
-
end
|
57
|
-
yield(out_r, in_w) if block_given?
|
58
|
-
in_r.close unless in_r.closed?
|
59
|
-
out_w.close unless out_w.closed?
|
60
|
-
pid, status = Process.waitpid2(pid)
|
61
|
-
[status.exited? && status.exitstatus.zero?, out_r.read]
|
62
|
-
end
|
63
|
-
|
64
|
-
def java_run(cmd, *args, &block)
|
65
|
-
runtime = java.lang.Runtime.get_runtime
|
66
|
-
process = runtime.exec([cmd, *args].to_java(:string))
|
67
|
-
input = JavaReaderWrapper.new(process.get_input_stream)
|
68
|
-
output = JavaWriterWrapper.new(process.get_output_stream)
|
69
|
-
error = JavaReaderWrapper.new(process.get_error_stream)
|
70
|
-
yield(input, output) if block_given?
|
71
|
-
output.close
|
72
|
-
success = process.wait_for.zero?
|
73
|
-
|
74
|
-
[success, input.read + error.read]
|
75
|
-
end
|
76
|
-
|
77
|
-
class JavaReaderWrapper
|
78
|
-
def initialize(input)
|
79
|
-
@input = input
|
80
|
-
end
|
81
|
-
|
82
|
-
def read
|
83
|
-
result = ""
|
84
|
-
while (c = @input.read) != -1
|
85
|
-
result << c.chr
|
86
|
-
end
|
87
|
-
result
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
class JavaWriterWrapper
|
92
|
-
def initialize(output)
|
93
|
-
output = java.io.OutputStreamWriter.new(output)
|
94
|
-
@output = java.io.BufferedWriter.new(output)
|
95
|
-
end
|
96
|
-
|
97
|
-
def puts(*messages)
|
98
|
-
messages.each do |message|
|
99
|
-
message += "\n" if /\n/ !~ message
|
100
|
-
@output.write(message)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def flush
|
105
|
-
@output.flush
|
106
|
-
end
|
107
|
-
|
108
|
-
def close
|
109
|
-
@output.close
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|