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

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.
@@ -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