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