File Coverage

blib/lib/meon/Web/ResponseXML.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package meon::Web::ResponseXML;
2              
3 2     2   5669530 use strict;
  2         22  
  2         156  
4 2     2   27 use warnings;
  2         10  
  2         140  
5              
6 2     2   969 use meon::Web::Util;
  0            
  0            
7             use XML::LibXML;
8             use Scalar::Util 'blessed';
9             use Moose;
10             use 5.010;
11              
12             has 'dom' => (is=>'rw',isa=>'XML::LibXML::Document',lazy_build=>1,trigger=>sub{ $_[0]->clear_xml_libxml; $_[0]->clear_elements; });
13             has '_xml_libxml' => (is=>'rw',isa=>'XML::LibXML',lazy=>1,default=>sub { XML::LibXML->new },clearer=>'clear_xml_libxml');
14             has 'elements' => (
15             is => 'rw',
16             isa => 'ArrayRef[Object]',
17             lazy_build => 1,
18             clearer => 'clear_elements',
19             traits => ['Array'],
20             handles => {
21             'push_element' => 'push',
22             'elements_all' => 'elements',
23             },
24             );
25              
26             sub _build_elements {
27             return [];
28             }
29              
30             sub _build_dom {
31             my ($self) = @_;
32              
33             my $dom = $self->_xml_libxml->createDocument("1.0", "UTF-8");
34             my $rxml = $dom->createElement('rxml');
35             $rxml->setNamespace('http://www.w3.org/1999/xhtml','xhtml',0);
36             $rxml->setNamespace('http://web.meon.eu/','');
37             $rxml->setNamespace('http://web.meon.eu/','w');
38             $dom->setDocumentElement($rxml);
39             return $dom;
40             }
41              
42             sub create_element {
43             my ($self, $name, $id) = @_;
44              
45             my $element = $self->dom->createElementNS('http://web.meon.eu/',$name);
46             $element->setAttribute('id'=>$id)
47             if defined $id;
48              
49             return $element;
50             }
51              
52             sub create_xhtml_element {
53             my ($self, $name, $id) = @_;
54              
55             my $element = $self->dom->createElementNS('http://www.w3.org/1999/xhtml',$name);
56             $element->setAttribute('id'=>$id)
57             if defined $id;
58              
59             return $element;
60             }
61              
62             sub append_xml {
63             my ($self, $xml) = @_;
64              
65             my $dom = $self->dom;
66              
67             given (ref $xml) {
68             when ('') {
69             my $parser = $self->_xml_libxml;
70             $dom->getDocumentElement->appendChild(
71             $parser->parse_balanced_chunk($xml)
72             );
73             }
74             when ('XML::LibXML::Element') {
75             $dom->getDocumentElement->appendChild($xml);
76             }
77             default { die 'what to do with '.$xml.'?'; }
78             }
79              
80             return $self;
81             }
82              
83             sub parse_xhtml_string {
84             my ($self, $xml) = @_;
85              
86             my $dom = $self->dom;
87              
88             my $parser = $self->_xml_libxml;
89             my $element = $parser->parse_string(
90             '<div xmlns="http://www.w3.org/1999/xhtml">'.$xml.'</div>'
91             )->getDocumentElement->firstChild;
92              
93             return $element;
94             }
95              
96             sub push_new_element {
97             my ($self, $name, $id) = @_;
98              
99             my $element = $self->create_element($name,$id);
100             $self->push_element($element);
101             return $element;
102             }
103              
104             sub get_element {
105             my ($self, $id) = @_;
106              
107             foreach my $element ($self->elements_all) {
108             my $eid = ($element->can('id') ? $element->id : $element->getAttribute('id'));
109             return $element
110             if (defined($eid) && ($id eq $eid));
111             }
112              
113             return undef;
114             }
115              
116             sub get_or_create_element {
117             my ($self, $id, $name) = @_;
118              
119             return
120             $self->get_element($id)
121             || $self->push_new_element($name)
122             ;
123             }
124              
125             sub add_xhtml_form {
126             my ($self, $xml) = @_;
127              
128             my $forms = $self->get_or_create_element('forms', 'forms');
129              
130             my $form = $self->parse_xhtml_string($xml);
131              
132             # add input like id-s to controll group divs
133             my $xpc = meon::Web::Util->xpc;
134             my (@inputs) = $xpc->findnodes(q{//x:input[@id!='']|//x:select[@id!='']|//x:textarea[@id!='']},$form);
135             foreach my $input (@inputs) {
136             my $control_group = $input->parentNode->parentNode;
137             next if $control_group->getAttribute('class') ne 'control-group';
138             my $control_id = 'control-group-'.$input->getAttribute('id');
139             $control_group->setAttribute(id => $control_id);
140             }
141             $forms->appendChild($form);
142              
143             return $self;
144             }
145              
146             sub add_xhtml_link {
147             my ($self, $link) = @_;
148              
149             confess 'is '.$link.' a link?'
150             unless blessed($link) && $link->isa('eusahub::Data::Link');
151              
152             my $forms = $self->get_or_create_element('links', 'links');
153             $forms->appendChild($link->as_xml);
154              
155             return $self;
156             }
157              
158             sub as_string { return $_[0]->as_xml->toString(1); }
159              
160             sub as_xml {
161             my ($self) = @_;
162              
163             my $dom = $self->dom;
164             my $root_el = $dom->getDocumentElement;
165             foreach my $element ($self->elements_all) {
166             $element = $element->as_xml
167             if $element->can('as_xml');
168              
169             $root_el->addChild($element);
170             }
171              
172             return $dom;
173             }
174              
175             1;