jrubyfx-fxmlloader-openjfx.patch 0.4.2-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,261 @@
1
+ require_relative './elts'
2
+
3
+ # By Chris on 15th May 2020
4
+ # Support OpenJFX, requires JRuby version that supports OpenJFX
5
+ # OpenJFX no longer includes javafx.geometry.InsetsBuilder
6
+ # Tested on OpenJFX version 11.0.2, 14.01 & 15 ea on 15th May 2020
7
+ class StupidFixTODOInsets
8
+ def initialize()
9
+ super
10
+ end
11
+ add_method_signature :getLeft, [Java::double]
12
+ def getLeft()
13
+
14
+ end
15
+
16
+ add_method_signature :setLeft, [Java::java.lang.Void, Java::double]
17
+ def setLeft(value)
18
+ left(value)
19
+ end
20
+
21
+ add_method_signature :getRight, [Java::double]
22
+ def getRight()
23
+
24
+ end
25
+
26
+ add_method_signature :setRight, [Java::java.lang.Void, Java::double]
27
+ def setRight(value)
28
+ right(value)
29
+ end
30
+ add_method_signature :getBottom, [Java::double]
31
+ def getBottom()
32
+
33
+ end
34
+
35
+ add_method_signature :setBottom, [Java::java.lang.Void, Java::double]
36
+ def setBottom(value)
37
+ bottom(value)
38
+ end
39
+ add_method_signature :getTop, [Java::double]
40
+ def getTop()
41
+
42
+ end
43
+
44
+ add_method_signature :setTop, [Java::java.lang.Void, Java::double]
45
+ def setTop(value)
46
+ top(value)
47
+ end
48
+
49
+ def size
50
+ 990
51
+ end
52
+ def to_s
53
+ "the thingabmabomb"
54
+ end
55
+ def inspect
56
+ "whozamawhatzit"
57
+ end
58
+ end
59
+
60
+ class ValueElement < Element
61
+ attr_accessor :fx_id
62
+ @fx_id = nil;
63
+ def processStartElement
64
+ super
65
+
66
+ updateValue(constructValue());
67
+
68
+ if (value.is_a? Builder)
69
+ processInstancePropertyAttributes();
70
+ else
71
+ processValue();
72
+ end
73
+ end
74
+
75
+ def processEndElement()
76
+ super
77
+
78
+ # Build the value, if necessary
79
+ if (value.is_a? Builder)
80
+ updateValue(value.build());
81
+ processValue();
82
+ else
83
+ processInstancePropertyAttributes();
84
+ end
85
+ processEventHandlerAttributes();
86
+ # Process static property attributes
87
+ if (staticPropertyAttributes.length > 0)
88
+ for attribute in staticPropertyAttributes
89
+ processPropertyAttribute(attribute);
90
+ end
91
+ end
92
+ # Process static property elements
93
+ if (staticPropertyElements.length > 0)
94
+ for element in staticPropertyElements
95
+ RubyWrapperBeanAdapter.put(value, element.sourceType, element.name, element.value);
96
+ end
97
+ end
98
+
99
+ rnest -1
100
+ rputs value, ((rfx_id(value) && rfx_id_set?(value)) || rno_show?(value) ? "" : "end")
101
+ if (parent != nil)
102
+ if (parent.isCollection())
103
+ parent.add(value);
104
+ else
105
+ parent.set value
106
+ end
107
+ end
108
+ end
109
+
110
+ def getListValue( parent, listPropertyName, value)
111
+ # If possible, coerce the value to the list item type
112
+ if (parent.isTyped())
113
+ listType = parent.getValueAdapter().getGenericType(listPropertyName);
114
+
115
+ if (listType != nil)
116
+ itemType = RubyWrapperBeanAdapter.getGenericListItemType(listType);
117
+
118
+ if (itemType.is_a? ParameterizedType)
119
+ itemType = (itemType).getRawType();
120
+ end
121
+
122
+ value = RubyWrapperBeanAdapter.coerce(value,itemType);
123
+ end
124
+ end
125
+
126
+ return value;
127
+ end
128
+
129
+ def processValue()
130
+ # If this is the root element, update the value
131
+ if (parent == nil)
132
+ root = value;
133
+
134
+ # checking version of fx namespace - throw exception if not supported
135
+ fxNSURI = xmlStreamReader.getNamespaceContext().getNamespaceURI("fx");
136
+ if (fxNSURI != nil)
137
+ fxVersion = fxNSURI[(fxNSURI.rindex("/") + 1)..-1];
138
+ if (parentLoader.compareJFXVersions(FxmlLoader::FX_NAMESPACE_VERSION, fxVersion) < 0)
139
+ raise LoadException.new("Loading FXML document of version " + fxVersion + " by JavaFX runtime supporting version " + FxmlLoader::FX_NAMESPACE_VERSION);
140
+ end
141
+ end
142
+
143
+ # checking the version JavaFX API - print warning if not supported
144
+ defaultNSURI = xmlStreamReader.getNamespaceContext().getNamespaceURI("");
145
+ if (defaultNSURI != nil)
146
+ nsVersion = defaultNSURI[(defaultNSURI.rindex("/") + 1)..-1]
147
+ jfx_version = if defined? FXL::JAVAFX_VERSION
148
+ FXL::JAVAFX_VERSION
149
+ else
150
+ "http://javafx.com/javafx/2.2"
151
+ end
152
+ if (parentLoader.compareJFXVersions(jfx_version, nsVersion) < 0)
153
+ Logging.getJavaFXLogger().warning("Loading FXML document with JavaFX API of version " + nsVersion + " by JavaFX runtime of version " + FXL::JAVAFX_VERSION);
154
+ end
155
+ end
156
+ end
157
+
158
+ # Add the value to the namespace
159
+ if (@fx_id != nil)
160
+ parentLoader.namespace[@fx_id] = value
161
+
162
+ # If the value defines an ID property, set it
163
+ idProperty = value.java_class.annotation(IDProperty.java_class);
164
+
165
+ if (idProperty != nil)
166
+ properties = getProperties();
167
+ # set fx:id property value to Node.id only if Node.id was not
168
+ # already set when processing start element attributes
169
+ if (properties[idProperty.value] == nil)
170
+ properties[idProperty.value()]= @fx_id;
171
+ end
172
+ end
173
+ rputs value, "__local_fx_id_setter.call(#{@fx_id.inspect}, self)"
174
+ rfx_id value, @fx_id
175
+ # Set the controller field value
176
+ if (parentLoader.controller != nil)
177
+ field = parentLoader.controller.instance_variable_set("@" + @fx_id, value)
178
+ end
179
+ end
180
+ end
181
+
182
+ def processCharacters()
183
+ type = value.java_class
184
+ defaultProperty = type.getAnnotation(DefaultProperty.java_class);
185
+
186
+ # If the default property is a read-only list, add the value to it;
187
+ # otherwise, set the value as the default property
188
+ if (defaultProperty != nil)
189
+ text = xmlStreamReader.getText();
190
+ #TODO: FIX
191
+ text = extraneousWhitespacePattern.matcher(text).replaceAll(" ");
192
+
193
+ defaultPropertyName = defaultProperty.value();
194
+ valueAdapter = getValueAdapter();
195
+
196
+ if (valueAdapter.read_only?(defaultPropertyName) && List.class.isAssignableFrom(valueAdapter.getType(defaultPropertyName)))
197
+ list = valueAdapter.get(defaultPropertyName);
198
+ list.add(getListValue(self, defaultPropertyName, text));
199
+ else
200
+ valueAdapter.put(defaultPropertyName, text.strip);
201
+ end
202
+ else
203
+ throw LoadException.new(type.getName() + " does not have a default property.");
204
+ end
205
+ end
206
+
207
+ def processAttribute( prefix, localName, value)
208
+ if (prefix != nil && prefix == (FXL::FX_NAMESPACE_PREFIX))
209
+ if (localName == (FXL::FX_ID_ATTRIBUTE))
210
+ # Verify that ID is a valid identifier
211
+ if (value == (FXL::NULL_KEYWORD))
212
+ raise LoadException.new("Invalid identifier.");
213
+ end
214
+ #
215
+ # value.length.times do |i|
216
+ # # TODO: FIX
217
+ # if (!Java.java.lang.Character.java_send :isJavaIdentifierPart, [Java::char], value[i].to_java(:char))
218
+ # raise LoadException.new("Invalid identifier.");
219
+ # end
220
+ # end
221
+ @fx_id = value;
222
+
223
+ elsif (localName == (FXL::FX_CONTROLLER_ATTRIBUTE))
224
+ if (parentLoader.current.parent != nil)
225
+ raise LoadException.new(FXL::FX_NAMESPACE_PREFIX + ":" + FXL::FX_CONTROLLER_ATTRIBUTE + " can only be applied to root element.");
226
+ end
227
+
228
+ if (parentLoader.controller != nil)
229
+ raise LoadException.new("Controller value already specified.");
230
+ end
231
+
232
+ if (!staticLoad)
233
+ type = nil
234
+ begin
235
+ type = value.constantize_by
236
+ rescue ClassNotFoundException => exception
237
+ raise LoadException.new(exception);
238
+ end
239
+
240
+ begin
241
+ if (parentLoader.controllerFactory == nil)
242
+ # TODO: does this work?
243
+ parentLoader.controller = type.new
244
+ else
245
+ parentLoder.controller = (parentLoader.controllerFactory.call(type));
246
+ end
247
+ rescue InstantiationException => exception
248
+ raise LoadException.new(exception);
249
+ rescue IllegalAccessException => exception
250
+ raise LoadException.new(exception);
251
+ end
252
+ end
253
+ else
254
+ raise LoadException.new("Invalid attribute.");
255
+ end
256
+ else
257
+ super(prefix, localName, value);
258
+ end
259
+ end
260
+
261
+ end
@@ -0,0 +1,800 @@
1
+ =begin
2
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
+ *
5
+ * This code is free software; you can redistribute it and/or modify it
6
+ * under the terms of the GNU General Public License version 2 only, as
7
+ * published by the Free Software Foundation. Oracle designates this
8
+ * particular file as subject to the "Classpath" exception as provided
9
+ * by Oracle in the LICENSE file that accompanied this code.
10
+ *
11
+ * This code is distributed in the hope that it will be useful, but WITHOUT
12
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
+ * version 2 for more details (a copy is included in the LICENSE file that
15
+ * accompanied this code).
16
+ *
17
+ * You should have received a copy of the GNU General Public License version
18
+ * 2 along with this work; if not, write to the Free Software Foundation,
19
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ *
21
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
+ * or visit www.oracle.com if you need additional information or have any
23
+ * questions.
24
+ */
25
+ =end
26
+
27
+
28
+ begin
29
+ # Attempt to load a javafx class
30
+ Java.javafx.application.Application
31
+ rescue LoadError, NameError
32
+ puts "JRubyFX and JavaFX runtime not found. Please load this file from JRubyFX"
33
+ exit -2
34
+ end
35
+
36
+ java_import 'javafx.fxml.JavaFXBuilderFactory'
37
+ java_import 'java.lang.InstantiationException', 'java.lang.IllegalAccessException'
38
+
39
+ java_import *%w[
40
+ java.io.IOException
41
+ java.io.InputStream
42
+ java.io.InputStreamReader
43
+ java.lang.ClassNotFoundException
44
+ java.lang.reflect.InvocationTargetException
45
+ java.lang.reflect.Modifier
46
+ java.lang.reflect.ParameterizedType
47
+ java.net.URL
48
+ java.nio.charset.Charset
49
+ java.util.AbstractMap
50
+ java.util.List
51
+ java.util.ResourceBundle
52
+
53
+ javafx.beans.DefaultProperty
54
+ javafx.beans.property.Property
55
+ javafx.beans.value.ChangeListener
56
+ javafx.beans.value.ObservableValue
57
+ javafx.collections.FXCollections
58
+ javafx.collections.ListChangeListener
59
+ javafx.collections.MapChangeListener
60
+ javafx.collections.ObservableList
61
+ javafx.collections.ObservableMap
62
+ javafx.event.Event
63
+ javafx.event.EventHandler
64
+ javafx.event.EventType
65
+ javafx.util.Builder
66
+ javafx.util.BuilderFactory
67
+ javafx.util.Callback
68
+
69
+ javax.script.Bindings
70
+ javax.script.ScriptContext
71
+ javax.script.ScriptEngine
72
+ javax.script.ScriptEngineManager
73
+ javax.script.ScriptException
74
+ javax.script.SimpleBindings
75
+ javax.xml.stream.XMLInputFactory
76
+ javax.xml.stream.XMLStreamConstants
77
+ javax.xml.stream.XMLStreamException
78
+ javax.xml.stream.XMLStreamReader
79
+ javax.xml.stream.util.StreamReaderDelegate
80
+
81
+ com.sun.javafx.beans.IDProperty
82
+ java.net.MalformedURLException
83
+ java.security.AccessController
84
+ java.security.PrivilegedAction
85
+ java.util.Locale
86
+ java.lang.NoSuchMethodException
87
+ java.util.StringTokenizer
88
+ sun.reflect.misc.ConstructorUtil
89
+ sun.reflect.misc.FieldUtil
90
+ sun.reflect.misc.MethodUtil
91
+ sun.reflect.misc.ReflectUtil]
92
+
93
+ class LoadException < Exception
94
+ def initialize(stuff)
95
+ super
96
+ end
97
+ end
98
+ $DEBUG_IT_FXML = false
99
+ def dp(*args)
100
+ p *args if $DEBUG_IT_FXML
101
+ end
102
+ def dputs(*args)
103
+ puts *args if $DEBUG_IT_FXML
104
+ end
105
+ def dprint(*args)
106
+ print *args if $DEBUG_IT_FXML
107
+ end
108
+ # TODO: clean this up
109
+ $RB_PREFIX = ""
110
+ def rnest(num)
111
+ if num > 0
112
+ $RB_PREFIX += " "
113
+ else
114
+ $RB_PREFIX = $RB_PREFIX[0...-1]
115
+ end
116
+ end
117
+ $RB_MAPPER = {}
118
+ $RB_CMAPPER = {}
119
+ $RB_IDMAPPER = {}
120
+ $RB_NShowMAPPER = {}
121
+ $last_elt = nil
122
+
123
+ def rno_show(elt)
124
+ $RB_NShowMAPPER[elt]=true
125
+ end
126
+ def rno_show?(elt)
127
+ !!$RB_NShowMAPPER[elt]
128
+ end
129
+
130
+ def rmap_wrap(elt)
131
+ if elt.kind_of? Java::ComSunJavafxCollections::ObservableListWrapper
132
+ SecretHashCompararator.new(elt)
133
+ else
134
+ elt
135
+ end
136
+ end
137
+ def rputs(elt, args)
138
+ if $DEBUG_IT_FXML_RB
139
+ if elt == nil
140
+ elt = $last_elt
141
+ else
142
+ $last_elt = elt = rmap_wrap(elt)
143
+ end
144
+ unless $RB_MAPPER[elt]
145
+ $RB_MAPPER[elt] = ""
146
+ end
147
+ $RB_MAPPER[elt] << $RB_PREFIX
148
+ $RB_MAPPER[elt] << args
149
+ $RB_MAPPER[elt] << "\n"
150
+ end
151
+ end
152
+
153
+ def rfx_id(elt, val=nil)
154
+ elt = rmap_wrap elt
155
+ if val
156
+ $RB_IDMAPPER[elt] = val
157
+ else
158
+ $RB_IDMAPPER[elt]
159
+ end
160
+ end
161
+ def rfx_id_set?(elt)
162
+ elt = rmap_wrap elt
163
+ !$RB_MAPPER[elt] or $RB_MAPPER[elt].include? "instance_variable_get(#{("@" + rfx_id(elt)).to_sym.inspect})"
164
+ end
165
+ def rmorph(old, new)
166
+ elt = rmap_wrap elt
167
+ $RB_MAPPER[new] = "build(FxmlBuilderBuilder, #{($RB_CMAPPER[old]||{}).inspect}, #{old.wrapped_class.ruby_class.inspect}) do\n"
168
+ end
169
+
170
+ def rctor(elt, k, v)
171
+ if $DEBUG_IT_FXML_RB
172
+ elt = rmap_wrap elt
173
+ $RB_CMAPPER[elt] = {} unless $RB_CMAPPER[elt]
174
+ $RB_CMAPPER[elt][k] = v
175
+ end
176
+ end
177
+ def rget(elt, action=:nuke_from_standard_orbit_captain)
178
+ elt = rmap_wrap elt
179
+ tmp = $RB_MAPPER[elt]
180
+ tmp.strip! if tmp
181
+ $RB_MAPPER[elt] = rfx_id(elt) ? "__local_fxml_controller.instance_variable_get(#{("@" + rfx_id(elt)).to_sym.inspect})" : nil
182
+
183
+ tmp
184
+ end
185
+ $RB_SCRIPT_ENGINE_MAPPINGS = {}
186
+ def rputs_script(sem, lang)
187
+ $RB_SCRIPT_ENGINE_MAPPINGS[sem] = lang
188
+ end
189
+
190
+ def rget_sem(sem)
191
+ $RB_SCRIPT_ENGINE_MAPPINGS[sem]
192
+ end
193
+
194
+ def rsem_out
195
+ if $RB_SCRIPT_ENGINE_MAPPINGS != {}
196
+ ["(__local_sem_inst = Java.javax.script.ScriptEngineManager.new).setBindings(javax.script.SimpleBindings.new(__local_namespace))",
197
+ *$RB_SCRIPT_ENGINE_MAPPINGS.map{|sem, lang|
198
+ "(__local_sem_lang_inst_#{lang} = __local_sem_inst.getEngineByName(#{lang.inspect}))" +
199
+ ".setBindings(__local_sem_inst.getBindings(), javax.script.ScriptContext.ENGINE_SCOPE)"
200
+ }
201
+ ].join("\n")
202
+ end
203
+ end
204
+
205
+ class SecretHashCompararator
206
+ attr_accessor :obj
207
+ def initialize(obj)
208
+ @obj = obj
209
+ end
210
+ def hash
211
+ @obj.object_id
212
+ end
213
+ def eql?(rhs)
214
+ self == rhs
215
+ end
216
+ def ==(rhs)
217
+ @obj.object_id == rhs.object_id or (rhs.is_a? SecretHashCompararator and @obj.object_id == rhs.hash)
218
+ end
219
+ end
220
+
221
+ class FxmlBuilderBuilder # the builder builder (builds builders)
222
+ @@bf = Java::javafx.fxml.JavaFXBuilderFactory.new(JRuby.runtime.jruby_class_loader)
223
+ def self.new(arg_map, builder_type)
224
+ builder = @@bf.getBuilder(builder_type)
225
+ arg_map.each do |k, v|
226
+ builder.put(k, v) # DON't use []= or we have to wrap it
227
+ end
228
+ builder.build
229
+ end
230
+ end
231
+
232
+ class FactoryBuilderBuilder # builder to build factories
233
+ def self.new(type, factory)
234
+ type = type.java_class
235
+ factoryMethod = nil
236
+ begin
237
+ factoryMethod = MethodUtil.getMethod(type, factory, []);
238
+ rescue NoSuchMethodException => exception
239
+ raise LoadException.new(exception);
240
+ end
241
+
242
+ begin
243
+ return MethodUtil.invoke(factoryMethod, nil, []);
244
+ rescue IllegalAccessException => exception
245
+ raise LoadException.new(exception);
246
+ rescue InvocationTargetException => exception
247
+ raise LoadException.new(exception);
248
+ end
249
+ end
250
+ end
251
+
252
+ # Override to safely get ruby class of non-java_class objects
253
+ class Class
254
+ def ruby_class
255
+ self
256
+ end
257
+ end
258
+
259
+ FXL = java_import('javafx.fxml.FXMLLoader')[0]
260
+ class FxmlLoader
261
+ attr_accessor :location, :root, :template, :builderFactory, :namespace, :staticLoad, :current, :controllerFactory, :charset
262
+ attr_accessor :scriptEngine
263
+ attr_reader :controller
264
+ FX_NAMESPACE_VERSION="1"
265
+ @@fxml_jit_info = {}
266
+ def initialize(url=nil, ctrlr=nil, resourcs=nil, buildFactory=nil, charset=nil, loaders=nil)
267
+ @location = url
268
+ @builderFactory = buildFactory || JavaFXBuilderFactory.new(JRuby.runtime.jruby_class_loader)
269
+ @template = false
270
+ @namespace = FXCollections.observableHashMap()
271
+ self.controller = ctrlr
272
+ @packages = []
273
+ @classes = {}
274
+ @root = nil
275
+ @charset = charset || Charset.forName(FXL::DEFAULT_CHARSET_NAME)
276
+ end
277
+
278
+ def controller=(controller)
279
+ @controller = controller
280
+ unless controller
281
+ @namespace.delete(FXL::CONTROLLER_KEYWORD)
282
+ else
283
+ @namespace[FXL::CONTROLLER_KEYWORD] = controller
284
+ end
285
+ end
286
+
287
+ # either :no_jit, or a number above 0 representing the number of times before jitting a fxml file
288
+ def load(jruby_exts = {jruby_ext: {}})
289
+ @jruby_ext = {jit: 0}.merge(jruby_exts[:jruby_ext])
290
+ # TODO: actually open it properly
291
+ unless jit_info = @@fxml_jit_info[file_path = @location.to_s]
292
+ validate = true
293
+ validate = @jruby_ext[:jit_validate] if @jruby_ext.has_key? :jit_validate
294
+ jit_info = @@fxml_jit_info[file_path] = FxmlJitInfo.new(file_path, @jruby_ext[:jit], @jruby_ext[:jit_save_to], @jruby_ext[:jit_cache], validate, @jruby_ext[:jit_opts])
295
+ end
296
+ inputStream = @location.open_stream
297
+ if @template
298
+ @root = nil
299
+ else
300
+ clearImports
301
+ end
302
+
303
+ @namespace[FXL::LOCATION_KEY] = @location
304
+ @namespace[FXL::RESOURCES_KEY] = @resources
305
+
306
+ @script_engine = nil
307
+
308
+ difx = $DEBUG_IT_FXML_RB # TODO: hack to make this somewhat better at recursion
309
+ # if we have it cached, use the jitted method
310
+ if jit_info.compiled?
311
+ begin
312
+ return :dont_load if @jruby_ext[:dont_load]
313
+ $DEBUG_IT_FXML_RB = jit_info.should_jit?
314
+ res = jit_info.__build_via_jit(@controller, @namespace, @jruby_ext)
315
+ $DEBUG_IT_FXML_RB = difx # restore
316
+ return res
317
+ rescue Exception, java.lang.Throwable
318
+ puts "JIT compiled method for #{@location.to_s} FAILED with error:"
319
+ puts $!
320
+ puts $!.backtrace
321
+ puts "Reverting to normal parsing..."
322
+ jit_info.jit_settings = :no_jit
323
+ jit_info.decompile
324
+ end
325
+ end
326
+
327
+ $DEBUG_IT_FXML_RB = jit_info.should_jit?
328
+
329
+ begin
330
+ xmlInputFactory = XMLInputFactory.newFactory
331
+ xmlInputFactory.setProperty("javax.xml.stream.isCoalescing", true)
332
+
333
+ # Some stream readers incorrectly report an empty string as the prefix
334
+ # for the default namespace; correct this as needed
335
+ inputStreamReader = InputStreamReader.new(inputStream, @charset);
336
+ @xmlStreamReader = SRDelegateClass.new(xmlInputFactory.createXMLStreamReader(inputStreamReader))
337
+ rescue XMLStreamException => e
338
+ raise LoadException.new(e)
339
+ end
340
+
341
+ # Parse the XML stream
342
+ begin
343
+ while @xmlStreamReader.hasNext()
344
+ event = @xmlStreamReader.next();
345
+ case event
346
+ when XMLStreamConstants::PROCESSING_INSTRUCTION
347
+ processProcessingInstruction
348
+ when XMLStreamConstants::COMMENT
349
+ processComment
350
+ when XMLStreamConstants::START_ELEMENT
351
+ processStartElement
352
+ when XMLStreamConstants::END_ELEMENT
353
+ processEndElement
354
+ when XMLStreamConstants::CHARACTERS
355
+ processCharacters
356
+ end
357
+ end
358
+ rescue XMLStreamException => exception
359
+ raise Exception.new(exception)
360
+ end
361
+ if @controller
362
+ # TODO: initialize should be called here
363
+ # Inject controller fields
364
+ @controller.instance_variable_set("@" + FXL::LOCATION_KEY, @location)
365
+ @controller.instance_variable_set("@" + FXL::RESOURCES_KEY, @resources)
366
+ end
367
+ if $DEBUG_IT_FXML_RB
368
+ code = "#{rsem_out}\n#{rget @root}"
369
+ jit_info.compile(code)
370
+ end
371
+ $RB_CMAPPER = {}
372
+ $RB_IDMAPPER = {}
373
+ $RB_MAPPER = {}
374
+ $RB_PREFIX = ""
375
+ $RB_NShowMAPPER = {}
376
+ $last_elt = nil
377
+ $RB_SCRIPT_ENGINE_MAPPINGS = {}
378
+
379
+ @xmlStreamReader = nil
380
+ $DEBUG_IT_FXML_RB = difx # restore
381
+ return @root
382
+ end
383
+
384
+ def clearImports
385
+ @packages.clear
386
+ @classes.clear
387
+ end
388
+
389
+ def processProcessingInstruction
390
+ piTarget = @xmlStreamReader.getPITarget().strip
391
+ if piTarget == FXL::LANGUAGE_PROCESSING_INSTRUCTION
392
+ processLanguage
393
+ elsif piTarget == FXL::IMPORT_PROCESSING_INSTRUCTION
394
+ processImport
395
+ end
396
+ end
397
+
398
+ def processLanguage
399
+ if @scriptEngine
400
+ raise LoadException.new("Page language already set.")
401
+ end
402
+
403
+ language = @xmlStreamReader.getPIData()
404
+
405
+ if @loadListener
406
+ @loadListener.readLanguageProcessingInstruction(language)
407
+ end
408
+
409
+ unless staticLoad
410
+ scriptEngineManager = getScriptEngineManager()
411
+ @scriptEngine = scriptEngineManager.getEngineByName(language)
412
+ rputs_script @scriptEngine, language
413
+ @scriptEngine.setBindings(scriptEngineManager.getBindings(), ScriptContext.ENGINE_SCOPE)
414
+ end
415
+ end
416
+
417
+ def processImport
418
+ target = @xmlStreamReader.getPIData().strip
419
+
420
+ if @loadListener
421
+ @loadListener.readImportProcessingInstruction(target)
422
+ end
423
+
424
+ if target.end_with?(".*")
425
+ importPackage(target[0,target.length - 2])
426
+ else
427
+ importClass(target)
428
+ end
429
+ end
430
+
431
+ def processComment
432
+ @loadListener.readComment(@xmlStreamReader.text) if @loadListener
433
+ end
434
+
435
+ def processStartElement()
436
+ # Create the element
437
+ createElement();
438
+
439
+ # Process the start tag
440
+ @current.processStartElement();
441
+
442
+ # Set the root value
443
+ unless @root
444
+ @root = @current.value;
445
+ rputs @root, "__local_jruby_ext[:on_root_set].call(self) if __local_jruby_ext[:on_root_set]"
446
+ @jruby_ext[:on_root_set].call(@root) if @jruby_ext[:on_root_set]
447
+ end
448
+ end
449
+
450
+ def createElement()
451
+ prefix = @xmlStreamReader.getPrefix();
452
+ localName = @xmlStreamReader.getLocalName();
453
+
454
+ if !prefix
455
+ i = localName.rindex('.')
456
+
457
+ if localName[(i ? i : -1) + 1] == localName[(i ? i : -1) + 1].downcase
458
+ name = localName[((i ? i : -1) + 1)..-1]
459
+
460
+ if (i == nil)
461
+ # This is an instance property
462
+ if @loadListener
463
+ @loadListener.beginPropertyElement(name, nil)
464
+ end
465
+
466
+ @current = PropertyElement.new(@current, @xmlStreamReader, @loadListener, self, name, nil)
467
+ else
468
+ # This is a static property
469
+ sourceType = getType(localName[0, i]);
470
+ if sourceType
471
+ if @loadListener
472
+ @loadListener.beginPropertyElement(name, sourceType);
473
+ end
474
+
475
+ @current = PropertyElement.new(@current, @xmlStreamReader, @loadListener, self,name, sourceType)
476
+ elsif (@staticLoad)
477
+ # The source type was not recognized
478
+ if @loadListener
479
+ @loadListener.beginUnknownStaticPropertyElement(localName);
480
+ end
481
+
482
+ @current = FXL::UnknownStaticPropertyElement.new
483
+ else
484
+ raise LoadException.new(localName + " is not a valid property.");
485
+ end
486
+ end
487
+ else
488
+ if (@current == nil && @root)
489
+ raise LoadException.new("Root value already specified.");
490
+ end
491
+
492
+ type = getType(localName);
493
+ prefixz = @xmlStreamReader.getLocation().getLineNumber().to_s + ": "
494
+ numz = 1
495
+ pppn = @current
496
+ while pppn
497
+ numz+=1
498
+ pppn = pppn.parent
499
+ end
500
+ prefixz = (" " * numz) + prefixz
501
+
502
+ if type
503
+ if @loadListener
504
+ @loadListener.beginInstanceDeclarationElement(type);
505
+ end
506
+ @current = InstanceDeclarationElement.new(@current, @xmlStreamReader, @loadListener, self, type)
507
+ elsif (@staticLoad)
508
+ # The type was not recognized
509
+ if @loadListener
510
+ @loadListener.beginUnknownTypeElement(localName);
511
+ end
512
+
513
+ @current = UnknownTypeElement.new(@current, @xmlStreamReader, @loadListener, self)
514
+ else
515
+ raise LoadException.new(localName + " is not a valid type.");
516
+ end
517
+ end
518
+ elsif prefix == FXL::FX_NAMESPACE_PREFIX
519
+ if localName == FXL::INCLUDE_TAG
520
+ if @loadListener
521
+ @loadListener.beginIncludeElement()
522
+ end
523
+ @current = IncludeElement.new(@current, @xmlStreamReader, @loadListener, self)
524
+ elsif localName == FXL::REFERENCE_TAG
525
+ if @loadListener
526
+ @loadListener.beginReferenceElement
527
+ end
528
+
529
+ @current = ReferenceElement.new(@current, @xmlStreamReader, @loadListener, self)
530
+ elsif localName == FXL::COPY_TAG
531
+ if @loadListener
532
+ @loadListener.beginCopyElement();
533
+ end
534
+
535
+ @current = CopyElement.new(@current, @xmlStreamReader, @loadListener, self)
536
+ elsif localName == FXL::ROOT_TAG
537
+ if @loadListener
538
+ @loadListener.beginRootElement();
539
+ end
540
+
541
+ @current = RootElement.new(@current, @xmlStreamReader, @loadListener, self)
542
+ elsif localName == FXL::SCRIPT_TAG
543
+ if @loadListener
544
+ @loadListener.beginScriptElement();
545
+ end
546
+
547
+ @current = ScriptElement.new(@current, @xmlStreamReader, @loadListener, self)
548
+ elsif localName == FXL::DEFINE_TAG
549
+ if @loadListener
550
+ @loadListener.beginDefineElement();
551
+ end
552
+
553
+ @current = DefineElement.new(@current, @xmlStreamReader, @loadListener, self)
554
+ else
555
+ raise LoadException.new(prefix + ":" + localName + " is not a valid element.");
556
+ end
557
+ else
558
+ raise LoadException.new("Unexpected namespace prefix: " + prefix + ".");
559
+ end
560
+ end
561
+
562
+ def processEndElement()
563
+ @current.processEndElement();
564
+ if @loadListener
565
+ @loadListener.endElement(@current.value);
566
+ end
567
+
568
+ # Move up the stack
569
+ @current = @current.parent;
570
+ end
571
+
572
+ def processCharacters()
573
+ # Process the characters
574
+ if (!@xmlStreamReader.isWhiteSpace())
575
+ @current.processCharacters();
576
+ end
577
+ end
578
+
579
+ def importPackage(name)
580
+ @packages << name
581
+ end
582
+
583
+ def importClass(name)
584
+ begin
585
+ loadType(name, true);
586
+ rescue ClassNotFoundException => exception
587
+ raise LoadException.new(exception);
588
+ end
589
+ end
590
+
591
+ def getType(name)
592
+ type = nil
593
+
594
+ if name[0] == name[0].downcase
595
+ # This is a fully-qualified class name
596
+ begin
597
+ type = loadType(name, false);
598
+ rescue ClassNotFoundException => exception
599
+ # No-op
600
+ end
601
+ else
602
+ # This is an unqualified class name
603
+ type = @classes[name];
604
+
605
+ unless type
606
+ # The class has not been loaded yet; look it up
607
+ @packages.each do |packageName|
608
+ begin
609
+ type = loadTypeForPackage(packageName, name);
610
+ rescue ClassNotFoundException => exception
611
+ # No-op
612
+ end
613
+ break if type
614
+ end
615
+ unless type
616
+ # check for ruby
617
+ # TODO: this should require an import or something perhaps? need to think more about this?
618
+ begin
619
+ type = name.constantize_by(".")
620
+ rescue
621
+ # No-op
622
+ end
623
+ end
624
+ @classes[name] = type if type
625
+ end
626
+ end
627
+
628
+ return type;
629
+ end
630
+
631
+ def loadType(name, cache)
632
+ i = name.index('.');
633
+ n = name.length;
634
+ while (i &&
635
+ i < n &&
636
+ name[i + 1] == name[i + 1].downcase)
637
+ i = name.index('.', i + 1);
638
+ end
639
+
640
+ if (i == nil || i == n)
641
+ raise ClassNotFoundException.new();
642
+ end
643
+
644
+ packageName = name[0, i];
645
+ className = name[(i + 1)..-1];
646
+
647
+ type = loadTypeForPackage(packageName, className);
648
+
649
+ if (cache)
650
+ @classes[className] = type
651
+ end
652
+
653
+ return type;
654
+ end
655
+
656
+
657
+ def getScriptEngineManager()
658
+ unless @scriptEngineManager
659
+ @scriptEngineManager = Java.javax.script.ScriptEngineManager.new
660
+ @scriptEngineManager.setBindings(SimpleBindings.new(@namespace))
661
+ end
662
+
663
+ return @scriptEngineManager;
664
+ end
665
+
666
+ def loadTypeForPackage(packageName, className=nil)
667
+ packageName = (packageName + "." + className.gsub('.', '$')) if className
668
+ begin
669
+ return JavaUtilities.get_proxy_class(packageName).java_class.to_java
670
+ rescue NameError => ex
671
+ # probably ruby class
672
+ begin
673
+ return packageName.constantize_by(".")
674
+ rescue
675
+ raise ClassNotFoundException.new(packageName) # nope, not our issue anymore
676
+ end
677
+ end
678
+ end
679
+ def compareJFXVersions(rtVer, nsVer)
680
+
681
+ retVal = 0;
682
+
683
+ if (rtVer == nil || "" == (rtVer) || nsVer == nil || "" == (nsVer))
684
+ return retVal;
685
+ end
686
+
687
+ if (rtVer == (nsVer))
688
+ return retVal;
689
+ end
690
+
691
+ # version string can contain '-'
692
+ dashIndex = rtVer.index("-");
693
+ dashIndex = -1 unless dashIndex
694
+ if (dashIndex > 0)
695
+
696
+ rtVer = rtVer[0, dashIndex]
697
+ end
698
+
699
+ # or "_"
700
+ underIndex = rtVer.index("_");
701
+ underIndex = -1 unless underIndex
702
+ if (underIndex > 0)
703
+
704
+ rtVer = rtVer[0, underIndex]
705
+ end
706
+
707
+ # do not try to compare if the string is not valid version format
708
+ if (!rtVer.match(/^(\d+)(\.\d+)*$/) || !nsVer.match(/^(\d+)(\.\d+)*$/))
709
+ return retVal;
710
+ end
711
+
712
+ nsVerTokenizer = StringTokenizer.new(nsVer, ".");
713
+ rtVerTokenizer = StringTokenizer.new(rtVer, ".");
714
+ nsDigit = 0
715
+ rtDigit = 0;
716
+ rtVerEnd = false;
717
+
718
+ while (nsVerTokenizer.hasMoreTokens() && retVal == 0)
719
+ nsDigit = nsVerTokenizer.nextToken().to_i
720
+ if (rtVerTokenizer.hasMoreTokens())
721
+ rtDigit = rtVerTokenizer.nextToken().to_i
722
+ retVal = rtDigit - nsDigit;
723
+ else
724
+ rtVerEnd = true;
725
+ break;
726
+ end
727
+ end
728
+
729
+ if (rtVerTokenizer.hasMoreTokens() && retVal == 0)
730
+ rtDigit = rtVerTokenizer.nextToken().to_i
731
+ if (rtDigit > 0)
732
+ retVal = 1;
733
+ end
734
+ end
735
+
736
+ if (rtVerEnd)
737
+ if (nsDigit > 0)
738
+ retVal = -1;
739
+ else
740
+ while (nsVerTokenizer.hasMoreTokens())
741
+ nsDigit = nsVerTokenizer.nextToken().to_i
742
+ if (nsDigit > 0)
743
+ retVal = -1;
744
+ break;
745
+ end
746
+ end
747
+ end
748
+ end
749
+
750
+ return retVal;
751
+ end
752
+ end
753
+
754
+ class SRDelegateClass < StreamReaderDelegate
755
+ def getPrefix()
756
+
757
+ prefix = super
758
+
759
+ if prefix && prefix.length == 0
760
+ prefix = nil
761
+ end
762
+ return prefix;
763
+ end
764
+
765
+ def getAttributePrefix(index)
766
+ prefix = super
767
+
768
+ if prefix && prefix.length == 0
769
+ prefix = nil
770
+ end
771
+ return prefix;
772
+ end
773
+ end
774
+
775
+ require_relative 'fxmlloader/j8_expression_value'
776
+ require_relative 'fxmlloader/elts'
777
+ require_relative 'fxmlloader/value_elts'
778
+ require_relative 'fxmlloader/real_elts'
779
+ require_relative 'fxmlloader/rrba'
780
+ require_relative 'fxmlloader/rorba'
781
+ require_relative 'fxmlloader/fxml_jit_info'
782
+ require_relative 'FXMLLoader-j8.jar'
783
+
784
+ java_import 'org.jruby.jfx8.KeyPath'
785
+ java_import 'org.jruby.jfx8.Expression'
786
+
787
+
788
+ class RRBAdapters < org.jruby.jfx8.RubyBeanAdapter
789
+ def get(names, key)
790
+ RubyWrapperBeanAdapter.for(names)[key]
791
+ end
792
+ def set(names, key, value)
793
+ RubyWrapperBeanAdapter.for(names)[key] = value
794
+ end
795
+ def contains(names, key)
796
+ RubyWrapperBeanAdapter.for(names).has_key? key
797
+ end
798
+ end
799
+
800
+ org.jruby.jfx8.RubyBeanAdapter.load_ruby_space RRBAdapters.new