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,483 @@
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 Builder
27
+
28
+ class BuilderException < Cheri::CheriException; end
29
+
30
+ class << self
31
+ def append_features(clazz) #:nodoc:
32
+ return super unless clazz.instance_of?(Class) &&
33
+ !clazz.instance_variable_get(:@__cheri_cfg).instance_of?(Config)
34
+ clazz.instance_variable_set(:@__cheri_cfg,Config.new(CheriModule))
35
+ # we don't support subclassing for builder modules installed at the
36
+ # top level (in Object). method_missing will be inherited, but will
37
+ # behave normally (just calls super if @__cheri_cfg not installed)
38
+ unless clazz == Object
39
+ clazz.module_eval do
40
+ class << self
41
+ def inherited(subclass)
42
+ cfg = @__cheri_cfg
43
+ subclass.module_eval do
44
+ # copy modules unless a more-derived subclass has already done so
45
+ unless @__cheri_cfg.instance_of?(Cheri::Builder::Config)
46
+ @__cheri_cfg = cfg.copy
47
+ end
48
+ end
49
+ # pass it up the chain
50
+ super
51
+ end
52
+ private :inherited
53
+ end
54
+ end
55
+ end
56
+ super
57
+ end
58
+ private :append_features
59
+
60
+ # call-seq:
61
+ # Cheri::Builder.module_included(module, class) -> Cheri::Builder
62
+ #
63
+ # Installs the specified module as a Cheri builder for the specified class. Note
64
+ # that the 'included module' needn't be included, or even a module, in order to
65
+ # participate as a Cheri builder, though normally it will be both.
66
+ #
67
+ # Modules should hook the <tt>append_features</tt> method, rather than <tt>included</tt>;
68
+ # the former allows inclusion to be aborted if exceptional conditions arise, whereas
69
+ # the latter is called after the fact:
70
+ #
71
+ # module MyBuilder
72
+ # include Cheri::Builder
73
+ # class << self
74
+ # def append_features(clazz)
75
+ # Cheri::Builder.module_included(self, clazz)
76
+ # super # allow inclusion to complete
77
+ # end
78
+ # private :append_features
79
+ # end #self
80
+ #
81
+ # end #MyBuilder
82
+ #
83
+ # Builders installed for a class will be inherited by its subclasses, with the
84
+ # exception of those installed for class Object; inclusion of Builder modules in
85
+ # Object is discouraged, but is permitted so simple scripts can include builders
86
+ # at the top level rather than having to define a class. But really, don't do it.
87
+ def module_included(mod,clazz)
88
+ return self unless clazz.instance_of?(Class)
89
+ append_features(clazz)
90
+ clazz.instance_variable_get(:@__cheri_cfg) << mod
91
+ self
92
+ end
93
+
94
+ # note: Cheri::Java needs factory method
95
+
96
+ # Create a new builder module using the BuilderBuilder.
97
+ def new_builder(*r,&k)
98
+ # TODO: usage message if no args or block supplied
99
+ Generator.new(*r,&k).run
100
+ end
101
+
102
+ end #self
103
+
104
+
105
+ # Instance methods
106
+
107
+
108
+ # call-seq:
109
+ # method_missing(symbol [, *args] [, &block]) -> result (if method matched)
110
+ #
111
+ def method_missing(sym,*r,&k)
112
+ # get the context for the current thread
113
+ if (ctx = __cheri_ctx)
114
+ # send to the context for processing
115
+ matched, result = ctx.send(sym,*r,&k)
116
+ # return the result if sym matched
117
+ return result if matched
118
+ end
119
+
120
+ # nothing matches, probable NameError/NoMethodError
121
+ super
122
+ end
123
+ private :method_missing
124
+
125
+ # call-seq:
126
+ # cheri([*args] [, &block]) -> CheriProxy if no block given, else result of block
127
+ #
128
+ def cheri(*r,&k)
129
+ if (ctx = __cheri_ctx)
130
+ if k
131
+ CheriFrame.new(ctx,*r,&k).run
132
+ else
133
+ ctx[:cheri_proxy] ||= CheriProxy.new(ctx,*r)
134
+ end
135
+ end
136
+ end
137
+ private :cheri
138
+
139
+
140
+ # call-seq:
141
+ # __cheri_ctx -> context object for the current instance/thread
142
+ #
143
+ def __cheri_ctx
144
+ unless (ic = @__cheri_ctx)
145
+ # don't create context unless we're an installed Cheri module
146
+ # (this is part of the solution for preventing Cheri modules installed
147
+ # at the top level (in Object) from being unintentionally inherited)
148
+ return unless (g = self.class.instance_variable_get(:@__cheri_cfg)).instance_of?(Config)
149
+ # using ||= in case another thread slipped by us
150
+ # TODO: is ||= actually atomic?
151
+ ic = @__cheri_ctx ||= InstanceContext.new(self,g)
152
+ end
153
+ ic.current
154
+ end
155
+ private :__cheri_ctx
156
+
157
+ # Module used by cheri(){} method. Supplies pseudo-factory that
158
+ # searches all installed factories.
159
+ module CheriModule
160
+
161
+ # Returns CheriFactory
162
+ def self.factory
163
+ CheriFactory
164
+ end
165
+
166
+ # Factory used by cheri(){} method - searches all installed
167
+ # factories.
168
+ module CheriFactory
169
+ # Searches all factories, in the reverse order their
170
+ # modules were included.
171
+ def self.builder(ctx,*r,&k)
172
+ ctx.cfg.mods.reverse_each do |m|
173
+ if m != CheriModule && m.respond_to?(:factory) && (f = m.factory)
174
+ if (b = f.builder(ctx,*r,&k))
175
+ return b
176
+ end
177
+ end
178
+ end
179
+ nil
180
+ end
181
+ end
182
+ end
183
+
184
+ # a base class for proxies
185
+ class BaseProxy
186
+ keep = /^(methods|instance_|__|=|class|to_s|eql\?|equal\?|inspect|instance_eval|instance_exec|respond_to\?)/
187
+ instance_methods.each do |m|
188
+ undef_method m unless m =~ keep
189
+ end
190
+
191
+
192
+ class << self
193
+ def impl(meths)
194
+ meths.each do |m|
195
+ self.module_eval <<-EOM
196
+ def #{m}(*r,&k)
197
+ @ctx.msend(mod,:#{m},*r,&k)
198
+ end
199
+ EOM
200
+ end
201
+ end
202
+ private :impl
203
+ end #self
204
+
205
+ def initialize(ctx,*r)
206
+ @ctx = ctx
207
+ end
208
+
209
+ # override to return builder module
210
+ def mod
211
+ CheriModule
212
+ end
213
+ private :mod
214
+
215
+ # call-seq:
216
+ # vget(:@var) -> @var in client instance
217
+ #
218
+ # Returns the value of the specified instance variable in client. Provided
219
+ # for use when instance_eval / instance_exec are used to evaluate blocks
220
+ # (:block_method => :eval or :block_method => :exec)
221
+ def vget(sym)
222
+ @ctx.client.instance_variable_get(sym)
223
+ end
224
+
225
+ # call-seq:
226
+ # vset(:@var, value) -> @var in client instance
227
+ #
228
+ # Sets the value of the specified instance variable in client. Provided
229
+ # for use when instance_eval / instance_exec are used to evaluate blocks
230
+ # (:block_method => :eval or :block_method => :exec)
231
+ def vset(sym,val)
232
+ @ctx.client.instance_variable_set(sym,val)
233
+ end
234
+
235
+ # prevent mind-boggling circular displays in IRB
236
+ def inspect
237
+ "#<#{self.class}:instance>"
238
+ end
239
+
240
+ def method_missing(*r,&k)
241
+ @ctx.msend(mod,*r,&k)
242
+ end
243
+ private :method_missing
244
+
245
+ end #BaseProxy
246
+
247
+ class CheriProxy < BaseProxy
248
+ # def [](opts)
249
+ # self
250
+ # end
251
+ end #CheriProxy
252
+
253
+ class CheriFrame
254
+ include Frame
255
+ def initialize(ctx,*r,&k)
256
+ super
257
+ @obj = ctx[:cheri_proxy] ||= CheriProxy.new(ctx,*r)
258
+ end
259
+ def mod
260
+ CheriModule
261
+ end
262
+ end #CheriFrame
263
+
264
+ module DefaultConsumer
265
+ G = 'get_' #:nodoc:
266
+ S = 'set_' #:nodoc:
267
+ I = 'is_' #:nodoc:
268
+
269
+ # call-seq:
270
+ # DefaultConsumer.consume(context,builder,sym,*args,&block) -> consumed?, ret_val
271
+ #
272
+ def self.consume(ctx,bld,sym,*args,&k)
273
+ obj = bld.object
274
+ puts "default consumer called for #{sym}"
275
+ s = sym.to_s
276
+ # if sym is already clearly a getter/setter/is-er (xxx=, xxx?, get_xxx, set_xxx, is_xxx),
277
+ # then leave it as is.
278
+ # (Note: tested the following line against s =~ /((\?|=)$|^(get_|set_|is_))/ - this is about
279
+ # 50% faster in MRI (C) Ruby, but currently slower in JRuby (0.9.9)...)
280
+ if (c = s[-1]) == ?= || c == ?? || s.rindex(G,0) || s.rindex(S,0) || s.rindex(I,0)
281
+ snd = sym
282
+ # otherwise, if there are args and the sym works as a setter (xxx=), then prefer
283
+ # that to a getter.
284
+ elsif !args.empty? && obj.respond_to?(snd = s << ?= ) # TODO: careful, what if sym was String?
285
+ # otherwise leave it as is
286
+ else
287
+ snd = sym
288
+ end
289
+ if obj.respond_to?(snd)
290
+ if !args.empty? && bld.respond_to?(:resolve?) && bld.resolve?
291
+ # context.resolve_method_constants(object,send_sym,args)
292
+ ctx.mrz(obj,snd,args)
293
+ end
294
+ res = nil
295
+ begin
296
+ res = obj.__send__(snd, *args)
297
+ rescue
298
+ return false,nil
299
+ end
300
+ # here's our little inside-out trick. really no different than saying
301
+ # obj1().obj2()...objn().doSomething(), except that multiple operations
302
+ # can be performed in the scope of the block. a bit like JavaScript's
303
+ # 'with' statement in that respect.
304
+ if k && res
305
+
306
+ # TODO: update comments
307
+ #
308
+ # get a cheri_yield builder for the return value and run it. the
309
+ # builder is obtained through the context rather than created directly,
310
+ # as different builders are used for different types of objects (Java vs.
311
+ # non-Java, for instance).
312
+ ctx.send(:cheri_yield,res,&k)
313
+ end
314
+ return true,res
315
+ end
316
+ return false,nil # consumed,ret_val
317
+ end #consume
318
+
319
+ end #DefaultConsumer
320
+
321
+
322
+ # TODO: comments
323
+ # The connecter of last resort
324
+ DefaultConnecter = TypeConnecter.new do
325
+ Eq = '='
326
+ St = 'set_'
327
+
328
+ type Object do
329
+ connect Object do |parent,obj,sym,props|
330
+ if parent.respond_to?(snd = (s = sym.to_s) + Eq) ||
331
+ parent.respond_to?(snd = St + s) ||
332
+ parent.respond_to?(snd = :add)
333
+ #puts "Builder::DefaultConnecter for #{parent}, #{obj}: #{snd}"
334
+ parent.__send__(snd,obj) rescue nil
335
+ end
336
+ nil
337
+ end
338
+ end
339
+ end
340
+
341
+
342
+ # The ConstantResolver classes/modules are designed primarily for use with
343
+ # Java classes, for which constant name specification/qualification can be
344
+ # especially onerous. This _might_ find some use in pure Ruby applications;
345
+ # the mechanism (substituting values for :Constant symbols found in constructor
346
+ # or method arguments) could conceivably be repurposed in interesting ways.
347
+ # Meanwhile, it was cleaner to define this here, rather than having to maintain
348
+ # separate versions of Context and all the attendant fuss.
349
+ class AbstractConstantResolver
350
+ # note that we pass args, not *args, as we want the original array
351
+ def resolve_ctor(clazz,args)
352
+ false
353
+ end
354
+
355
+ def resolve_meth(object,method_name,args)
356
+ false
357
+ end
358
+ end #AbstractConstantResolver
359
+
360
+ class CherifyBuilder < BaseBuilder
361
+ def initialize(context,sym,object,*args,&block)
362
+ super(context,sym,*args,&block)
363
+ @obj = object
364
+ @clazz = object.class
365
+ @no_create = true
366
+ end
367
+ end #CherifyBuilder
368
+
369
+ class CheriYieldBuilder < BaseBuilder
370
+ def initialize(context,sym,object,*args,&block)
371
+ super(context,sym,*args,&block)
372
+ @obj = object
373
+ @clazz = object.class
374
+ @no_create = true
375
+ @not_child = true
376
+ end
377
+ end #CheriYieldBuilder
378
+
379
+ module CherifyFactory # < Cheri::AbstractFactory
380
+ def self.builder(context,sym,*args,&block)
381
+ return nil unless sym == :cherify
382
+ # TODO: validate second arg is hash if present
383
+ raise Cheri.argument_error(args.length, 1..2) unless args.length == 1 || args.length == 2
384
+ CherifyBuilder.new(context,sym,*args,&block)
385
+ end
386
+ end #CherifyFactory
387
+
388
+ # TODO: comments
389
+ module CheriYieldFactory # < Cheri::AbstractFactory
390
+ def self.builder(context,sym,*args,&block)
391
+ return nil unless sym == :cheri_yield
392
+ raise Cheri.argument_error(args.length, 1) unless args.length == 1
393
+ CheriYieldBuilder.new(context,sym,*args,&block)
394
+ end
395
+ end #CheriYieldFactory
396
+
397
+ # A do-nothing factory. May be safley returned by the +factory+ method
398
+ # of builder modules that don't supply builders
399
+ module NilFactory
400
+ def self.builder(*r,&k)
401
+ end
402
+ end
403
+
404
+ module NilConnecter
405
+ def self.prepare(*r)
406
+ end
407
+ end
408
+
409
+
410
+ class Aggregate < Array
411
+ def initialize(*args,&k)
412
+ args.each do |a|
413
+ self << a
414
+ end
415
+ yield self if block_given?
416
+ end
417
+ alias_method :app, :<<
418
+ #protected :app # broken in JRuby 1.0.0RC-1
419
+ def <<(elem)
420
+ app(elem) unless include?(elem)
421
+ end
422
+ end #Aggregate
423
+
424
+ # class to aggregate factories
425
+ class SuperFactory < Aggregate
426
+ def builder(ctx,sym,*r,&k)
427
+ each do |f|
428
+ if (b = f.builder(ctx,sym,*r,&k))
429
+ return b
430
+ end
431
+ end
432
+ nil
433
+ end
434
+ end #SuperFactory
435
+
436
+
437
+ # class to aggregate connecters
438
+ class SuperConnecter < Aggregate
439
+ def prepare(*r)
440
+ each do |ctr|
441
+ return true if ctr.prepare(*r)
442
+ end
443
+ false
444
+ end
445
+ end
446
+
447
+ # class to aggregate consumers
448
+ class SuperConsumer < Aggregate
449
+ def consume(*r,&k)
450
+ each do |cns|
451
+ c, v = cns.consume(*r,&k)
452
+ return c,v if c
453
+ end
454
+ return false, nil
455
+ end
456
+ end #SuperConsumer
457
+
458
+ # class to aggregate resolvers
459
+ # TODO: the Java resolver won't play nicely right now; raises if it fails to resolve
460
+ class SuperResolver < Aggregate
461
+ def resolve_ctor(*r)
462
+ each do |rsv|
463
+ return true if rsv.resolve_ctor(*r)
464
+ end
465
+ false
466
+ end
467
+ def resolve_meth(*r)
468
+ each do |rsv|
469
+ return true if rsv.resolve_meth(*r)
470
+ end
471
+ false
472
+ end
473
+ end
474
+
475
+
476
+ DefaultFactory = SuperFactory.new do |f|
477
+ f << CherifyFactory
478
+ f << CheriYieldFactory
479
+ end
480
+
481
+
482
+ end #Builder
483
+ end #Cheri