cheri 0.0.2

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 (79) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README +98 -0
  3. data/Rakefile +121 -0
  4. data/examples/hello_world_1.rb +28 -0
  5. data/examples/table_1.rb +44 -0
  6. data/lib/cheri/awt.rb +41 -0
  7. data/lib/cheri/builder.rb +31 -0
  8. data/lib/cheri/builder/awt/connecter.rb +63 -0
  9. data/lib/cheri/builder/awt/constants.rb +1003 -0
  10. data/lib/cheri/builder/awt/main.rb +191 -0
  11. data/lib/cheri/builder/awt/types.rb +220 -0
  12. data/lib/cheri/builder/base.rb +533 -0
  13. data/lib/cheri/builder/config.rb +187 -0
  14. data/lib/cheri/builder/connecter.rb +386 -0
  15. data/lib/cheri/builder/context.rb +655 -0
  16. data/lib/cheri/builder/generator.rb +425 -0
  17. data/lib/cheri/builder/html/charsets.rb +154 -0
  18. data/lib/cheri/builder/html/common.rb +32 -0
  19. data/lib/cheri/builder/html/connecter.rb +57 -0
  20. data/lib/cheri/builder/html/element.rb +156 -0
  21. data/lib/cheri/builder/html/main.rb +116 -0
  22. data/lib/cheri/builder/html/types.rb +123 -0
  23. data/lib/cheri/builder/main.rb +483 -0
  24. data/lib/cheri/builder/swing/connecter.rb +141 -0
  25. data/lib/cheri/builder/swing/constants.rb +420 -0
  26. data/lib/cheri/builder/swing/main.rb +446 -0
  27. data/lib/cheri/builder/swing/types.rb +270 -0
  28. data/lib/cheri/builder/xml/charsets.rb +154 -0
  29. data/lib/cheri/builder/xml/common.rb +32 -0
  30. data/lib/cheri/builder/xml/connecter.rb +42 -0
  31. data/lib/cheri/builder/xml/element.rb +189 -0
  32. data/lib/cheri/builder/xml/main.rb +130 -0
  33. data/lib/cheri/builder/xml/types.rb +36 -0
  34. data/lib/cheri/cheri.rb +70 -0
  35. data/lib/cheri/cjx.rb +3 -0
  36. data/lib/cheri/explorer.rb +32 -0
  37. data/lib/cheri/explorer/explorer.rb +560 -0
  38. data/lib/cheri/html.rb +31 -0
  39. data/lib/cheri/image/Delete24.gif +0 -0
  40. data/lib/cheri/image/Find24.gif +0 -0
  41. data/lib/cheri/image/FindAgain24.gif +0 -0
  42. data/lib/cheri/image/Refresh24.gif +0 -0
  43. data/lib/cheri/image/Search24.gif +0 -0
  44. data/lib/cheri/image/Thumbs.db +0 -0
  45. data/lib/cheri/image/cheri_icon_16x16.png +0 -0
  46. data/lib/cheri/image/cheri_icon_24x24.png +0 -0
  47. data/lib/cheri/image/cheri_logo_medium.png +0 -0
  48. data/lib/cheri/image/close_10x10.png +0 -0
  49. data/lib/cheri/image/close_10x10s.png +0 -0
  50. data/lib/cheri/image/close_12x12.png +0 -0
  51. data/lib/cheri/image/close_14x14.png +0 -0
  52. data/lib/cheri/image/close_24x24.png +0 -0
  53. data/lib/cheri/image/close_dim2_12x12.png +0 -0
  54. data/lib/cheri/image/close_dim_12x12.png +0 -0
  55. data/lib/cheri/image/cls_tree.png +0 -0
  56. data/lib/cheri/image/con_tree.png +0 -0
  57. data/lib/cheri/image/jruby_14x16.png +0 -0
  58. data/lib/cheri/image/jruby_logo.png +0 -0
  59. data/lib/cheri/image/mod_tree.png +0 -0
  60. data/lib/cheri/image/obj_tree.png +0 -0
  61. data/lib/cheri/image/ruby_16x16.png +0 -0
  62. data/lib/cheri/image/vars_tree.png +0 -0
  63. data/lib/cheri/java.rb +26 -0
  64. data/lib/cheri/java/builder.rb +28 -0
  65. data/lib/cheri/java/builder/main.rb +407 -0
  66. data/lib/cheri/java/builder/util.rb +480 -0
  67. data/lib/cheri/java/java.rb +56 -0
  68. data/lib/cheri/jruby.rb +32 -0
  69. data/lib/cheri/jruby/explorer.rb +43 -0
  70. data/lib/cheri/jruby/explorer/common.rb +38 -0
  71. data/lib/cheri/jruby/explorer/dialogs.rb +383 -0
  72. data/lib/cheri/jruby/explorer/explorer.rb +904 -0
  73. data/lib/cheri/jruby/explorer/splash.rb +80 -0
  74. data/lib/cheri/jruby/explorer/viewer.rb +619 -0
  75. data/lib/cheri/jruby/explorer/viewers.rb +1057 -0
  76. data/lib/cheri/jruby/jruby.rb +59 -0
  77. data/lib/cheri/swing.rb +41 -0
  78. data/lib/cheri/xml.rb +31 -0
  79. metadata +135 -0
@@ -0,0 +1,480 @@
1
+ #--
2
+ # Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+ #
24
+
25
+ module Cheri
26
+ module Java
27
+ module Builder
28
+
29
+ module Util
30
+ class << self
31
+ #:stopdoc:
32
+ S = 'set'
33
+ G = 'get'
34
+ I = 'is'
35
+ U = '_'
36
+ #:startdoc:
37
+
38
+ # call-seq:
39
+ # Util.uf('str') -> 'Str'
40
+ # Util.upper_first('str') -> 'Str'
41
+ #
42
+ # Like String#capitalize, but only alters the first character, so
43
+ # Util.upper_first('abCdeF') -> 'AbCdeF'.
44
+ def uf(y)
45
+ s = y.to_s
46
+ s[0] = s[0,1].upcase[0] unless s.empty?
47
+ s
48
+ end
49
+ alias_method :upper_first, :uf
50
+
51
+ # call-seq:
52
+ # Util.cc('my_string') -> 'MyString'
53
+ # Util.camel_case('my_string') -> 'MyString'
54
+ # Util.upper_camel_case('my_string') -> 'MyString'
55
+ #
56
+ # create upper-camel-case string
57
+ def cc(sym)
58
+ s = String === sym ? sym.dup : sym.to_s
59
+ if s.index(?_)
60
+ s.split(U).collect do |n| uf(n); end.join
61
+ else
62
+ # preserve existing camel-case, just force first char to upper
63
+ uf(s)
64
+ end
65
+ end
66
+ alias_method :camel_case, :cc #:nodoc:
67
+ alias_method :upper_camel_case, :cc #:nodoc:
68
+
69
+ # call-seq:
70
+ # Util.lcc('my_string') -> 'myString'
71
+ # Util.lower_camel_case('my_string') -> 'myString'
72
+ #
73
+ def lcc(str)
74
+ s = String === str ? str.dup : str.to_s
75
+ # get lower-camel-case method name
76
+ a = s.split(U)
77
+ a.each_index do |i| a[i].capitalize! if i > 0; end.join
78
+ end
79
+ alias_method :lower_camel_case, :lcc #:nodoc:
80
+
81
+ def setter?(s)
82
+ s.to_s.rindex(S,0)
83
+ end
84
+ alias_method :is_setter, :setter?
85
+
86
+ def getter?(s)
87
+ s.to_s.rindex(G,0)
88
+ end
89
+ alias_method :is_getter, :getter?
90
+
91
+ def iser?(s)
92
+ (s = s.to_s).rindex(I,0) || ?? == s[-1]
93
+ end
94
+ alias_method :is_iser, :iser?
95
+
96
+ def acc?(s)
97
+ (c = (s = s.to_s)[-1]) == ?= || c == ?? || s.rindex(G,0) || s.rindex(S,0) || s.rindex(I,0)
98
+ end
99
+ alias_method :is_accessor, :acc?
100
+
101
+ def setter(y)
102
+ :"set#{cc(y)}"
103
+ end
104
+ alias_method :make_setter, :setter
105
+
106
+ def getter(y)
107
+ :"get#{cc(y)}"
108
+ end
109
+ alias_method :make_getter, :getter
110
+
111
+ def iser(y)
112
+ :"is#{cc(y)}"
113
+ end
114
+ alias_method :make_iser, :iser
115
+
116
+ # symbols are considered constants if the first
117
+ # character is capitalized
118
+ def const?(s)
119
+ (c = s.to_s[0]) >= ?A && c <= ?Z
120
+ end
121
+ alias_method :is_constant, :const?
122
+ end #self
123
+ end #Util
124
+
125
+ module Interfaces
126
+ #:stopdoc:
127
+ CJava = Cheri::Java
128
+ #:startdoc:
129
+ ListenerInfo = Struct.new(:clazz, :methods, :add_method_name)
130
+ @impls = {}
131
+ class << self
132
+ def get_listener_impl(info)
133
+ @impls[info.clazz] ||= create_listener_impl(info)
134
+ end
135
+ def create_listener_impl(info)
136
+ # TODO: logic to deal with JRuby pre-1.0.0, remove later
137
+ if (clazz = info.clazz).instance_of?(Module)
138
+ impl = Class.new do
139
+ include clazz
140
+ end
141
+ else
142
+ impl = Class.new(clazz)
143
+ end
144
+ info.methods.each do |m|
145
+ n = m.name
146
+ impl.module_eval <<-EOM
147
+ def #{n}=(blk)
148
+ @#{n} = blk
149
+ end
150
+ def #{n}(e)
151
+ @#{n}.call(e) if @#{n}
152
+ end
153
+ EOM
154
+ end
155
+ impl
156
+ end
157
+ def get_listener_info(java_class,method_name)
158
+ java_class.java_instance_methods.each do |m|
159
+ if m.name.match(/add(\w+)Listener/) &&
160
+ m.argument_types.length == 1 &&
161
+ m.argument_types[0].name.match(/([\w|.]+)Listener/)
162
+ clazz = m.argument_types[0]
163
+ methods = clazz.java_instance_methods
164
+ methods.each do |im|
165
+ if im.name == method_name
166
+ return ListenerInfo.new(CJava.get_class(clazz.name),methods,m.name)
167
+ end
168
+ end
169
+ end
170
+ end
171
+ nil
172
+ end
173
+ end # self
174
+ end #Interfaces
175
+
176
+ # TODO: leftover from JRBuilder, rethink for Cheri
177
+
178
+ module Constants
179
+ #:stopdoc:
180
+ CJava = Cheri::Java
181
+ #:startdoc:
182
+ class ConstRec
183
+ def initialize(t,d,n=nil)
184
+ @t = t
185
+ @d = d
186
+ @n = n if n
187
+ end
188
+ def type_cls
189
+ @t
190
+ end
191
+ def decl_cls
192
+ @d
193
+ end
194
+ def next_rec
195
+ @n
196
+ end
197
+ def next_rec=(n)
198
+ @n = n
199
+ end
200
+ end
201
+ @method_cache = {}
202
+ class << self
203
+ def resolve_ctor(clazz,args,constants)
204
+ return true if args.empty?
205
+ # try the simple resolve first
206
+ const_arr = simple_resolve(clazz,args)
207
+ return true unless const_arr
208
+ # check against constructor argument types
209
+ argc = args.length
210
+ key = "#{clazz.java_class.name}##{argc}"
211
+ ctor_args = @method_cache[key]
212
+ unless ctor_args
213
+ ctor_args = []
214
+ clazz.java_class.constructors.each do |ctor|
215
+ ctor_args << ctor.argument_types if ctor.arity == argc
216
+ end
217
+ @method_cache[key] = ctor_args
218
+ end
219
+ if ctor_args.empty?
220
+ raise NoMethodError,"No constructor found for class '#{clazz.java_class.name} with argument count #{argc}"
221
+ end
222
+ arg_type_resolve(clazz,const_arr,ctor_args,args,constants)
223
+ end
224
+
225
+ def resolve_meth(clazz,method_name,args,constants)
226
+ return true if args.empty?
227
+ # try the simple resolve first
228
+ const_arr = simple_resolve(clazz,args)
229
+ return true unless const_arr
230
+ argc = args.length
231
+ cased_method_name = Util.lcc(method_name)
232
+ key = "#{clazz.java_class.name}##{cased_method_name}##{argc}"
233
+ method_args = @method_cache[key]
234
+ unless method_args
235
+ method_args = []
236
+ clazz.java_class.java_instance_methods.each do |method|
237
+ if method.arity == argc && method.name == cased_method_name
238
+ method_args << method.argument_types
239
+ end
240
+ end
241
+ @method_cache[key] = method_args
242
+ end
243
+ if method_args.empty?
244
+ raise NoMethodError,"No method '#{method_name}' found in class '#{clazz.java_class.name} with argument count #{argc}"
245
+ end
246
+ arg_type_resolve(clazz,const_arr,method_args,args,constants)
247
+ end
248
+
249
+ private
250
+ def simple_resolve(clazz,args)
251
+ ca = nil
252
+ 0.upto(args.length-1) do |i|
253
+ a = args[i]
254
+ next unless const?(a)
255
+ begin
256
+ # try the easy lookup on this class first
257
+ args[i] = clazz.const_get(a)
258
+ rescue
259
+ (ca ||= []) << [a,i,nil]
260
+ end
261
+ end
262
+ ca
263
+ end
264
+
265
+ private
266
+
267
+ Strong = 3
268
+ Weak = 2
269
+ def arg_type_resolve(obj_cls,const_arr,target_args,args,constants)
270
+ # first whittle it down on regular args
271
+ argc = args.length
272
+ # skip this step if all args are constants, or if
273
+ # there is only one ctor/method
274
+ unless argc == const_arr.length || target_args.length == 1
275
+ 0.upto(argc-1) do |i|
276
+ arg = args[i]
277
+ next if const?(arg)
278
+ (target_args.length - 1).downto(0) do |t|
279
+ arg_type_arr = target_args[t]
280
+ unless Types.type_matches_arg(arg_type_arr[i],arg)
281
+ target_args.delete_at(t)
282
+ if target_args.empty?
283
+ raise NoMethodError,"No matching method/constructor for args [#{args.join(', ')}], class #{obj_cls}"
284
+ end
285
+ end
286
+ end
287
+ end
288
+ end
289
+
290
+ matches = Array.new(target_args.length) {
291
+ Array.new(const_arr.length) {
292
+ Array.new(2) }}
293
+ # for each :CONSTANT found in args,
294
+ 0.upto(const_arr.length - 1) do |c|
295
+ # the :CONSTANT symbol
296
+ const_sym = const_arr[c][0]
297
+ # the position of the :CONSTANT in args
298
+ i = const_arr[c][1]
299
+ # for each ctor/method
300
+ (target_args.length - 1).downto(0) do |t|
301
+ # the expected type of the ith arg
302
+ target_type = target_args[t][i]
303
+ # first, see if the target type defines the :CONSTANT
304
+ begin
305
+ ttcls = CJava.get_class(target_type.name)
306
+ value = ttcls.const_get(const_sym)
307
+ if Types.type_matches_arg(target_type,value)
308
+ matches[t][c][0] = Strong
309
+ matches[t][c][1] = value
310
+ # strong match, no need to check the cached values
311
+ next
312
+ end
313
+ rescue
314
+ end
315
+ # go through the constant defs, and take the first
316
+ # one that matches
317
+ # TODO: check package names and give preference to
318
+ # the definition that occurs in the same package
319
+ # (or nearest package, longest match on pkg name?)
320
+ found_match = false
321
+ rec_arr = constants.get(const_arr[c][0])
322
+ if rec_arr
323
+ 0.upto(rec_arr.length-1) do |r|
324
+
325
+ # TODO: try low-level class for const_type
326
+
327
+ const_type = CJava.get_class(rec_arr[r].type_cls)
328
+ # TODO: need better type comparison
329
+ if target_type == const_type || # covers primitives, there's probably a better way...
330
+ target_type.assignable_from?(const_type.java_class)
331
+ found_match = true
332
+ matches[t][c][0] = Weak
333
+ matches[t][c][1] = CJava.get_class(rec_arr[r].decl_cls).const_get(const_sym)
334
+ break
335
+ end
336
+ end
337
+ end
338
+ unless found_match
339
+ target_args.delete_at(t)
340
+ matches.delete_at(t)
341
+ if target_args.empty?
342
+ # TODO: need to pass in class/method names for better message
343
+ raise NoMethodError,"No matching method/constructor for args/constants [#{args.join(', ')}]"
344
+ end
345
+ end
346
+ end
347
+ end
348
+ # some fairly simplistic logic to choose the best candidate
349
+ # set of constants when multiple ctors/methods are matched.
350
+ # probably better to raise an exception asking the user to
351
+ # specifify the actual Java constants, but I want to play
352
+ # with this for a while first.
353
+ hi_score = 0
354
+ target = nil
355
+ 0.upto(matches.length-1) do |i|
356
+ score = 0
357
+ 0.upto(matches[i].length-1) do |j|
358
+ val = matches[i][j]
359
+ score += val[0] if val
360
+ end
361
+ if score > hi_score
362
+ hi_score = score
363
+ target = i
364
+ end
365
+ end
366
+ # plug the values into the args array
367
+ 0.upto(const_arr.length-1) do |c|
368
+ args[const_arr[c][1]] = matches[target][c][1]
369
+ end
370
+ true
371
+ end
372
+
373
+ def const?(y)
374
+ y.instance_of?(Symbol) && (c = y.to_s[0]) >= ?A && c <= ?Z
375
+ end
376
+
377
+ end #self
378
+ end #Constants
379
+
380
+ # TODO: leftover from JRBuilder, rethink for Cheri
381
+ module Types
382
+ #:stopdoc:
383
+ BYTE_MIN = -128
384
+ BYTE_MAX = 127
385
+ CHAR_MIN = 0
386
+ CHAR_MAX = 65535
387
+ SHORT_MIN = -32768
388
+ SHORT_MAX = 32767
389
+ INT_MIN = -2147483648
390
+ INT_MAX = 2147483647
391
+ LONG_MIN = -9223372036854775808
392
+ LONG_MAX = 9223372036854775807
393
+ FLOAT_MIN = 1.401298464324817E-45
394
+ FLOAT_MAX = 3.4028234663852886E38
395
+ DOUBLE_MIN = 4.9E-324
396
+ DOUBLE_MAX = 1.7976931348623157E308
397
+ #:startdoc:
398
+ @map = {
399
+ 'boolean' => [[TrueClass, nil],[FalseClass,nil],[NilClass,nil]],
400
+ 'byte' => [[Fixnum, [BYTE_MIN,BYTE_MAX]]],
401
+ 'char' => [[Fixnum, [CHAR_MIN,CHAR_MAX]]],
402
+ 'short' => [[Fixnum, [SHORT_MIN,SHORT_MAX]]],
403
+ 'int' => [[Fixnum, [INT_MIN,INT_MAX]]],
404
+ 'long' => [[Fixnum, [LONG_MIN,LONG_MAX]]],
405
+ # definitely not right
406
+ #'float' => [[Numeric, [FLOAT_MIN,FLOAT_MAX]]],
407
+ #'double' => [[Numeric, [DOUBLE_MIN,DOUBLE_MAX]]],
408
+ # TODO: need better matching for float/double
409
+ 'float' => [[Numeric, nil]],
410
+ 'double' => [[Numeric, nil]],
411
+
412
+ 'java.lang.Boolean' => [[TrueClass, nil],[FalseClass,nil],[NilClass,nil]],
413
+ 'java.lang.Byte' => [[Fixnum, [BYTE_MIN,BYTE_MAX]],[NilClass,nil]],
414
+ 'java.lang.Character' => [[Fixnum, [CHAR_MIN,CHAR_MAX]],[NilClass,nil]],
415
+ 'java.lang.Short' => [[Fixnum, [SHORT_MIN,SHORT_MAX]],[NilClass,nil]],
416
+ 'java.lang.Integer' => [[Fixnum, [INT_MIN,INT_MAX]],[NilClass,nil]],
417
+ 'java.lang.Long' => [[Fixnum, [LONG_MIN,LONG_MAX]],[NilClass,nil]],
418
+ # definitely not right
419
+ #'java.lang.Float' => [[Numeric, [FLOAT_MIN,FLOAT_MAX]],[NilClass,nil]],
420
+ #'java.lang.Double' => [[Numeric, [DOUBLE_MIN,DOUBLE_MAX]],[NilClass,nil]],
421
+ # TODO: need better matching for float/double
422
+ 'java.lang.Float' => [[Numeric, nil],[NilClass,nil]],
423
+ 'java.lang.Double' => [[Numeric, nil],[NilClass,nil]],
424
+ 'java.lang.Number' => [[Numeric,nil],[NilClass,nil]],
425
+
426
+ 'java.Math.BigInteger' => [[Integer,nil],[NilClass,nil]],
427
+ 'java.Math.BigDecimal' => [[Numeric,nil],[NilClass,nil]],
428
+
429
+ 'java.lang.String' => [[String,nil],[NilClass,nil]],
430
+ 'java.lang.Object' => [[Object,nil]]
431
+ }
432
+ class << self
433
+ # type must be a JavaClass
434
+ def type_matches_arg(type,arg)
435
+ return type.assignable_from?(arg.java_class) if arg.respond_to?(:java_class)
436
+ if can_match_type(type.name)
437
+ return does_type_match(type.name,arg)
438
+ else
439
+ # TODO: deal with subclasses of non-final types in TypeMap
440
+ warn "warning: can't evaluate type #{type.name}"
441
+ return false
442
+ end
443
+ end
444
+
445
+
446
+ # call-seq:
447
+ # can_match_type(type_cls_name) -> true or false
448
+ #
449
+ # this should be called first, otherwise the response
450
+ # of does_type_match is ambiguous
451
+ # TODO: deal with subclasses of non-final types
452
+ def can_match_type(n)
453
+ @map[n] != nil
454
+ end
455
+
456
+ # call-seq:
457
+ # does_type_match(type_cls_name, value) -> true or false
458
+ #
459
+ # TODO: deal with subclasses of non-final types
460
+ def does_type_match(n,v)
461
+ rtypes = @map[n]
462
+ return false unless rtypes
463
+ rtypes.each do |t|
464
+ if v.kind_of?(t[0])
465
+ range = t[1]
466
+ if range
467
+ return v >= range[0] && v <= range[1]
468
+ else
469
+ return true
470
+ end
471
+ end
472
+ end
473
+ false
474
+ end
475
+ end # self
476
+ end #Types
477
+
478
+ end #Builder
479
+ end #Java
480
+ end #Cheri