polyrex 0.8.18 → 0.8.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/polyrex.rb +125 -23
  2. metadata +2 -2
data/lib/polyrex.rb CHANGED
@@ -1,4 +1,4 @@
1
- #/usr/bin/ruby
1
+ #/usr/bin/env ruby
2
2
 
3
3
  # file: polyrex.rb
4
4
 
@@ -6,10 +6,30 @@ require 'polyrex-schema'
6
6
  require 'line-tree'
7
7
  require 'polyrex-objects'
8
8
  require 'polyrex-createobject'
9
- require 'ostruct'
10
9
  require 'polyrex-object-methods'
11
10
  require 'recordx-xslt'
12
11
  require 'rexle'
12
+ require 'recordx'
13
+
14
+ module Enumerable
15
+ def repeated_permutation(size, &blk)
16
+ f = proc do |memo, &blk|
17
+ if memo.size == size
18
+ blk.call memo
19
+ else
20
+ self.each do |i|
21
+ f.call memo + [i], &blk
22
+ end
23
+ end
24
+ end
25
+
26
+ if block_given?
27
+ f.call [], &blk
28
+ else
29
+ Enumerator.new(f, :call, [])
30
+ end
31
+ end
32
+ end
13
33
 
14
34
  class Polyrex
15
35
  attr_accessor :summary_fields, :xslt_schema, :id_counter, :schema
@@ -21,7 +41,8 @@ class Polyrex
21
41
  if location then
22
42
  open(location)
23
43
  summary_h = Hash[*@doc.root.xpath("summary/*").map {|x| [x.name, x.text]}.flatten]
24
- @summary = OpenStruct.new summary_h
44
+ #@summary = OpenStruct.new summary_h
45
+ @summary = RecordX.new summary_h
25
46
  @summary_fields = summary_h.keys.map(&:to_sym)
26
47
  end
27
48
 
@@ -29,7 +50,7 @@ class Polyrex
29
50
  end
30
51
 
31
52
  def create(id=nil)
32
- # @create is a PolyrexCreateObject, @parent_node is a REXML::Element pointing to the current record
53
+ # @create is a PolyrexCreateObject, @parent_node is a Rexle::Element pointing to the current record
33
54
 
34
55
  @create.id = id || @id_counter
35
56
  @create.record = @parent_node.name == 'records' ? @parent_node.root : @parent_node.root.element('records')
@@ -95,7 +116,8 @@ class Polyrex
95
116
  def schema=(s)
96
117
  open s
97
118
  summary_h = Hash[*@doc.root.xpath("summary/*").map {|x| [x.name, x.text]}.flatten]
98
- @summary = OpenStruct.new summary_h
119
+ #@summary = OpenStruct.new summary_h
120
+ @summary = RecordX.new summary_h
99
121
  @summary_fields = summary_h.keys.map(&:to_sym)
100
122
  self
101
123
  end
@@ -133,7 +155,7 @@ class Polyrex
133
155
  # -- required for the parsing feature
134
156
  doc = Rexle.new(PolyrexSchema.new(schema).to_s)
135
157
  @format_masks = doc.root.xpath('//format_mask/text()')
136
- #puts '@format_masks : ' + @format_masks.inspect
158
+
137
159
  schema_rpath = schema.gsub(/\[[^\]]+\]/,'')
138
160
 
139
161
  @recordx = schema_rpath.split('/')
@@ -185,23 +207,27 @@ class Polyrex
185
207
  self.method(name).call(value)
186
208
  end
187
209
  end
188
-
189
- raw_summary = schema[/\[([^\]]+)/,1]
210
+
211
+ raw_summary = schema[/^\w+\[([^\]]+)/,1]
190
212
  raw_lines = buffer.strip.split(/\r?\n|\r(?!\n)/)
191
-
213
+
192
214
  if raw_summary then
193
215
  a_summary = raw_summary.split(',').map(&:strip)
194
-
216
+
195
217
  while raw_lines.first[/#{a_summary.join('|')}:\s+\w+/] do
196
- label, val = raw_lines.shift.match(/(\w+):\s+([^$]+)$/).captures
218
+
219
+ label, val = raw_lines.shift.match(/(\w+):\s+([^$]+)$/).captures
197
220
  @summary.send((label + '=').to_sym, val)
198
221
  end
222
+
199
223
  end
200
224
 
201
- @summary.format_mask = @format_mask
225
+ @summary.format_mask = @format_masks
226
+
202
227
  format_line!(@parent_node.root, LineTree.new(raw_lines.join("\n").strip).to_a)
228
+
203
229
  end
204
-
230
+
205
231
  def load_handlers(schema)
206
232
  @create = PolyrexCreateObject.new(schema, @id_counter)
207
233
 
@@ -214,7 +240,7 @@ class Polyrex
214
240
  end
215
241
 
216
242
  def format_line!(records, a, i=0)
217
-
243
+
218
244
  a.each do |x|
219
245
 
220
246
  unless @recordx[i] then
@@ -225,19 +251,25 @@ class Polyrex
225
251
  tag_name = @recordx[i].to_s
226
252
  line = x.shift
227
253
 
228
-
229
254
  unless @format_masks[i][/^\(.*\)$/] then
230
255
 
231
256
  @field_names = @format_masks[i].to_s.scan(/\[!(\w+)\]/).flatten.map(&:to_sym)
232
257
 
258
+ =begin
233
259
  t = regexify_fmask(@format_masks[i]) #.sub(/\[/,'\[').sub(/\]/,'\]')
234
-
235
- a = t.reverse.split(/(?=\)[^\(]+\()/).reverse.map &:reverse
260
+ a = t.reverse.split(/(?=\)[^\(]+\()/).reverse.map &:reverse
236
261
  patterns = tail_map(a)
262
+ =end
237
263
 
264
+ patterns = possible_patterns(@format_masks[i])
238
265
  pattern = patterns.detect {|x| line.match(/#{x.join}/)}.join
239
-
240
266
  field_values = line.match(/#{pattern}/).captures
267
+ found_quotes = find_qpattern(pattern)
268
+
269
+ if found_quotes then
270
+ found_quotes.each {|i| field_values[i] = field_values[i][1..-2]}
271
+ end
272
+
241
273
  field_values += [''] * (@field_names.length - field_values.length)
242
274
  else
243
275
 
@@ -252,6 +284,7 @@ class Polyrex
252
284
  @field_names = format_masks[i].to_s.scan(/\[!(\w+)\]/).flatten.map(&:to_sym)
253
285
 
254
286
  field_values = line.match(/#{pattern}/).captures
287
+
255
288
  end
256
289
 
257
290
  @id_counter.succ!
@@ -263,7 +296,7 @@ class Polyrex
263
296
 
264
297
  @field_names.zip(field_values).each do |name, value|
265
298
  field = Rexle::Element.new(name.to_s)
266
- field.text = value
299
+ field.text = value
267
300
  summary.add field
268
301
  end
269
302
 
@@ -341,9 +374,36 @@ class Polyrex
341
374
 
342
375
  end
343
376
 
377
+ def diminishing_permutation(max_fields)
378
+ result = max_fields.times.inject([]) do |r,i|
379
+ r + [1,0].repeated_permutation(max_fields-i).to_a
380
+ end
381
+ end
382
+
383
+ def find_qpattern(s)
384
+ s.split(/(?=\([^\)]+\))/).map.with_index\
385
+ .select{|x,i| x[/\["'\]\[\^"'\]\+\["'\]/] }.map(&:last)
386
+ end
387
+
388
+ def fmask_delimiters(f)
389
+ a = f.split(/(?=\[!\w+\])/)[0..-2].map do |x|
390
+
391
+ aa = x.split(/(?=[^\]]+$)/)
392
+
393
+ if aa.length == 2 and aa.first[/\[!\w+\]/] then
394
+ field, delimiter = *aa
395
+ delimiter ||= '$'
396
+ d = delimiter[0]
397
+ d
398
+ end
399
+ end
400
+ end
401
+
402
+
403
+ # jr140412 to be removed
344
404
  def regexify_fmask(f)
345
405
 
346
- a = f.split(/(?=\[!\w+\])/).map do |x|
406
+ a = f.split(/(?=\[!\w+\])/).i do |x|
347
407
 
348
408
  aa = x.split(/(?=[^\]]+$)/)
349
409
 
@@ -351,7 +411,7 @@ class Polyrex
351
411
  field, delimiter = *aa
352
412
  delimiter ||= '$'
353
413
  d = delimiter[0]
354
- "([^%s]+)%s" % ([d] * 2)
414
+ "('[^']+'|[^%s]+)%s" % ([d] * 2)
355
415
  else
356
416
  x.sub(/\[!\w+\]/,'(.*)')
357
417
  end
@@ -360,9 +420,44 @@ class Polyrex
360
420
  a.join
361
421
  end
362
422
 
423
+ #jr140412 to be removed
363
424
  def tail_map(a)
364
425
  [a] + (a.length > 1 ? tail_map(a[0..-2]) : [])
365
426
  end
427
+
428
+ def possible_patterns(format_mask)
429
+
430
+ tot_fields = format_mask.scan(/\[!\w+\]/).length
431
+ return [['(.*)']] if tot_fields <= 1
432
+ main_fields = tot_fields - 1
433
+ qpattern = %q{(["'][^"']+["'])}
434
+
435
+ a = fmask_delimiters(format_mask)
436
+ r = diminishing_permutation(main_fields)
437
+
438
+ if r.length > 2 then
439
+ itemx = [r.slice!(-2)]
440
+ r2 = r[0..-3] + itemx + r[-2..-1]
441
+ else
442
+ r2 = r
443
+ end
444
+
445
+ rr = r2.map do |x|
446
+ x.each_with_index.map do |item, i|
447
+ d = a[i]
448
+ case item
449
+ when 1
450
+ i > 0 ? d + qpattern : qpattern
451
+ when 0
452
+ s = "([^%s]+)" % d
453
+ i > 0 ? d + s : s
454
+ end
455
+ end
456
+ end
457
+
458
+ rrr = rr.take(2**main_fields).map {|x| x + [a[-1] + '(.*)']} + rr
459
+
460
+ end
366
461
 
367
462
  def load_find_by(schema)
368
463
  a = PolyrexObjectMethods.new(schema).to_a
@@ -381,9 +476,16 @@ class Polyrex
381
476
  self.instance_eval methodx.join("\n")
382
477
  end
383
478
 
479
+
384
480
  def refresh_summary()
385
- @summary_fields.each do |x|
386
- @doc.root.element('summary/' + x.to_s).text = @summary.method(x).call
481
+ summary = @doc.root.element('summary')
482
+ @summary.to_h.each do |k,v|
483
+ e = summary.element(k.to_s)
484
+ if e then
485
+ e.text = v
486
+ else
487
+ summary.add Rexle::Element.new(k.to_s).add_text(v)
488
+ end
387
489
  end
388
490
  end
389
491
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: polyrex
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.8.18
5
+ version: 0.8.19
6
6
  platform: ruby
7
7
  authors:
8
8
  - James Robertson
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-04-12 00:00:00 +01:00
13
+ date: 2012-04-15 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency