jruby-win32ole 0.8.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.
Files changed (47) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +4 -0
  3. data/README +0 -0
  4. data/Rakefile +8 -0
  5. data/VERSION +1 -0
  6. data/bin/make_data.rb +12 -0
  7. data/bin/sample +11 -0
  8. data/build.xml +74 -0
  9. data/jruby-win32ole.gemspec +21 -0
  10. data/lib/jruby-win32ole.rb +39 -0
  11. data/lib/jruby-win32ole/version.rb +5 -0
  12. data/lib/racob-x64.dll +0 -0
  13. data/lib/racob-x86.dll +0 -0
  14. data/lib/racob.jar +0 -0
  15. data/lib/win32ole/utils.rb +230 -0
  16. data/lib/win32ole/win32ole.jar +0 -0
  17. data/lib/win32ole/win32ole_error.rb +13 -0
  18. data/lib/win32ole/win32ole_event.rb +38 -0
  19. data/lib/win32ole/win32ole_method.rb +135 -0
  20. data/lib/win32ole/win32ole_param.rb +45 -0
  21. data/lib/win32ole/win32ole_ruby.rb +115 -0
  22. data/lib/win32ole/win32ole_type.rb +148 -0
  23. data/lib/win32ole/win32ole_typelib.rb +76 -0
  24. data/lib/win32ole/win32ole_variable.rb +41 -0
  25. data/lib/win32ole/win32ole_variant.rb +52 -0
  26. data/nbproject/build-impl.xml +800 -0
  27. data/nbproject/genfiles.properties +8 -0
  28. data/nbproject/private/config.properties +0 -0
  29. data/nbproject/private/private.properties +8 -0
  30. data/nbproject/private/private.xml +4 -0
  31. data/nbproject/project.properties +71 -0
  32. data/nbproject/project.xml +14 -0
  33. data/samples/browser_connect.rb +10 -0
  34. data/samples/const_load.rb +10 -0
  35. data/samples/dir_enum_bench.rb +24 -0
  36. data/samples/dispatch_bench.rb +44 -0
  37. data/samples/file_system_object.rb +7 -0
  38. data/samples/fs.rb +50 -0
  39. data/samples/ie_plus_events.rb +45 -0
  40. data/samples/ie_simple.rb +20 -0
  41. data/samples/ie_simple_clsid.rb +13 -0
  42. data/samples/sbem.rb +11 -0
  43. data/samples/small_enum_bench.rb +126 -0
  44. data/src/org/jruby/ext/win32ole/RubyInvocationProxy.java +34 -0
  45. data/src/org/jruby/ext/win32ole/RubyWIN32OLE.java +278 -0
  46. data/src/win32ole/Win32oleService.java +29 -0
  47. metadata +113 -0
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *~
2
+ output
3
+ pkg/*
4
+ build/*
5
+ dist/*
6
+ *.gem
7
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in jruby-win32ole.gemspec
4
+ gemspec
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ task :compile do
5
+ require 'ant'
6
+ ant ['-f', 'build.xml']
7
+ cp 'dist/win32ole.jar', 'lib/win32ole/win32ole.jar'
8
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.8.0
data/bin/make_data.rb ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fileutils'
4
+
5
+ number_of_files = 1_000
6
+ directory = "c:/opt/test_data"
7
+
8
+ Dir.mkdir directory unless File.exists? directory
9
+ number_of_files.times do |i|
10
+ file = directory + "/" + i.to_s
11
+ FileUtils.touch file
12
+ end
data/bin/sample ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/sh
2
+
3
+ #jruby --server -J-Xdebug -J-Xrunjdwp:transport=dt_socket,address=8001,server=y,suspend=y -J-Djava.library.path=lib -Ilib samples/$1.rb
4
+ #jruby --server -J-Dcom.jacob.debug=true -J-Djava.library.path=lib -Ilib samples/$1.rb
5
+ #jruby --server -J-agentlib:hprof=heap=dump -J-Djava.library.path=lib -Ilib samples/$1.rb
6
+ #jruby --server -J-verbose:gc -J-Djava.library.path=lib -Ilib samples/$1.rb
7
+ #jruby --server -J-agentpath:"C:\Program Files\NetBeans 6.8\profiler3\lib\deployed\jdk15\windows\profilerinterface.dll=\"C:\Program Files\NetBeans 6.8\profiler3\lib\"",5140 -J-Djava.library.path=lib -Ilib samples/$1.rb
8
+
9
+ jruby -J-verbose:gc -J-Dcom.jacob.autogc=true -J-Dcom.jacob.gc_count=50000 -J-Dcom.jacob.debug=true -J-Djruby.backtrace.style=raw --server -J-Djava.library.path=lib -Ilib samples/$1.rb $2 $3
10
+
11
+ #jruby -J-Dcom.jacob.autogc=false -J-Dcom.jacob.debug=true -J-Djruby.backtrace.style=raw -J-Dcom.jacob.autogc=true -J-Djruby.ji.objectProxyCache=false --server -J-Djava.library.path=. -Idist samples/$1.rb $2 $3
data/build.xml ADDED
@@ -0,0 +1,74 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- You may freely edit this file. See commented blocks below for -->
3
+ <!-- some examples of how to customize the build. -->
4
+ <!-- (If you delete it and reopen the project it will be recreated.) -->
5
+ <!-- By default, only the Clean and Build commands use this build script. -->
6
+ <!-- Commands such as Run, Debug, and Test only use this build script if -->
7
+ <!-- the Compile on Save feature is turned off for the project. -->
8
+ <!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
9
+ <!-- in the project's Project Properties dialog box.-->
10
+ <project name="win32ole" default="default" basedir=".">
11
+ <description>Builds, tests, and runs the project win32ole.</description>
12
+ <import file="nbproject/build-impl.xml"/>
13
+ <!--
14
+
15
+ There exist several targets which are by default empty and which can be
16
+ used for execution of your tasks. These targets are usually executed
17
+ before and after some main targets. They are:
18
+
19
+ -pre-init: called before initialization of project properties
20
+ -post-init: called after initialization of project properties
21
+ -pre-compile: called before javac compilation
22
+ -post-compile: called after javac compilation
23
+ -pre-compile-single: called before javac compilation of single file
24
+ -post-compile-single: called after javac compilation of single file
25
+ -pre-compile-test: called before javac compilation of JUnit tests
26
+ -post-compile-test: called after javac compilation of JUnit tests
27
+ -pre-compile-test-single: called before javac compilation of single JUnit test
28
+ -post-compile-test-single: called after javac compilation of single JUunit test
29
+ -pre-jar: called before JAR building
30
+ -post-jar: called after JAR building
31
+ -post-clean: called after cleaning build products
32
+
33
+ (Targets beginning with '-' are not intended to be called on their own.)
34
+
35
+ Example of inserting an obfuscator after compilation could look like this:
36
+
37
+ <target name="-post-compile">
38
+ <obfuscate>
39
+ <fileset dir="${build.classes.dir}"/>
40
+ </obfuscate>
41
+ </target>
42
+
43
+ For list of available properties check the imported
44
+ nbproject/build-impl.xml file.
45
+
46
+
47
+ Another way to customize the build is by overriding existing main targets.
48
+ The targets of interest are:
49
+
50
+ -init-macrodef-javac: defines macro for javac compilation
51
+ -init-macrodef-junit: defines macro for junit execution
52
+ -init-macrodef-debug: defines macro for class debugging
53
+ -init-macrodef-java: defines macro for class execution
54
+ -do-jar-with-manifest: JAR building (if you are using a manifest)
55
+ -do-jar-without-manifest: JAR building (if you are not using a manifest)
56
+ run: execution of project
57
+ -javadoc-build: Javadoc generation
58
+ test-report: JUnit report generation
59
+
60
+ An example of overriding the target for project execution could look like this:
61
+
62
+ <target name="run" depends="win32ole-impl.jar">
63
+ <exec dir="bin" executable="launcher.exe">
64
+ <arg file="${dist.jar}"/>
65
+ </exec>
66
+ </target>
67
+
68
+ Notice that the overridden target depends on the jar target and not only on
69
+ the compile target as the regular run target does. Again, for a list of available
70
+ properties which you can use, check the target you are overriding in the
71
+ nbproject/build-impl.xml file.
72
+
73
+ -->
74
+ </project>
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "jruby-win32ole/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'jruby-win32ole'
7
+ s.version = JRuby::WIN32OLE::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = 'Thomas E. Enebo'
10
+ s.email = 'tom.enebo@gmail.com'
11
+ s.homepage = 'http://github.com/enebo/jruby-win32ole'
12
+ s.summary = %q{A Gem for win32ole support on JRuby}
13
+ s.description = %q{A Gem for win32ole support on JRuby}
14
+
15
+ s.rubyforge_project = "jruby-win32ole"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,39 @@
1
+ require 'java'
2
+
3
+ # Set location so the loader can find the native dll it needs
4
+ arch = ENV_JAVA['sun.arch.data.model'] == '32' ? 'x86' : 'x64'
5
+ java.lang.System.set_property 'racob.dll.path',
6
+ File.dirname(__FILE__) + "/racob-#{arch}.dll"
7
+
8
+ require 'racob.jar'
9
+
10
+ require 'win32ole/win32ole' # <- java native impl of WIN32OLE
11
+ require 'win32ole/win32ole_ruby' # <- ruby impl of WIN32OLE
12
+
13
+ java_import java.util.Calendar
14
+
15
+ java_import org.racob.com.Variant
16
+ java_import org.racob.com.Automation
17
+ java_import org.racob.com.ComFailException
18
+ java_import org.racob.com.ComThread
19
+ java_import org.racob.com.Dispatch
20
+ java_import org.racob.com.DispatchEvents
21
+ java_import org.racob.com.EnumVariant
22
+ java_import org.racob.com.FuncDesc
23
+ java_import org.racob.com.TypeInfo
24
+ java_import org.racob.com.TypeLib
25
+ java_import org.racob.com.VarDesc
26
+ java_import org.racob.com.VariantUtilities
27
+
28
+ java_import org.jruby.ext.win32ole.RubyWIN32OLE
29
+ java_import org.jruby.ext.win32ole.RubyInvocationProxy
30
+
31
+
32
+ require 'win32ole/win32ole_error'
33
+ require 'win32ole/win32ole_method'
34
+ require 'win32ole/win32ole_variant'
35
+ require 'win32ole/win32ole_variable'
36
+ require 'win32ole/win32ole_event'
37
+ require 'win32ole/win32ole_param'
38
+ require 'win32ole/win32ole_type'
39
+ require 'win32ole/win32ole_typelib'
@@ -0,0 +1,5 @@
1
+ module JRuby
2
+ module WIN32OLE
3
+ VERSION = "0.8.0"
4
+ end
5
+ end
data/lib/racob-x64.dll ADDED
Binary file
data/lib/racob-x86.dll ADDED
Binary file
data/lib/racob.jar ADDED
Binary file
@@ -0,0 +1,230 @@
1
+ require 'win32ole/win32ole_variant'
2
+
3
+ class WIN32OLE
4
+ module Utils
5
+ # FIXME: I don't know specifically if this is a GMT or local date?
6
+ OUT_OF_RANGE_DATE = Time.local(1899, 12, 30)
7
+
8
+ def SafeStringValue(str)
9
+ return str if str.kind_of?(::String)
10
+ if str.respond_to?(:to_str)
11
+ str = str.to_str
12
+ return str if str.kind_of?(::String)
13
+ end
14
+ raise TypeError
15
+ end
16
+
17
+ def WIN32OLE_TYPEValue(value)
18
+ raise TypeError.new("1st argument should be WIN32OLE_TYPE object") unless value.kind_of? WIN32OLE_TYPE
19
+ value
20
+ end
21
+
22
+ # Convert the supplied variant value to an equivalent Ruby value.
23
+ # If dispose is true then also dispose the variant itself.
24
+ def from_variant(value)
25
+ object = VariantUtilities.variant_to_object(value)
26
+ case object
27
+ when Dispatch then
28
+ object = WIN32OLE.new(object)
29
+ when java.util.Date then
30
+ object = java_date2ruby_time(object)
31
+ end
32
+
33
+ # Jacob will return null on out of bound dates whereas MRI returns
34
+ # some date windows normally returns. We will match this.
35
+ if object.nil? && !value.nil?
36
+ case value.getvt
37
+ when Variant::VariantDate, (Variant::VariantDate|Variant::VariantByref) then
38
+ object = OUT_OF_RANGE_DATE
39
+
40
+ end
41
+ end
42
+
43
+ object
44
+ end
45
+
46
+ # Simliar to MRI:vtdate2rbtime but we work with Java date instead of
47
+ # raw variant type
48
+ def java_date2ruby_time(date)
49
+ calendar = Calendar.get_instance
50
+ calendar.time = date
51
+
52
+ Time.local(calendar.get(Calendar::YEAR),
53
+ calendar.get(Calendar::MONTH),
54
+ calendar.get(Calendar::DAY_OF_MONTH),
55
+ calendar.get(Calendar::HOUR_OF_DAY),
56
+ calendar.get(Calendar::MINUTE),
57
+ calendar.get(Calendar::SECOND))
58
+ end
59
+
60
+ def methods_with_flag(flag)
61
+ members = []
62
+ all_methods(typeinfo_from_ole) do |typeinfo, old_typeinfo, desc, docs, i|
63
+ if desc.invkind & flag
64
+ members << WIN32OLE_METHOD.new(nil, typeinfo, old_typeinfo, desc, docs, i)
65
+ end
66
+ nil
67
+ end
68
+ members
69
+ end
70
+
71
+ def all_methods(typeinfo, &block) # MRI: olemethod_from_typeinfo
72
+ return unless typeinfo # Not all ole servers have this info
73
+
74
+ # Find method in this type.
75
+ ret = find_all_methods_in(nil, typeinfo, &block)
76
+ return ret if ret
77
+
78
+ # Now check all other type impls
79
+ typeinfo.impl_types_count.times do |i|
80
+ begin
81
+ href = typeinfo.get_ref_type_of_impl_type(i)
82
+ ref_typeinfo = typeinfo.get_ref_type_info(href)
83
+ ret = find_all_methods_in(typeinfo, ref_typeinfo, &block)
84
+ return ret if ret
85
+ rescue ComFailException => e
86
+ puts "Error getting impl types #{e}"
87
+ end
88
+ end
89
+ nil
90
+ end
91
+
92
+ # MRI: ole_method_sub
93
+ def find_all_methods_in(old_typeinfo, typeinfo, &block)
94
+ typeinfo.funcs_count.times do |i|
95
+ begin
96
+ desc = typeinfo.get_func_desc(i)
97
+ docs = typeinfo.get_documentation(desc.memid)
98
+ ret = yield typeinfo, old_typeinfo, desc, docs, i
99
+ return ret if ret
100
+ rescue ComFailException => e
101
+ puts "Error getting method info #{e}"
102
+ end
103
+ end
104
+ nil
105
+ end
106
+
107
+ def typeinfo_from_ole # MRI: typeinfo_from_ole
108
+ typeinfo = type_info
109
+ docs = typeinfo.get_documentation(-1)
110
+ type_lib = typeinfo.get_containing_type_lib
111
+ type_lib.get_type_info_count.times do |i|
112
+ begin
113
+ tdocs = type_lib.get_documentation(i)
114
+ return type_lib.get_type_info(i) if tdocs.name == docs.name
115
+ rescue ComFailException => e
116
+ # We continue on failure.
117
+ end
118
+ end
119
+ type_info # Actually MRI seems like it could fail in weird case
120
+ end
121
+
122
+ def load_typelib(path_reg, arch)
123
+ path = path_reg.open(arch) { |r| r.read(nil) }[1]
124
+ # puts "PATH = #{path}"
125
+ begin
126
+ Automation.loadTypeLib(path)
127
+ rescue ComFailException => e
128
+ # puts "Failed to load #{name} fom #{path} because: #{e}"
129
+ nil
130
+ end
131
+ end
132
+
133
+ def find_all_typeinfo(typelib)
134
+ typelib.type_info_count.times do |i|
135
+ docs = typelib.get_documentation(i)
136
+ next unless docs
137
+ info = typelib.get_type_info(i)
138
+ next unless info
139
+ yield info, docs
140
+ end
141
+ end
142
+
143
+ def all_vars(typeinfo)
144
+ typeinfo.vars_count.times do |i|
145
+ desc = typeinfo.get_var_desc(i)
146
+ next unless desc
147
+ names = typeinfo.get_names(desc.memid)
148
+ next if !names || names.length == 0
149
+ name = names[0]
150
+ next unless name
151
+ yield desc, name
152
+ end
153
+ end
154
+
155
+ def reg_each_key_for(reg, subkey, &block)
156
+ reg.open(subkey) do |subkey_reg|
157
+ subkey_reg.each_key { |key, wtime| block.call(subkey_reg, key) }
158
+ end
159
+ end
160
+
161
+ # Walks all guid/clsid entries and yields every single version
162
+ # of those entries to the supplied block. See search_registry as
163
+ # an example of its usage.
164
+ def typelib_registry_each_guid_version
165
+ Win32::Registry::HKEY_CLASSES_ROOT.open('TypeLib') do |reg|
166
+ reg.each_key do |guid, wtime|
167
+ reg.open(guid) do |guid_reg|
168
+ guid_reg.each_key do |version_string, wtime|
169
+ version = version_string.to_f
170
+ begin
171
+ guid_reg.open(version_string) do |version_reg|
172
+ yield guid, version, version_reg
173
+ end
174
+ rescue Win32::Registry::Error => e
175
+ # Version Entry may not contain anything. Skip.
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ def registry_subkey(reg, *valid_subkeys)
184
+ reg.each_key do |inner, wtime|
185
+ reg_each_key_for(reg, inner) do |subkey_reg, subkey|
186
+ yield subkey_reg, subkey if valid_subkeys.include? subkey
187
+ end
188
+ end
189
+ end
190
+
191
+ def search_registry(typelib_name) # MRI: oletypelib_search_registry
192
+ typelib_registry_each_guid_version do |guid, version, reg|
193
+ name = reg.read(nil)[1] || ''
194
+ registry_subkey(reg, 'win32', 'win64') do |arch_reg, arch|
195
+ type_lib = load_typelib(arch_reg, arch)
196
+ # puts "GUID #{guid} #{version} #{arch} #{type_lib}"
197
+ return type_lib if type_lib && name == typelib_name
198
+ end
199
+ end
200
+ nil
201
+ end
202
+
203
+ def typedesc_value(vt, type_details=nil)
204
+ type_string = WIN32OLE::VARIANT.variant_to_string(vt) || "Unknown Type #{vt}"
205
+
206
+ type_details << type_string if type_details
207
+
208
+ if vt == WIN32OLE::VARIANT::VT_PTR && type_details
209
+ # TODO: Add detail logic
210
+ end
211
+
212
+ type_details ? type_details : type_string
213
+ end
214
+
215
+ def variable_kind_string(varkind)
216
+ case varkind
217
+ when VarDesc::VAR_PERINSTANCE then
218
+ "PERINSTANCE"
219
+ when VarDesc::VAR_STATIC then
220
+ "STATIC"
221
+ when VarDesc::VAR_CONST then
222
+ "CONSTANT"
223
+ when VarDesc::VAR_DISPATCH then
224
+ "DISPATCH"
225
+ else
226
+ "UNKNOWN"
227
+ end
228
+ end
229
+ end
230
+ end
Binary file
@@ -0,0 +1,13 @@
1
+ class WIN32OLERuntimeError < RuntimeError
2
+ def initialize(cause=nil)
3
+ @cause = cause
4
+ end
5
+
6
+ def backtrace
7
+ @cause ? @cause.backtrace : super
8
+ end
9
+
10
+ def to_s
11
+ @cause ? @cause.to_s : super
12
+ end
13
+ end