File Coverage

lib/Badger/Config/Schema.pm
Criterion Covered Total %
statement 63 68 92.6
branch 14 18 77.7
condition 7 14 50.0
subroutine 7 9 77.7
pod 1 6 16.6
total 92 115 80.0


line stmt bran cond sub pod time code
1             package Badger::Config::Schema;
2              
3 7     7   48 use Badger::Debug ':dump';
  7         13  
  7         42  
4 7     7   2933 use Badger::Config::Item;
  7         15  
  7         436  
5             use Badger::Class
6 7         63 version => 0.01,
7             debug => 0,
8             base => 'Badger::Base',
9             import => 'class CLASS',
10             words => 'CONFIG_SCHEMA',
11             utils => 'is_object',
12             # accessors => 'items',
13             constants => 'HASH ARRAY DELIMITER',
14             constant => {
15             CONFIG_METHOD => 'configure',
16             CONFIG_ITEM => 'Badger::Config::Item',
17             VALUE => 1,
18             NOTHING => 0,
19             },
20             messages => {
21             bad_type => 'Invalid type prefix specified for %s: %s',
22             bad_method => 'Missing method for the %s %s configuration item: %s',
23             dup_item => 'Duplicate specification for scheme item: %s',
24             bad_fallback => 'Invalid fallback item specified for %s: %s',
25 7     7   62 };
  7         16  
26              
27             sub init {
28 21     21 1 40 my ($self, $config) = @_;
29 21         49 $self->init_schema($config);
30 21         34 return $self;
31             }
32              
33             sub init_schema {
34 21     21 0 29 my ($self, $config) = @_;
35 21         42 my $iclass = $self->CONFIG_ITEM;
36 21         43 my ($name, $info, @aka, $fallback, $test, $item);
37              
38 21   66     52 my $fall = $config->{ fallback } || $self;
39 21         62 my $list = $self->{ items } = [ ];
40 21         37 my $hash = $self->{ item } = { };
41              
42 21         33 my $schema = $config->{ schema };
43 21         26 my $extend = $config->{ extend };
44              
45 21         23 $self->debug("fallback is $fall") if DEBUG;
46             # allow target class to be specified so we can resolve things like
47             # package variables later
48             # $self->{ class } = $config->{ class } || $config->{ target };
49              
50             # $self->debug("extending on from ", $self->dump_data($extend));
51              
52 21         83 $self->debug("Generating schema from config: ", $self->dump_data($config))
53             if DEBUG;
54              
55             # We allow a scheme to be specified as a list reference in case the
56             # order of evaluation is important. For convenience, we also accept
57             # a hash ref for a schema specification where the order isn't important.
58             # The values in the hash array can themselves be hash references or
59             # simple values which we assume is the default value.
60             $schema = [
61             map {
62 21 100       81 my $k = $_;
  6         7  
63 6         7 my $v = $schema->{ $k };
64 6 50       30 ref $v eq HASH
65             ? { name => $k, %$v }
66             : { name => $k, default => $v }
67             }
68             keys %$schema
69             ] if ref $schema eq HASH;
70              
71 21 100       74 $schema = [ @$schema, $extend ? @$extend : () ];
72              
73 21         31 $self->debug("Canonical schema config: ", $self->dump_data($schema))
74             if DEBUG;
75              
76 21         53 while (@$schema) {
77 75         106 $name = shift @$schema;
78 75         87 $item = undef;
79 75         107 $info = undef;
80              
81             # TODO: not sure about this - we change the name....
82             # skip anything we've already done
83              
84 75         86 $self->debug("schema item: $name\n") if DEBUG;
85              
86 75 100       210 if (ref $name eq HASH) {
    100          
87 7         9 $info = $name;
88             $name = $info->{ name }
89 7   50     16 || return $self->error("Invalid hash (no name): ", $self->dump_data($info));
90             }
91             elsif (is_object(CONFIG_ITEM, $name)) {
92 15         19 $item = $name;
93 15         23 $name = $item->name;
94             }
95             else {
96 53         98 $info = { name => $name };
97             }
98 75         127 $self->debug("name: $name info: $info") if DEBUG;
99              
100 75   33     259 $info->{ fallback_provider } ||= $fall;
101              
102 75   66     301 $item ||= $self->CONFIG_ITEM->new($info);
103 75         158 $name = $item->name;
104              
105 75 100       158 next if $hash->{ $name };
106              
107 72         78 $self->debug("generated item: $item") if DEBUG;
108              
109 72         123 foreach my $alias ($item->names) {
110             # return $self->error_msg( dup_item => $name )
111             # if $hash->{ $name };
112 98         197 $hash->{ $alias } = $item;
113             }
114 72         80 $self->debug("adding $name => $item to schema") if DEBUG;
115 72         157 push(@$list, $item);
116             }
117              
118 21         38 $self->debug("created schema: ", $self->dump_data($self->{ items }))
119             if DEBUG;
120              
121 21         54 return $self;
122             }
123              
124              
125             sub fallback {
126 0     0 0 0 my ($self, $name, $type, $data) = @_;
127 0         0 return $self->error_msg( bad_fallback => $name, $type );
128             }
129              
130              
131             sub configure {
132 38     38 0 85 my ($self, $config, $target, $class) = @_;
133 38         84 my $items = $self->{ items };
134 38         68 my ($element, $name, $alias, $code, @args, $ok, $value);
135              
136 38   33     65 $class ||= $target;
137              
138 38         46 $self->debug("configure(", CLASS->dump_data_inline($config), ')') if DEBUG;
139 38         48 $self->debug("configure element: ", CLASS->dump_data($items)) if DEBUG;
140              
141 38         74 ELEMENT: foreach $element (@$items) {
142 275 100       576 $element->try->configure($config, $target, $class)
143             || return $self->decline($element->reason);
144             }
145              
146 37         111 return $self;
147             }
148              
149              
150             sub item {
151 0     0 0 0 my $self = shift;
152 0         0 my $item = $self->{ item };
153             return @_
154 0 0       0 ? $item->{ $_[0] }
155             : $item;
156             }
157              
158             sub items {
159 20     20 0 29 my $self = shift;
160 20         24 my $items = $self->{ items };
161             return wantarray
162 20 50       47 ? @$items
163             : $items;
164              
165              
166             }
167              
168             1;