xamplr 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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