jrubyfx-fxmlloader-openjfx.patch 0.4.2-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.
- checksums.yaml +7 -0
- data/LICENSE +25 -0
- data/README +17 -0
- data/Rakefile +72 -0
- data/lib/FXMLLoader-j8.jar +0 -0
- data/lib/fxmlloader/elts.rb +576 -0
- data/lib/fxmlloader/fxml_jit_info.rb +158 -0
- data/lib/fxmlloader/j8_expression_value.rb +290 -0
- data/lib/fxmlloader/real_elts.rb +708 -0
- data/lib/fxmlloader/rorba.rb +107 -0
- data/lib/fxmlloader/rrba.rb +769 -0
- data/lib/fxmlloader/value_elts.rb +261 -0
- data/lib/jrubyfx-fxmlloader.rb +800 -0
- metadata +59 -0
@@ -0,0 +1,158 @@
|
|
1
|
+
# * Copyright (c) 2013 Patrick Plenefisch
|
2
|
+
# * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
3
|
+
# *
|
4
|
+
# * This code is free software; you can redistribute it and/or modify it
|
5
|
+
# * under the terms of the GNU General Public License version 2 only, as
|
6
|
+
# * published by the Free Software Foundation. Oracle designates this
|
7
|
+
# * particular file as subject to the "Classpath" exception as provided
|
8
|
+
# * by Oracle in the LICENSE file that accompanied this code.
|
9
|
+
# *
|
10
|
+
# * This code is distributed in the hope that it will be useful, but WITHOUT
|
11
|
+
# * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
12
|
+
# * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
13
|
+
# * version 2 for more details (a copy is included in the LICENSE file that
|
14
|
+
# * accompanied this code).
|
15
|
+
# *
|
16
|
+
# * You should have received a copy of the GNU General Public License version
|
17
|
+
# * 2 along with this work; if not, write to the Free Software Foundation,
|
18
|
+
# * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
19
|
+
# *
|
20
|
+
|
21
|
+
require 'digest/sha1'
|
22
|
+
require 'fileutils'
|
23
|
+
|
24
|
+
def javafx
|
25
|
+
Java::javafx
|
26
|
+
end
|
27
|
+
|
28
|
+
Infinity = 1.0/0.0
|
29
|
+
|
30
|
+
class FxmlJitInfo
|
31
|
+
include JRubyFX
|
32
|
+
def self.hash(file)
|
33
|
+
Digest::SHA1.hexdigest(File.read file)
|
34
|
+
end
|
35
|
+
def self.load_aot(file, cache, validate = true)
|
36
|
+
if validate
|
37
|
+
hash = hash(file)
|
38
|
+
f_hash = File.open(cache, "r", &:readline).strip
|
39
|
+
return false if "# #{hash} encoding: utf-8" != f_hash
|
40
|
+
end
|
41
|
+
hash = Digest::SHA1.hexdigest(File.basename file)
|
42
|
+
require cache
|
43
|
+
JRubyFX::GeneratedAssets.const_get("AOT#{hash}").new rescue nil
|
44
|
+
end
|
45
|
+
# TODO: store jit settings in here instead of $RB_* variables
|
46
|
+
attr_accessor :file_name, :raw_code, :jit_settings
|
47
|
+
def initialize(file_name, jit_settings=1, outfile=nil, cache_dir=nil,validate = true, opts = nil)
|
48
|
+
@file_name = file_name
|
49
|
+
@no_write = (opts && opts[:no_write]) || false
|
50
|
+
if @file_name.start_with? "file:"
|
51
|
+
@file_name = @file_name.gsub(/^file\:/, '')
|
52
|
+
elsif @file_name.start_with? "jar:"
|
53
|
+
@no_write = true
|
54
|
+
elsif @file_name.start_with? "compoundjar:"
|
55
|
+
@no_write = true
|
56
|
+
end
|
57
|
+
@jit_settings = jit_settings
|
58
|
+
@run_count = 0
|
59
|
+
@opts = opts
|
60
|
+
@outfile = if @outfile
|
61
|
+
outfile
|
62
|
+
else
|
63
|
+
cache_dir = cache_dir || File.join(File.dirname(@file_name), ".jrubyfx_cache")
|
64
|
+
FileUtils.mkpath(cache_dir) unless File.directory?(cache_dir) or @no_write
|
65
|
+
@f_hash = Digest::SHA1.hexdigest(File.basename @file_name)
|
66
|
+
File.join(cache_dir, "#{@f_hash}.rb")
|
67
|
+
end
|
68
|
+
if File.exist?(@outfile) && !(opts && opts[:force])
|
69
|
+
@compiled = self.class.load_aot(@file_name, @outfile, validate)
|
70
|
+
if @compiled
|
71
|
+
dputs "got #{file_name} from cache"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
def hash
|
76
|
+
FxmlJitInfo.hash(@file_name)
|
77
|
+
end
|
78
|
+
def should_jit?
|
79
|
+
return false if @jit_settings == :no_jit || compiled?
|
80
|
+
return true if (@run_count += 1) >= @jit_settings
|
81
|
+
end
|
82
|
+
def compiled?
|
83
|
+
!!@compiled
|
84
|
+
end
|
85
|
+
def decompile
|
86
|
+
@compiled = nil
|
87
|
+
end
|
88
|
+
def __build_via_jit(__local_fxml_controller, __local_namespace, __local_jruby_ext)
|
89
|
+
@compiled.__build_via_jit(__local_fxml_controller, __local_namespace, __local_jruby_ext)
|
90
|
+
end
|
91
|
+
def compile(code=@raw_code)
|
92
|
+
@raw_code = code
|
93
|
+
# TODO: begin rescue end
|
94
|
+
full_code = <<METHOD_DEF
|
95
|
+
def __build_via_jit(__local_fxml_controller, __local_namespace, __local_jruby_ext)
|
96
|
+
__local_fx_id_setter = lambda do |name, __i|
|
97
|
+
__local_namespace[name] = __i
|
98
|
+
__local_fxml_controller.instance_variable_set(("@\#{name}").to_sym, __i)
|
99
|
+
end
|
100
|
+
#{code}
|
101
|
+
end
|
102
|
+
METHOD_DEF
|
103
|
+
;#)
|
104
|
+
unless @no_write
|
105
|
+
begin
|
106
|
+
jit_aot_cache(full_code)
|
107
|
+
rescue
|
108
|
+
p $!
|
109
|
+
jit_no_cache(full_code)
|
110
|
+
end
|
111
|
+
else
|
112
|
+
jit_no_cache(full_code)
|
113
|
+
end
|
114
|
+
if @opts && @opts[:compiled_hook]
|
115
|
+
@opts[:compiled_hook].call(@outfile)
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
def jit_no_cache(full_code)
|
121
|
+
dputs "JIT only, no aot for #{@file_name}"
|
122
|
+
self.instance_eval full_code
|
123
|
+
@compiled = true
|
124
|
+
end
|
125
|
+
|
126
|
+
def jit_aot_cache(full_code)
|
127
|
+
File.open(@outfile, "w") do |f|
|
128
|
+
hash = hash()
|
129
|
+
f << <<AOT
|
130
|
+
# #{hash} encoding: utf-8
|
131
|
+
# @@ 1
|
132
|
+
|
133
|
+
########################### DO NOT MODIFY THIS FILE ###########################
|
134
|
+
# This file was automatically generated by JRubyFX-fxmlloader on #
|
135
|
+
# #{Time.now} for #{@file_name}
|
136
|
+
########################### DO NOT MODIFY THIS FILE ###########################
|
137
|
+
|
138
|
+
module JRubyFX
|
139
|
+
module GeneratedAssets
|
140
|
+
class AOT#{@f_hash}
|
141
|
+
include JRubyFX
|
142
|
+
#{full_code}
|
143
|
+
def hash
|
144
|
+
#{hash.inspect}
|
145
|
+
end
|
146
|
+
def compiled?
|
147
|
+
true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
AOT
|
153
|
+
end
|
154
|
+
puts "saved #{@outfile} to cache"
|
155
|
+
require @outfile
|
156
|
+
@compiled = JRubyFX::GeneratedAssets.const_get("AOT#{@f_hash}").new rescue nil
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,290 @@
|
|
1
|
+
#/*
|
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
|
+
|
26
|
+
|
27
|
+
#/**
|
28
|
+
# * Class representing an observable expression value.
|
29
|
+
# */
|
30
|
+
class RRExpressionValue < Java::javafx.beans.value.ObservableValueBase
|
31
|
+
#// Monitors a namespace for changes along a key path
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
def initialize(namespace, expression, type)
|
36
|
+
super()
|
37
|
+
if (namespace == nil)
|
38
|
+
raise "NullPointerException.new();"
|
39
|
+
end
|
40
|
+
|
41
|
+
if (expression == nil)
|
42
|
+
raise "NullPointerException.new();"
|
43
|
+
end
|
44
|
+
|
45
|
+
if (type == nil)
|
46
|
+
raise "NullPointerException.new();"
|
47
|
+
end
|
48
|
+
|
49
|
+
@listenerCount = 0;
|
50
|
+
|
51
|
+
@namespace = namespace;
|
52
|
+
@expression = expression;
|
53
|
+
@type = type;
|
54
|
+
|
55
|
+
arguments = expression.getArguments();
|
56
|
+
@argumentMonitors = java.util.ArrayList.new(arguments.size());
|
57
|
+
|
58
|
+
for argument in arguments
|
59
|
+
@argumentMonitors.add(KeyPathMonitor.new(self, argument.iterator()));
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def getValue()
|
65
|
+
return RubyWrapperBeanAdapter.coerce(@expression.evaluate(@namespace), @type);
|
66
|
+
end
|
67
|
+
|
68
|
+
def addListener( listener)
|
69
|
+
if (@listenerCount == 0)
|
70
|
+
monitorArguments();
|
71
|
+
end
|
72
|
+
|
73
|
+
super(listener);
|
74
|
+
@listenerCount += 1
|
75
|
+
end
|
76
|
+
|
77
|
+
def removeListener( listener)
|
78
|
+
super(listener);
|
79
|
+
@listenerCount-=1
|
80
|
+
|
81
|
+
if (@listenerCount == 0)
|
82
|
+
unmonitorArguments();
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def monitorArguments()
|
87
|
+
for argumentMonitor in @argumentMonitors
|
88
|
+
argumentMonitor.monitor(@namespace);
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def unmonitorArguments()
|
93
|
+
for argumentMonitor in @argumentMonitors
|
94
|
+
argumentMonitor.unmonitor();
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
class KeyPathMonitor
|
101
|
+
@key = nil;
|
102
|
+
@next = nil
|
103
|
+
|
104
|
+
@namespace = nil;
|
105
|
+
|
106
|
+
|
107
|
+
class ListChangeImpl
|
108
|
+
include ListChangeListener
|
109
|
+
|
110
|
+
def initialize(this)
|
111
|
+
@this = this
|
112
|
+
end
|
113
|
+
|
114
|
+
def onChanged(change)
|
115
|
+
@this.list_changed(change)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
class MapChangeImpl
|
121
|
+
include MapChangeListener
|
122
|
+
|
123
|
+
def initialize(this)
|
124
|
+
@this = this
|
125
|
+
end
|
126
|
+
|
127
|
+
def onChanged(change)
|
128
|
+
@this.map_changed(change)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
class ChangeListenerImpl
|
135
|
+
include ChangeListener
|
136
|
+
|
137
|
+
def initialize(this)
|
138
|
+
@this = this
|
139
|
+
end
|
140
|
+
|
141
|
+
def changed(ov, old, new)
|
142
|
+
@this.normal_changed(ov, old, new)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def initialize(this, keyPathIterator)
|
147
|
+
@key = keyPathIterator.next();
|
148
|
+
@this = this
|
149
|
+
|
150
|
+
|
151
|
+
@listChangeListener = ListChangeImpl.new(self)
|
152
|
+
|
153
|
+
|
154
|
+
@mapChangeListener = MapChangeImpl.new(self)
|
155
|
+
|
156
|
+
|
157
|
+
@propertyChangeListener = ChangeListenerImpl.new(self)
|
158
|
+
|
159
|
+
if (keyPathIterator.hasNext())
|
160
|
+
@next = KeyPathMonitor.new(this, keyPathIterator);
|
161
|
+
else
|
162
|
+
@next = nil;
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def list_changed(change)
|
167
|
+
while (change.next())
|
168
|
+
index = @key.to_i
|
169
|
+
|
170
|
+
if (index >= change.getFrom() && index < change.getTo())
|
171
|
+
@this.fireValueChangedEvent();
|
172
|
+
remonitor();
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def map_changed(change)
|
178
|
+
if (@key == (change.getKey()))
|
179
|
+
@this.fireValueChangedEvent();
|
180
|
+
remonitor();
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def normal_changed(observable, oldValue, newValue)
|
185
|
+
if (@key == (observable.getName()))
|
186
|
+
|
187
|
+
@this.fireValueChangedEvent();
|
188
|
+
remonitor();
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def monitor(namespace)
|
193
|
+
if (namespace.is_a? ObservableList)
|
194
|
+
old_verbose = $VERBOSE
|
195
|
+
begin
|
196
|
+
$VERBOSE = nil
|
197
|
+
namespace.addListener @listChangeListener
|
198
|
+
ensure
|
199
|
+
# always re-set to old value, even if block raises an exception
|
200
|
+
$VERBOSE = old_verbose
|
201
|
+
end
|
202
|
+
elsif (namespace.is_a? ObservableMap)
|
203
|
+
old_verbose = $VERBOSE
|
204
|
+
begin
|
205
|
+
$VERBOSE = nil
|
206
|
+
namespace.addListener @mapChangeListener
|
207
|
+
ensure
|
208
|
+
# always re-set to old value, even if block raises an exception
|
209
|
+
$VERBOSE = old_verbose
|
210
|
+
end
|
211
|
+
else
|
212
|
+
namespaceAdapter = RubyWrapperBeanAdapter.for(namespace);
|
213
|
+
propertyModel = namespaceAdapter.getPropertyModel(@key).to_java
|
214
|
+
if (propertyModel != nil)
|
215
|
+
old_verbose = $VERBOSE
|
216
|
+
begin
|
217
|
+
$VERBOSE = nil
|
218
|
+
propertyModel.addListener @propertyChangeListener
|
219
|
+
ensure
|
220
|
+
# always re-set to old value, even if block raises an exception
|
221
|
+
$VERBOSE = old_verbose
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
@namespace = namespaceAdapter;
|
226
|
+
end
|
227
|
+
|
228
|
+
@namespace = namespace;
|
229
|
+
|
230
|
+
if (@next != nil)
|
231
|
+
value = Expression.get(@namespace, @key)
|
232
|
+
if (value != nil)
|
233
|
+
@next.monitor(value);
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def unmonitor()
|
239
|
+
if (@namespace.is_a? ObservableList)
|
240
|
+
old_verbose = $VERBOSE
|
241
|
+
begin
|
242
|
+
$VERBOSE = nil
|
243
|
+
@namespace.removeListener @listChangeListener
|
244
|
+
ensure
|
245
|
+
# always re-set to old value, even if block raises an exception
|
246
|
+
$VERBOSE = old_verbose
|
247
|
+
end
|
248
|
+
elsif (@namespace.is_a? ObservableMap)
|
249
|
+
old_verbose = $VERBOSE
|
250
|
+
begin
|
251
|
+
$VERBOSE = nil
|
252
|
+
@namespace.removeListener @mapChangeListener
|
253
|
+
ensure
|
254
|
+
# always re-set to old value, even if block raises an exception
|
255
|
+
$VERBOSE = old_verbose
|
256
|
+
end
|
257
|
+
elsif (@namespace != nil)
|
258
|
+
namespaceAdapter = @namespace;
|
259
|
+
propertyModel = namespaceAdapter.getPropertyModel(@key);
|
260
|
+
|
261
|
+
if (propertyModel != nil)
|
262
|
+
old_verbose = $VERBOSE
|
263
|
+
begin
|
264
|
+
$VERBOSE = nil
|
265
|
+
propertyModel.removeListener @propertyChangeListener
|
266
|
+
ensure
|
267
|
+
# always re-set to old value, even if block raises an exception
|
268
|
+
$VERBOSE = old_verbose
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
@namespace = nil;
|
274
|
+
|
275
|
+
if (@next != nil)
|
276
|
+
@next.unmonitor();
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def remonitor()
|
281
|
+
if (@next != nil)
|
282
|
+
@next.unmonitor();
|
283
|
+
value = Expression.get(@namespace, @key);
|
284
|
+
if (value != nil)
|
285
|
+
@next.monitor(value);
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
@@ -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
|