Empact-roxml 2.5.1 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|