jrubyfx-fxmlloader-master 0.4.master.2015.9.30-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,708 @@
1
+ class OBJFXBuilderWrapper < Java::java.util.AbstractMap
2
+ include Java::javafx.util.Builder
3
+ def initialize(safeobj, type)
4
+ super()
5
+ @type = type
6
+ @obj = safeobj
7
+ end
8
+
9
+ def wrapped_class
10
+ @type
11
+ end
12
+
13
+ def on_put(&on_put)
14
+ @on_put = on_put
15
+ end
16
+
17
+ def build
18
+ @obj.build.tap{|x| rmorph self, x}
19
+ end
20
+
21
+ def containsKey(o)
22
+ @obj.containsKey(o)
23
+ end
24
+
25
+ def get(o)
26
+ @obj.get(o)
27
+ end
28
+
29
+ def put(k, v)
30
+ @on_put.call(k, v) if @on_put
31
+ @obj.put(k, v)
32
+ end
33
+
34
+ def [](o)
35
+ get(o)
36
+ end
37
+ def []=(k, v)
38
+ put(k, v)
39
+ end
40
+
41
+ def entrySet
42
+ java.util.HashMap.new({}).entrySet
43
+ end
44
+
45
+ def ==(rhs)
46
+ self.equal? rhs # do pointer comparison
47
+ end
48
+
49
+ def inspect
50
+ "#<ObjectBuilderWrapper:#{self.object_id.to_s 16} type=#{@type}, child=#{@obj.class.inspect}>"
51
+ end
52
+ end
53
+
54
+ class InstanceDeclarationElement < ValueElement
55
+ attr_accessor :type, :constant, :factory
56
+
57
+ def initialize(current, xmlStreamReader, loadListener, parentLoader, type)
58
+ super(current, xmlStreamReader, loadListener, parentLoader)
59
+ @type = type;
60
+ @constant = nil;
61
+ @factory = nil;
62
+ end
63
+
64
+ def processAttribute( prefix, localName, value)
65
+ if (prefix != nil && prefix == (FXL::FX_NAMESPACE_PREFIX))
66
+ if (localName == (FXL::FX_VALUE_ATTRIBUTE))
67
+ @value = value;
68
+ elsif (localName == (FXL::FX_CONSTANT_ATTRIBUTE))
69
+ @constant = value;
70
+ elsif (localName == (FXL::FX_FACTORY_ATTRIBUTE))
71
+ @factory = value;
72
+ else
73
+ super(prefix, localName, value);
74
+ end
75
+ else
76
+ super(prefix, localName, value);
77
+ end
78
+ end
79
+
80
+ def constructValue()
81
+ value = nil
82
+ if (@value != nil)
83
+ value = RubyWrapperBeanAdapter.coerce(@value, type);
84
+ elsif (constant != nil)
85
+ value = RubyWrapperBeanAdapter.getConstantValue(type, constant);
86
+ elsif (factory != nil)
87
+ factoryMethod = nil
88
+ begin
89
+ factoryMethod = MethodUtil.getMethod(type, factory, []);
90
+ rescue NoSuchMethodException => exception
91
+ raise LoadException.new(exception);
92
+ end
93
+
94
+ begin
95
+ value = MethodUtil.invoke(factoryMethod, nil, []);
96
+ rescue IllegalAccessException => exception
97
+ raise LoadException.new(exception);
98
+ rescue InvocationTargetException => exception
99
+ raise LoadException.new(exception);
100
+ end
101
+ else
102
+ value = (parentLoader.builderFactory == nil) ? nil : parentLoader.builderFactory.getBuilder(type);
103
+ if (value.is_a? Builder or (value.respond_to?(:java_object) && value.java_object.is_a?(Builder)))
104
+ begin
105
+ value.size
106
+ rescue java.lang.UnsupportedOperationException => ex
107
+ dputs "########################## WARNING #############################3"
108
+ value = OBJFXBuilderWrapper.new(value, type)
109
+ value.on_put {|k, v| rctor value, k, v }
110
+ end
111
+ end
112
+ if (value == nil)
113
+ begin
114
+ #TODO: does this work?
115
+ value = type.ruby_class.new
116
+ rescue InstantiationException => exception
117
+ raise LoadException.new(exception);
118
+ rescue IllegalAccessException => exception
119
+ raise LoadException.new(exception);
120
+ end
121
+ else
122
+ end
123
+ end
124
+ if factory
125
+ rputs value, "build(FactoryBuilderBuilder, #{type.ruby_class}, #{factory.inspect}) do"
126
+ elsif @value
127
+ rno_show(value)
128
+ rputs value, value.inspect
129
+ else
130
+ rputs value, "build(#{type.ruby_class}) do"
131
+ end
132
+ rnest 1
133
+ return value;
134
+ end
135
+ end
136
+
137
+ # Element representing an unknown type
138
+ class UnknownTypeElement < ValueElement
139
+
140
+ def initialize()
141
+ dputs "oh no...."
142
+ end
143
+ # TODO: cleanup
144
+ # Map type representing an unknown value
145
+ # def UnknownValueMap extends AbstractMap<String, Object>
146
+ # def<?> items = ArrayList.new<Object>();
147
+ # def<String, Object> values = HashMap.new<String, Object>();
148
+ #
149
+ # def get(Object key)
150
+ # if (key == nil)
151
+ # raise NullPointerException.new();
152
+ # end
153
+ #
154
+ # return (key == (java_class().getAnnotation(DefaultProperty.java_class).value()))
155
+ # ? items : values.get(key);
156
+ # end
157
+ #
158
+ # def put(String key, Object value)
159
+ # if (key == nil)
160
+ # raise NullPointerException.new();
161
+ # end
162
+ #
163
+ # if (key == (java_class().getAnnotation(DefaultProperty.java_class).value()))
164
+ # raise IllegalArgumentException.new();
165
+ # end
166
+ #
167
+ # return values.put(key, value);
168
+ # end
169
+ #
170
+ # def entrySet()
171
+ # return Collections.emptySet();
172
+ # end
173
+ # end
174
+
175
+ def processEndElement()
176
+ # No-op
177
+ end
178
+
179
+ def constructValue()
180
+ return UnknownValueMap.new();
181
+ end
182
+ end
183
+
184
+ # Element representing an include
185
+ class IncludeElement < ValueElement
186
+ # TODO: cleanup
187
+ attr_accessor :source, :resources, :charset
188
+ def initialize(current, xmlStreamReader, loadListener, parentLoader)
189
+ super
190
+ @source = nil;
191
+ @resources = parentLoader.resources;
192
+ @charset = parentLoader.charset;
193
+ end
194
+
195
+ def processAttribute(prefix, localName, value)
196
+
197
+ if (prefix == nil)
198
+ if (localName == (FXL::INCLUDE_SOURCE_ATTRIBUTE))
199
+ if (loadListener != nil)
200
+ loadListener.readInternalAttribute(localName, value);
201
+ end
202
+
203
+ source = value;
204
+ elsif (localName == (FXL::INCLUDE_RESOURCES_ATTRIBUTE))
205
+ if (loadListener != nil)
206
+ loadListener.readInternalAttribute(localName, value);
207
+ end
208
+
209
+ resources = ResourceBundle.getBundle(value, Locale.getDefault(),
210
+ parentLoader.resources.java_class().getClassLoader());
211
+ elsif (localName == (FXL::INCLUDE_CHARSET_ATTRIBUTE))
212
+ if (loadListener != nil)
213
+ loadListener.readInternalAttribute(localName, value);
214
+ end
215
+
216
+ charset = Charset.forName(value);
217
+ else
218
+ super(prefix, localName, value);
219
+ end
220
+ else
221
+ super(prefix, localName, value);
222
+ end
223
+ end
224
+
225
+ def constructValue()
226
+ if (source == nil)
227
+ raise LoadException.new(FXL::INCLUDE_SOURCE_ATTRIBUTE + " is required.");
228
+ end
229
+
230
+ location = nil
231
+ if (source[0] == '/')
232
+ location = classLoader.getResource(source[1..-1]);
233
+ else
234
+ if (location == nil)
235
+ raise LoadException.new("Base location is undefined.");
236
+ end
237
+
238
+ location = URL.new(location, source);
239
+ end
240
+
241
+ fxmlLoader = FxmlLoader.new(location, controller, resources,
242
+ parentLoader.builderFactory, charset,
243
+ loaders);
244
+ fxmlLoader.parentLoader = parentSelf
245
+
246
+ if (isCyclic(parentSelf, fxmlLoader))
247
+ raise IOException.new(
248
+ String.format(
249
+ "Including \"%s\" in \"%s\" created cyclic reference.",
250
+ fxmlLoader.location.toExternalForm(),
251
+ parentSelf.location.toExternalForm()));
252
+ end
253
+ fxmlLoader.setClassLoader(classLoader);
254
+ fxmlLoader.setStaticLoad(staticLoad);
255
+
256
+ value = fxmlLoader.load();
257
+
258
+ if (fx_id != nil)
259
+ id = fx_id + FXL::CONTROLLER_SUFFIX;
260
+ controller = fxmlLoader.getController();
261
+
262
+ namespace.put(id, controller);
263
+
264
+ if (parentLoader.controller != nil)
265
+ field = getControllerFields().get(id);
266
+
267
+ if (field != nil)
268
+ begin
269
+ field.set(parentLoader.controller, controller);
270
+ rescue IllegalAccessException => exception
271
+ raise LoadException.new(exception);
272
+ end
273
+ end
274
+ end
275
+ end
276
+
277
+ return value;
278
+ end
279
+ end
280
+
281
+ # Element representing a reference
282
+ class ReferenceElement < ValueElement
283
+ attr_accessor :source
284
+ @source = nil;
285
+
286
+ def processAttribute(prefix, localName, value)
287
+ if (prefix == nil)
288
+ if (localName == (FXL::REFERENCE_SOURCE_ATTRIBUTE))
289
+ if (loadListener != nil)
290
+ loadListener.readInternalAttribute(localName, value);
291
+ end
292
+ @source = value;
293
+ else
294
+ super(prefix, localName, value);
295
+ end
296
+ else
297
+ super(prefix, localName, value);
298
+ end
299
+ end
300
+
301
+ def constructValue()
302
+ if (source == nil)
303
+ raise LoadException.new(FXL::REFERENCE_SOURCE_ATTRIBUTE + " is required.");
304
+ end
305
+
306
+ path = KeyPath.parse(source);
307
+ if (!Expression.isDefined(parentLoader.namespace, path))
308
+ raise LoadException.new("Value \"" + source + "\" does not exist.");
309
+ end
310
+
311
+ return Expression.get(parentLoader.namespace, path);
312
+ end
313
+ end
314
+
315
+ # Element representing a copy
316
+ class CopyElement < ValueElement
317
+ attr_accessor :source
318
+ @source = nil;
319
+
320
+ def processAttribute(prefix, localName, value)
321
+
322
+ if (prefix == nil)
323
+ if (localName == (FXL::COPY_SOURCE_ATTRIBUTE))
324
+ if (loadListener != nil)
325
+ loadListener.readInternalAttribute(localName, value);
326
+ end
327
+
328
+ @source = value;
329
+ else
330
+ super(prefix, localName, value);
331
+ end
332
+ else
333
+ super(prefix, localName, value);
334
+ end
335
+ end
336
+
337
+ def constructValue()
338
+ if (source == nil)
339
+ raise LoadException.new(FXL::COPY_SOURCE_ATTRIBUTE + " is required.");
340
+ end
341
+
342
+ path = KeyPath.parse(source);
343
+ if (!Expression.isDefined(namespace, path))
344
+ raise LoadException.new("Value \"" + source + "\" does not exist.");
345
+ end
346
+
347
+ sourceValue = Expression.get(namespace, path);
348
+ sourceValueType = sourceValue.java_class();
349
+
350
+ constructor = nil;
351
+ begin
352
+ constructor = ConstructorUtil.getConstructor(sourceValueType, [sourceValueType]);
353
+ rescue NoSuchMethodException => exception
354
+ # No-op
355
+ end
356
+
357
+ value=nil
358
+ if (constructor != nil)
359
+ begin
360
+ #TODO: try to do evil things here
361
+ ReflectUtil.checkPackageAccess(sourceValueType);
362
+ value = constructor.newInstance(sourceValue);
363
+ rescue InstantiationException => exception
364
+ raise LoadException.new(exception);
365
+ rescue IllegalAccessException => exception
366
+ raise LoadException.new(exception);
367
+ rescue InvocationTargetException => exception
368
+ raise LoadException.new(exception);
369
+ end
370
+ else
371
+ raise LoadException.new("Can't copy value " + sourceValue + ".");
372
+ end
373
+
374
+ return value;
375
+ end
376
+ end
377
+
378
+ # Element representing a predefined root value
379
+ class RootElement < ValueElement
380
+ @type = nil
381
+
382
+ def processAttribute( prefix, localName, value)
383
+
384
+ if (prefix == nil)
385
+ if (localName == (FXL::ROOT_TYPE_ATTRIBUTE))
386
+ if (loadListener != nil)
387
+ loadListener.readInternalAttribute(localName, value);
388
+ end
389
+
390
+ @type = value;
391
+ else
392
+ super(prefix, localName, value);
393
+ end
394
+ else
395
+ super(prefix, localName, value);
396
+ end
397
+ end
398
+
399
+ def constructValue()
400
+ if (@type == nil)
401
+ raise LoadException.new(FXL::ROOT_TYPE_ATTRIBUTE + " is required.");
402
+ end
403
+
404
+ type = parentLoader.getType(@type);
405
+
406
+ if (type == nil)
407
+ raise LoadException.new(@type + " is not a valid type.");
408
+ end
409
+
410
+ value=nil
411
+ root = parentLoader.root
412
+ if (root == nil)
413
+ if $JRUBYFX_AOT_COMPILING
414
+ root = parentLoader.root = type.ruby_class.new
415
+ value = root
416
+ else
417
+ raise LoadException.new("Root hasn't been set. Use method setRoot() before load.");
418
+ end
419
+ else
420
+ if (!type.isAssignableFrom(root.java_class()))
421
+ raise LoadException.new("Root is not an instance of " + type.getName() + ".");
422
+ end
423
+
424
+ value = root;
425
+ end
426
+ rputs value, "with(__local_fxml_controller) do"
427
+ rnest 1
428
+ return value;
429
+ end
430
+ end
431
+
432
+ # Element representing a property
433
+ class PropertyElement < Element
434
+ attr_accessor :name, :sourceType, :readOnly
435
+
436
+ def initialize(current, xmlStreamReader, loadListener, parentLoader, name, sourceType)
437
+
438
+ @name = nil
439
+ @sourceType = nil
440
+ @readOnly = nil
441
+ super(current, xmlStreamReader, loadListener, parentLoader)
442
+ if (parent == nil)
443
+ raise LoadException.new("Invalid root element.");
444
+ end
445
+
446
+ if (parent.value == nil)
447
+ raise LoadException.new("Parent element does not support property elements.");
448
+ end
449
+
450
+ @name = name;
451
+ @sourceType = sourceType;
452
+
453
+ if (sourceType == nil)
454
+ # The element represents an instance property
455
+ if (name.start_with?(FXL::EVENT_HANDLER_PREFIX))
456
+ raise LoadException.new("\"" + name + "\" is not a valid element name.");
457
+ end
458
+
459
+ parentProperties = parent.getProperties();
460
+ if (parent.isTyped())
461
+ @readOnly = parent.getValueAdapter().read_only?(name);
462
+ else
463
+ # If the map already defines a value for the property, assume
464
+ # that it is read-only
465
+ @readOnly = parentProperties.has_key?(name);
466
+ end
467
+
468
+ if (@readOnly)
469
+ value = parentProperties[name]
470
+ if (value == nil)
471
+ raise LoadException.new("Invalid property.");
472
+ end
473
+ updateValue(value);
474
+ end
475
+ else
476
+ # The element represents a static property
477
+ @readOnly = false;
478
+ end
479
+ end
480
+
481
+ def isCollection()
482
+ return (@readOnly) ? super() : false;
483
+ end
484
+
485
+ def add( element)
486
+ @pushd = true
487
+ rp = nil
488
+ # Coerce the element to the list item type
489
+ if (parent.isTyped())
490
+ listType = parent.getValueAdapter().getGenericType(name);
491
+ lit = RubyWrapperBeanAdapter.getListItemType(listType)
492
+ # FIXME: HACK!
493
+ if element.class.inspect == "Java::JavaNet::URL"
494
+ lit = Java::java.lang.String.java_class
495
+ rp = rget(element).match(/build\(FxmlBuilderBuilder, \{"value"=>(.*)\}, Java::JavaNet::URL\) do\n( )*end/)[1]
496
+ end
497
+ element = RubyWrapperBeanAdapter.coerce(element, lit);
498
+ end
499
+
500
+ # Add the item to the list
501
+ super(element, name, rp);
502
+ end
503
+
504
+ def set( value)
505
+ @pushd = true
506
+ # Update the value
507
+ updateValue(value);
508
+
509
+ if (sourceType == nil)
510
+ # Apply value to parent element's properties
511
+ parent.getProperties[name] = value
512
+ else
513
+ if (parent.value.is_a? Builder)
514
+ # Defer evaluation of the property
515
+ parent.staticPropertyElements.add(self);
516
+ else
517
+ # Apply the static property value
518
+ RubyWrapperBeanAdapter.put3(parent.value, sourceType, name, value);
519
+ end
520
+ end
521
+ end
522
+
523
+ def processAttribute( prefix, localName, value)
524
+ if (!readOnly)
525
+ raise LoadException.new("Attributes are not supported for writable property elements.");
526
+ end
527
+
528
+ super(prefix, localName, value);
529
+ end
530
+
531
+ def processEndElement()
532
+ super();
533
+ if (readOnly)
534
+ processInstancePropertyAttributes();
535
+ processEventHandlerAttributes();
536
+ unless @pushd
537
+ rputs parent.value, "with(get#{@name[0].upcase}#{@name[1..-1]}) do\n#{rget(@value)||@value.inspect}\nend" unless parent.value == @value
538
+ end
539
+ end
540
+ end
541
+
542
+ def processCharacters()
543
+ if (!readOnly)
544
+ text = xmlStreamReader.getText();
545
+ #TODO: normal regexes
546
+ text = extraneousWhitespacePattern.matcher(text).replaceAll(" ");
547
+
548
+ set(text.strip());
549
+ else
550
+ super();
551
+ end
552
+ end
553
+ end
554
+
555
+ # Element representing an unknown static property
556
+ class UnknownStaticPropertyElement < Element
557
+ def initialize
558
+ if (parent == nil)
559
+ raise LoadException.new("Invalid root element.");
560
+ end
561
+
562
+ if (parent.value == nil)
563
+ raise LoadException.new("Parent element does not support property elements.");
564
+ end
565
+ end
566
+
567
+ def isCollection()
568
+ return false;
569
+ end
570
+
571
+ def set( value)
572
+ updateValue(value);
573
+ end
574
+
575
+ def processCharacters()
576
+ text = xmlStreamReader.getText();
577
+ # TODO: REGEX!
578
+ text = extraneousWhitespacePattern.matcher(text).replaceAll(" ");
579
+
580
+ updateValue(text.strip());
581
+ end
582
+ end
583
+
584
+ # Element representing a script block
585
+ class ScriptElement < Element
586
+ def initialize(current, xmlStreamReader, loadListener, parentLoader)
587
+ super
588
+ @source = nil;
589
+ @charset = parentLoader.charset;
590
+ end
591
+
592
+ def isCollection()
593
+ return false;
594
+ end
595
+
596
+ def processStartElement()
597
+ super();
598
+
599
+ if (@source != nil && !staticLoad)
600
+ i = @source.rindex(".");
601
+ if (i == nil)
602
+ raise ("Cannot determine type of script \"" + @source + "\".");
603
+ end
604
+ extension = @source[(i + 1)..-1];
605
+ scriptEngine = nil
606
+ #TODO: use JRUBY stuff
607
+ oldLoader = Thread.currentThread().getContextClassLoader();
608
+ begin
609
+ Thread.currentThread().setContextClassLoader(classLoader);
610
+ scriptEngineManager = getScriptEngineManager();
611
+ scriptEngine = scriptEngineManager.getEngineByExtension(extension);
612
+ ensure
613
+ Thread.currentThread().setContextClassLoader(oldLoader);
614
+ end
615
+
616
+ if (scriptEngine == nil)
617
+ raise ("Unable to locate scripting engine for" + " extension " + extension + ".");
618
+ end
619
+
620
+ scriptEngine.setBindings(scriptEngineManager.getBindings(), ScriptContext.ENGINE_SCOPE);
621
+
622
+ begin
623
+ location = nil
624
+ if (@source[0] == '/')
625
+ location = classLoader.getResource(@source[(1)..-1]);
626
+ else
627
+ if (parentLoader.location == nil)
628
+ raise LoadException.new("Base location is undefined.");
629
+ end
630
+
631
+ location = URL.new(parentLoader.location, @source);
632
+ end
633
+
634
+ InputStreamReader scriptReader = nil;
635
+ begin
636
+ scriptReader = InputStreamReader.new(location.openStream(), @charset);
637
+ scriptEngine.eval(scriptReader);
638
+ rescue ScriptException => exception
639
+ exception.printStackTrace();
640
+ ensure
641
+ if (scriptReader != nil)
642
+ scriptReader.close();
643
+ end
644
+ end
645
+ rescue IOException => exception
646
+ raise LoadException.new(exception);
647
+ end
648
+ end
649
+ end
650
+
651
+ def processEndElement()
652
+ super();
653
+ if (value != nil && !parentLoader.staticLoad)
654
+ # Evaluate the script
655
+ begin
656
+ rputs nil, "__local_sem_lang_inst_#{rget_sem(parentLoader.scriptEngine)}.eval(#{value.to_s.inspect})"
657
+ parentLoader.scriptEngine.eval( value.to_s);
658
+ rescue ScriptException => exception
659
+ STDERR.puts (exception.getMessage());
660
+ end
661
+ end
662
+ end
663
+
664
+ def processCharacters()
665
+ if (@source != nil)
666
+ raise LoadException.new("Script source already specified.");
667
+ end
668
+
669
+ if (parentLoader.scriptEngine == nil && !parentLoader.staticLoad)
670
+ raise LoadException.new("Page language not specified.");
671
+ end
672
+ updateValue(xmlStreamReader.getText());
673
+ end
674
+
675
+ def processAttribute(prefix, localName, value)
676
+ if (prefix == nil && localName == (FXL::SCRIPT_SOURCE_ATTRIBUTE))
677
+ if (loadListener != nil)
678
+ loadListener.readInternalAttribute(localName, value);
679
+ end
680
+
681
+ @source = value;
682
+ elsif (localName == (FXL::SCRIPT_CHARSET_ATTRIBUTE))
683
+ if (loadListener != nil)
684
+ loadListener.readInternalAttribute(localName, value);
685
+ end
686
+
687
+ @charset = Charset.forName(value);
688
+ else
689
+ raise LoadException.new(prefix == nil ? localName : prefix + ":" + localName + " is not a valid attribute.");
690
+ end
691
+ end
692
+ end
693
+
694
+ # Element representing a define block
695
+ class DefineElement < Element
696
+ def isCollection()
697
+ return true;
698
+ end
699
+
700
+ def add(element)
701
+ rputs parent.value, rget(element)
702
+ # No-op
703
+ end
704
+
705
+ def processAttribute(prefix, localName, value)
706
+ raise LoadException.new("Element does not support attributes.");
707
+ end
708
+ end