Class: Polyrex

Inherits:
Object
  • Object
show all
Includes:
RXFReadWriteModule
Defined in:
lib/polyrex.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(location = nil, schema: nil, id_counter: '1', delimiter: '', debug: false) ⇒ Polyrex

Returns a new instance of Polyrex.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/polyrex.rb', line 47

def initialize(location=nil, schema: nil, id_counter: '1',
               delimiter: '', debug: false)

  @id_counter, @debug = id_counter, debug
  @format_masks = []

  self.method(:schema=).call(schema) if schema  
  
  if location then      

    s, type = RXFReader.read(location)
    return import(s) if s =~ /^\<\?polyrex\b/
    
    @local_filepath = location if type == :file or type == :dfs

    openx(s)
    puts 'before schema' if @debug
    if schema then

      fields = @schema[/\/.*/].scan(/\[([^\]]+)/).map \
        {|x| x.first.split(',').map(&:strip)}
      refresh_records self.records, fields, 0

    end

    @summary = RecordX.new @doc.root.xpath("summary/*")
    @summary_fields = @summary.keys
    

  end
  
  @polyrex_xslt = RecordxXSLT.new
  #@parent_node = @doc.root if @doc

  set_delimiter(delimiter)
end

Instance Attribute Details

#delimiter ⇒ Object

Returns the value of attribute delimiter.



44
45
46
# File 'lib/polyrex.rb', line 44

def delimiter
  @delimiter
end

#format_masks ⇒ Object

-- start of full text edit methods



178
179
180
# File 'lib/polyrex.rb', line 178

def format_masks
  @format_masks
end

#id_counter ⇒ Object

Returns the value of attribute id_counter.



44
45
46
# File 'lib/polyrex.rb', line 44

def id_counter
  @id_counter
end

#schema ⇒ Object

Returns the value of attribute schema.



44
45
46
# File 'lib/polyrex.rb', line 44

def schema
  @schema
end

#summary_fields ⇒ Object

Returns the value of attribute summary_fields.



44
45
46
# File 'lib/polyrex.rb', line 44

def summary_fields
  @summary_fields
end

#type ⇒ Object

Returns the value of attribute type.



44
45
46
# File 'lib/polyrex.rb', line 44

def type
  @type
end

#xslt ⇒ Object

Returns the value of attribute xslt.



44
45
46
# File 'lib/polyrex.rb', line 44

def xslt
  @xslt
end

#xslt_schema ⇒ Object

Returns the value of attribute xslt_schema.



44
45
46
# File 'lib/polyrex.rb', line 44

def xslt_schema
  @xslt_schema
end

Instance Method Details

#add(pxobj) ⇒ Object



84
85
86
# File 'lib/polyrex.rb', line 84

def add(pxobj)
  self.record.add pxobj.node
end

#build(records, indent = 0) ⇒ Object



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/polyrex.rb', line 314

def build(records, indent=0)

  records.map do |item|

    summary = item.element 'summary'
    format_mask = summary.text('format_mask').to_s
    line = format_mask.gsub(/\[![^\]]+\]/){|x| summary.text(x[2..-2]).to_s}
    puts 'line: ' + line.inspect if @debug

    recordsx = item.element('records').elements.to_a
    
    if recordsx.length > 0 then
      line = line + "\n" + build(recordsx, indent + 1).join("\n") 
    end
    ('  ' * indent) + line
  end
end

#content(options = {}) ⇒ Object



88
89
90
# File 'lib/polyrex.rb', line 88

def content(options={})
  CGI.unescapeHTML(to_xml(options))
end

#create(id: @id_counter) ⇒ Object



92
93
94
95
# File 'lib/polyrex.rb', line 92

def create(id: @id_counter)
  puts 'id: ' + id.inspect if @debug
  @create = PolyrexCreateObject.new(id: id, record: @doc.root)
end

#delete(x = nil) ⇒ Object



97
98
99
100
101
102
103
104
# File 'lib/polyrex.rb', line 97

def delete(x=nil)

  if x.to_i.to_s  == x.to_s then
    @doc.root.delete("//[@id='#{x}'")
  else
    @doc.root.xpath(x).each(&:delete)
  end
end

#each_recursive(parent = self, level = 0, &blk) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
# File 'lib/polyrex.rb', line 117

def each_recursive(parent=self, level=0, &blk)
  
  parent.records.each.with_index do |x, index|

    blk.call(x, parent, level, index) if block_given?

    each_recursive(x, level+1, &blk) if x.records.any?
    
  end
  
end

#element(s) ⇒ Object



198
199
200
# File 'lib/polyrex.rb', line 198

def element(s)
  @doc.root.element(s)
end

#export(filepath) ⇒ Object



129
130
131
# File 'lib/polyrex.rb', line 129

def export(filepath)
  FileX.write filepath, to_s()
end

#find_by_id(id) ⇒ Object

-- start of crud methods --



157
158
159
160
161
162
163
164
# File 'lib/polyrex.rb', line 157

def find_by_id(id)
  
  puts 'inside find_by_id: ' + id if @debug
  #return @doc if @debug
  @parent_node = @doc.root.element("//[@id='#{id}']")
  @objects[@parent_node.name.to_sym].new(@parent_node, id: @id)
  
end

#id(id) ⇒ Object



166
167
168
169
# File 'lib/polyrex.rb', line 166

def id(id)
  @parent_node = @doc.root.element("//[@id='#{id}']")
  self
end

#leaf_nodes_to_dx ⇒ Object



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/polyrex.rb', line 202

def leaf_nodes_to_dx()
  
  schema, record_name = @summary.schema\
                              .match(/([^\/]+\/([^\/]+)\[[^\[]+$)/).captures
  
  xml = RexleBuilder.new

  xml.items do
    xml.summary do
      xml.schema schema.sub(/(\/\w+)\[([^\]]+)\]/,'\1(\2)')
    end
    xml.records 
  end
  
  doc = Rexle.new xml.to_a
  body = doc.root.element 'records'
  a = self.xpath('//' + record_name)

  a.each do |record|
    body.add record.deep_clone
  end

  make_dynarex doc.root
end

#order=(val) ⇒ Object



171
172
173
# File 'lib/polyrex.rb', line 171

def order=(val)
  @order = val.to_s
end

#parse(x = nil, options = {}) ⇒ Object Also known as: import



182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/polyrex.rb', line 182

def parse(x=nil, options={})

  buffer, type = RXFReader.read(x)
  
  if type == :unknown and buffer.lines.length <= 1 then
    raise PolyrexException, 'File not found: ' + x.inspect
  end
  
  buffer = yield if block_given?          
  string_parse buffer.clone, options

  self
end

#record ⇒ Object



133
134
135
# File 'lib/polyrex.rb', line 133

def record()
  @parent_node
end

#records ⇒ Object



227
228
229
230
231
232
233
# File 'lib/polyrex.rb', line 227

def records

  @doc.root.xpath("records/*").map do |node|      
    Kernel.const_get(node.name.capitalize).new node, id: @id_counter
  end
  
end

#rxpath(s) ⇒ Object



235
236
237
238
239
240
241
242
243
244
# File 'lib/polyrex.rb', line 235

def rxpath(s)
  
  a = @doc.root.xpath s.split('/').map \
                {|x| x.sub('[','[summary/').prepend('records/')}.join('/')
  
  a.map do |node| 
    Kernel.const_get(node.name.capitalize).new node, id: node.attributes[:id]
  end

end

#save(filepath = nil, opt = {}, options: opt, pretty: false) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/polyrex.rb', line 142

def save(filepath=nil, opt={}, options: opt, pretty: false)    
  
  refresh_summary
  filepath ||= @local_filepath
  @local_filepath = filepath
  
  options.merge!({pretty: pretty}) if options.empty?
  xml = @doc.to_s(options)
  
  buffer = block_given? ? yield(xml) : xml
  FileX.write filepath, buffer
end

#summary ⇒ Object



263
264
265
# File 'lib/polyrex.rb', line 263

def summary
  @summary
end

#to_a ⇒ Object



267
268
269
# File 'lib/polyrex.rb', line 267

def to_a()
  recordx_map @doc.root
end

#to_dynarex ⇒ Object



271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/polyrex.rb', line 271

def to_dynarex()

  root = @doc.root.deep_clone

  summary = root.element('summary')
  #summary.delete('format_mask')
  #summary.element('recordx_type').text = 'dynarex'

  summary.add root.element('records/*/summary/format_mask').clone    
  e = summary.element('schema')
  e.text = e.text[/[^\/]+\/[^\/]+/].sub(/(\/\w+)\[([^\]]+)\]/,'\1(\2)')

  make_dynarex(root)
end

#to_opml ⇒ Object



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/polyrex.rb', line 286

def to_opml()
  
  puts '@schema: ' + @schema.inspect if @debug
  
  head, body = @schema.split(/(?<=\])/,2)
  schema_body = body.gsub(/(?<=\[)[^\]]+/) do |x|
    x.split(/\s*,\s*/).map {|field| '@' + field + ':' + field}.join(', ')
  end
  schema_head = head.gsub(/(?<=\[)[^\]]+/) do |x|
    x.split(/\s*,\s*/).map {|field| field + ':' + field}.join(', ')
  end

  puts 'schema_body: ' + schema_body.inspect if @debug
  puts 'schema_head: ' + schema_head.inspect if @debug
  xslt_schema = schema_head.sub(/^\w+/,'opml>head') + 
      schema_body.gsub(/\w+(?=\[)/,'outline')\
      .sub(/\/(\w+)(?=\[)/,'/body>outline')
      
  puts 'xslt_schema: ' + xslt_schema.inspect if @debug
  
  recxslt = RecordxXSLT.new(schema: @schema, xslt_schema: xslt_schema)
  
  Rexslt.new(recxslt.to_xslt, self.to_xml).to_s    
  
end

#to_s(header: true) ⇒ Object



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/polyrex.rb', line 312

def to_s(header: true)

  def build(records, indent=0)

    records.map do |item|

      summary = item.element 'summary'
      format_mask = summary.text('format_mask').to_s
      line = format_mask.gsub(/\[![^\]]+\]/){|x| summary.text(x[2..-2]).to_s}
      puts 'line: ' + line.inspect if @debug

      recordsx = item.element('records').elements.to_a
      
      if recordsx.length > 0 then
        line = line + "\n" + build(recordsx, indent + 1).join("\n") 
      end
      ('  ' * indent) + line
    end
  end

  sumry = ''


  summary_fields = self.summary.to_h.keys

  %w(recordx_type schema format_mask).each {|x| summary_fields.delete x}
  sumry = summary_fields.map {|x| x.to_s + ': ' + \
                     self.summary.method(x.to_sym).call}.join("\n") + "\n"


  if @raw_header then
    declaration = @raw_header
  else

    smry_fields = %i(schema)              
    if self.delimiter.length > 0 then
      smry_fields << :delimiter 
    else
      smry_fields << :format_mask
    end

    s = smry_fields.map {|x|  "%s=\"%s\"" % \
      [x, self.summary.send(x).to_s.gsub('"', '\"') ]}.join ' '

    declaration = %Q(<?polyrex %s?>\n) % s
  end

  docheader = declaration + "\n" + sumry
  out = build(self.records).join("\n")
  header ? docheader + "\n" + out : out
  
end

#to_tree ⇒ Object



365
366
367
368
369
370
371
372
373
374
375
# File 'lib/polyrex.rb', line 365

def to_tree()
  
  s = @schema.gsub(/(?<=\[)[^\]]+/) do |x|
    x.split(/\s*,\s*/).map {|field| '@' + field + ':' + field}.join(', ')
  end

  xslt_schema = s.gsub(/\w+(?=\[)/,'item').sub(/^\w+/,'tree')                    
  recxslt = RecordxXSLT.new(schema: @schema, xslt_schema: xslt_schema)    
  Rexslt.new(recxslt.to_xslt, self.to_xml).to_s        
  
end

#to_xml(options = {}) ⇒ Object



137
138
139
140
# File 'lib/polyrex.rb', line 137

def to_xml(options={})
  refresh_summary
  @doc.to_s(options)
end

#to_xslt ⇒ Object



377
378
379
380
# File 'lib/polyrex.rb', line 377

def to_xslt()    
  @polyrex_xslt.schema = @schema
  @polyrex_xslt.to_xslt
end

#xpath(s, &blk) ⇒ Object



382
383
384
385
386
387
388
389
# File 'lib/polyrex.rb', line 382

def xpath(s, &blk)

  if block_given? then
    @doc.root.xpath(s, &blk)
  else
    @doc.root.xpath s
  end
end