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,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