cheri 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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