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   46 use Badger::Debug ':dump';
  7         10  
  7         41  
4 7     7   2785 use Badger::Config::Item;
  7         24  
  7         462  
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   54 };
  7         11  
26              
27             sub init {
28 21     21 1 54 my ($self, $config) = @_;
29 21         59 $self->init_schema($config);
30 21         39 return $self;
31             }
32              
33             sub init_schema {
34 21     21 0 35 my ($self, $config) = @_;
35 21         38 my $iclass = $self->CONFIG_ITEM;
36 21         29 my ($name, $info, @aka, $fallback, $test, $item);
37              
38 21   66     49 my $fall = $config->{ fallback } || $self;
39 21         71 my $list = $self->{ items } = [ ];
40 21         43 my $hash = $self->{ item } = { };
41              
42 21         29 my $schema = $config->{ schema };
43 21         33 my $extend = $config->{ extend };
44              
45 21         25 $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         22 $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       70 my $k = $_;
  6         12  
63 6         7 my $v = $schema->{ $k };
64 6 50       38 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       83 $schema = [ @$schema, $extend ? @$extend : () ];
72              
73 21         28 $self->debug("Canonical schema config: ", $self->dump_data($schema))
74             if DEBUG;
75              
76 21         51 while (@$schema) {
77 75         99 $name = shift @$schema;
78 75         88 $item = undef;
79 75         94 $info = undef;
80              
81             # TODO: not sure about this - we change the name....
82             # skip anything we've already done
83              
84 75         85 $self->debug("schema item: $name\n") if DEBUG;
85              
86 75 100       195 if (ref $name eq HASH) {
    100          
87 7         7 $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         18 $item = $name;
93 15         24 $name = $item->name;
94             }
95             else {
96 53         110 $info = { name => $name };
97             }
98 75         91 $self->debug("name: $name info: $info") if DEBUG;
99              
100 75   33     286 $info->{ fallback_provider } ||= $fall;
101              
102 75   66     321 $item ||= $self->CONFIG_ITEM->new($info);
103 75         147 $name = $item->name;
104              
105 75 100       160 next if $hash->{ $name };
106              
107 72         89 $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         86 $self->debug("adding $name => $item to schema") if DEBUG;
115 72         146 push(@$list, $item);
116             }
117              
118 21         24 $self->debug("created schema: ", $self->dump_data($self->{ items }))
119             if DEBUG;
120              
121 21         48 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         58 my ($element, $name, $alias, $code, @args, $ok, $value);
135              
136 38   33     82 $class ||= $target;
137              
138 38         45 $self->debug("configure(", CLASS->dump_data_inline($config), ')') if DEBUG;
139 38         41 $self->debug("configure element: ", CLASS->dump_data($items)) if DEBUG;
140              
141 38         76 ELEMENT: foreach $element (@$items) {
142 275 100       587 $element->try->configure($config, $target, $class)
143             || return $self->decline($element->reason);
144             }
145              
146 37         123 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 26 my $self = shift;
160 20         28 my $items = $self->{ items };
161             return wantarray
162 20 50       42 ? @$items
163             : $items;
164              
165              
166             }
167              
168             1;