File Coverage

blib/lib/XML/XPathScript/Template.pm
Criterion Covered Total %
statement 71 97 73.2
branch 13 24 54.1
condition 4 15 26.6
subroutine 18 25 72.0
pod 11 11 100.0
total 117 172 68.0


line stmt bran cond sub pod time code
1             package XML::XPathScript::Template;
2              
3 24     24   73447 use strict;
  24         44  
  24         773  
4 24     24   114 use warnings;
  24         39  
  24         631  
5              
6 24     24   112 use Carp;
  24         40  
  24         1504  
7 24     24   134 use Scalar::Util qw/ reftype /;
  24         139  
  24         2439  
8 24     24   216865 use Data::Dumper;
  24         321854  
  24         2016  
9 24     24   15258 use XML::XPathScript::Template::Tag;
  24         74  
  24         812  
10 24     24   19544 use Clone qw/ clone /;
  24         270935  
  24         2401  
11 24     24   217 use Scalar::Util qw/ refaddr /;
  24         50  
  24         1613  
12              
13 24         320 use overload '&{}' => \&_overload_func,
14 24     24   164 q{""} => \&_overload_quote;
  24         51  
15              
16             our $VERSION = '1.54';
17              
18             sub new {
19 3     3 1 32 my( $class ) = @_;
20              
21 3         8 my $self = {};
22 3         10 bless $self, $class;
23              
24 3         10 return $self;
25             }
26              
27             sub set { ##no critic
28 12 50   12 1 4923 croak "method set called with more than two arguments" if @_ > 3;
29              
30 12         25 my( $self, $tag, $attribute_ref ) = @_;
31              
32 12         37 my $type = reftype $tag;
33 4   33     32 my @templates = # templates to change
34             !$type ? $self->{$tag}
35             ||= new XML::XPathScript::Template::Tag
36 12 50 66     172 : $type eq 'ARRAY' ? map { $self->{$_}
    100          
37             ||= new XML::XPathScript::Template::Tag
38             } @$tag
39             : croak "tag cannot be of type $type"
40             ;
41              
42 12         51 $_->set( $attribute_ref ) for @templates;
43              
44 12         33 return;
45             }
46              
47             sub copy {
48 3     3 1 1491 my( $self, $src, $copy, $attributes_ref ) = @_;
49              
50 3 50       16 croak "tag $src not found in template"
51             unless $self->{$src};
52              
53 3         7 my %attributes = %{ $self->{$src} };
  3         14  
54 3 100       11 %attributes = map { $_ => $attributes{ $_ } }@$attributes_ref
  1         4  
55             if $attributes_ref;
56            
57 3         33 $self->set( $copy, \%attributes );
58              
59 3         11 return;
60             }
61              
62             sub alias {
63 2     2 1 2029 my( $self, $src, $copy ) = @_;
64              
65 2 100       31 $self->{$_} = $self->{$src} for ref( $copy ) ? @$copy : $copy;
66              
67 2         7 return;
68             }
69              
70              
71             sub dump { ##no critic
72 0     0 1 0 my( $self, @tags ) = @_;
73            
74 0         0 my %template = %{$self};
  0         0  
75            
76 0 0       0 @tags = keys %template unless @tags;
77            
78 0         0 %template = map { $_ => $template{ $_ } } @tags;
  0         0  
79            
80 0         0 return Data::Dumper->Dump( [ \%template ], [ 'template' ] );
81             }
82              
83             sub clear {
84 0     0 1 0 my( $self, $tags ) = @_;
85              
86 0 0       0 delete $self->{ $_ } for $tags
  0         0  
87             ? @$tags
88             : grep { !/^:/ } keys %$self; ##no critic
89 0         0 return;
90             }
91              
92              
93             sub is_alias {
94 2     2 1 571 my( $self, $tag ) = @_;
95              
96 2         6 my $id = $self->{$tag};
97              
98 14 100       97 my @aliases = grep { $_ ne $tag
  2         10  
99             and refaddr( $self->{$_} ) eq refaddr( $id ) }
100 2         3 keys %{$self};
101              
102 2         13 return @aliases;
103             }
104              
105             sub unalias {
106 1     1 1 3 my( $self, $tag ) = @_;
107              
108 1         5 my $fresh = new XML::XPathScript::Template::Tag;
109              
110 1         7 $fresh->set( $self->{$tag} );
111              
112 1         3 $self->{$tag} = $fresh;
113              
114 1         4 return;
115             }
116              
117             sub namespace {
118 0     0 1 0 my( $self, $namespace ) = @_;
119              
120 0   0     0 return $self->{ ":$namespace" } ||= new XML::XPathScript::Template;
121             }
122              
123             sub resolve {
124 0     0 1 0 my $template = shift;
125 0 0       0 my( $namespace, $tag ) = @_ == 2 ? @_ : ( undef, @_ );
126              
127 24     24   21511 no warnings qw/ uninitialized /;
  24         63  
  24         8542  
128 0         0 $namespace = ':'.$namespace;
129              
130 0   0     0 return ( ( $template->{$namespace} && # selection order
131             ( $template->{$namespace}{$tag} # foo:bar
132             || $template->{$namespace}{'*'} ) ) # foo:*
133             || $template->{$tag} # bar
134             || $template->{'*'} ); # *
135             # (and undef if nothing)
136             }
137              
138             sub import_template {
139 1     1 1 7 my( $self, $other_template ) = @_;
140              
141 1 50 33     4 carp "incorrect call for import_template(): no argument or is not a template"
142             unless $other_template and $other_template =~ /HASH/;
143              
144 1         4 for my $k ( keys %$other_template ) {
145 1 50       6 if ( 0 == index $k, ':' ) { # it's a namespace
146 0         0 my $ns = $k;
147 0         0 $ns =~ s/^://;
148 0         0 my $subtemplate = $self->namespace( $ns );
149 0         0 $subtemplate->import( $other_template->{$k} );
150             }
151             else { # it's a regular tag
152 1         5 $self->set( $k => $other_template->{$k} );
153             }
154             }
155              
156 1         3 return;
157             }
158              
159             sub _overload_func {
160 0     0   0 my $self = shift;
161 0     0   0 return sub { $self->set( @_ ) }
162 0         0 }
163              
164             sub _overload_quote {
165 3     3   5 my $self = shift;
166 3         27 return $self;
167 0     0     return sub { $self };
  0            
168             }
169              
170             1;
171              
172             __END__