Empact-roxml 2.5.1 → 2.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +25 -0
- data/Manifest.txt +0 -4
- data/README.rdoc +12 -2
- data/examples/posts.rb +1 -1
- data/examples/twitter.rb +1 -1
- data/lib/roxml.rb +59 -149
- data/lib/roxml/definition.rb +60 -150
- data/lib/roxml/extensions.rb +4 -1
- data/lib/roxml/extensions/array/conversions.rb +0 -23
- data/lib/roxml/extensions/deprecation.rb +1 -1
- data/lib/roxml/extensions/string.rb +0 -15
- data/lib/roxml/extensions/string/conversions.rb +0 -38
- data/lib/roxml/hash_definition.rb +5 -40
- data/lib/roxml/xml/references.rb +20 -8
- data/roxml.gemspec +4 -4
- data/spec/definition_spec.rb +120 -193
- data/spec/examples/library_spec.rb +8 -3
- data/spec/examples/post_spec.rb +1 -1
- data/spec/roxml_spec.rb +14 -14
- data/test/bugs/rexml_bugs.rb +1 -1
- data/test/mocks/dictionaries.rb +8 -7
- data/test/mocks/mocks.rb +19 -19
- data/test/test_helper.rb +1 -0
- data/test/unit/definition_test.rb +22 -96
- data/test/unit/deprecations_test.rb +1 -74
- data/test/unit/to_xml_test.rb +6 -6
- data/test/unit/xml_attribute_test.rb +1 -1
- data/test/unit/xml_block_test.rb +3 -3
- data/test/unit/xml_bool_test.rb +4 -4
- data/test/unit/xml_convention_test.rb +3 -3
- data/test/unit/xml_hash_test.rb +5 -14
- data/test/unit/xml_initialize_test.rb +2 -6
- data/test/unit/xml_name_test.rb +5 -24
- data/test/unit/xml_namespace_test.rb +2 -2
- data/test/unit/xml_object_test.rb +5 -5
- data/test/unit/xml_required_test.rb +1 -1
- data/test/unit/xml_text_test.rb +2 -2
- metadata +12 -17
- data/lib/roxml/extensions/active_support.rb +0 -54
- data/spec/string_spec.rb +0 -15
- data/test/release/dependencies_test.rb +0 -32
- data/test/unit/xml_construct_test.rb +0 -77
data/History.txt
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
== 3.0 ???
|
2
|
+
|
3
|
+
* major enhancements
|
4
|
+
|
5
|
+
* Remove previously deprecated functionality
|
6
|
+
* Error on any unrecognized options
|
7
|
+
* Normalize hash declaration syntax:
|
8
|
+
* for :key => '@string', string is taken to be the :from argument
|
9
|
+
* for :key => {:from => '@string', :as => Type}, the arguments are just the same as a regular declaration
|
10
|
+
|
11
|
+
* minor enhancements
|
12
|
+
|
13
|
+
* Include 't' and 'f' in the list of possible boolean values, since rails uses them
|
14
|
+
* Remove :attrs hash syntax. Not particularly helpful & somewhat obfuscatory. Use :key, :value instead.
|
15
|
+
* Default attrs ending in '_at' to DateTime. This can be overriden via :as
|
16
|
+
* Default attrs ending in '_on' to Date. This can be overriden via :as
|
17
|
+
|
18
|
+
== 2.5.2 (March 12, 2009)
|
19
|
+
|
20
|
+
* minor enhancements
|
21
|
+
|
22
|
+
* Remove dependency on an Object#try which conflicted with ActiveSupport 2.3's version
|
23
|
+
* Document the :to_xml option for attr references
|
24
|
+
* Require active_support directly, as it's less brittle and plays nicer with other libraries
|
25
|
+
|
1
26
|
== 2.5.1 (March 2, 2009)
|
2
27
|
|
3
28
|
* minor enhancements
|
data/Manifest.txt
CHANGED
@@ -21,7 +21,6 @@ examples/xml/twitter.xml
|
|
21
21
|
lib/roxml.rb
|
22
22
|
lib/roxml/definition.rb
|
23
23
|
lib/roxml/extensions.rb
|
24
|
-
lib/roxml/extensions/active_support.rb
|
25
24
|
lib/roxml/extensions/array.rb
|
26
25
|
lib/roxml/extensions/array/conversions.rb
|
27
26
|
lib/roxml/extensions/deprecation.rb
|
@@ -46,7 +45,6 @@ spec/roxml_spec.rb
|
|
46
45
|
spec/shared_specs.rb
|
47
46
|
spec/spec.opts
|
48
47
|
spec/spec_helper.rb
|
49
|
-
spec/string_spec.rb
|
50
48
|
spec/xml/parser_spec.rb
|
51
49
|
tasks/rspec.rake
|
52
50
|
tasks/test.rake
|
@@ -83,7 +81,6 @@ test/fixtures/person_with_guarded_mothers.xml
|
|
83
81
|
test/fixtures/person_with_mothers.xml
|
84
82
|
test/mocks/dictionaries.rb
|
85
83
|
test/mocks/mocks.rb
|
86
|
-
test/release/dependencies_test.rb
|
87
84
|
test/test_helper.rb
|
88
85
|
test/unit/definition_test.rb
|
89
86
|
test/unit/deprecations_test.rb
|
@@ -91,7 +88,6 @@ test/unit/to_xml_test.rb
|
|
91
88
|
test/unit/xml_attribute_test.rb
|
92
89
|
test/unit/xml_block_test.rb
|
93
90
|
test/unit/xml_bool_test.rb
|
94
|
-
test/unit/xml_construct_test.rb
|
95
91
|
test/unit/xml_convention_test.rb
|
96
92
|
test/unit/xml_hash_test.rb
|
97
93
|
test/unit/xml_initialize_test.rb
|
data/README.rdoc
CHANGED
@@ -1,5 +1,15 @@
|
|
1
|
-
ROXML Ruby Object to XML mapping library.
|
2
|
-
|
1
|
+
ROXML Ruby Object to XML mapping library.
|
2
|
+
|
3
|
+
For more information visit:
|
4
|
+
|
5
|
+
http://roxml.rubyforge.org/rdoc/
|
6
|
+
http://empact.github.com/roxml/
|
7
|
+
http://rubyforge.org/projects/roxml/
|
8
|
+
|
9
|
+
Progress on this project is (more or less) tracked at:
|
10
|
+
|
11
|
+
http://www.pivotaltracker.com/project/4109
|
12
|
+
|
3
13
|
|
4
14
|
=Quick Start Guide
|
5
15
|
|
data/examples/posts.rb
CHANGED
@@ -8,7 +8,7 @@ class Post
|
|
8
8
|
xml_reader :hash, :from => :attr
|
9
9
|
xml_reader :description, :from => :attr
|
10
10
|
xml_reader :tag, :from => :attr
|
11
|
-
xml_reader :
|
11
|
+
xml_reader :created_at, :from => '@time'
|
12
12
|
xml_reader :others, :from => :attr, :as => Integer
|
13
13
|
xml_reader :extended, :from => :attr
|
14
14
|
end
|
data/examples/twitter.rb
CHANGED
@@ -21,7 +21,7 @@ class Status
|
|
21
21
|
|
22
22
|
xml_reader :id, :as => Integer
|
23
23
|
xml_reader :text
|
24
|
-
xml_reader :created_at
|
24
|
+
xml_reader :created_at # This defaults to :as => DateTime, due to the '_at'
|
25
25
|
xml_reader :source
|
26
26
|
xml_reader :truncated?
|
27
27
|
xml_reader :in_reply_to_status_id, :as => Integer
|
data/lib/roxml.rb
CHANGED
@@ -8,84 +8,26 @@ require 'uri'
|
|
8
8
|
end
|
9
9
|
|
10
10
|
module ROXML # :nodoc:
|
11
|
-
VERSION = '2.5.
|
11
|
+
VERSION = '2.5.2'
|
12
12
|
|
13
13
|
def self.included(base) # :nodoc:
|
14
|
-
base.extend ClassMethods::Accessors,
|
15
|
-
ClassMethods::Declarations,
|
16
|
-
ClassMethods::Operations
|
17
14
|
base.class_eval do
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
extend ClassMethods::Accessors,
|
16
|
+
ClassMethods::Declarations,
|
17
|
+
ClassMethods::Operations
|
18
|
+
include InstanceMethods
|
21
19
|
end
|
22
20
|
end
|
23
21
|
|
24
22
|
module InstanceMethods # :nodoc:
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
# Provides access to ROXML::ClassMethods::Accessors::tag_refs directly from an instance of a ROXML class
|
34
|
-
def tag_refs
|
35
|
-
self.class.tag_refs_without_deprecation
|
36
|
-
end
|
37
|
-
deprecate :tag_refs => :roxml_attrs
|
38
|
-
end
|
39
|
-
|
40
|
-
module Construction
|
41
|
-
# xml_initialize is called at the end of the #from_xml operation on objects
|
42
|
-
# where xml_construct is not in place. Override xml_initialize in order to establish
|
43
|
-
# post-import behavior. For example, you can use xml_initialize to map xml attribute
|
44
|
-
# values into the object standard initialize function, thus enabling a ROXML object
|
45
|
-
# to freely be either xml-backed or instantiated directly via #new.
|
46
|
-
# An example of this follows:
|
47
|
-
#
|
48
|
-
# class Measurement
|
49
|
-
# include ROXML
|
50
|
-
#
|
51
|
-
# xml_reader :units, :from => :attr
|
52
|
-
# xml_reader :value, :from => :content
|
53
|
-
#
|
54
|
-
# def xml_initialize
|
55
|
-
# # the object is instantiated, and all xml attributes are imported
|
56
|
-
# # and available, i.e., value and units below are the same value and units
|
57
|
-
# # found in the xml via the xml_reader declarations above.
|
58
|
-
# initialize(value, units)
|
59
|
-
# end
|
60
|
-
#
|
61
|
-
# def initialize(value, units = 'pixels')
|
62
|
-
# @value = Float(value)
|
63
|
-
# @units = units.to_s
|
64
|
-
# if @units.starts_with? 'hundredths-'
|
65
|
-
# @value /= 100
|
66
|
-
# @units = @units.split('hundredths-')[1]
|
67
|
-
# end
|
68
|
-
# end
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# #xml_initialize may be written to take arguments, in which case extra arguments
|
72
|
-
# from from_xml will be passed into the function.
|
73
|
-
#
|
74
|
-
def xml_initialize # :nodoc:
|
75
|
-
end
|
76
|
-
deprecate :xml_initialize => :after_parse
|
77
|
-
end
|
78
|
-
|
79
|
-
module Conversions
|
80
|
-
# Returns a LibXML::XML::Node or a REXML::Element representing this object
|
81
|
-
def to_xml(name = nil)
|
82
|
-
returning XML::Node.new((name || self.class.tag_name).to_s) do |root|
|
83
|
-
self.class.roxml_attrs.each do |attr|
|
84
|
-
ref = attr.to_ref(self)
|
85
|
-
v = ref.to_xml
|
86
|
-
unless v.nil?
|
87
|
-
ref.update_xml(root, v)
|
88
|
-
end
|
23
|
+
# Returns a LibXML::XML::Node or a REXML::Element representing this object
|
24
|
+
def to_xml(name = self.class.tag_name)
|
25
|
+
returning XML::Node.new(name.to_s) do |root|
|
26
|
+
self.class.roxml_attrs.each do |attr|
|
27
|
+
ref = attr.to_ref(self)
|
28
|
+
value = ref.to_xml
|
29
|
+
unless value.nil?
|
30
|
+
ref.update_xml(root, value)
|
89
31
|
end
|
90
32
|
end
|
91
33
|
end
|
@@ -169,13 +111,19 @@ module ROXML # :nodoc:
|
|
169
111
|
# but in this case an underscored version of the name is applied, for convenience.
|
170
112
|
def xml_convention(to_proc_able = nil, &block)
|
171
113
|
raise ArgumentError, "conventions are already set" if @roxml_naming_convention
|
172
|
-
|
173
|
-
|
174
|
-
|
114
|
+
@roxml_naming_convention =
|
115
|
+
if to_proc_able
|
116
|
+
raise ArgumentError, "only one conventions can be set" if block_given?
|
117
|
+
to_proc_able.to_proc
|
118
|
+
elsif block_given?
|
119
|
+
block
|
120
|
+
end
|
175
121
|
end
|
176
122
|
|
177
123
|
def roxml_naming_convention # :nodoc:
|
178
|
-
(@roxml_naming_convention ||
|
124
|
+
(@roxml_naming_convention || begin
|
125
|
+
superclass.roxml_naming_convention if superclass.respond_to?(:roxml_naming_convention)
|
126
|
+
end).freeze
|
179
127
|
end
|
180
128
|
|
181
129
|
# Declares a reference to a certain xml element, whether an attribute, a node,
|
@@ -269,7 +217,7 @@ module ROXML # :nodoc:
|
|
269
217
|
#
|
270
218
|
# xml_reader :counts, :as => [Integer]
|
271
219
|
#
|
272
|
-
# Even an array of
|
220
|
+
# Even an array of text nodes can be specified with :as => []
|
273
221
|
#
|
274
222
|
# xml_reader :quotes, :as => []
|
275
223
|
#
|
@@ -320,7 +268,7 @@ module ROXML # :nodoc:
|
|
320
268
|
# a collection of key-value pairs represented in your xml. You create a hash declaration by
|
321
269
|
# passing a hash mapping as the type argument. A few examples:
|
322
270
|
#
|
323
|
-
# ===== Hash of
|
271
|
+
# ===== Hash of element contents
|
324
272
|
# For xml such as this:
|
325
273
|
#
|
326
274
|
# <dictionary>
|
@@ -439,30 +387,30 @@ module ROXML # :nodoc:
|
|
439
387
|
# [:else] Default value for attribute, if missing from the xml on .from_xml
|
440
388
|
# [:required] If true, throws RequiredElementMissing when the element isn't present
|
441
389
|
# [:frozen] If true, all results are frozen (using #freeze) at parse-time.
|
442
|
-
# [:cdata]
|
443
|
-
#
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
390
|
+
# [:cdata] true for values which should be input from or output as cdata elements
|
391
|
+
# [:to_xml] this proc is applied to the attributes value outputting the instance via #to_xml
|
392
|
+
#
|
393
|
+
def xml_attr(*syms, &block)
|
394
|
+
opts = syms.extract_options!
|
395
|
+
syms.map do |sym|
|
396
|
+
returning Definition.new(sym, opts, &block) do |attr|
|
397
|
+
if roxml_attrs.map(&:accessor).include? attr.accessor
|
398
|
+
raise "Accessor #{attr.accessor} is already defined as XML accessor in class #{self.name}"
|
399
|
+
end
|
400
|
+
@roxml_attrs << attr
|
448
401
|
end
|
449
|
-
@roxml_attrs << attr
|
450
402
|
end
|
451
403
|
end
|
452
404
|
|
453
|
-
def xml(sym, writable = false, type_and_or_opts = nil, opts = nil, &block) #:nodoc:
|
454
|
-
send(writable ? :xml_accessor : :xml_reader, sym, type_and_or_opts, opts, &block)
|
455
|
-
end
|
456
|
-
deprecate :xml => "use xml_attr, xml_reader, or xml_accessor instead"
|
457
|
-
|
458
405
|
# Declares a read-only xml reference. See xml_attr for details.
|
459
406
|
#
|
460
407
|
# Note that while xml_reader does not create a setter for this attribute,
|
461
408
|
# its value can be modified indirectly via methods. For more complete
|
462
409
|
# protection, consider the :frozen option.
|
463
|
-
def xml_reader(
|
464
|
-
|
465
|
-
|
410
|
+
def xml_reader(*syms, &block)
|
411
|
+
xml_attr(*syms, &block).each do |attr|
|
412
|
+
add_reader(attr)
|
413
|
+
end
|
466
414
|
end
|
467
415
|
|
468
416
|
# Declares a writable xml reference. See xml_attr for details.
|
@@ -470,45 +418,22 @@ module ROXML # :nodoc:
|
|
470
418
|
# Note that while xml_accessor does create a setter for this attribute,
|
471
419
|
# you can use the :frozen option to prevent its value from being
|
472
420
|
# modified indirectly via methods.
|
473
|
-
def xml_accessor(
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
end
|
478
|
-
|
479
|
-
# This method is deprecated, please use xml_initialize instead
|
480
|
-
def xml_construct(*args) # :nodoc:
|
481
|
-
present_tags = tag_refs_without_deprecation.map(&:accessor)
|
482
|
-
missing_tags = args - present_tags
|
483
|
-
unless missing_tags.empty?
|
484
|
-
raise ArgumentError, "All construction tags must be declared first using xml, " +
|
485
|
-
"xml_reader, or xml_accessor. #{missing_tags.join(', ')} is missing. " +
|
486
|
-
"#{present_tags.join(', ')} are declared."
|
421
|
+
def xml_accessor(*syms, &block)
|
422
|
+
xml_attr(*syms, &block).each do |attr|
|
423
|
+
add_reader(attr)
|
424
|
+
attr_writer(attr.attr_name)
|
487
425
|
end
|
488
|
-
@xml_construction_args = args
|
489
426
|
end
|
490
|
-
deprecate :xml_construct => :xml_initialize
|
491
427
|
|
492
428
|
private
|
493
429
|
def add_reader(attr)
|
494
430
|
define_method(attr.accessor) do
|
495
|
-
instance_variable_get(
|
431
|
+
instance_variable_get(attr.instance_variable_name)
|
496
432
|
end
|
497
433
|
end
|
498
434
|
end
|
499
435
|
|
500
436
|
module Accessors
|
501
|
-
def xml_construction_args # :nodoc:
|
502
|
-
@xml_construction_args ||= []
|
503
|
-
end
|
504
|
-
deprecate :xml_construction_args
|
505
|
-
|
506
|
-
# A helper which enables us to detect when the xml_name has been explicitly set
|
507
|
-
def xml_name? #:nodoc:
|
508
|
-
@roxml_tag_name
|
509
|
-
end
|
510
|
-
deprecate :xml_name?
|
511
|
-
|
512
437
|
# Returns the tag name (also known as xml_name) of the class.
|
513
438
|
# If no tag name is set with xml_name method, returns default class name
|
514
439
|
# in lowercase.
|
@@ -526,24 +451,23 @@ module ROXML # :nodoc:
|
|
526
451
|
end
|
527
452
|
|
528
453
|
def roxml_tag_name # :nodoc:
|
529
|
-
@roxml_tag_name ||
|
454
|
+
@roxml_tag_name || begin
|
455
|
+
superclass.roxml_tag_name if superclass.respond_to?(:roxml_tag_name)
|
456
|
+
end
|
530
457
|
end
|
531
458
|
|
532
459
|
def roxml_namespace # :nodoc:
|
533
|
-
@roxml_namespace ||
|
460
|
+
@roxml_namespace || begin
|
461
|
+
superclass.roxml_namespace if superclass.respond_to?(:roxml_namespace)
|
462
|
+
end
|
534
463
|
end
|
535
464
|
|
536
465
|
# Returns array of internal reference objects, such as attributes
|
537
466
|
# and composed XML objects
|
538
467
|
def roxml_attrs
|
539
468
|
@roxml_attrs ||= []
|
540
|
-
(@roxml_attrs + (superclass.
|
541
|
-
end
|
542
|
-
|
543
|
-
def tag_refs # :nodoc:
|
544
|
-
roxml_attrs.map {|a| a.to_ref(nil) }
|
469
|
+
(@roxml_attrs + (superclass.respond_to?(:roxml_attrs) ? superclass.roxml_attrs : [])).freeze
|
545
470
|
end
|
546
|
-
deprecate :tag_refs => :roxml_attrs
|
547
471
|
end
|
548
472
|
|
549
473
|
module Operations
|
@@ -569,32 +493,18 @@ module ROXML # :nodoc:
|
|
569
493
|
def from_xml(data, *initialization_args)
|
570
494
|
xml = XML::Node.from(data)
|
571
495
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
returning new(*initialization_args) do |inst|
|
579
|
-
roxml_attrs.each do |attr|
|
580
|
-
value = attr.to_ref(inst).value_in(xml)
|
581
|
-
setter = :"#{attr.variable_name}="
|
582
|
-
inst.respond_to?(setter) \
|
583
|
-
? inst.send(setter, value) \
|
584
|
-
: inst.instance_variable_set("@#{attr.variable_name}", value)
|
585
|
-
end
|
586
|
-
inst.try(:after_parse)
|
496
|
+
returning new(*initialization_args) do |inst|
|
497
|
+
roxml_attrs.each do |attr|
|
498
|
+
value = attr.to_ref(inst).value_in(xml)
|
499
|
+
inst.respond_to?(attr.setter) \
|
500
|
+
? inst.send(attr.setter, value) \
|
501
|
+
: inst.instance_variable_set(attr.instance_variable_name, value)
|
587
502
|
end
|
503
|
+
inst.send(:after_parse) if inst.respond_to?(:after_parse, true)
|
588
504
|
end
|
589
505
|
rescue ArgumentError => e
|
590
506
|
raise e, e.message + " for class #{self}"
|
591
507
|
end
|
592
|
-
|
593
|
-
# Deprecated in favor of #from_xml
|
594
|
-
def parse(data) # :nodoc:
|
595
|
-
from_xml(data)
|
596
|
-
end
|
597
|
-
deprecate :parse => :from_xml
|
598
508
|
end
|
599
509
|
end
|
600
510
|
end
|
data/lib/roxml/definition.rb
CHANGED
@@ -12,47 +12,39 @@ end
|
|
12
12
|
|
13
13
|
module ROXML
|
14
14
|
class Definition # :nodoc:
|
15
|
-
attr_reader :name, :type, :wrapper, :hash, :blocks, :accessor, :to_xml
|
15
|
+
attr_reader :name, :type, :wrapper, :hash, :blocks, :accessor, :to_xml, :attr_name
|
16
16
|
bool_attr_reader :name_explicit, :array, :cdata, :required, :frozen
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def initialize(sym, *args, &block)
|
29
|
-
@accessor = sym
|
30
|
-
if @accessor.to_s.ends_with?('_on')
|
31
|
-
ActiveSupport::Deprecation.warn "In 3.0, attributes with names ending with _on will default to Date type, rather than :text"
|
32
|
-
end
|
33
|
-
if @accessor.to_s.ends_with?('_at')
|
34
|
-
ActiveSupport::Deprecation.warn "In 3.0, attributes with names ending with _at will default to DateTime type, rather than :text"
|
35
|
-
end
|
18
|
+
def initialize(sym, opts = {}, &block)
|
19
|
+
opts.assert_valid_keys(:from, :in, :as,
|
20
|
+
:else, :required, :frozen, :cdata, :to_xml)
|
21
|
+
@default = opts.delete(:else)
|
22
|
+
@to_xml = opts.delete(:to_xml)
|
23
|
+
@name_explicit = opts.has_key?(:from) && opts[:from].is_a?(String)
|
24
|
+
@cdata = opts.delete(:cdata)
|
25
|
+
@required = opts.delete(:required)
|
26
|
+
@frozen = opts.delete(:frozen)
|
27
|
+
@wrapper = opts.delete(:in)
|
36
28
|
|
37
|
-
|
38
|
-
opts[:as] ||=
|
29
|
+
@accessor = sym.to_s
|
30
|
+
opts[:as] ||=
|
31
|
+
if @accessor.ends_with?('?')
|
32
|
+
:bool
|
33
|
+
elsif @accessor.ends_with?('_on')
|
34
|
+
Date
|
35
|
+
elsif @accessor.ends_with?('_at')
|
36
|
+
DateTime
|
37
|
+
end
|
39
38
|
|
40
|
-
@array = opts[:as].is_a?(Array)
|
39
|
+
@array = opts[:as].is_a?(Array)
|
41
40
|
@blocks = collect_blocks(block, opts[:as])
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
unless self.class.silence_xml_name_warning?
|
50
|
-
warn "WARNING: As of 2.3, a breaking change has been in the naming of sub-objects. " +
|
51
|
-
"ROXML now considers the xml_name of the sub-object before falling back to the accessor name of the parent. " +
|
52
|
-
"Use :from on the parent declaration to override this behavior. Set ROXML::SILENCE_XML_NAME_WARNING to avoid this message."
|
53
|
-
self.class.silence_xml_name_warning!
|
54
|
-
end
|
55
|
-
opts[:from] ||= @type.tag_name
|
42
|
+
@type = extract_type(opts[:as])
|
43
|
+
if @type.respond_to?(:roxml_tag_name)
|
44
|
+
# "WARNING: As of 2.3, a breaking change has been in the naming of sub-objects. " +
|
45
|
+
# "ROXML now considers the xml_name of the sub-object before falling back to the accessor name of the parent. " +
|
46
|
+
# "Use :from on the parent declaration to override this behavior. Set ROXML::SILENCE_XML_NAME_WARNING to avoid this message."
|
47
|
+
opts[:from] ||= @type.roxml_tag_name
|
56
48
|
end
|
57
49
|
|
58
50
|
if opts[:from] == :content
|
@@ -62,12 +54,15 @@ module ROXML
|
|
62
54
|
elsif opts[:from] == :attr
|
63
55
|
@type = :attr
|
64
56
|
opts[:from] = nil
|
57
|
+
elsif opts[:from] == :name
|
58
|
+
opts[:from] = '*'
|
65
59
|
elsif opts[:from].to_s.starts_with?('@')
|
66
60
|
@type = :attr
|
67
61
|
opts[:from].sub!('@', '')
|
68
62
|
end
|
69
63
|
|
70
|
-
@
|
64
|
+
@attr_name = accessor.to_s.chomp('?')
|
65
|
+
@name = (opts[:from] || @attr_name).to_s
|
71
66
|
@name = @name.singularize if hash? || array?
|
72
67
|
if hash? && (hash.key.name? || hash.value.name?)
|
73
68
|
@name = '*'
|
@@ -76,8 +71,12 @@ module ROXML
|
|
76
71
|
raise ArgumentError, "Can't specify both :else default and :required" if required? && @default
|
77
72
|
end
|
78
73
|
|
79
|
-
def
|
80
|
-
|
74
|
+
def instance_variable_name
|
75
|
+
:"@#{attr_name}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def setter
|
79
|
+
:"#{attr_name}="
|
81
80
|
end
|
82
81
|
|
83
82
|
def hash
|
@@ -127,23 +126,11 @@ module ROXML
|
|
127
126
|
array ? results : results.first
|
128
127
|
end
|
129
128
|
|
130
|
-
BLOCK_TO_FLOAT = lambda do |val|
|
131
|
-
all(val) do |v|
|
132
|
-
Float(v) unless v.blank?
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
BLOCK_TO_INT = lambda do |val|
|
137
|
-
all(val) do |v|
|
138
|
-
Integer(v) unless v.blank?
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
129
|
def self.fetch_bool(value, default)
|
143
|
-
value = value.
|
144
|
-
if %w{true yes 1}.include? value
|
130
|
+
value = value.to_s.downcase
|
131
|
+
if %w{true yes 1 t}.include? value
|
145
132
|
true
|
146
|
-
elsif %w{false no 0}.include? value
|
133
|
+
elsif %w{false no 0 f}.include? value
|
147
134
|
false
|
148
135
|
else
|
149
136
|
default
|
@@ -152,10 +139,16 @@ module ROXML
|
|
152
139
|
|
153
140
|
CORE_BLOCK_SHORTHANDS = {
|
154
141
|
# Core Shorthands
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
142
|
+
Integer => lambda do |val|
|
143
|
+
all(val) do |v|
|
144
|
+
Integer(v) unless v.blank?
|
145
|
+
end
|
146
|
+
end,
|
147
|
+
Float => lambda do |val|
|
148
|
+
all(val) do |v|
|
149
|
+
Float(v) unless v.blank?
|
150
|
+
end
|
151
|
+
end,
|
159
152
|
Fixnum => lambda do |val|
|
160
153
|
all(val) do |v|
|
161
154
|
v.to_i unless v.blank?
|
@@ -203,9 +196,6 @@ module ROXML
|
|
203
196
|
end
|
204
197
|
|
205
198
|
def collect_blocks(block, as)
|
206
|
-
ActiveSupport::Deprecation.warn ":as => :float is deprecated. Use :as => Float instead" if as == :float
|
207
|
-
ActiveSupport::Deprecation.warn ":as => :integer is deprecated. Use :as => Integer instead" if as == :integer
|
208
|
-
|
209
199
|
if as.is_a?(Array)
|
210
200
|
unless as.one? || as.empty?
|
211
201
|
raise ArgumentError, "multiple :as types (#{as.map(&:inspect).join(', ')}) is not supported. Use a block if you want more complicated behavior."
|
@@ -220,104 +210,24 @@ module ROXML
|
|
220
210
|
as = (block ? :bool_combined : :bool_standalone)
|
221
211
|
end
|
222
212
|
as = self.class.block_shorthands.fetch(as) do
|
223
|
-
unless as.respond_to?(:from_xml) || as.
|
224
|
-
|
213
|
+
unless as.respond_to?(:from_xml) || (as.respond_to?(:first) && as.first.respond_to?(:from_xml)) || (as.is_a?(Hash) && !(as.keys & [:key, :value]).empty?)
|
214
|
+
raise ArgumentError, "Invalid :as argument #{as}" unless as.nil?
|
225
215
|
end
|
226
216
|
nil
|
227
217
|
end
|
228
218
|
[as, block].compact
|
229
219
|
end
|
230
220
|
|
231
|
-
def
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
@default = opts.delete(:else)
|
239
|
-
@to_xml = opts.delete(:to_xml)
|
240
|
-
@name_explicit = opts.has_key?(:from) && opts[:from].is_a?(String)
|
241
|
-
@cdata = opts.delete(:cdata)
|
242
|
-
@required = opts.delete(:required)
|
243
|
-
@frozen = opts.delete(:frozen)
|
244
|
-
@wrapper = opts.delete(:in)
|
245
|
-
|
246
|
-
@cdata ||= extract_from_as(opts, :cdata, "Please use :cdata => true")
|
247
|
-
|
248
|
-
if opts[:as].is_a?(Array) && opts[:as].size > 1
|
249
|
-
ActiveSupport::Deprecation.warn ":as should point to a single item. #{opts[:as].join(', ')} should be declared some other way."
|
250
|
-
end
|
251
|
-
|
252
|
-
opts
|
253
|
-
end
|
254
|
-
|
255
|
-
def extract_from_as(opts, entry, message)
|
256
|
-
# remove with deprecateds...
|
257
|
-
if [*opts[:as]].include?(entry)
|
258
|
-
ActiveSupport::Deprecation.warn ":as => #{entry.inspect} is deprecated. #{message}"
|
259
|
-
if opts[:as] == entry
|
260
|
-
opts[:as] = nil
|
261
|
-
else
|
262
|
-
opts[:as].delete(entry)
|
263
|
-
end
|
264
|
-
true
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
def extract_type(args, opts)
|
269
|
-
types = (opts.keys & TYPE_KEYS)
|
270
|
-
# type arg
|
271
|
-
if args.one? && types.empty?
|
272
|
-
type = args.first
|
273
|
-
if type.is_a? Array
|
274
|
-
ActiveSupport::Deprecation.warn "Array declarations should be passed as the :as parameter, for future release."
|
275
|
-
@array = true
|
276
|
-
return type.first || :text
|
277
|
-
elsif type.is_a? Hash
|
278
|
-
ActiveSupport::Deprecation.warn "Hash declarations should be passed as the :as parameter, for future release."
|
279
|
-
return HashDefinition.new(type)
|
280
|
-
elsif type == :content
|
281
|
-
ActiveSupport::Deprecation.warn ":content as a type declaration is deprecated. Use :from => '.' or :from => :content instead"
|
282
|
-
opts[:from] = :content
|
283
|
-
return :text
|
284
|
-
elsif type == :attr
|
285
|
-
ActiveSupport::Deprecation.warn ":attr as a type declaration is deprecated. Use :from => '@attr_name' or :from => :attr instead"
|
286
|
-
opts[:from].sub!('@', '') if opts[:from].to_s.starts_with?('@') # this is added back next line...
|
287
|
-
opts[:from] = opts[:from].nil? ? :attr : "@#{opts[:from]}"
|
288
|
-
return :attr
|
289
|
-
else
|
290
|
-
ActiveSupport::Deprecation.warn "Type declarations should be passed as the :as parameter, for future release."
|
291
|
-
return type
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
unless args.empty?
|
296
|
-
raise ArgumentError, "too many arguments (#{(args + types).join(', ')}). Should be name, type, and " +
|
297
|
-
"an options hash, with the type and options optional"
|
298
|
-
end
|
299
|
-
|
300
|
-
if opts[:as].is_a?(Hash)
|
301
|
-
return HashDefinition.new(opts[:as])
|
302
|
-
elsif opts[:as].respond_to?(:from_xml)
|
303
|
-
return opts[:as]
|
304
|
-
elsif opts[:as].is_a?(Array) && opts[:as].first.respond_to?(:from_xml)
|
221
|
+
def extract_type(as)
|
222
|
+
if as.is_a?(Hash)
|
223
|
+
return HashDefinition.new(as)
|
224
|
+
elsif as.respond_to?(:from_xml)
|
225
|
+
return as
|
226
|
+
elsif as.is_a?(Array) && as.first.respond_to?(:from_xml)
|
305
227
|
@array = true
|
306
|
-
return
|
307
|
-
end
|
308
|
-
|
309
|
-
# type options
|
310
|
-
if types.one?
|
311
|
-
opts[:from] = opts.delete(types.first)
|
312
|
-
if opts[:from] == :content
|
313
|
-
opts[:from] = 'content'
|
314
|
-
ActiveSupport::Deprecation.warn ":content is now a reserved as an alias for '.'. Use the string 'content' instead"
|
315
|
-
end
|
316
|
-
types.first
|
317
|
-
elsif types.empty?
|
318
|
-
:text
|
228
|
+
return as.first
|
319
229
|
else
|
320
|
-
|
230
|
+
:text
|
321
231
|
end
|
322
232
|
end
|
323
233
|
end
|