im_onix 1.2.3 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -6
- data/README.md +1 -1
- data/bin/onix_bench.rb +16 -0
- data/im_onix.gemspec +3 -1
- data/lib/onix/addressee.rb +2 -1
- data/lib/onix/barcode.rb +6 -0
- data/lib/onix/builder.rb +22 -6
- data/lib/onix/code.rb +42 -44
- data/lib/onix/date.rb +17 -11
- data/lib/onix/entity.rb +3 -2
- data/lib/onix/identifier.rb +69 -64
- data/lib/onix/market_publishing_detail.rb +1 -0
- data/lib/onix/onix21.rb +26 -24
- data/lib/onix/product.rb +7 -9
- data/lib/onix/product_part.rb +2 -2
- data/lib/onix/{product_supplies_extractor.rb → product_supplies_methods.rb} +3 -3
- data/lib/onix/publisher_representative.rb +11 -0
- data/lib/onix/related_product.rb +2 -2
- data/lib/onix/related_work.rb +2 -1
- data/lib/onix/sender.rb +1 -1
- data/lib/onix/serializer.rb +5 -5
- data/lib/onix/subset.rb +158 -114
- metadata +33 -3
data/lib/onix/subset.rb
CHANGED
@@ -4,13 +4,13 @@ require 'cgi'
|
|
4
4
|
module ONIX
|
5
5
|
class ShortToRef
|
6
6
|
def self.names
|
7
|
-
@shortnames ||= YAML.load(File.open(File.dirname(__FILE__) + "/../../data/shortnames.yml"))
|
7
|
+
@shortnames ||= YAML.load(File.open(File.dirname(__FILE__) + "/../../data/shortnames.yml")).freeze
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
class RefToShort
|
12
12
|
def self.names
|
13
|
-
@refnames ||= ShortToRef.names.invert
|
13
|
+
@refnames ||= ShortToRef.names.invert.freeze
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -25,6 +25,18 @@ module ONIX
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
# String only code-like class
|
29
|
+
class TextAttr
|
30
|
+
attr_accessor :code, :human
|
31
|
+
|
32
|
+
def self.from_code(code)
|
33
|
+
obj = self.new
|
34
|
+
obj.code = code
|
35
|
+
obj.human = code
|
36
|
+
obj
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
28
40
|
module Attributes
|
29
41
|
# @return [Hash<String,Code>]
|
30
42
|
attr_accessor :attributes
|
@@ -44,16 +56,24 @@ module ONIX
|
|
44
56
|
# @return [Class]
|
45
57
|
def self.attribute_class(attr)
|
46
58
|
case attr
|
47
|
-
when "
|
48
|
-
|
49
|
-
when "
|
50
|
-
|
51
|
-
when "
|
52
|
-
|
59
|
+
when "sourcename"
|
60
|
+
TextAttr
|
61
|
+
when "sourcetype"
|
62
|
+
RecordSourceType
|
63
|
+
when "collationkey"
|
64
|
+
TextAttr
|
53
65
|
when "dateformat"
|
54
66
|
DateFormat
|
55
67
|
when "datestamp"
|
56
68
|
DateStamp
|
69
|
+
when "language"
|
70
|
+
LanguageCode
|
71
|
+
when "textcase"
|
72
|
+
TextCase
|
73
|
+
when "textformat"
|
74
|
+
TextFormat
|
75
|
+
when "textscript"
|
76
|
+
ScriptCode
|
57
77
|
else
|
58
78
|
nil
|
59
79
|
end
|
@@ -73,6 +93,7 @@ module ONIX
|
|
73
93
|
|
74
94
|
# instanciate Subset form Nokogiri::XML::Element
|
75
95
|
# @param [Nokogiri::XML::Element] n
|
96
|
+
# @return [Subset]
|
76
97
|
def self.parse(n)
|
77
98
|
o = self.new
|
78
99
|
o.parse(n)
|
@@ -81,8 +102,11 @@ module ONIX
|
|
81
102
|
|
82
103
|
# parse Nokogiri::XML::Element
|
83
104
|
# @param [Nokogiri::XML::Element] n
|
105
|
+
# @return [void]
|
84
106
|
def parse(n) end
|
85
107
|
|
108
|
+
# called when tag is not defined
|
109
|
+
# @param [String] tag
|
86
110
|
def unsupported(tag)
|
87
111
|
# raise SubsetUnsupported, [self.class, tag.name]
|
88
112
|
# puts "WARN subset tag unsupported #{self.class}##{tag.name} (#{self.class.short_to_ref(tag.name)})"
|
@@ -91,10 +115,6 @@ module ONIX
|
|
91
115
|
def tag_match(v)
|
92
116
|
TagNameMatcher.new(v)
|
93
117
|
end
|
94
|
-
|
95
|
-
def self.tag_match(v)
|
96
|
-
TagNameMatcher.new(v)
|
97
|
-
end
|
98
118
|
end
|
99
119
|
|
100
120
|
# for class DSL
|
@@ -172,16 +192,9 @@ module ONIX
|
|
172
192
|
@array
|
173
193
|
end
|
174
194
|
|
175
|
-
|
176
|
-
if @array and @pluralize
|
177
|
-
pluralize(underscore(@name))
|
178
|
-
else
|
179
|
-
underscore(@name)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
195
|
+
# @return [String]
|
183
196
|
def underscore_name
|
184
|
-
@underscore_name ||=
|
197
|
+
@underscore_name ||= (@array && @pluralize) ? pluralize(underscore(@name)) : underscore(@name)
|
185
198
|
end
|
186
199
|
|
187
200
|
def class_name
|
@@ -216,6 +229,9 @@ module ONIX
|
|
216
229
|
end
|
217
230
|
|
218
231
|
class SubsetArray < Array
|
232
|
+
# @param [Symbol] k
|
233
|
+
# @param [String] p
|
234
|
+
# @return [SubsetArray]
|
219
235
|
def human_code_match(k, p)
|
220
236
|
case p
|
221
237
|
when Regexp
|
@@ -236,6 +252,9 @@ module ONIX
|
|
236
252
|
end
|
237
253
|
end
|
238
254
|
|
255
|
+
# @param [Symbol] k
|
256
|
+
# @param [String] p
|
257
|
+
# @return [SubsetArray]
|
239
258
|
def code_match(k, p)
|
240
259
|
case p
|
241
260
|
when Regexp
|
@@ -259,137 +278,155 @@ module ONIX
|
|
259
278
|
|
260
279
|
# DSL
|
261
280
|
class SubsetDSL < Subset
|
262
|
-
|
263
|
-
|
264
|
-
@
|
265
|
-
|
281
|
+
class << self
|
282
|
+
# convert short name notation to reference
|
283
|
+
# @param [String] name
|
284
|
+
# @return [String]
|
285
|
+
def short_to_ref(name)
|
286
|
+
ShortToRef.names[name]
|
287
|
+
end
|
266
288
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
sup = sup.superclass
|
289
|
+
# convert reference name notation to short
|
290
|
+
# @param [String] name
|
291
|
+
# @return [String]
|
292
|
+
def ref_to_short(name)
|
293
|
+
RefToShort.names[name]
|
273
294
|
end
|
274
|
-
els
|
275
|
-
end
|
276
295
|
|
277
|
-
|
278
|
-
|
279
|
-
|
296
|
+
# infinity constant for cardinality
|
297
|
+
def n
|
298
|
+
Float::INFINITY
|
299
|
+
end
|
280
300
|
|
281
|
-
|
282
|
-
@
|
283
|
-
|
301
|
+
# define a scope
|
302
|
+
# @param [Symbol] name
|
303
|
+
# @param [Lambda] lambda
|
304
|
+
# @return [void]
|
305
|
+
def scope(name, lambda)
|
306
|
+
@scopes ||= {}
|
307
|
+
@scopes[name] = lambda
|
308
|
+
end
|
284
309
|
|
285
|
-
|
286
|
-
|
287
|
-
@elements[name] = ElementParser.new(name, type, options)
|
288
|
-
short_name = self.ref_to_short(name)
|
289
|
-
if short_name
|
290
|
-
@elements[short_name] = @elements[name].dup
|
291
|
-
@elements[short_name].short = true
|
310
|
+
def registered_scopes
|
311
|
+
@scopes || {}
|
292
312
|
end
|
293
313
|
|
294
|
-
|
314
|
+
def register_scopes(scopes)
|
315
|
+
@scopes ||= {}
|
316
|
+
@scopes = scopes.merge(@scopes)
|
317
|
+
end
|
295
318
|
|
296
|
-
|
319
|
+
# define unique element
|
320
|
+
# @param [String] name
|
321
|
+
# @param [Symbol] type
|
322
|
+
# @param [Hash] options
|
323
|
+
# @return [void]
|
324
|
+
def element(name, type, options = {})
|
325
|
+
@elements ||= {}
|
326
|
+
@elements[name] = ElementParser.new(name, type, options)
|
327
|
+
short_name = self.ref_to_short(name)
|
328
|
+
if short_name
|
329
|
+
@elements[short_name] = @elements[name].dup
|
330
|
+
@elements[short_name].short = true
|
331
|
+
end
|
297
332
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
333
|
+
attr_accessor @elements[name].to_sym
|
334
|
+
|
335
|
+
alias_method "#{@elements[name].underscore_name}_with_attributes".to_sym, @elements[name].to_sym
|
336
|
+
|
337
|
+
current_element = @elements[name]
|
338
|
+
define_method current_element.to_sym do |args = nil|
|
339
|
+
val = instance_variable_get(current_element.to_instance)
|
340
|
+
if val.respond_to?(:__getobj__)
|
341
|
+
val.__getobj__
|
306
342
|
else
|
307
|
-
val
|
343
|
+
if val.is_a?(SubsetArray) and val.first and val.first.is_a?(TextWithAttributes)
|
344
|
+
val.map { |v| v.respond_to?(:__getobj__) ? v.__getobj__ : v }
|
345
|
+
else
|
346
|
+
val
|
347
|
+
end
|
308
348
|
end
|
309
349
|
end
|
350
|
+
|
351
|
+
if @elements[name].shortcut
|
352
|
+
current_element = @elements[name]
|
353
|
+
alias_method "#{current_element.shortcut.to_s}_with_attributes".to_sym, "#{@elements[name].underscore_name}_with_attributes".to_sym
|
354
|
+
alias_method current_element.shortcut, @elements[name].to_sym
|
355
|
+
end
|
356
|
+
|
357
|
+
@elements[name]
|
310
358
|
end
|
311
359
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
360
|
+
# define multiple elements
|
361
|
+
# shortcut for element :array=>true
|
362
|
+
# @param [String] name
|
363
|
+
# @param [Symbol] type
|
364
|
+
# @param [Hash] options
|
365
|
+
# @return [void]
|
366
|
+
def elements(name, type, options = {})
|
367
|
+
self.element(name, type, options.merge(:array => true))
|
316
368
|
end
|
317
|
-
end
|
318
369
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
370
|
+
# registered elements for this subset
|
371
|
+
# @return [Hash]
|
372
|
+
def registered_elements
|
373
|
+
@elements || {}
|
374
|
+
end
|
323
375
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
while sup.respond_to?(:registered_elements)
|
328
|
-
els.merge!(sup.registered_elements) if sup.registered_elements
|
329
|
-
sup = sup.superclass
|
376
|
+
def register_elements(elements)
|
377
|
+
@elements ||= {}
|
378
|
+
@elements.merge!(elements)
|
330
379
|
end
|
331
|
-
els
|
332
|
-
end
|
333
380
|
|
334
|
-
|
335
|
-
|
336
|
-
|
381
|
+
def get_class(name)
|
382
|
+
ONIX.const_get(name) if ONIX.const_defined?(name)
|
383
|
+
end
|
337
384
|
|
338
|
-
|
339
|
-
|
385
|
+
def inherited(sublass)
|
386
|
+
sublass.register_scopes(self.registered_scopes)
|
387
|
+
sublass.register_elements(self.registered_elements)
|
388
|
+
end
|
340
389
|
end
|
341
390
|
|
342
391
|
def initialize
|
343
392
|
# initialize plural as Array
|
344
|
-
self.
|
393
|
+
self.registered_elements.values.each do |e|
|
345
394
|
if e.is_array?
|
346
|
-
|
347
|
-
subset_array = SubsetArray.new
|
348
|
-
subset_klass = self.class.get_class(e.class_name)
|
349
|
-
if subset_klass.respond_to? :registered_scopes
|
350
|
-
subset_klass.registered_scopes.each do |n, l|
|
351
|
-
unless subset_array.respond_to? n.to_s
|
352
|
-
subset_array.define_singleton_method(n.to_s) do
|
353
|
-
instance_exec(&l)
|
354
|
-
end
|
355
|
-
end
|
356
|
-
end
|
357
|
-
end
|
358
|
-
instance_variable_set(e.to_instance, subset_array)
|
395
|
+
register_subset_array(e)
|
359
396
|
end
|
360
397
|
end
|
361
398
|
end
|
362
399
|
|
363
|
-
def
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
Float::INFINITY
|
400
|
+
def register_subset_array(e)
|
401
|
+
# register a contextual SubsetArray object
|
402
|
+
subset_array = SubsetArray.new
|
403
|
+
subset_klass = self.get_class(e.class_name)
|
404
|
+
if subset_klass.respond_to?(:registered_scopes)
|
405
|
+
subset_klass.registered_scopes.each do |n, l|
|
406
|
+
unless subset_array.respond_to?(n.to_s)
|
407
|
+
subset_array.define_singleton_method(n.to_s) do
|
408
|
+
instance_exec(&l)
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
instance_variable_set(e.to_instance, subset_array)
|
378
414
|
end
|
379
415
|
|
380
|
-
def
|
381
|
-
self.class.
|
416
|
+
def registered_elements
|
417
|
+
self.class.registered_elements
|
382
418
|
end
|
383
419
|
|
384
420
|
def get_class(name)
|
385
421
|
self.class.get_class(name)
|
386
422
|
end
|
387
423
|
|
424
|
+
# @param [Nokogiri::XML::Element] n
|
425
|
+
# @return [void]
|
388
426
|
def parse(n)
|
389
427
|
parse_attributes(n.attributes)
|
390
428
|
n.elements.each do |t|
|
391
|
-
|
392
|
-
e = self.get_registered_element(name)
|
429
|
+
e = self.registered_elements[t.name]
|
393
430
|
if e
|
394
431
|
primitive = true
|
395
432
|
case e.type
|
@@ -429,7 +466,15 @@ module ONIX
|
|
429
466
|
if val
|
430
467
|
if primitive && t.attributes.length > 0
|
431
468
|
if t.attributes["textformat"] && t.attributes["textformat"].to_s == "05" # content is XHTML
|
432
|
-
|
469
|
+
xhtml = CGI.unescapeHTML(t.children.map { |x| x.to_s }.join.strip)
|
470
|
+
if Nokogiri::XML.parse(xhtml).root # check if val is really XHTML
|
471
|
+
val = xhtml
|
472
|
+
else
|
473
|
+
xhtml = CGI.unescapeHTML(val)
|
474
|
+
if Nokogiri::XML.parse(xhtml).root
|
475
|
+
val = xhtml
|
476
|
+
end
|
477
|
+
end
|
433
478
|
end
|
434
479
|
val = TextWithAttributes.new(val)
|
435
480
|
val.parse(t.attributes)
|
@@ -441,7 +486,6 @@ module ONIX
|
|
441
486
|
instance_variable_set(e.to_instance, e.parse_lambda(val))
|
442
487
|
end
|
443
488
|
end
|
444
|
-
|
445
489
|
else
|
446
490
|
unsupported(t)
|
447
491
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: im_onix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julien Boulnois
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,34 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: ruby-prof
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: nokogiri
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -455,6 +483,7 @@ files:
|
|
455
483
|
- lib/onix/ancillary_content.rb
|
456
484
|
- lib/onix/audience.rb
|
457
485
|
- lib/onix/audience_range.rb
|
486
|
+
- lib/onix/barcode.rb
|
458
487
|
- lib/onix/builder.rb
|
459
488
|
- lib/onix/cited_content.rb
|
460
489
|
- lib/onix/code.rb
|
@@ -496,9 +525,10 @@ files:
|
|
496
525
|
- lib/onix/product_contact.rb
|
497
526
|
- lib/onix/product_form_feature.rb
|
498
527
|
- lib/onix/product_part.rb
|
499
|
-
- lib/onix/
|
528
|
+
- lib/onix/product_supplies_methods.rb
|
500
529
|
- lib/onix/product_supply.rb
|
501
530
|
- lib/onix/professional_affiliation.rb
|
531
|
+
- lib/onix/publisher_representative.rb
|
502
532
|
- lib/onix/publishing_detail.rb
|
503
533
|
- lib/onix/related_material.rb
|
504
534
|
- lib/onix/related_product.rb
|