rgen-xsd 0.1.0 → 0.2.0
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/CHANGELOG +6 -0
- data/Rakefile +1 -1
- data/lib/rgen/xsd/xsi_instantiator.rb +101 -43
- metadata +4 -4
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
@@ -17,8 +17,16 @@ class XSIInstantiator
|
|
17
17
|
@namespaces = []
|
18
18
|
end
|
19
19
|
|
20
|
+
# options:
|
21
|
+
# :unresolved_refs: an array to which unresolved references will be appended
|
22
|
+
# :problems: an array to which problems during instantiation will be appended
|
23
|
+
# :fragment_ref: a fragment ref object which will be set on every model element created
|
20
24
|
def instantiate(file, options={})
|
21
|
-
@unresolved_refs = []
|
25
|
+
@unresolved_refs = options[:unresolved_refs] || []
|
26
|
+
@fragment_ref = options[:fragment_ref]
|
27
|
+
@problems = options[:problems]
|
28
|
+
@target_identifier_provider = options[:target_identifier_provider] ||
|
29
|
+
lambda do |node| node["id"] end
|
22
30
|
root = nil
|
23
31
|
root_class = options[:root_class].andand.ecore || root_class(doc.root.name)
|
24
32
|
File.open(file) do |f|
|
@@ -42,7 +50,7 @@ class XSIInstantiator
|
|
42
50
|
if prefix == "xml"
|
43
51
|
href = "http://www.w3.org/XML/1998/namespace"
|
44
52
|
elsif prefix
|
45
|
-
|
53
|
+
report_problem "WARN: Can not resolve namespace prefix #{prefix}"
|
46
54
|
end
|
47
55
|
end
|
48
56
|
[href, name]
|
@@ -54,41 +62,59 @@ class XSIInstantiator
|
|
54
62
|
node.attribute_nodes.find{|n| is_xsi_type?(n)}.andand.text
|
55
63
|
end
|
56
64
|
|
57
|
-
def instantiate_node(node, eclass)
|
58
|
-
element
|
59
|
-
|
60
|
-
|
65
|
+
def instantiate_node(node, eclass, element=nil, wrapper_features=nil)
|
66
|
+
if !element
|
67
|
+
element = eclass.instanceClass.new
|
68
|
+
element.fragment_ref = @fragment_ref if @fragment_ref
|
69
|
+
@env << element
|
70
|
+
end
|
71
|
+
set_attribute_values(element, node, wrapper_features)
|
61
72
|
simple_content = ""
|
62
|
-
can_take_any = eclass.eAllAttributes.any?{|a| a.name == "anyObject"}
|
63
73
|
node.children.each do |c|
|
64
74
|
if c.text?
|
65
75
|
simple_content << c.text
|
66
76
|
elsif c.element?
|
67
|
-
|
68
|
-
f
|
69
|
-
|
70
|
-
|
77
|
+
if wrapper_features
|
78
|
+
feats = wrapper_features.select{|f| xml_name(f) == c.name}
|
79
|
+
else
|
80
|
+
feats = features_by_xml_name(element.class, c.name) || []
|
81
|
+
end
|
71
82
|
if feats.size == 1
|
72
83
|
begin
|
73
84
|
if feats.first.is_a?(RGen::ECore::EReference)
|
74
|
-
|
75
|
-
|
85
|
+
if feats.first.containment
|
86
|
+
element.setOrAddGeneric(feats.first.name,
|
87
|
+
instantiate_node(c, reference_target_type(feats.first, xsi_type_value(c))))
|
88
|
+
else
|
89
|
+
proxy = RGen::MetamodelBuilder::MMProxy.new(@target_identifier_provider.call(c))
|
90
|
+
@unresolved_refs <<
|
91
|
+
RGen::Instantiator::ReferenceResolver::UnresolvedReference.new(element, feats.first.name, proxy)
|
92
|
+
element.setOrAddGeneric(feats.first.name, proxy)
|
93
|
+
end
|
76
94
|
else
|
77
95
|
element.setOrAddGeneric(feats.first.name, value_from_string(element, feats.first, c.text))
|
78
96
|
end
|
79
97
|
rescue Exception => e
|
80
|
-
|
98
|
+
report_problem "#{e}\n#{e.backtrace.join("\n")}", node
|
81
99
|
end
|
82
100
|
else
|
83
|
-
if
|
101
|
+
if wrapper_features
|
102
|
+
# already inside a wrapper
|
103
|
+
wrapper_feats = []
|
104
|
+
else
|
105
|
+
wrapper_feats = features_by_xml_wrapper_name(element.class, c.name) || []
|
106
|
+
end
|
107
|
+
if wrapper_feats.size > 0
|
108
|
+
instantiate_node(c, eclass, element, wrapper_feats)
|
109
|
+
elsif can_take_any(eclass)
|
84
110
|
begin
|
85
|
-
# currently the XML node is added to the model
|
86
|
-
element.setOrAddGeneric("anyObject", c)
|
111
|
+
# TODO: currently the XML node is added to the model
|
112
|
+
# element.setOrAddGeneric("anyObject", c)
|
87
113
|
rescue Exception => e
|
88
|
-
|
114
|
+
report_problem "#{e}\n#{e.backtrace.join("\n")}", node
|
89
115
|
end
|
90
116
|
else
|
91
|
-
|
117
|
+
report_problem "could not determine reference for tag #{c.name}, #{feats.size} options", node
|
92
118
|
end
|
93
119
|
end
|
94
120
|
end
|
@@ -112,13 +138,15 @@ class XSIInstantiator
|
|
112
138
|
attr_node.namespace.andand.href == "http://www.w3.org/2001/XMLSchema-instance" && attr_node.node_name == "type"
|
113
139
|
end
|
114
140
|
|
115
|
-
def set_attribute_values(element, node)
|
141
|
+
def set_attribute_values(element, node, wrapper_features)
|
116
142
|
node.attribute_nodes.each do |attrnode|
|
117
143
|
next if is_xsi_type?(attrnode)
|
118
144
|
name = attrnode.node_name
|
119
|
-
|
120
|
-
f
|
121
|
-
|
145
|
+
if wrapper_features
|
146
|
+
feats = wrapper_features.select{|f| xml_name(f) == name}
|
147
|
+
else
|
148
|
+
feats = features_by_xml_name(element.class, name) || []
|
149
|
+
end
|
122
150
|
if feats.size == 1
|
123
151
|
f = feats.first
|
124
152
|
str = node.attr(name)
|
@@ -135,25 +163,27 @@ class XSIInstantiator
|
|
135
163
|
elsif name == "schemaLocation" || name == "noNamespaceSchemaLocation"
|
136
164
|
# ignore, this may occure with any XML element
|
137
165
|
else
|
138
|
-
|
166
|
+
report_problem "could not determine feature for attribute #{name}, #{feats.size} options", node
|
139
167
|
end
|
140
168
|
end
|
141
169
|
end
|
142
170
|
|
143
171
|
def value_from_string(element, f, str)
|
144
172
|
if f.is_a?(RGen::ECore::EAttribute)
|
145
|
-
|
146
|
-
when RGen::ECore::EInt
|
147
|
-
str.to_i
|
148
|
-
when RGen::ECore::EFloat
|
149
|
-
str.to_f
|
150
|
-
when RGen::ECore::EEnum
|
173
|
+
if f.eType.is_a?(RGen::ECore::EEnum)
|
151
174
|
str.to_sym
|
152
|
-
when RGen::ECore::EBoolean
|
153
|
-
(str == "true")
|
154
175
|
else
|
155
|
-
|
156
|
-
|
176
|
+
case f.eType.instanceClassName
|
177
|
+
when "Integer"
|
178
|
+
str.to_i
|
179
|
+
when "Float"
|
180
|
+
str.to_f
|
181
|
+
when "Boolean"
|
182
|
+
(str == "true")
|
183
|
+
else
|
184
|
+
str
|
185
|
+
end
|
186
|
+
end
|
157
187
|
else
|
158
188
|
proxy = RGen::MetamodelBuilder::MMProxy.new(str)
|
159
189
|
@unresolved_refs <<
|
@@ -188,8 +218,12 @@ class XSIInstantiator
|
|
188
218
|
end
|
189
219
|
end
|
190
220
|
|
191
|
-
def
|
192
|
-
|
221
|
+
def report_problem(desc, node=nil)
|
222
|
+
if node
|
223
|
+
@problems << "#{desc} at line #{node.line}"
|
224
|
+
else
|
225
|
+
@problems << desc
|
226
|
+
end
|
193
227
|
end
|
194
228
|
|
195
229
|
def classes_by_xml_name(name)
|
@@ -203,21 +237,45 @@ class XSIInstantiator
|
|
203
237
|
@classes_by_xml_name[name]
|
204
238
|
end
|
205
239
|
|
206
|
-
def features_by_xml_name(name)
|
207
|
-
|
208
|
-
@features_by_xml_name
|
209
|
-
@
|
240
|
+
def features_by_xml_name(clazz, name)
|
241
|
+
@features_by_xml_name ||= {}
|
242
|
+
return @features_by_xml_name[clazz][name] || [] if @features_by_xml_name[clazz]
|
243
|
+
@features_by_xml_name[clazz] = {}
|
244
|
+
clazz.ecore.eAllStructuralFeatures.each do |f|
|
210
245
|
n = xml_name(f)
|
211
|
-
@features_by_xml_name[n] ||= []
|
212
|
-
@features_by_xml_name[n] << f
|
246
|
+
@features_by_xml_name[clazz][n] ||= []
|
247
|
+
@features_by_xml_name[clazz][n] << f
|
248
|
+
end
|
249
|
+
@features_by_xml_name[clazz][name]
|
250
|
+
end
|
251
|
+
|
252
|
+
def features_by_xml_wrapper_name(clazz, name)
|
253
|
+
@features_by_xml_wrapper_name ||= {}
|
254
|
+
return @features_by_xml_wrapper_name[clazz][name] || [] if @features_by_xml_wrapper_name[clazz]
|
255
|
+
@features_by_xml_wrapper_name[clazz] = {}
|
256
|
+
clazz.ecore.eAllStructuralFeatures.each do |f|
|
257
|
+
n = xml_wrapper_name(f)
|
258
|
+
if n
|
259
|
+
@features_by_xml_wrapper_name[clazz][n] ||= []
|
260
|
+
@features_by_xml_wrapper_name[clazz][n] << f
|
261
|
+
end
|
213
262
|
end
|
214
|
-
@
|
263
|
+
@features_by_xml_wrapper_name[clazz][name]
|
264
|
+
end
|
265
|
+
|
266
|
+
def can_take_any(eclass)
|
267
|
+
@can_take_any ||= {}
|
268
|
+
@can_take_any[eclass] ||= eclass.eAllAttributes.any?{|a| a.name == "anyObject"}
|
215
269
|
end
|
216
270
|
|
217
271
|
def xml_name(o)
|
218
272
|
annotation_value(o, "xmlName") || o.name
|
219
273
|
end
|
220
274
|
|
275
|
+
def xml_wrapper_name(o)
|
276
|
+
annotation_value(o, "xmlWrapperName")
|
277
|
+
end
|
278
|
+
|
221
279
|
def annotation_value(o, key)
|
222
280
|
anno = o.eAnnotations.find{|a| a.source == "xsd"}
|
223
281
|
anno.andand.details.andand.find{|d| d.key == key}.andand.value
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rgen-xsd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-19 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rgen
|
16
|
-
requirement: &
|
16
|
+
requirement: &24218064 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 0.6.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *24218064
|
25
25
|
description: Derive RGen/ECore metamodels from XML schema and load/store XML documents
|
26
26
|
conforming to the schema as RGen models
|
27
27
|
email: martin dot thiede at gmx de
|