hutch-xamplr 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/Rakefile +1 -0
  2. data/VERSION.yml +2 -2
  3. data/examples/random-people-shared-addresses/Makefile +2 -2
  4. data/examples/random-people-shared-addresses/batch-load-users.rb +2 -5
  5. data/examples/random-people-shared-addresses/find-mentions.rb +1 -4
  6. data/examples/random-people-shared-addresses/find-people-by-address.rb +1 -4
  7. data/examples/random-people-shared-addresses/optimise.rb +1 -4
  8. data/examples/random-people-shared-addresses/people.rb +0 -15
  9. data/examples/random-people-shared-addresses/query.rb +1 -4
  10. data/examples/random-people-shared-addresses/query2.rb +1 -4
  11. data/examples/random-people-shared-addresses/results.write.BASELINE +298 -0
  12. data/examples/random-people-shared-addresses/results.write.NEW_ATTR_ENCODING +294 -0
  13. data/examples/random-people-shared-addresses/settings.rb +3 -0
  14. data/examples/random-people/batch-load-users.rb +1 -4
  15. data/examples/random-people/optimise.rb +1 -4
  16. data/examples/random-people/people.rb +0 -3
  17. data/examples/random-people/query.rb +1 -5
  18. data/examples/random-people/query2.rb +1 -4
  19. data/examples/random-people/settings.rb +3 -0
  20. data/examples/random-people/what-to-query-on.rb +1 -3
  21. data/examples/read-testing/Makefile +10 -0
  22. data/examples/read-testing/load.rb +65 -0
  23. data/examples/read-testing/read.rb +51 -0
  24. data/examples/read-testing/results.read.BASELINE +6 -0
  25. data/examples/read-testing/results.read.FAST +5 -0
  26. data/examples/read-testing/rrr.rb +87 -0
  27. data/examples/read-testing/settings.rb +2 -0
  28. data/examples/read-testing/xampl-gen.rb +36 -0
  29. data/examples/read-testing/xml/text.xml +8 -0
  30. data/lib/xamplr.rb +10 -1
  31. data/lib/xamplr/exceptions.rb +97 -0
  32. data/lib/xamplr/from-xml-orig.rb +350 -0
  33. data/lib/xamplr/from-xml.rb +272 -183
  34. data/lib/xamplr/handwritten/example.rb +0 -58
  35. data/lib/xamplr/handwritten/hand-example.rb +0 -27
  36. data/lib/xamplr/handwritten/test-handwritten.rb +0 -37
  37. data/lib/xamplr/mixins.rb +10 -48
  38. data/lib/xamplr/persist-to-xml.rb +249 -0
  39. data/lib/xamplr/persistence.rb +44 -412
  40. data/lib/xamplr/persistence.rb.more_thread_safe +0 -13
  41. data/lib/xamplr/persistence.rb.partially_thread_safe +0 -13
  42. data/lib/xamplr/persister.rb +298 -0
  43. data/lib/xamplr/{persister → persisters}/caches.rb +0 -0
  44. data/lib/xamplr/{persister → persisters}/caching.rb +1 -1
  45. data/lib/xamplr/{persister → persisters}/filesystem.rb +4 -5
  46. data/lib/xamplr/{persister → persisters}/in-memory.rb +1 -1
  47. data/lib/xamplr/{persister → persisters}/simple.rb +0 -0
  48. data/lib/xamplr/{persister → persisters}/tokyo-cabinet.rb +53 -15
  49. data/lib/xamplr/simpleTemplate/{input-c.r4 → obsolete/input-c.r4} +0 -0
  50. data/lib/xamplr/simpleTemplate/{play.r6.txt → obsolete/play.r6.txt} +0 -0
  51. data/lib/xamplr/simpleTemplate/{play_more.r6.txt → obsolete/play_more.r6.txt} +0 -0
  52. data/lib/xamplr/simpleTemplate/{test001.r5 → obsolete/test001.r5} +0 -0
  53. data/lib/xamplr/simpleTemplate/{test002.r5 → obsolete/test002.r5} +0 -0
  54. data/lib/xamplr/simpleTemplate/{test003.r5 → obsolete/test003.r5} +0 -0
  55. data/lib/xamplr/templates/child_indexed.template +1 -1
  56. data/lib/xamplr/templates/element_classes.template +1 -1
  57. data/lib/xamplr/templates/element_data.template +0 -39
  58. data/lib/xamplr/templates/element_empty.template +0 -40
  59. data/lib/xamplr/templates/element_mixed.template +0 -41
  60. data/lib/xamplr/templates/element_simple.template +0 -40
  61. data/lib/xamplr/test-support/bench.rb +6 -26
  62. data/lib/xamplr/test-support/test.rb +1 -89
  63. data/lib/xamplr/visitor.rb +0 -778
  64. data/lib/xamplr/visitors.rb +573 -0
  65. data/lib/xamplr/xampl-generator.rb +1 -1
  66. data/lib/xamplr/xampl-hand-generated.rb +0 -85
  67. data/lib/xamplr/xampl-module.rb +36 -0
  68. data/lib/xamplr/xampl-object-internals.rb +6 -0
  69. data/lib/xamplr/xampl-object.rb +10 -341
  70. data/lib/xamplr/xampl-persisted-object.rb +122 -0
  71. data/lib/xamplr/xml-text.rb +117 -0
  72. metadata +53 -18
  73. data/lib/xamplr/persister/subversion.rb +0 -61
  74. data/lib/xamplr/rac.sh +0 -6
  75. data/lib/xamplr/rac_gen.sh +0 -1
  76. data/lib/xamplr/templates/child_indexed.template.000 +0 -87
@@ -23,7 +23,7 @@
23
23
  accessed
24
24
  index = #{element.attribute_name}.get_the_index
25
25
  if(nil == index) then
26
- raise XamplException.new("no value for the index '#{element.indexed_by_attr}' of #{element.attribute_name} defined in : " << #{element.attribute_name}.pp_xml)
26
+ raise Xampl::XamplException.new("no value for the index '#{element.indexed_by_attr}' of #{element.attribute_name} defined in : " << #{element.attribute_name}.pp_xml)
27
27
  end
28
28
 
29
29
  existing = @#{element.attribute_name}_child[index]
@@ -7,5 +7,5 @@
7
7
  | elsif "mixed" == @element.kind then
8
8
  | element_mixed(result)
9
9
  | else
10
- | raise XamplException.new(:unkown_kind_of_element, "unknown element kind: '#{@element.kind}'")
10
+ | raise Xampl::XamplException.new(:unkown_kind_of_element, "unknown element kind: '#{@element.kind}'")
11
11
  | end
@@ -64,47 +64,8 @@
64
64
  |
65
65
  |}
66
66
  |
67
- |
68
- |if @element.persisted then
69
67
  |
70
68
 
71
- @@to_yaml_properties = [ "@#{@element.indexed_by_attr}" ]
72
- @@to_yaml_properties_all = [
73
- |
74
- |else
75
- |
76
-
77
- @@to_yaml_properties = [
78
- |
79
- |end
80
- |
81
- |@element.attribute_child.each{ | attribute |
82
- |
83
- "@#{attribute.name}",
84
- |
85
- |}
86
- |
87
- "@children",
88
- "@_content"
89
- ]
90
-
91
- def to_yaml_properties
92
- |
93
- |if @element.persisted then
94
- |
95
- if is_yaml_root(self) then
96
- return @@to_yaml_properties_all
97
- else
98
- return @@to_yaml_properties
99
- end
100
- |
101
- |else
102
- |
103
- @@to_yaml_properties
104
- |
105
- |end
106
- |
107
- end
108
69
  |
109
70
  |if @element.persisted then
110
71
  |
@@ -63,46 +63,6 @@
63
63
  |}
64
64
  |
65
65
  |if @element.persisted then
66
- |
67
-
68
- @@to_yaml_properties = [ "@#{@element.indexed_by_attr}" ]
69
- @@to_yaml_properties_all = [
70
-
71
- |
72
- |else
73
- |
74
-
75
- @@to_yaml_properties = [
76
- |
77
- |end
78
- |
79
- |@element.attribute_child.each{ | attribute |
80
- |
81
- "@#{attribute.name}",
82
- |
83
- |}
84
- |
85
- ]
86
-
87
- def to_yaml_properties
88
- |
89
- |if @element.persisted then
90
- |
91
- if is_yaml_root(self) then
92
- return @@to_yaml_properties_all
93
- else
94
- return @@to_yaml_properties
95
- end
96
- |
97
- |else
98
- |
99
- @@to_yaml_properties
100
- |
101
- |end
102
- |
103
- end
104
- |
105
- |if @element.persisted then
106
66
  |
107
67
 
108
68
  def #{@element.class_name}.lookup(pid)
@@ -63,47 +63,6 @@
63
63
  |}
64
64
  |
65
65
  |if @element.persisted then
66
- |
67
-
68
- @@to_yaml_properties = [ "@#{@element.indexed_by_attr}" ]
69
- @@to_yaml_properties_all = [
70
-
71
- |
72
- |else
73
- |
74
-
75
- @@to_yaml_properties = [
76
- |
77
- | end
78
- |
79
- |@element.attribute_child.each{ | attribute |
80
- |
81
- "@#{attribute.name}",
82
- |
83
- |}
84
- |
85
- "@children"
86
- ]
87
-
88
- def to_yaml_properties
89
- |
90
- |if @element.persisted then
91
- |
92
- if is_yaml_root(self) then
93
- return @@to_yaml_properties_all
94
- else
95
- return @@to_yaml_properties
96
- end
97
- |
98
- |else
99
- |
100
- @@to_yaml_properties
101
- |
102
- |end
103
- |
104
- end
105
- |
106
- |if @element.persisted then
107
66
  |
108
67
 
109
68
  def #{@element.class_name}.lookup(pid)
@@ -63,46 +63,6 @@
63
63
  |}
64
64
  |
65
65
  |if @element.persisted then
66
- |
67
-
68
- @@to_yaml_properties = [ "@#{@element.indexed_by_attr}" ]
69
- @@to_yaml_properties_all = [
70
- |
71
- |else
72
- |
73
-
74
- @@to_yaml_properties = [
75
- |
76
- |end
77
- |
78
- |@element.attribute_child.each{ | attribute |
79
- |
80
- "@#{attribute.name}",
81
- |
82
- |}
83
- |
84
- "@_content"
85
- ]
86
-
87
- def to_yaml_properties
88
- |
89
- |if @element.persisted then
90
- |
91
- if is_yaml_root(self) then
92
- return @@to_yaml_properties_all
93
- else
94
- return @@to_yaml_properties
95
- end
96
- |
97
- |else
98
- |
99
- @@to_yaml_properties
100
- |
101
- |end
102
- |
103
- end
104
- |
105
- |if @element.persisted then
106
66
  |
107
67
 
108
68
  def #{@element.class_name}.lookup(pid)
@@ -13,21 +13,18 @@ include Benchmark
13
13
  # results from 16 October 2005
14
14
  #
15
15
 
16
- #Rebuilding From String (YAML & XML) count: 1000 (est. ~ 11s)
16
+ #Rebuilding From String (XML) count: 1000 (est. ~ 11s)
17
17
  # user system total real
18
- #yaml 2.590000 0.050000 2.640000 ( 3.180061)
19
18
  #xml 5.970000 0.080000 6.050000 ( 6.573804)
20
19
  #ruby 1.660000 0.030000 1.690000 ( 2.017015)
21
20
 
22
- #Serialize to String (YAML & XML) count: 1000 (est. ~ 25s)
21
+ #Serialize to String (XML) count: 1000 (est. ~ 25s)
23
22
  # user system total real
24
- #yaml 14.360000 0.250000 14.610000 ( 16.128599)
25
23
  #xml 1.460000 0.020000 1.480000 ( 1.576753)
26
24
  #ruby 0.890000 0.010000 0.900000 ( 1.102071)
27
25
 
28
- #Round Tripping (YAML & XML) count: 1000 (est. ~ 40s)
26
+ #Round Tripping (XML) count: 1000 (est. ~ 40s)
29
27
  # user system total real
30
- #yaml 17.420000 0.270000 17.690000 ( 19.390348)
31
28
  #xml 7.890000 0.110000 8.000000 ( 8.860720)
32
29
  #ruby 2.780000 0.040000 2.820000 ( 3.131707)
33
30
 
@@ -62,10 +59,8 @@ module Bench
62
59
  #ruby_printer = RubyPrinter.new
63
60
  #ruby_s = ruby_printer.to_ruby(thing)
64
61
  ruby_s = thing.to_ruby
65
- yaml_s = thing.as_yaml
66
62
  xml_s = thing.persist
67
63
 
68
- #puts yaml_s
69
64
  puts xml_s
70
65
  puts ruby_s
71
66
  puts "++++++++++++++++++++++++++++++++++++"
@@ -73,13 +68,8 @@ module Bench
73
68
  puts big_thing.to_ruby
74
69
  puts "++++++++++++++++++++++++++++++++++++"
75
70
 
76
- puts "Rebuilding From String (YAML & XML) count: #{count} (est. ~ 11s)"
71
+ puts "Rebuilding From String (XML) count: #{count} (est. ~ 11s)"
77
72
  bm(10) do | x |
78
- x.report("yaml") {
79
- count.times {
80
- something = XamplObject.from_yaml(yaml_s)
81
- }
82
- }
83
73
  x.report("xml") {
84
74
  count.times {
85
75
  another_big_thing = XamplObject.from_xml_string(xml_s)
@@ -92,13 +82,8 @@ module Bench
92
82
  }
93
83
  end
94
84
 
95
- puts "Serialize to String (YAML & XML) count: #{count} (est. ~ 25s)"
85
+ puts "Serialize to String (XML) count: #{count} (est. ~ 25s)"
96
86
  bm(10) do | x |
97
- x.report("yaml") {
98
- count.times {
99
- yaml_s = thing.as_yaml
100
- }
101
- }
102
87
  x.report("xml") {
103
88
  count.times {
104
89
  xml_s = thing.persist
@@ -111,13 +96,8 @@ module Bench
111
96
  }
112
97
  end
113
98
 
114
- puts "Round Tripping (YAML & XML) count: #{count} (est. ~ 40s)"
99
+ puts "Round Tripping (XML) count: #{count} (est. ~ 40s)"
115
100
  bm(10) do | x |
116
- x.report("yaml") {
117
- count.times {
118
- something = XamplObject.from_yaml(thing.as_yaml)
119
- }
120
- }
121
101
  x.report("xml") {
122
102
  count.times {
123
103
  another_thing = XamplObject.from_xml_string(thing.persist)
@@ -257,50 +257,6 @@ class TestXampl < Test::Unit::TestCase
257
257
  check_parents(big_thing)
258
258
  end
259
259
 
260
- def test_yaml_round_trip
261
- emph_content_1 = "there"
262
- emph1 = Emph.new
263
- emph1 << emph_content_1
264
-
265
- emph_content_2 = "are"
266
- emph2 = Emph.new
267
- emph2.content = emph_content_2
268
-
269
- desc1 = Description.new
270
- desc1.kind = "desc1"
271
-
272
- desc1.is_changed = nil
273
- desc1 << "hello " << emph1 << "! How " << emph2 << " you?"
274
-
275
- thing = Thing.new
276
- thing.pid = "thing"
277
- thing.new_stuff.kind = "stuff1"
278
- thing << desc1
279
-
280
- big_thing = Thing.new("big_thing")
281
- big_thing << "leading content" << thing << "trailing content"
282
-
283
- check_parents(big_thing)
284
-
285
- #puts YAML::dump(big_thing)
286
- #puts big_thing.test_to_xml
287
-
288
- #something = XamplObject.from_yaml(YAML::dump(big_thing))
289
- pp_xml = big_thing.pp_xml
290
- bt_as_yaml = big_thing.as_yaml
291
-
292
- something = XamplObject.from_yaml(bt_as_yaml)
293
-
294
- assert_not_same(something, big_thing)
295
- assert_equal(something.test_to_xml, big_thing.persist)
296
- check_parents(something)
297
-
298
- something = XamplObject.from_yaml(big_thing.as_yaml)
299
- assert_equal(something.test_to_xml, big_thing.persist)
300
- assert_not_same(something, big_thing)
301
- check_parents(something)
302
- end
303
-
304
260
  def test_from_xml
305
261
  emph_content_1 = "there"
306
262
  emph1 = Emph.new
@@ -563,25 +519,6 @@ class TestXampl < Test::Unit::TestCase
563
519
  assert(thing === found)
564
520
  end
565
521
 
566
- def test_in_memory_persistence_yaml
567
- pname = "test_in_memory_persistence_yaml" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
568
- Xampl.enable_persister(pname, :in_memory, :yaml_format)
569
- persister2 = Xampl.persister
570
-
571
- stuff = Stuff.new
572
- thing = Thing.new
573
- thing.pid = "thing"
574
- thing << stuff
575
-
576
- Xampl.introduce_to_persister(thing)
577
- Xampl.sync
578
- Xampl.clear_cache
579
- found = Xampl.lookup(Thing, "thing")
580
-
581
- assert_not_equal(thing, found)
582
- assert(thing === found)
583
- end
584
-
585
522
  def test_in_memory_persistence_rollback
586
523
  pname = "first" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
587
524
  original_persister = Xampl.enable_persister(pname, :in_memory)
@@ -854,30 +791,6 @@ class TestXampl < Test::Unit::TestCase
854
791
  assert_equal(thing.object_id, found.object_id)
855
792
  end
856
793
 
857
- def test_filesystem_persistence_yaml
858
- pname = "test_filesystem_persistence_yaml" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
859
- Xampl.enable_persister(pname, :filesystem, :yaml_format)
860
- persister2 = Xampl.persister
861
-
862
- stuff = Stuff.new
863
- thing = Thing.new
864
- thing.pid = "thing"
865
- thing << stuff
866
-
867
- Xampl.introduce_to_persister(thing)
868
- Xampl.sync
869
-
870
- thing.info = "force emptying"
871
-
872
- Xampl.rollback
873
-
874
- assert(thing.load_needed)
875
-
876
- found = Xampl.lookup(Thing, "thing")
877
-
878
- assert_equal(thing.object_id, found.object_id)
879
- end
880
-
881
794
  def test_filesystem_persistence_automatic
882
795
  stuff = Stuff.new
883
796
  thing = Thing.new
@@ -1045,12 +958,11 @@ class TestXampl < Test::Unit::TestCase
1045
958
 
1046
959
  keep_new_thing = new_thing
1047
960
 
1048
- # these (to xml, ruby, yaml) will NOT suck the child thing into memory
961
+ # these (to xml, ruby) will NOT suck the child thing into memory
1049
962
  xml = thing.test_to_xml
1050
963
 
1051
964
  ruby = thing.to_ruby
1052
965
  ruby_thing = XamplObject.from_ruby(ruby)
1053
- yaml_thing = XamplObject.from_yaml(thing.as_yaml)
1054
966
 
1055
967
  assert_equal(0, Xampl.persister.read_count, "not in the cache")
1056
968
 
@@ -1,4 +1,3 @@
1
-
2
1
  module Xampl
3
2
 
4
3
  class Visitor
@@ -137,782 +136,5 @@ module Xampl
137
136
  @cycling = false
138
137
  end
139
138
  end
140
-
141
- class CountingVisitor < Visitor
142
- attr_accessor :count
143
-
144
- def initialize
145
- super
146
- @count = 0
147
- end
148
-
149
- def before_visit(xampl)
150
- @count += 1
151
- end
152
- end
153
-
154
- class ResetIsChanged < Visitor
155
- def initialize
156
- super
157
- end
158
-
159
- def start(xampl, verbose=false)
160
- @verbose = verbose
161
- if verbose
162
- puts "RESET IS CHANGED.... #{xampl}"
163
- puts "SKIPPING!!!" unless xampl.persist_required and xampl.load_needed
164
- end
165
-
166
- return if xampl.persist_required and xampl.load_needed
167
- super(xampl)
168
- end
169
-
170
- def before_visit(xampl)
171
- if xampl.is_changed then
172
- puts "RESET CHANGED: #{xampl} and continue" if verbose
173
- xampl.is_changed = false;
174
- else
175
- puts "RESET CHANGED: #{xampl} block" if verbose
176
- @no_children = true
177
- end
178
- end
179
- end
180
-
181
- class MarkChangedDeep < Visitor
182
- def initialize
183
- super
184
- end
185
-
186
- def before_visit(xampl)
187
- xampl.changed if xampl.persist_required
188
- end
189
- end
190
-
191
- class PrettyXML < Visitor
192
- attr_accessor :ns_to_prefix, :start_body, :body, :out
193
- attr_accessor :indent, :indent_step
194
-
195
- @@compact = true
196
-
197
- def PrettyXML.compact
198
- @@compact
199
- end
200
-
201
- def PrettyXML.compact=(v)
202
- @@compact = v
203
- end
204
-
205
- def initialize(out="", skip=[])
206
- super()
207
-
208
- @out = out
209
- @indent = ""
210
- @indent_step = " "
211
- @start_attr_indent = ""
212
- @was_attr = false
213
-
214
- @depth = 0
215
-
216
- @skip = {}
217
- skip.each{ | ns |
218
- @skip[ns] = ns
219
- }
220
-
221
- @ns_to_prefix = {}
222
- @start_body = nil
223
- @body = ""
224
- @attr_list = nil
225
-
226
- @insert_comment = nil
227
- end
228
-
229
- def short_circuit
230
- body << @insert_comment if @insert_comment
231
- @insert_comment = nil
232
- end
233
-
234
- def cycle(xampl)
235
- @short_circuit = true
236
- @insert_comment = "<!-- CYCLE -->"
237
- return true
238
- end
239
-
240
- def revisit(xampl)
241
- @insert_comment = "<!-- You've seen this before -->"
242
- #body << "<!-- You've seen this before -->"
243
- return true
244
- end
245
-
246
- def register_ns(ns)
247
- if (0 == ns.length) then
248
- return ""
249
- end
250
-
251
- prefix = ns_to_prefix[ns]
252
- if (nil == prefix) then
253
- preferred = XamplObject.lookup_preferred_ns_prefix(ns)
254
- prefix = "" << preferred << ":" if preferred
255
- prefix = "ns" << ns_to_prefix.size.to_s << ":" unless prefix
256
- ns_to_prefix[ns] = prefix
257
- end
258
- return prefix
259
- end
260
-
261
- def attr_esc(s)
262
- if (s.kind_of? XamplObject)
263
- return attr_esc(s.to_xml)
264
- end
265
-
266
- result = s.to_s.dup
267
-
268
- result.gsub!("&", "&amp;")
269
- result.gsub!("<", "&lt;")
270
- result.gsub!(">", "&gt;")
271
- result.gsub!("'", "&apos;")
272
- result.gsub!("\"", "&quot;")
273
-
274
- return result
275
- end
276
-
277
- def content_esc(s)
278
- result = s.to_s.dup
279
-
280
- return result if (s.kind_of? XamplObject)
281
-
282
- result.gsub!("&", "&amp;")
283
- result.gsub!("<", "&lt;")
284
-
285
- return result
286
- end
287
-
288
- def attribute(xampl)
289
- @attr_list = []
290
- pid = nil
291
- if (nil != xampl.attributes) then
292
- xampl.attributes.each{ | attr_spec |
293
- unless @skip[attr_spec[2]] then
294
- value = xampl.instance_variable_get(attr_spec[0])
295
- if value then
296
- prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
297
- @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'")
298
- end
299
- end
300
- }
301
- @attr_list.sort!
302
- end
303
- #@attr_list << " xampl:marker='OKAY: #{ xampl }'"
304
- end
305
-
306
- def persist_attribute(xampl)
307
- @attr_list = []
308
- if xampl.persist_required then
309
- index = xampl.indexed_by.to_s
310
- if index then
311
- value = xampl.get_the_index
312
- @attr_list << (" " << index << "='" << attr_esc(value) << "'") if value
313
- end
314
- else
315
- attribute(xampl)
316
- #@attr_list << " xampl:wtf='WTF??'"
317
- end
318
- end
319
-
320
- def show_attributes(attr_indent)
321
- if (nil == @attr_list) then
322
- return ""
323
- else
324
- result = @attr_list.join(attr_indent)
325
- if (0 == result.length) then
326
- return ""
327
- else
328
- return result
329
- end
330
- end
331
- end
332
-
333
- def do_indent
334
- return "\n" << @indent << (@indent_step * @depth)
335
- end
336
-
337
- def start_element(xampl)
338
- xampl.accessed
339
-
340
- if @revisiting or @cycling then
341
- @short_circuit = true
342
- persist_attribute(xampl)
343
- else
344
- attribute(xampl)
345
- end
346
-
347
- tag = xampl.tag
348
- ns = xampl.ns
349
- indent = do_indent
350
- tag_info = "" << "<" << register_ns(ns) << tag
351
- attr_indent = "" << indent << (" " * tag_info.size)
352
- unless @start_body then
353
- @start_attr_indent = attr_indent
354
- attr_defn = show_attributes(attr_indent)
355
- @start_body = "" << indent << tag_info << attr_defn
356
- @was_attr = true if 0 < attr_defn.size
357
- else
358
- @body << indent << tag_info << show_attributes(attr_indent)
359
- end
360
- end
361
-
362
- def end_element(xampl)
363
- tag = xampl.tag
364
- ns = xampl.ns
365
- if @@compact then
366
- @body << "</" << register_ns(ns) << tag << ">"
367
- else
368
- @body << do_indent << "</" << register_ns(ns) << tag << ">"
369
- end
370
- end
371
-
372
- def define_ns
373
- result = ""
374
- indent = @was_attr
375
- ns_to_prefix.each{ | ns, prefix |
376
- result = sprintf("%s%s xmlns:%s='%s'", result, indent ? @start_attr_indent : "", prefix[0..-2], ns)
377
- indent = true
378
- }
379
- return result
380
- end
381
-
382
- def done
383
- out << @start_body << define_ns << @body
384
- end
385
-
386
- def before_visit_without_content(xampl)
387
- start_element(xampl)
388
- @body << "/>"
389
- end
390
-
391
- def before_visit_simple_content(xampl)
392
- start_element(xampl)
393
- @body << ">"
394
- @body << content_esc(xampl._content) if xampl._content
395
- end_element(xampl)
396
- end
397
-
398
- def before_visit_data_content(xampl)
399
- start_element(xampl)
400
- @body << ">"
401
- @body << content_esc(xampl._content) if xampl._content
402
- @depth += 1
403
- end
404
-
405
- def after_visit_data_content(xampl)
406
- @depth += -1
407
- end_element(xampl)
408
- end
409
-
410
- def before_visit_mixed_content(xampl)
411
- start_element(xampl)
412
- @body << ">"
413
- @depth += 1
414
- end
415
-
416
- def after_visit_mixed_content(xampl)
417
- @depth -= 1
418
- end_element(xampl)
419
- end
420
-
421
- def before_visit(xampl)
422
- unless xampl.kind_of?(XamplObject) and @skip[xampl.ns] then
423
- if xampl.respond_to? "before_visit_by_element_kind" then
424
- xampl.before_visit_by_element_kind(self)
425
- else
426
- @body << xampl.to_s
427
- end
428
- else
429
- @no_children = true
430
- end
431
- end
432
-
433
- def after_visit(xampl)
434
- xampl.after_visit_by_element_kind(self) if xampl.respond_to? "after_visit_by_element_kind"
435
- end
436
-
437
- def visit_string(string)
438
- @body << string
439
- end
440
- end
441
-
442
- class PersistXML < Visitor
443
- attr_accessor :ns_to_prefix, :start_body, :body, :out, :mentions
444
-
445
- def initialize(out="", mentions=nil)
446
- super()
447
-
448
- @out = out
449
- @was_attr = false
450
-
451
- @mentions = mentions
452
-
453
- @ns_to_prefix = {}
454
- @start_body = nil
455
- @body = ""
456
- @attr_list = nil
457
- end
458
-
459
- def cycle(xampl)
460
- raise XamplException.new(:cycle_detected_in_xampl_cluster) unless xampl.kind_of?(XamplPersistedObject)
461
- return true
462
- end
463
-
464
- def revisit(xampl)
465
- return true
466
- end
467
-
468
- def register_ns(ns)
469
- if (0 == ns.length) then
470
- return ""
471
- end
472
-
473
- prefix = ns_to_prefix[ns]
474
- if (nil == prefix) then
475
- preferred = XamplObject.lookup_preferred_ns_prefix(ns)
476
- prefix = "" << preferred << ":" if preferred
477
- prefix = "ns" << ns_to_prefix.size.to_s << ":" unless prefix
478
- ns_to_prefix[ns] = prefix
479
- end
480
- return prefix
481
- end
482
-
483
- def attr_esc(s)
484
- if (s.kind_of? XamplObject)
485
- return attr_esc(s.to_xml)
486
- end
487
-
488
- result = s.to_s.dup
489
-
490
- result.gsub!("&", "&amp;")
491
- result.gsub!("<", "&lt;")
492
- result.gsub!(">", "&gt;")
493
- result.gsub!("'", "&apos;")
494
- result.gsub!("\"", "&quot;")
495
-
496
- return result
497
- end
498
-
499
- def content_esc(s)
500
- result = s.to_s.dup
501
-
502
- return result if (s.kind_of? XamplObject)
503
-
504
- result.gsub!("&", "&amp;")
505
- result.gsub!("<", "&lt;")
506
-
507
- return result
508
- end
509
-
510
- def attribute(xampl)
511
- @attr_list = []
512
- if (nil != xampl.attributes) then
513
- xampl.attributes.each{ | attr_spec |
514
- prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
515
- value = xampl.instance_variable_get(attr_spec[0])
516
- @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'") \
517
- unless nil == value
518
- }
519
- end
520
- end
521
-
522
- def persist_attribute(xampl)
523
- @attr_list = []
524
- pattr = xampl.indexed_by.to_s
525
- if (nil != xampl.attributes) then
526
- xampl.attributes.each{ | attr_spec |
527
- if pattr == attr_spec[1] then
528
- prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
529
- value = xampl.instance_variable_get(attr_spec[0])
530
- @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'") \
531
- unless nil == value
532
- break
533
- end
534
- }
535
- end
536
- end
537
-
538
- def show_attributes
539
- result = @attr_list.join(" ")
540
- if (0 == result.length) then
541
- return ""
542
- else
543
- return result
544
- end
545
- end
546
-
547
- def start_element(xampl)
548
- tag = xampl.tag
549
- ns = xampl.ns
550
- tag_info = "" << "<" << register_ns(ns) << tag
551
- unless @start_body then
552
- attribute(xampl)
553
- attr_defn = show_attributes
554
- @start_body = "" << tag_info << attr_defn
555
- @was_attr = true if 0 < attr_defn.size
556
- else
557
- if xampl.persist_required then
558
- @mentions << xampl if @mentions
559
- @no_children = true
560
- persist_attribute(xampl)
561
- else
562
- attribute(xampl)
563
- end
564
- @body << tag_info << show_attributes
565
- end
566
- end
567
-
568
- def end_element(xampl)
569
- tag = xampl.tag
570
- ns = xampl.ns
571
- @body << "</" << register_ns(ns) << tag << ">"
572
- end
573
-
574
- def define_ns
575
- result = ""
576
- ns_to_prefix.each{ | ns, prefix |
577
- result = sprintf("%s xmlns:%s='%s'", result, prefix[0..-2], ns)
578
- }
579
- return result
580
- end
581
-
582
- def done
583
- out << @start_body << define_ns << @body
584
- end
585
-
586
- def before_visit_without_content(xampl)
587
- start_element(xampl)
588
- @body << "/>"
589
- end
590
-
591
- def before_visit_simple_content(xampl)
592
- start_element(xampl)
593
- if @no_children then
594
- @body << "/>"
595
- else
596
- @body << ">"
597
- @body << content_esc(xampl._content) if xampl._content
598
- end_element(xampl)
599
- end
600
- end
601
-
602
- def before_visit_data_content(xampl)
603
- start_element(xampl)
604
- if @no_children then
605
- @body << "/>"
606
- else
607
- @body << ">"
608
- @body << content_esc(xampl._content) if xampl._content
609
- end
610
- end
611
-
612
- def after_visit_data_content(xampl)
613
- end_element(xampl) unless @no_children
614
- end
615
-
616
- def before_visit_mixed_content(xampl)
617
- if @no_children then
618
- @body << "/>"
619
- else
620
- start_element(xampl)
621
- @body << ">"
622
- end
623
- end
624
-
625
- def after_visit_mixed_content(xampl)
626
- end_element(xampl) unless @no_children
627
- end
628
-
629
- def before_visit(xampl)
630
- if xampl.respond_to? "before_visit_by_element_kind" then
631
- xampl.before_visit_by_element_kind(self)
632
- else
633
- @body << xampl.to_s
634
- end
635
- end
636
-
637
- def after_visit(xampl)
638
- xampl.after_visit_by_element_kind(self) if xampl.respond_to? "after_visit_by_element_kind"
639
- end
640
-
641
- def visit_string(string)
642
- @body << string
643
- end
644
- end
645
-
646
- class CopyXML < Visitor
647
- attr_accessor :ns_to_prefix, :start_body, :body
648
-
649
- def CopyXML.copy(root, translate_pids={})
650
- CopyXML.new.make_copy(root, translate_pids)
651
- end
652
-
653
- def make_copy(root, translate_pids)
654
- @was_attr = false
655
-
656
- @ns_to_prefix = {}
657
- @start_body = nil
658
- @body = ""
659
- @attr_list = nil
660
-
661
- @pid_translations_old_to_new = translate_pids
662
- @pid_translations_new_to_old = translate_pids.invert
663
-
664
- @persisted_xampl_found = { @current_root.get_the_index => root }
665
- @copies_by_old_pid = {}
666
-
667
- while true do
668
- copy_these = []
669
-
670
- @persisted_xampl_found.each do | pid, xampl |
671
- copy_these << xampl unless @copies_by_old_pid[pid]
672
- end
673
-
674
- break if 0 == copy_these.length
675
-
676
- @persisted_xampl_found = {}
677
- copy_these.each do | xampl |
678
- @current_root = xampl
679
- @out = ""
680
- @copies_by_old_pid[@current_root.get_the_index] = @out
681
-
682
- copy_xampl(@current_root)
683
- end
684
- end
685
-
686
- return @copies_by_old_pid
687
- end
688
-
689
- def copy_xampl(root)
690
- start(root).done
691
- end
692
-
693
- @@base_pid = Time.now.to_i.to_s + "_"
694
- @@gen_pid = 0
695
-
696
- def get_the_new_pid(xampl)
697
- current_pid = xampl.get_the_index
698
- @persisted_xampl_found[current_pid] = xampl
699
-
700
- new_pid = @pid_translations_old_to_new[current_pid]
701
-
702
- unless new_pid then
703
- @@gen_pid += 1
704
- new_pid = @@base_pid + @@gen_pid.to_s
705
-
706
- @pid_translations_old_to_new[current_pid] = new_pid
707
- @pid_translations_new_to_old[new_pid] = current_pid
708
- end
709
-
710
- return new_pid
711
- end
712
-
713
- def cycle(xampl)
714
- raise XamplException.new(:cycle_detected_in_xampl_cluster) unless xampl.kind_of?(XamplPersistedObject)
715
- return true
716
- end
717
-
718
- def revisit(xampl)
719
- return true
720
- end
721
-
722
- def register_ns(ns)
723
- if (0 == ns.length) then
724
- return ""
725
- end
726
-
727
- prefix = ns_to_prefix[ns]
728
- if (nil == prefix) then
729
- preferred = XamplObject.lookup_preferred_ns_prefix(ns)
730
- prefix = "" << preferred << ":" if preferred
731
- prefix = "ns" << ns_to_prefix.size.to_s << ":" unless prefix
732
- ns_to_prefix[ns] = prefix
733
- end
734
- return prefix
735
- end
736
-
737
- def attr_esc(s)
738
- if (s.kind_of? XamplObject)
739
- return attr_esc(s.to_xml)
740
- end
741
-
742
- result = s.to_s.dup
743
-
744
- result.gsub!("&", "&amp;")
745
- result.gsub!("<", "&lt;")
746
- result.gsub!(">", "&gt;")
747
- result.gsub!("'", "&apos;")
748
- result.gsub!("\"", "&quot;")
749
-
750
- return result
751
- end
752
-
753
- def content_esc(s)
754
- result = s.to_s.dup
755
-
756
- return result if (s.kind_of? XamplObject)
757
-
758
- result.gsub!("&", "&amp;")
759
- result.gsub!("<", "&lt;")
760
-
761
- return result
762
- end
763
-
764
- def attribute(xampl)
765
- @attr_list = []
766
- if (nil != xampl.attributes) then
767
- xampl.attributes.each{ | attr_spec |
768
- prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
769
- value = get_the_new_pid(xampl.instance_variable_get(attr_spec[0]))
770
- @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'") \
771
- unless nil == value
772
- }
773
- end
774
- end
775
-
776
- def persist_attribute(xampl)
777
- @attr_list = []
778
- pattr = xampl.indexed_by.to_s
779
- if (nil != xampl.attributes) then
780
- xampl.attributes.each{ | attr_spec |
781
- if pattr == attr_spec[1] then
782
- prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
783
- value = xampl.instance_variable_get(attr_spec[0])
784
- @attr_list << (" " << prefix << attr_spec[1] << "='" << attr_esc(value) << "'") \
785
- unless nil == value
786
- break
787
- end
788
- }
789
- end
790
- end
791
-
792
- def show_attributes
793
- result = @attr_list.join(" ")
794
- if (0 == result.length) then
795
- return ""
796
- else
797
- return result
798
- end
799
- end
800
-
801
- def start_element(xampl)
802
- tag = xampl.tag
803
- ns = xampl.ns
804
- tag_info = "" << "<" << register_ns(ns) << tag
805
- unless @start_body then
806
- attribute(xampl)
807
- attr_defn = show_attributes
808
- @start_body = "" << tag_info << attr_defn
809
- @was_attr = true if 0 < attr_defn.size
810
- else
811
- if xampl.persist_required then
812
- @no_children = true
813
- persist_attribute(xampl)
814
- else
815
- attribute(xampl)
816
- end
817
- @body << tag_info << show_attributes
818
- end
819
- end
820
-
821
- def end_element(xampl)
822
- tag = xampl.tag
823
- ns = xampl.ns
824
- @body << "</" << register_ns(ns) << tag << ">"
825
- end
826
-
827
- def define_ns
828
- result = ""
829
- ns_to_prefix.each{ | ns, prefix |
830
- result = sprintf("%s xmlns:%s='%s'", result, prefix[0..-2], ns)
831
- }
832
- return result
833
- end
834
-
835
- def done
836
- out << @start_body << define_ns << @body
837
- end
838
-
839
- def before_visit_without_content(xampl)
840
- start_element(xampl)
841
- @body << "/>"
842
- end
843
-
844
- def before_visit_simple_content(xampl)
845
- start_element(xampl)
846
- if @no_children then
847
- @body << "/>"
848
- else
849
- @body << ">"
850
- @body << content_esc(xampl._content) if xampl._content
851
- end_element(xampl)
852
- end
853
- end
854
-
855
- def before_visit_data_content(xampl)
856
- start_element(xampl)
857
- if @no_children then
858
- @body << "/>"
859
- else
860
- @body << ">"
861
- @body << content_esc(xampl._content) if xampl._content
862
- end
863
- end
864
-
865
- def after_visit_data_content(xampl)
866
- end_element(xampl) unless @no_children
867
- end
868
-
869
- def before_visit_mixed_content(xampl)
870
- if @no_children then
871
- @body << "/>"
872
- else
873
- start_element(xampl)
874
- @body << ">"
875
- end
876
- end
877
-
878
- def after_visit_mixed_content(xampl)
879
- end_element(xampl) unless @no_children
880
- end
881
-
882
- def before_visit(xampl)
883
- if xampl.respond_to? "before_visit_by_element_kind" then
884
- xampl.before_visit_by_element_kind(self)
885
- else
886
- @body << xampl.to_s
887
- end
888
- end
889
-
890
- def after_visit(xampl)
891
- xampl.after_visit_by_element_kind(self) if xampl.respond_to? "after_visit_by_element_kind"
892
- end
893
-
894
- def visit_string(string)
895
- @body << string
896
- end
897
- end
898
-
899
- module XamplObject
900
- def pp_xml(out="", skip=[])
901
- PrettyXML.new(out, skip).start(self).done
902
- end
903
-
904
- def to_xml(out="", skip=[])
905
- PersistXML.new(out).start(self).done
906
- end
907
-
908
- def copy_xampl(root, translate_pids={})
909
- CopyXML.copy(root, translate_pids)
910
- end
911
-
912
- def mark_changed_deep
913
- MarkChangedDeep.new.start(self)
914
- end
915
- end
916
-
917
139
  end
918
140