File Coverage

blib/lib/Net/Braintree/Xml.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Net::Braintree::Xml;
2 1     1   5 use strict;
  1         2  
  1         37  
3              
4 1     1   308 use XML::Simple;
  0            
  0            
5             use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS );
6             use Exporter;
7             our @ISA = qw(Exporter);
8             our @EXPORT = qw(hash_to_xml xml_to_hash array collect_from_array);
9             our @EXPORT_OK = qw();
10             use Net::Braintree::Util;
11             use DateTime::Format::Atom;
12             use XML::LibXML;
13              
14             sub hash_to_xml {
15             my $hash = shift;
16             my $doc = XML::LibXML::Document->createDocument('1.0', 'UTF-8');
17             my $root_key = (keys %$hash)[0];
18             my $element = XML::LibXML::Element->new($root_key);
19              
20             my $value = $hash->{$root_key};
21             my $node = add_node($element, $value);
22             $doc->setDocumentElement($element);
23              
24             return $doc->toString(1);
25             }
26              
27             sub add_node {
28             my ($parent, $value) = @_;
29             if(is_hashref($value)){
30             build_from_hash($parent, $value);
31             } elsif(is_arrayref($value)){
32             build_from_array($parent, $value);
33             } else {
34             $parent->appendText($value) if $value;
35             }
36             }
37              
38             sub build_from_hash {
39             my($parent, $value) = @_;
40             while(my($key, $child_value) = each(%$value)) {
41             build_node($key, $child_value, $parent);
42             }
43             }
44              
45             sub build_from_array {
46             my($parent, $value) = @_;
47             $parent->setAttribute('type', 'array');
48             foreach my $child_value (@$value) {
49             build_node('item', $child_value, $parent);
50             }
51             }
52              
53             sub build_node {
54             my($node_name, $child_value, $parent) = @_;
55             my $child = XML::LibXML::Element->new($node_name);
56             add_node($child, $child_value);
57             $parent->appendChild($child);
58             }
59              
60             sub xml_to_hash {
61             my $return = XMLin(shift, KeyAttr => [], KeepRoot => 1);
62             my $scrubbed = scrubbed($return);
63             return $scrubbed;
64             }
65              
66             sub scrubbed {
67             my $tree = shift;
68             if (is_hashref($tree)) {
69             return collect_from_hash($tree);
70             }
71             if (is_arrayref($tree)) {
72             return collect_from_array($tree);
73             }
74             return $tree;
75             }
76              
77             sub collect_from_array {
78             my ($tree) = @_;
79             my @new_array = ();
80             foreach my $value (@$tree) {
81             push(@new_array, scrubbed($value));
82             }
83             return \@new_array;
84             }
85              
86             sub collect_from_hash {
87             my ($tree) = @_;
88             my $new_hash = {};
89              
90             my %types = (
91             'array' => \&array,
92             'boolean' => \&boolean,
93             'integer' => \&integer,
94             'datetime' => \&datetime,
95             'date' => \&date
96             );
97              
98             foreach my $type (keys %types) {
99             return $types{$type}->($tree) if is_of_type($type, $tree);
100             }
101             return $tree->{'content'} if exists($tree->{'content'});
102             return undef if is_nil($tree);
103             while(my ($key, $subtree) = each(%$tree)) {
104             $new_hash->{sub_dashes($key)} = scrubbed($subtree);
105             }
106             return $new_hash;
107             }
108              
109             sub is_of_type {
110             my ($type, $tree) = @_;
111             no warnings;
112             return 0 unless $tree->{'type'};
113             return $tree->{'type'} eq $type;
114             }
115              
116             sub is_nil {
117             my $tree = shift;
118             return 0 unless $tree->{'nil'};
119             return $tree->{'nil'} eq "true";
120             }
121              
122             sub boolean {
123             return shift->{'content'} eq 'true' ? 1 : 0;
124             }
125              
126             sub integer {
127             return shift->{'content'};
128             }
129              
130             my $f = DateTime::Format::Atom->new();
131              
132             sub datetime {
133             my $dt = $f->parse_datetime(shift->{'content'});
134             }
135              
136             sub date {
137             my $date = shift->{'content'};
138             $date .= 'T00:00:00Z';
139             my $dt = $f->parse_datetime($date);
140             }
141              
142             sub array {
143             my $tree = shift;
144              
145             delete $tree->{type};
146             my $subtree = (values %$tree)[0];
147             if (ref $subtree eq 'HASH') {
148             return [scrubbed($subtree)];
149             } elsif (ref $subtree eq 'ARRAY') {
150             return scrubbed(force_array($subtree));
151             } elsif (defined($subtree)) {
152             return [$subtree];
153             } else {
154             return [];
155             }
156              
157             }
158              
159              
160             sub sub_dashes {
161             my $string = shift;
162             $string =~ s/-/_/g;
163             return $string;
164             }
165              
166             sub force_array {
167             my $subtree = shift;
168             return $subtree if(is_arrayref($subtree));
169             return [$subtree];
170             }
171              
172             1;