Class: Xampl::PersistXML

Inherits:
Visitor show all
Defined in:
lib/xamplr/persist-to-xml.rb

Instance Attribute Summary collapse

Attributes inherited from Visitor

#no_children, #no_siblings

Instance Method Summary collapse

Methods inherited from Visitor

#around_visit, #method_missing, #reset, #short_circuit, #start, #substitute_in_visit

Constructor Details

#initialize(out = "", mentions = nil, substitutions = {}) ⇒ PersistXML

Returns a new instance of PersistXML.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/xamplr/persist-to-xml.rb', line 7

def initialize(out="", mentions=nil, substitutions={})
  super()

  @out = out
  @was_attr = false

  @mentions = mentions
  @pid_substitutions = substitutions

  @ns_to_prefix = {}
  @start_body = nil
  @body = ""
  @attr_list = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Xampl::Visitor

Instance Attribute Details

#bodyObject

Returns the value of attribute body.



5
6
7
# File 'lib/xamplr/persist-to-xml.rb', line 5

def body
  @body
end

#mentionsObject

Returns the value of attribute mentions.



5
6
7
# File 'lib/xamplr/persist-to-xml.rb', line 5

def mentions
  @mentions
end

#ns_to_prefixObject

Returns the value of attribute ns_to_prefix.



5
6
7
# File 'lib/xamplr/persist-to-xml.rb', line 5

def ns_to_prefix
  @ns_to_prefix
end

#outObject

Returns the value of attribute out.



5
6
7
# File 'lib/xamplr/persist-to-xml.rb', line 5

def out
  @out
end

#start_bodyObject

Returns the value of attribute start_body.



5
6
7
# File 'lib/xamplr/persist-to-xml.rb', line 5

def start_body
  @start_body
end

Instance Method Details

#after_visit(xampl) ⇒ Object



260
261
262
# File 'lib/xamplr/persist-to-xml.rb', line 260

def after_visit(xampl)
  xampl.after_visit_by_element_kind(self) if xampl.respond_to? "after_visit_by_element_kind"
end

#after_visit_data_content(xampl) ⇒ Object



235
236
237
# File 'lib/xamplr/persist-to-xml.rb', line 235

def after_visit_data_content(xampl)
  end_element(xampl) unless @no_children
end

#after_visit_mixed_content(xampl) ⇒ Object



248
249
250
# File 'lib/xamplr/persist-to-xml.rb', line 248

def after_visit_mixed_content(xampl)
  end_element(xampl) unless @no_children
end

#attr_esc(s) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/xamplr/persist-to-xml.rb', line 67

def attr_esc(s)
  # This depends on ruby 1.9
  return attr_esc(s.to_xml) if (s.kind_of? XamplObject)

  begin
    options = {
      :invalid => :replace,
      :undef=>:replace,
      :xml => :attr
    }
    result = s.to_s.dup.encode('UTF-8', 'UTF-8', options)

    return result
  rescue => e
    puts "Naughty Programmer! No! Bad!: #{ e } encoding in: #{ s.encoding }, out: #{ result.encoding }"
    puts e.backtrace
  end

  return ''
end

#attr_esc_slow(s) ⇒ Object

def attr_esc_fast(s)

end


53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/xamplr/persist-to-xml.rb', line 53

def attr_esc_slow(s)
  return attr_esc(s.to_xml) if (s.kind_of? XamplObject)

  result = s.to_s.dup

  result.gsub!("&", "&")
  result.gsub!("<", "&lt;")
  result.gsub!(">", "&gt;")
  result.gsub!("'", "&apos;")
  result.gsub!("\"", "&quot;")

  return "\"result\""
end

#attribute(xampl) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/xamplr/persist-to-xml.rb', line 108

def attribute(xampl)
  @attr_list = []
  pattr = xampl.indexed_by.to_s

  if (nil != xampl.attributes) then
    xampl.attributes.each do |attr_spec|
      prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
      value = nil
      if pattr == attr_spec[1] then
        value = @pid_substitutions[xampl]
#            puts "#{ File.basename __FILE__ }:#{ __LINE__ } [#{__method__}] xampl: #{ xampl }, substitute: #{ value }" if value
        value = xampl.instance_variable_get(attr_spec[0]) unless value
      else
        value = xampl.instance_variable_get(attr_spec[0])
      end
      @attr_list << (" " << prefix << attr_spec[1] << '=' << attr_esc(value)) unless nil == value
    end
  end
end

#before_visit(xampl) ⇒ Object



252
253
254
255
256
257
258
# File 'lib/xamplr/persist-to-xml.rb', line 252

def before_visit(xampl)
  if xampl.respond_to? "before_visit_by_element_kind" then
    xampl.before_visit_by_element_kind(self)
  else
    @body << xampl.to_s
  end
end

#before_visit_data_content(xampl) ⇒ Object



225
226
227
228
229
230
231
232
233
# File 'lib/xamplr/persist-to-xml.rb', line 225

def before_visit_data_content(xampl)
  start_element(xampl)
  if @no_children then
    @body << "/>"
  else
    @body << ">"
    @body << content_esc(xampl._content) if xampl._content
  end
end

#before_visit_mixed_content(xampl) ⇒ Object



239
240
241
242
243
244
245
246
# File 'lib/xamplr/persist-to-xml.rb', line 239

def before_visit_mixed_content(xampl)
  if @no_children then
    @body << "/>"
  else
    start_element(xampl)
    @body << ">"
  end
end

#before_visit_simple_content(xampl) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/xamplr/persist-to-xml.rb', line 199

def before_visit_simple_content(xampl)
  start_element(xampl)
  if @no_children then
    @body << "/>"
  else
    @body << ">"
    begin
      @body.concat(content_esc(xampl._content)) if xampl._content
    rescue => e
      begin
        s = xampl._content.force_encoding(@body.encoding)
        @body.concat(content_esc(s)) if xampl._content
      rescue => e
        puts "EXCEPTION: #{ e }"
        puts "body encoding: #{ @body.encoding }"
        puts "xampl._content encoding: #{ xampl._content.encoding }"
        puts "content_esc(xampl._content) encoding: #{ content_esc(xampl._content).encoding }"
        puts "xampl._content: [[[#{ xampl._content }]]]"
#          puts "body so far: [[[#{ @body }]]]"
        raise e
      end
    end
    end_element(xampl)
  end
end

#before_visit_without_content(xampl) ⇒ Object



194
195
196
197
# File 'lib/xamplr/persist-to-xml.rb', line 194

def before_visit_without_content(xampl)
  start_element(xampl)
  @body << "/>"
end

#content_esc(s) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/xamplr/persist-to-xml.rb', line 88

def content_esc(s)
  return content_esc(s.to_s.dup) if (s.kind_of? XamplObject)

  begin
    options = {
      :invalid => :replace,
      :undef=>:replace,
      :xml => :text
    }
    result = s.to_s.dup.encode('UTF-8', 'UTF-8', options)

    return result
  rescue => e
    puts "Naughty Programmer! No! Bad!: #{ e } encoding in: #{ s.encoding }, out: #{ result.encoding }"
    puts e.backtrace
  end

  return ''
end

#cycle(xampl) ⇒ Object

Raises:



22
23
24
25
# File 'lib/xamplr/persist-to-xml.rb', line 22

def cycle(xampl)
  raise XamplException.new(:cycle_detected_in_xampl_cluster) unless xampl.kind_of?(XamplPersistedObject)
  return true
end

#define_nsObject



181
182
183
184
185
186
187
188
# File 'lib/xamplr/persist-to-xml.rb', line 181

def define_ns
  result = ""
  ns_to_prefix.each do |ns, prefix|
#        result = sprintf("%s xmlns:%s='%s'", result, prefix[0..-2], ns)
    result = sprintf("%s xmlns:%s=\"%s\"", result, prefix[0..-2], ns)
  end
  return result
end

#doneObject



190
191
192
# File 'lib/xamplr/persist-to-xml.rb', line 190

def done
  out << @start_body << define_ns << @body
end

#end_element(xampl) ⇒ Object



175
176
177
178
179
# File 'lib/xamplr/persist-to-xml.rb', line 175

def end_element(xampl)
  tag = xampl.tag
  ns = xampl.ns
  @body << "</" << register_ns(ns) << tag << ">"
end

#persist_attribute(xampl) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/xamplr/persist-to-xml.rb', line 128

def persist_attribute(xampl)
  @attr_list = []
  pattr = xampl.indexed_by.to_s
  if (nil != xampl.attributes) then
    xampl.attributes.each do |attr_spec|
      if pattr == attr_spec[1] then
        prefix = (2 < attr_spec.length) ? register_ns(attr_spec[2]) : ""
        value = @pid_substitutions[xampl]
#            puts "#{ File.basename __FILE__ }:#{ __LINE__ } [#{__method__}] xampl: #{ xampl }, substitute: #{ value }" if value
        value = xampl.instance_variable_get(attr_spec[0]) unless value
        @attr_list << (" " << prefix << attr_spec[1] << '=' << attr_esc(value)) unless nil == value
        break
      end
    end
  end
end

#register_ns(ns) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/xamplr/persist-to-xml.rb', line 31

def register_ns(ns)
  if (0 == ns.length) then
    return ""
  end

  prefix = ns_to_prefix[ns]
  if (nil == prefix) then
    preferred = XamplObject.lookup_preferred_ns_prefix(ns)
    prefix = "" << preferred << ":" if preferred
    prefix = "ns" << ns_to_prefix.size.to_s << ":" unless prefix
    ns_to_prefix[ns] = prefix
  end
  return prefix
end

#revisit(xampl) ⇒ Object



27
28
29
# File 'lib/xamplr/persist-to-xml.rb', line 27

def revisit(xampl)
  return true
end

#show_attributesObject



145
146
147
148
149
150
151
152
# File 'lib/xamplr/persist-to-xml.rb', line 145

def show_attributes
  result = @attr_list.join(" ")
  if (0 == result.length) then
    return ""
  else
    return result
  end
end

#start_element(xampl) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/xamplr/persist-to-xml.rb', line 154

def start_element(xampl)
  tag = xampl.tag
  ns = xampl.ns
  tag_info = "" << "<" << register_ns(ns) << tag
  unless @start_body then
    attribute(xampl)
    attr_defn = show_attributes
    @start_body = "" << tag_info << attr_defn
    @was_attr = true if 0 < attr_defn.size
  else
    if xampl.persist_required then
      @mentions << xampl if @mentions
      @no_children = true
      persist_attribute(xampl)
    else
      attribute(xampl)
    end
    @body << tag_info << show_attributes
  end
end

#visit_string(string) ⇒ Object



264
265
266
# File 'lib/xamplr/persist-to-xml.rb', line 264

def visit_string(string)
  @body << string
end