File Coverage

blib/lib/PRANG/Graph/Quantity.pm
Criterion Covered Total %
statement 6 46 13.0
branch 0 20 0.0
condition 0 17 0.0
subroutine 2 7 28.5
pod 0 5 0.0
total 8 95 8.4


line stmt bran cond sub pod time code
1              
2             package PRANG::Graph::Quantity;
3             $PRANG::Graph::Quantity::VERSION = '0.20';
4 1     1   2109 use Moose;
  1         2  
  1         6  
5 1     1   6022 use MooseX::Params::Validate;
  1         3  
  1         5  
6              
7             has 'min' =>
8             is => "ro",
9             isa => "Int",
10             predicate => "has_min",
11             ;
12              
13             has 'max' =>
14             is => "ro",
15             isa => "Int",
16             predicate => "has_max",
17             ;
18              
19             has 'child' =>
20             is => "ro",
21             isa => "PRANG::Graph::Node",
22             required => 1,
23             ;
24              
25             has 'attrName' =>
26             is => "ro",
27             isa => "Str",
28             required => 1,
29             ;
30              
31 0     0 0   sub accept_many {1}
32              
33             sub accept {
34 0     0 0   my $self = shift;
35 0           my ( $node, $ctx, $lax ) = pos_validated_list(
36             \@_,
37             { isa => 'XML::LibXML::Node' },
38             { isa => 'PRANG::Graph::Context' },
39             { isa => 'Bool', optional => 1 },
40             );
41            
42 0           my $found = $ctx->quant_found;
43 0           my $ok = defined $self->child->node_ok($node, $ctx);
44 0 0         return if not $ok;
45 0 0         my ($key, $value, $x, $ns) = $self->child->accept($node, $ctx, $lax)
46             or $ctx->exception(
47             "internal error: node ok, but then not accepted?",
48             $node,
49             );
50 0           $found++;
51 0           $ctx->quant_found($found);
52 0 0 0       if ( $self->has_max and $found > $self->max ) {
53 0           $ctx->exception("node appears too many times", $node);
54             }
55 0           ($key, $value, $x, $ns);
56             }
57              
58             sub complete {
59 0     0 0   my $self = shift;
60 0           my ( $ctx ) = pos_validated_list(
61             \@_,
62             { isa => 'PRANG::Graph::Context' },
63             );
64            
65 0           my $found = $ctx->quant_found;
66 0   0       return !( $self->has_min and $found < $self->min );
67             }
68              
69             sub expected {
70 0     0 0   my $self = shift;
71 0           my ( $ctx ) = pos_validated_list(
72             \@_,
73             { isa => 'PRANG::Graph::Context' },
74             );
75            
76 0           my $desc;
77 0 0         if ( $self->has_min ) {
78 0 0         if ( $self->has_max ) {
79 0           $desc = "between ".$self->min." and ".$self->max;
80             }
81             else {
82 0           $desc = "at least ".$self->min;
83             }
84             }
85             else {
86 0 0         if ( $self->has_max ) {
87 0           $desc = "optionally up to ".$self->max;
88             }
89             else {
90 0           $desc = "zero or more";
91             }
92             }
93 0           my @expected = $self->child->expected($ctx);
94 0           return("($desc of: ", @expected, ")");
95             }
96              
97             sub output {
98 0     0 0   my $self = shift;
99 0           my ( $item, $node, $ctx ) = pos_validated_list(
100             \@_,
101             { isa => 'Object' },
102             { isa => 'XML::LibXML::Element' },
103             { isa => 'PRANG::Graph::Context' },
104             );
105            
106 0           my $attrName = $self->attrName;
107 0           my $val = $item->$attrName;
108 0 0 0       if ( $self->has_max and $self->max == 1 ) {
109              
110             # this is an 'optional'-type thingy
111 0 0         if ( defined $val ) {
112 0           $self->child->output($item,$node,$ctx,value => $val);
113             }
114             }
115             else {
116              
117             # this is an arrayref-type thingy
118 0 0 0       if ( !$val and !$self->has_min ) {
    0 0        
      0        
119              
120             # ok, that's fine
121             }
122             elsif ( $val and (ref($val)||"") ne "ARRAY" ) {
123              
124             # that's not
125 0           die "item $item / slot $attrName is $val, not"
126             ."an ArrayRef";
127             }
128             else {
129 0           for ( my $i = 0; $i <= $#$val; $i++) {
130 0           $ctx->quant_found($i+1);
131 0           $self->child->output(
132             $item,$node,$ctx,
133             value => $val->[$i],
134             slot => $i,
135             );
136             }
137             }
138             }
139             }
140              
141             with 'PRANG::Graph::Node';
142              
143             1;
144              
145             __END__
146              
147             =head1 NAME
148              
149             PRANG::Graph::Quantity - a bounded quantity of graph nodes
150              
151             =head1 SYNOPSIS
152              
153             See L<PRANG::Graph::Meta::Element> source and
154             L<PRANG::Graph::Node> for examples and information.
155              
156             =head1 DESCRIPTION
157              
158             This graph node specifies that the XML graph at this point has a
159             quantity of text nodes, elements or element choices depending on the
160             type of entries in the B<child> property.
161              
162             If the quantity is always 1, that is, the element is required and may
163             only appear one, then the element does not have one of these objects
164             in their graph.
165              
166             =head1 ATTRIBUTES
167              
168             =over
169              
170             =item B<PRANG::Graph::Node child>
171              
172             The B<child> property provides the next portion of the XML Graph.
173             Depending on the type of entry, it will accept and emit nodes in a
174             particular way.
175              
176             Entries must be one of L<PRANG::Graph::Choice>,
177             L<PRANG::Graph::Element>, or L<PRANG::Graph::Text>.
178              
179             =item B<Int min>
180              
181             =item B<Int max>
182              
183             Bounds on the number of times this graph node will match.
184              
185             =item B<attrName>
186              
187             Used when emitting; specifies the method to call to retrieve the item
188             to be output.
189              
190             =back
191              
192             =head1 SEE ALSO
193              
194             L<PRANG::Graph::Meta::Class>, L<PRANG::Graph::Meta::Element>,
195             L<PRANG::Graph::Context>, L<PRANG::Graph::Node>
196              
197             Lower order L<PRANG::Graph::Node> types:
198              
199             L<PRANG::Graph::Choice>, L<PRANG::Graph::Element>,
200             L<PRANG::Graph::Text>
201              
202             =head1 AUTHOR AND LICENCE
203              
204             Development commissioned by NZ Registry Services, and carried out by
205             Catalyst IT - L<http://www.catalyst.net.nz/>
206              
207             Copyright 2009, 2010, NZ Registry Services. This module is licensed
208             under the Artistic License v2.0, which permits relicensing under other
209             Free Software licenses.
210              
211             =cut
212