xamplr 1.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.
Files changed (142) hide show
  1. data/CHANGES.txt +13 -0
  2. data/LICENSE +3 -0
  3. data/README.rdoc +26 -0
  4. data/README.rdoc.orig +118 -0
  5. data/Rakefile +85 -0
  6. data/VERSION.yml +4 -0
  7. data/examples/random-people-shared-addresses/Makefile +16 -0
  8. data/examples/random-people-shared-addresses/batch-load-users.rb +83 -0
  9. data/examples/random-people-shared-addresses/find-mentions.rb +47 -0
  10. data/examples/random-people-shared-addresses/find-people-by-address.rb +104 -0
  11. data/examples/random-people-shared-addresses/optimise.rb +16 -0
  12. data/examples/random-people-shared-addresses/people.rb +35 -0
  13. data/examples/random-people-shared-addresses/query.rb +75 -0
  14. data/examples/random-people-shared-addresses/query2.rb +73 -0
  15. data/examples/random-people-shared-addresses/random-names.csv +10000 -0
  16. data/examples/random-people-shared-addresses/settings.rb +3 -0
  17. data/examples/random-people-shared-addresses/what-to-query-on.rb +82 -0
  18. data/examples/random-people-shared-addresses/xampl-gen.rb +36 -0
  19. data/examples/random-people-shared-addresses/xml/people.xml +14 -0
  20. data/examples/random-people/Makefile +16 -0
  21. data/examples/random-people/batch-load-users.rb +61 -0
  22. data/examples/random-people/optimise.rb +16 -0
  23. data/examples/random-people/people.rb +22 -0
  24. data/examples/random-people/query.rb +73 -0
  25. data/examples/random-people/query2.rb +73 -0
  26. data/examples/random-people/random-names.csv +10000 -0
  27. data/examples/random-people/rawtc.rb +91 -0
  28. data/examples/random-people/settings.rb +3 -0
  29. data/examples/random-people/what-to-query-on.rb +80 -0
  30. data/examples/random-people/xampl-gen.rb +36 -0
  31. data/examples/random-people/xml/people.xml +11 -0
  32. data/examples/read-testing/Makefile +10 -0
  33. data/examples/read-testing/load.rb +65 -0
  34. data/examples/read-testing/read.rb +51 -0
  35. data/examples/read-testing/rrr.rb +87 -0
  36. data/examples/read-testing/settings.rb +2 -0
  37. data/examples/read-testing/xampl-gen.rb +36 -0
  38. data/examples/read-testing/xml/text.xml +8 -0
  39. data/examples/tokyo-cabinet-experimental/expt-query.rb +42 -0
  40. data/examples/tokyo-cabinet-experimental/expt-query2.rb +42 -0
  41. data/examples/tokyo-cabinet-experimental/expt-query3.rb +41 -0
  42. data/examples/tokyo-cabinet-experimental/expt-reader.rb +32 -0
  43. data/examples/tokyo-cabinet-experimental/expt.rb +61 -0
  44. data/examples/tokyo-cabinet-experimental/xampl-gen.rb +36 -0
  45. data/examples/tokyo-cabinet-experimental/xml/tcx.xml +6 -0
  46. data/lib/xampl-generator.rb +3 -0
  47. data/lib/xampl.rb +3 -0
  48. data/lib/xamplr-generator.rb +10 -0
  49. data/lib/xamplr.rb +37 -0
  50. data/lib/xamplr/README-POSSIBLE-PROBLEMS +5 -0
  51. data/lib/xamplr/TODO +1 -0
  52. data/lib/xamplr/exceptions.rb +97 -0
  53. data/lib/xamplr/from-xml-orig.rb +350 -0
  54. data/lib/xamplr/from-xml.rb +439 -0
  55. data/lib/xamplr/gen-elements.xml +6230 -0
  56. data/lib/xamplr/gen.elements.xml +108 -0
  57. data/lib/xamplr/generate-elements.rb +15 -0
  58. data/lib/xamplr/generator.rb +5 -0
  59. data/lib/xamplr/graphml-out.rb +470 -0
  60. data/lib/xamplr/handwritten/example.rb +698 -0
  61. data/lib/xamplr/handwritten/hand-example.rb +533 -0
  62. data/lib/xamplr/handwritten/test-handwritten.rb +873 -0
  63. data/lib/xamplr/indexed-array.rb +115 -0
  64. data/lib/xamplr/mixins.rb +397 -0
  65. data/lib/xamplr/my.gen.elements.xml +461 -0
  66. data/lib/xamplr/notifications.rb +57 -0
  67. data/lib/xamplr/obsolete/fsdb.rb +62 -0
  68. data/lib/xamplr/persist-to-xml.rb +249 -0
  69. data/lib/xamplr/persistence.rb +522 -0
  70. data/lib/xamplr/persistence.rb.more_thread_safe +771 -0
  71. data/lib/xamplr/persistence.rb.partially_thread_safe +763 -0
  72. data/lib/xamplr/persister.rb +310 -0
  73. data/lib/xamplr/persisters/caches.rb +186 -0
  74. data/lib/xamplr/persisters/caching.rb +172 -0
  75. data/lib/xamplr/persisters/filesystem.rb +60 -0
  76. data/lib/xamplr/persisters/in-memory.rb +180 -0
  77. data/lib/xamplr/persisters/simple.rb +59 -0
  78. data/lib/xamplr/persisters/tokyo-cabinet.rb +641 -0
  79. data/lib/xamplr/simpleTemplate/danger.rx +4 -0
  80. data/lib/xamplr/simpleTemplate/obsolete/input-c.r4 +35 -0
  81. data/lib/xamplr/simpleTemplate/obsolete/play.r6.txt +12 -0
  82. data/lib/xamplr/simpleTemplate/obsolete/play_more.r6.txt +20 -0
  83. data/lib/xamplr/simpleTemplate/obsolete/test001.r5 +8 -0
  84. data/lib/xamplr/simpleTemplate/obsolete/test002.r5 +13 -0
  85. data/lib/xamplr/simpleTemplate/obsolete/test003.r5 +37 -0
  86. data/lib/xamplr/simpleTemplate/old/r6.000.rb +122 -0
  87. data/lib/xamplr/simpleTemplate/old/r6.001.rb +145 -0
  88. data/lib/xamplr/simpleTemplate/play.r6 +12 -0
  89. data/lib/xamplr/simpleTemplate/play_more.r6 +20 -0
  90. data/lib/xamplr/simpleTemplate/play_noblanks.r6 +21 -0
  91. data/lib/xamplr/simpleTemplate/playq.r6 +16 -0
  92. data/lib/xamplr/simpleTemplate/r6.rb +87 -0
  93. data/lib/xamplr/simpleTemplate/simple-template.rb +75 -0
  94. data/lib/xamplr/templates/child.template +47 -0
  95. data/lib/xamplr/templates/child_indexed.template +89 -0
  96. data/lib/xamplr/templates/child_modules.template +5 -0
  97. data/lib/xamplr/templates/element_classes.template +11 -0
  98. data/lib/xamplr/templates/element_data.template +282 -0
  99. data/lib/xamplr/templates/element_empty.template +285 -0
  100. data/lib/xamplr/templates/element_mixed.template +277 -0
  101. data/lib/xamplr/templates/element_simple.template +276 -0
  102. data/lib/xamplr/templates/package.template +26 -0
  103. data/lib/xamplr/test-support/Makefile +47 -0
  104. data/lib/xamplr/test-support/bench-cache.rb +80 -0
  105. data/lib/xamplr/test-support/bench-script.rb +21 -0
  106. data/lib/xamplr/test-support/bench.rb +116 -0
  107. data/lib/xamplr/test-support/bench2.rb +132 -0
  108. data/lib/xamplr/test-support/test-cache.rb +147 -0
  109. data/lib/xamplr/test-support/test-data/binding.xml +7 -0
  110. data/lib/xamplr/test-support/test-data/example.xml +14 -0
  111. data/lib/xamplr/test-support/test-data/internationalization-utf8.txt +1 -0
  112. data/lib/xamplr/test-support/test-data/labels.xml +37 -0
  113. data/lib/xamplr/test-support/test-data/labels001.xml +38 -0
  114. data/lib/xamplr/test-support/test-deep-change.rb +135 -0
  115. data/lib/xamplr/test-support/test-elements.rb +109 -0
  116. data/lib/xamplr/test-support/test-indexed-array.rb +169 -0
  117. data/lib/xamplr/test-support/test-misc.rb +73 -0
  118. data/lib/xamplr/test-support/test-names.rb +67 -0
  119. data/lib/xamplr/test-support/test-rollback.rb +106 -0
  120. data/lib/xamplr/test-support/test.rb +1504 -0
  121. data/lib/xamplr/to-ruby.rb +220 -0
  122. data/lib/xamplr/to-xml.rb +158 -0
  123. data/lib/xamplr/version.rb +67 -0
  124. data/lib/xamplr/visitor.rb +140 -0
  125. data/lib/xamplr/visitors.rb +573 -0
  126. data/lib/xamplr/xampl-generator.rb +533 -0
  127. data/lib/xamplr/xampl-hand-generated.rb +1535 -0
  128. data/lib/xamplr/xampl-module.rb +36 -0
  129. data/lib/xamplr/xampl-object-internals.rb +6 -0
  130. data/lib/xamplr/xampl-object.rb +202 -0
  131. data/lib/xamplr/xampl-persisted-object.rb +122 -0
  132. data/lib/xamplr/xml-text.rb +117 -0
  133. data/lib/xamplr/xml/document.xml +7 -0
  134. data/lib/xamplr/xml/elements.xml +101 -0
  135. data/lib/xamplr/xml/elements000.xml +73 -0
  136. data/lib/xamplr/xml/example.xml +23 -0
  137. data/lib/xamplr/xml/options.xml +12 -0
  138. data/lib/xamplr/xml/uche.xml +38 -0
  139. data/lib/xamplr/yEd-sample.graphml +300 -0
  140. data/test/test_helper.rb +10 -0
  141. data/test/xamplr_test.rb +7 -0
  142. metadata +245 -0
@@ -0,0 +1,350 @@
1
+ require "xamplr-pp"
2
+
3
+ module Xampl
4
+
5
+ class FromXML_original < Xampl_PP
6
+
7
+ attr :checkWellFormed, false
8
+ attr :is_realising, false
9
+ attr :tokenise_content, false
10
+
11
+ @@by_tag = {}
12
+ @@by_ns_tag = {}
13
+
14
+ def initialize(recovering=false)
15
+ super()
16
+ @recovering = recovering
17
+ end
18
+
19
+ def FromXML_original.reset_registry
20
+ @@by_tag = {}
21
+ @@by_ns_tag = {}
22
+ end
23
+
24
+ def FromXML_original.register(tag, ns_tag, klass)
25
+ @@by_ns_tag[ns_tag] = [ klass ]
26
+ a = @@by_tag[tag]
27
+ if (nil == a) then
28
+ @@by_tag[tag] = [ klass ]
29
+ else
30
+ found = false
31
+ a.each { | thing | found = found | (thing == klass) }
32
+ a << klass unless found
33
+ end
34
+ end
35
+
36
+ def FromXML_original.registered(name)
37
+ klass = @@by_ns_tag[name]
38
+ klass = @@by_tag[name] unless klass
39
+ klass = [] unless klass
40
+ return klass
41
+ end
42
+
43
+ def resolve(name)
44
+ return name
45
+ end
46
+
47
+ def setup_parse(filename, tokenise_content=true, is_realising=false)
48
+ @processNamespace = true
49
+ @reportNamespaceAttributes = false
50
+ @checkWellFormed = false
51
+ @resolver = self
52
+
53
+ @is_realising = is_realising
54
+ @tokenise_content = tokenise_content
55
+
56
+ setInput(File.new(filename))
57
+ end
58
+
59
+ def setup_parse_string(string, tokenise_content=true, is_realising=false)
60
+ @processNamespace = true
61
+ @reportNamespaceAttributes = false
62
+ @checkWellFormed = false
63
+ @resolver = self
64
+
65
+ @is_realising = is_realising
66
+ @tokenise_content = tokenise_content
67
+
68
+ setInput(string)
69
+ end
70
+
71
+ def parse(filename, tokenise_content=true, is_realising=false)
72
+ begin
73
+ setup_parse(filename, tokenise_content, is_realising)
74
+ element, ignore = parse_element
75
+ return element
76
+ rescue Exception => e
77
+ puts "trouble parsing file: '#{filename}'"
78
+ puts "Exception: #{e}"
79
+ raise
80
+ end
81
+ end
82
+
83
+ def realise_string(string, tokenise_content=true, target=nil)
84
+ return parse_string(string, tokenise_content, true, target)
85
+ end
86
+
87
+ def parse_string(string, tokenise_content=true, is_realising=false, target=nil)
88
+ begin
89
+ setup_parse_string(string, tokenise_content, is_realising)
90
+ element, ignore = parse_element(nil, target)
91
+ return element
92
+ rescue Exception => e
93
+ puts "trouble parsing string: '#{string}'"
94
+ puts "Exception: #{e}"
95
+ raise
96
+ end
97
+ end
98
+
99
+ def FromXML_original.tokenise_string(str, strip=true)
100
+ return nil unless str
101
+ str.strip! if strip
102
+ str.gsub!(/[ \n\r\t][ \n\r\t]*/, " ")
103
+ return str
104
+ end
105
+
106
+ def parse_element(parent=nil, target=nil)
107
+ next_interesting_event unless parent
108
+
109
+ existing_element = nil
110
+ element = nil
111
+
112
+ requires_caching = false
113
+
114
+ if startElement? then
115
+ if ((nil != @namespace) and (0 < @namespace.size)) then
116
+ klass_name = "{#{@namespace}}#{@name}"
117
+ klasses = FromXML_original.registered(klass_name)
118
+ if (0 == klasses.size) then
119
+ xml_text = XMLText.new
120
+ xml_text.build(self)
121
+ xml_text = parent.note_adding_text_content(xml_text, @is_realising)
122
+ parent.add_content(xml_text, @tokenise_content) if xml_text
123
+ # puts "#{__LINE__ }:: add_content [#{xml_text}] --> [#{parent.content}]"
124
+ return xml_text, false
125
+ end
126
+ if (1 < klasses.size) then
127
+ raise XamplException.new("there is more than one '#{@name}' tag in namespace '#{@namespace}'\nplease report this error")
128
+ end
129
+ else
130
+ klasses = FromXML_original.registered(@name)
131
+ if (0 == klasses.size) then
132
+ raise XamplException.new("do not recognise tag '#{@name}' (no namespace specified)")
133
+ end
134
+ if (1 < klasses.size) then
135
+ raise XamplException.new("there is more than one '#{@name}' tag (no namespace specified)")
136
+ end
137
+ end
138
+
139
+ unless @is_realising then
140
+ @attributeValue.size.times do |i|
141
+ FromXML_original.tokenise_string @attributeValue[i]
142
+ end
143
+ end
144
+
145
+ if target then
146
+ element = target
147
+ target.load_needed = false
148
+ target = nil
149
+ element.init_attributes(@attributeName, @attributeNamespace, @attributeValue)
150
+ element.note_attributes_initialised(@is_realising)
151
+ else
152
+ if klasses[0].persisted? then
153
+ @attributeName.each_index do |i|
154
+ if @attributeName[i] == klasses[0].persisted?.to_s then
155
+ existing_element = Xampl.find_known(klasses[0], @attributeValue[i])
156
+ if existing_element then
157
+ # so we've found the element. Now what??? We can do several
158
+ # reasonable things:
159
+ #
160
+ # 1) continue parsing into the found element
161
+ # 2) simply return the found element
162
+ # 3) replace the found element with the new element
163
+ #
164
+ # The first one is dubious, so we won't.
165
+ # The second and third option both make complete sense
166
+ #
167
+ # We are going to do the second
168
+ #
169
+ # BTW, 'existing element' means a representation of this element already in memory
170
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
171
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
172
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
173
+ # puts "FOUND AN EXISTING THING... #{ klasses[0] } #{ @attributeValue[i] }"
174
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
175
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
176
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
177
+ # caller(0).each { | trace | puts " #{trace}"}
178
+ # existing_element.reset_contents
179
+ # element = existing_element
180
+ # existing_element = nil
181
+ # puts "#{File.basename(__FILE__)} #{__LINE__} EXISTING ELEMENT: #{ existing_element }"
182
+ # puts "#{File.basename(__FILE__)} #{__LINE__} WOW, must handle the existing element correctly"
183
+ element = existing_element #TODO -- IS THIS RIGHT????????????????????????
184
+ end
185
+ unless element then
186
+ element = klasses[0].new
187
+ requires_caching = @recovering
188
+ # puts "#{File.basename(__FILE__)} #{__LINE__} WOW, what about recovering????"
189
+ #TODO -- IS THIS RIGHT????????????????????????
190
+ requires_caching = true #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
191
+ unless @recovering then
192
+ element.force_load if parent
193
+ end
194
+ element.note_created(@is_realising)
195
+ end
196
+
197
+ break
198
+ end
199
+ end
200
+ end
201
+
202
+ unless element then
203
+ element = klasses[0].new
204
+ element.note_created(@is_realising)
205
+ end
206
+
207
+ element.note_initialise_attributes_with(@attributeName, @attributeNamespace, @attributeValue, @is_realising)
208
+ element.init_attributes(@attributeName, @attributeNamespace, @attributeValue)
209
+ element.note_attributes_initialised(@is_realising)
210
+
211
+ if requires_caching and element and element.persist_required then
212
+ # puts "ELEMENT: #{element}, #{element.class.name}"
213
+ Xampl.cache(element)
214
+ # found = Xampl.find_known(element.class, element.get_the_index)
215
+ # puts "OK? #{found == element} found: #{found}, element: #{element}"
216
+ # puts "=============================================================================="
217
+ end
218
+
219
+ #element = element.note_add_to_parent(parent, @is_realising)
220
+ #element.append_to(parent) if parent
221
+ end
222
+
223
+ while not endDocument?
224
+ case nextEvent
225
+ when START_DOCUMENT
226
+ return element if @recovering
227
+ return existing_element || element
228
+ when END_DOCUMENT
229
+ return element if @recovering
230
+ return existing_element || element
231
+ when START_ELEMENT
232
+ child, ignore_child = parse_element(element)
233
+ unless ignore_child then
234
+ case child
235
+ when XamplObject then
236
+ child = child.note_add_to_parent(element, @is_realising) if child
237
+ child = element.note_add_child(child, @is_realising) if element
238
+ child.append_to(element) if element and child
239
+ when XMLText then
240
+ puts "UNRECOGNISED Well-formed XML: #{child.to_s[0..25]}..."
241
+ else
242
+ puts "WHAT IS THIS??? #{child.class.name}"
243
+ end
244
+ # if child.kind_of? XamplObject then
245
+ # child = child.note_add_to_parent(element, @is_realising) if child
246
+ # child = element.note_add_child(child, @is_realising) if element
247
+ # child.append_to(element) if element and child
248
+ # else
249
+ # puts "WHAT IS THIS??? #{child.class.name}"
250
+ # end
251
+ end
252
+ when END_ELEMENT
253
+ element = element.note_closed(@is_realising)
254
+ return element if @recovering
255
+ return existing_element || element
256
+ when TEXT, CDATA_SECTION, ENTITY_REF
257
+ if element.has_mixed_content then
258
+ the_text = element.note_adding_text_content(@text, @is_realising)
259
+ # element.add_content(the_text, @tokenise_content)
260
+ element << the_text
261
+ # puts "#{__LINE__ }:: add_content [#{the_text}]"
262
+ else
263
+ unless whitespace? then
264
+ the_text = element.note_adding_text_content(@text, @is_realising)
265
+ # 16 Mar 2007 -- this was making preformatted text content impossible
266
+ # element.add_content(the_text, @tokenise_content)
267
+ element.add_content(the_text, false)
268
+ # puts "#{__LINE__ }:: add_content [#{the_text}] --> [#{element.content}]"
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
274
+ return element if @recovering
275
+ return existing_element || element
276
+ end
277
+
278
+ def next_interesting_event
279
+ if (endDocument?) then
280
+ return Xampl_PP::END_DOCUMENT
281
+ end
282
+
283
+ boring = true
284
+ while boring do
285
+ event = nextEvent
286
+ case event
287
+ when Xampl_PP::START_DOCUMENT
288
+ boring = true
289
+ when Xampl_PP::END_DOCUMENT
290
+ boring = false
291
+ when Xampl_PP::START_ELEMENT
292
+ boring = false
293
+ when Xampl_PP::END_ELEMENT
294
+ boring = false
295
+ when Xampl_PP::TEXT
296
+ boring = false
297
+ when Xampl_PP::CDATA_SECTION
298
+ boring = false
299
+ when Xampl_PP::ENTITY_REF
300
+ boring = false
301
+ when Xampl_PP::IGNORABLE_WHITESPACE
302
+ boring = true
303
+ when Xampl_PP::PROCESSING_INSTRUCTION
304
+ boring = true
305
+ when Xampl_PP::COMMENT
306
+ boring = true
307
+ when Xampl_PP::DOCTYPE
308
+ boring = true
309
+ end
310
+ end
311
+ return event
312
+ end
313
+
314
+ def attributeCount
315
+ return @attributeName.length
316
+ end
317
+
318
+ def attributeName(i)
319
+ return @attributeName[i]
320
+ end
321
+
322
+ def attributeNamespace(i)
323
+ return @attributeNamespace[i]
324
+ end
325
+
326
+ def attributeQName(i)
327
+ return @attributeQName[i]
328
+ end
329
+
330
+ def attributePrefix(i)
331
+ return @attributePrefix[i]
332
+ end
333
+
334
+ def attributeValue(i)
335
+ return @attributeValue[i]
336
+ end
337
+
338
+ def depth
339
+ return depth
340
+ end
341
+
342
+ def line
343
+ return line
344
+ end
345
+
346
+ def column
347
+ return column
348
+ end
349
+ end
350
+ end
@@ -0,0 +1,439 @@
1
+ require 'libxml'
2
+
3
+ module Xampl
4
+
5
+ class FromXML
6
+
7
+ attr :checkWellFormed, false
8
+ attr :is_realising, false
9
+ attr :tokenise_content, false
10
+
11
+ @reader = nil
12
+
13
+ @@by_tag = {}
14
+ @@by_ns_tag = {}
15
+
16
+ def initialize(recovering=false)
17
+ @recovering = recovering
18
+
19
+ @attribute_name = Array.new(32)
20
+ @attribute_namespace = Array.new(32)
21
+ @attribute_value = Array.new(32)
22
+
23
+ @insert_end_element = false
24
+ @faking_an_end_element = false
25
+ @just_opened_an_element = false
26
+ end
27
+
28
+ def FromXML.reset_registry
29
+ @@by_tag = {}
30
+ @@by_ns_tag = {}
31
+ end
32
+
33
+ def FromXML.register(tag, ns_tag, klass)
34
+ @@by_ns_tag[ns_tag] = [ klass ]
35
+ a = @@by_tag[tag]
36
+ if (nil == a) then
37
+ @@by_tag[tag] = [ klass ]
38
+ else
39
+ found = false
40
+ a.each { | thing | found = found | (thing == klass) }
41
+ a << klass unless found
42
+ end
43
+ end
44
+
45
+ def FromXML.registered(name)
46
+ klass = @@by_ns_tag[name]
47
+ klass = @@by_tag[name] unless klass
48
+ klass = [] unless klass
49
+ return klass
50
+ end
51
+
52
+ def resolve(name)
53
+ #TODO -- ???
54
+ return name
55
+ end
56
+
57
+ def setup_parse(filename, tokenise_content=true, is_realising=false)
58
+ @resolver = self
59
+
60
+ @is_realising = is_realising
61
+ @tokenise_content = tokenise_content
62
+
63
+ @reader = LibXML::XML::Reader.file(filename,
64
+ :options => LibXML::XML::Parser::Options::NOENT |
65
+ LibXML::XML::Parser::Options::NONET |
66
+ LibXML::XML::Parser::Options::NOCDATA |
67
+ LibXML::XML::Parser::Options::DTDATTR |
68
+ LibXML::XML::Parser::Options::COMPACT)
69
+ #TODO CLOSE THIS THING!!
70
+ end
71
+
72
+ def setup_parse_string(string, tokenise_content=true, is_realising=false)
73
+ @resolver = self
74
+
75
+ @is_realising = is_realising
76
+ @tokenise_content = tokenise_content
77
+
78
+ # setInput(string)
79
+ @reader = LibXML::XML::Reader.string(string,
80
+ :options => LibXML::XML::Parser::Options::NOENT |
81
+ LibXML::XML::Parser::Options::NONET |
82
+ LibXML::XML::Parser::Options::NOCDATA |
83
+ LibXML::XML::Parser::Options::DTDATTR |
84
+ LibXML::XML::Parser::Options::COMPACT)
85
+ #TODO CLOSE THIS THING!!
86
+ end
87
+
88
+ def parse(filename, tokenise_content=true, is_realising=false)
89
+ begin
90
+ setup_parse(filename, tokenise_content, is_realising)
91
+ element, ignore = parse_element
92
+ return element
93
+ rescue Exception => e
94
+ puts "trouble parsing file: '#{filename}'"
95
+ puts "Exception: #{e}"
96
+ raise
97
+ end
98
+ end
99
+
100
+ def realise_string(string, tokenise_content=true, target=nil)
101
+ return parse_string(string, tokenise_content, true, target)
102
+ end
103
+
104
+ def parse_string(string, tokenise_content=true, is_realising=false, target=nil)
105
+ begin
106
+ setup_parse_string(string, tokenise_content, is_realising)
107
+ element, ignore = parse_element(nil, target)
108
+ return element
109
+ rescue Exception => e
110
+ puts "trouble parsing string: '#{string}'"
111
+ puts "Exception: #{e}"
112
+ raise
113
+ end
114
+ end
115
+
116
+ def FromXML.tokenise_string(str, strip=true)
117
+ return nil unless str
118
+ str.strip! if strip
119
+ str.gsub!(/[ \n\r\t][ \n\r\t]*/, " ")
120
+ return str
121
+ end
122
+
123
+ def parse_element(parent=nil, target=nil)
124
+ find_the_first_element
125
+ return unless start_element?
126
+
127
+ namespace = @reader.namespace_uri
128
+ name = @reader.local_name
129
+
130
+ existing_element = nil
131
+ element = nil
132
+
133
+ requires_caching = false
134
+
135
+ build_attribute_arrays
136
+
137
+ if ((nil != namespace) and (0 < namespace.size)) then
138
+ klass_name = "{#{namespace}}#{name}"
139
+ klasses = FromXML.registered(klass_name)
140
+ if (0 == klasses.size) then
141
+ xml_text = XMLText.new
142
+ xml_text.build(self)
143
+ xml_text = parent.note_adding_text_content(xml_text, @is_realising)
144
+ parent.add_content(xml_text, @tokenise_content) if xml_text
145
+ return xml_text, false
146
+ end
147
+ if (1 < klasses.size) then
148
+ raise XamplException.new("there is more than one '#{name}' tag in namespace '#{namespace}'\nplease report this error")
149
+ end
150
+ else
151
+ klasses = FromXML.registered(name)
152
+ if (0 == klasses.size) then
153
+ raise XamplException.new("do not recognise tag '#{name}' (no namespace specified)")
154
+ end
155
+ if (1 < klasses.size) then
156
+ raise XamplException.new("there is more than one '#{name}' tag (no namespace specified)")
157
+ end
158
+ end
159
+
160
+ unless @is_realising then
161
+ @attribute_value.size.times do |i|
162
+ FromXML.tokenise_string @attribute_value[i]
163
+ end
164
+ end
165
+
166
+ if target then
167
+ element = target
168
+ target.load_needed = false
169
+ target = nil
170
+ element.init_attributes(@attribute_name, @attribute_namespace, @attribute_value)
171
+ element.note_attributes_initialised(@is_realising)
172
+ else
173
+ if klasses[0].persisted? then
174
+ @attribute_name.each_index do |i|
175
+ if @attribute_name[i] == klasses[0].persisted?.to_s then
176
+ existing_element = Xampl.find_known(klasses[0], @attribute_value[i])
177
+ if existing_element then
178
+ # so we've found the element. Now what??? We can do several
179
+ # reasonable things:
180
+ #
181
+ # 1) continue parsing into the found element
182
+ # 2) simply return the found element
183
+ # 3) replace the found element with the new element
184
+ #
185
+ # The first one is dubious, so we won't.
186
+ # The second and third option both make complete sense
187
+ #
188
+ # We are going to do the second
189
+ #
190
+ # BTW, 'existing element' means a representation of this element already in memory
191
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
192
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
193
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
194
+ # puts "FOUND AN EXISTING THING... #{ klasses[0] } #{ @attribute_value[i] }"
195
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
196
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
197
+ # puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
198
+ # caller(0).each { | trace | puts " #{trace}"}
199
+ # existing_element.reset_contents
200
+ # element = existing_element
201
+ # existing_element = nil
202
+ # puts "#{File.basename(__FILE__)} #{__LINE__} EXISTING ELEMENT: #{ existing_element }"
203
+ # puts "#{File.basename(__FILE__)} #{__LINE__} WOW, must handle the existing element correctly"
204
+ element = existing_element #TODO -- IS THIS RIGHT????????????????????????
205
+ end
206
+ unless element then
207
+ element = klasses[0].new
208
+ requires_caching = @recovering
209
+ # puts "#{File.basename(__FILE__)} #{__LINE__} WOW, what about recovering????"
210
+ #TODO -- IS THIS RIGHT????????????????????????
211
+ requires_caching = true #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
212
+ unless @recovering then
213
+ element.force_load if parent
214
+ end
215
+ element.note_created(@is_realising)
216
+ end
217
+
218
+ break
219
+ end
220
+ end
221
+ end
222
+
223
+ unless element then
224
+ element = klasses[0].new
225
+ element.note_created(@is_realising)
226
+ end
227
+
228
+ element.note_initialise_attributes_with(@attribute_name, @attribute_namespace, @attribute_value, @is_realising)
229
+ element.init_attributes(@attribute_name, @attribute_namespace, @attribute_value)
230
+ element.note_attributes_initialised(@is_realising)
231
+
232
+ if requires_caching and element and element.persist_required then
233
+ Xampl.cache(element)
234
+ end
235
+
236
+ #element = element.note_add_to_parent(parent, @is_realising)
237
+ #element.append_to(parent) if parent
238
+ end
239
+
240
+ while next_reader_event
241
+ case current_node_type
242
+
243
+ =begin
244
+ TODO -- can these ever happen?
245
+ when START_DOCUMENT
246
+ return element if @recovering
247
+ return existing_element || element
248
+ when END_DOCUMENT
249
+ return element if @recovering
250
+ return existing_element || element
251
+
252
+ =end
253
+
254
+ when LibXML::XML::Reader::TYPE_ELEMENT
255
+ child, ignore_child = parse_element(element)
256
+
257
+ unless ignore_child then
258
+ case child
259
+ when XamplObject then
260
+ child = child.note_add_to_parent(element, @is_realising) if child
261
+ child = element.note_add_child(child, @is_realising) if element
262
+ child.append_to(element) if element and child
263
+ when XMLText then
264
+ puts "UNRECOGNISED Well-formed XML: #{child.to_s[0..25]}..."
265
+ else
266
+ puts "WHAT IS THIS??? #{child.class.name}"
267
+ end
268
+ end
269
+ when LibXML::XML::Reader::TYPE_END_ELEMENT
270
+ element = element.note_closed(@is_realising)
271
+ return element if @recovering
272
+ return existing_element || element
273
+ when LibXML::XML::Reader::TYPE_TEXT, LibXML::XML::Reader::TYPE_CDATA, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_ENTITY_REFERENCE
274
+ if element.has_mixed_content then
275
+ text = @reader.read_string
276
+ the_text = element.note_adding_text_content(text, @is_realising)
277
+ element << the_text
278
+ else
279
+ text = @reader.read_string
280
+ the_text = element.note_adding_text_content(text, @is_realising)
281
+ element.add_content(the_text, false)
282
+ end
283
+ else
284
+ end
285
+ end
286
+
287
+ return element if @recovering
288
+ return existing_element || element
289
+ end
290
+
291
+ def current_node_type
292
+ if @faking_an_end_element then
293
+ LibXML::XML::Reader::TYPE_END_ELEMENT
294
+ else
295
+ @reader.node_type
296
+ end
297
+ end
298
+
299
+ =begin
300
+ def describe_current_element_type()
301
+ case @reader.node_type
302
+ when LibXML::XML::Reader::TYPE_ATTRIBUTE
303
+ puts "ATTRIBUTE"
304
+ when LibXML::XML::Reader::TYPE_DOCUMENT
305
+ puts "DOCUMENT"
306
+ when LibXML::XML::Reader::TYPE_ELEMENT
307
+ attribute_count = @reader.attribute_count
308
+ puts "ELEMENT #{ @reader.local_name }, ns: #{ @reader.namespace_uri }, #attributes: #{ attribute_count }, depth: #{ @reader.depth }"
309
+ puts " FAKING END ELEMENT" if @faking_an_end_element
310
+ when LibXML::XML::Reader::TYPE_END_ELEMENT
311
+ puts "END ELEMENT"
312
+ when LibXML::XML::Reader::TYPE_TEXT
313
+ puts "TEXT [[#{ @reader.read_string }]]"
314
+ when LibXML::XML::Reader::TYPE_CDATA
315
+ puts "CDATA [[#{ @reader.read_string }]]"
316
+ when LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE
317
+ puts "SIGNIFICANT white space [[#{ @reader.read_string }]]"
318
+ when LibXML::XML::Reader::TYPE_ENTITY_REFERENCE
319
+ puts "entity ref"
320
+ when LibXML::XML::Reader::TYPE_WHITESPACE
321
+ puts "whitespace"
322
+ when LibXML::XML::Reader::TYPE_PROCESSING_INSTRUCTION
323
+ puts "processing instruction"
324
+ when LibXML::XML::Reader::TYPE_COMMENT
325
+ puts "comment"
326
+ when LibXML::XML::Reader::TYPE_DOCUMENT_TYPE
327
+ puts "doc type"
328
+
329
+ when LibXML::XML::Reader::TYPE_XML_DECLARATION
330
+ puts "xml decl"
331
+ when LibXML::XML::Reader::TYPE_NONE
332
+ puts "NONE!!"
333
+ when LibXML::XML::Reader::TYPE_NOTATION
334
+ puts "notifiation"
335
+ when LibXML::XML::Reader::TYPE_DOCUMENT_FRAGMENT
336
+ puts "doc fragment"
337
+ when LibXML::XML::Reader::TYPE_ENTITY
338
+ puts "entity"
339
+ when LibXML::XML::Reader::TYPE_END_ENTITY
340
+ puts "end entity"
341
+ else
342
+ puts "UNKNOWN: #{@reader.node_type}"
343
+ end
344
+ end
345
+ =end
346
+
347
+ def next_reader_event
348
+ if @insert_end_element then
349
+ @faking_an_end_element = true
350
+ @insert_end_element = false
351
+ return
352
+ end
353
+
354
+ @faking_an_end_element = false
355
+
356
+ #describe_current_element_type
357
+
358
+ okay = @reader.read
359
+
360
+ @just_opened_an_element = start_element?
361
+ @insert_end_element = (@just_opened_an_element and @reader.empty_element?)
362
+
363
+ #describe_current_element_type
364
+
365
+ okay
366
+ end
367
+
368
+ def start_element?
369
+ current_node_type == LibXML::XML::Reader::TYPE_ELEMENT
370
+ end
371
+
372
+ def whitespace?
373
+ current_note_type == LibXML::XML::Reader::TYPE_WHITESPACE
374
+ end
375
+
376
+ def find_the_first_element
377
+ while true do
378
+ break if start_element?
379
+ break unless next_reader_event
380
+ end
381
+ @just_opened_an_element = start_element?
382
+ end
383
+
384
+ def build_attribute_arrays
385
+
386
+ @attribute_name.clear
387
+ @attribute_namespace.clear
388
+ @attribute_value.clear
389
+
390
+ return unless LibXML::XML::Reader::TYPE_ELEMENT == current_node_type
391
+
392
+ if @reader.has_attributes? then
393
+ attribute_count = @reader.attribute_count
394
+ @reader.move_to_first_attribute
395
+ attribute_count.times do | i |
396
+ if @reader.namespace_declaration? then
397
+ @reader.move_to_next_attribute
398
+ next
399
+ end
400
+
401
+ @attribute_name << @reader.local_name
402
+ @attribute_namespace << @reader.namespace_uri
403
+ @attribute_value << @reader.value
404
+
405
+ @reader.move_to_next_attribute
406
+ end
407
+ end
408
+ end
409
+
410
+ def attributeCount
411
+ return @attribute_name.length
412
+ end
413
+
414
+ def attributeName(i)
415
+ return @attribute_name[i]
416
+ end
417
+
418
+ def attributeNamespace(i)
419
+ return @attribute_namespace[i]
420
+ end
421
+
422
+ def attributeValue(i)
423
+ return @attribute_value[i]
424
+ end
425
+
426
+ def depth
427
+ return @reader.depth
428
+ end
429
+
430
+ def line
431
+ return @reader.line_number
432
+ end
433
+
434
+ def column
435
+ return @reader.column_number
436
+ end
437
+ end
438
+
439
+ end