File Coverage

blib/lib/Log/Report/Domain.pm
Criterion Covered Total %
statement 50 94 53.1
branch 8 44 18.1
condition 7 18 38.8
subroutine 13 20 65.0
pod 9 10 90.0
total 87 186 46.7


line stmt bran cond sub pod time code
1             # Copyrights 2007-2017 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.02.
5 13     13   70 use warnings;
  13         21  
  13         360  
6 13     13   55 use strict;
  13         19  
  13         296  
7              
8             package Log::Report::Domain;
9 13     13   49 use vars '$VERSION';
  13         20  
  13         553  
10             $VERSION = '1.22';
11              
12 13     13   77 use base 'Log::Report::Minimal::Domain';
  13         21  
  13         3358  
13              
14 13     13   6588 use Log::Report 'log-report';
  13         24  
  13         134  
15 13     13   70 use Log::Report::Util qw/parse_locale/;
  13         30  
  13         687  
16 13     13   67 use Scalar::Util qw/blessed/;
  13         18  
  13         479  
17              
18 13     13   2936 use Log::Report::Translator;
  13         26  
  13         10899  
19              
20              
21             sub init($)
22 7     7 0 59 { my ($self, $args) = @_;
23 7         40 $self->SUPER::init($args);
24 7         65 $self->{LRD_ctxt_def} = {};
25 7         23 $self;
26             }
27              
28             #----------------
29              
30 10     10 1 25 sub nativeLanguage() {shift->{LRD_native}}
31 94     94 1 225 sub translator() {shift->{LRD_transl}}
32 0     0 1 0 sub contextRules() {shift->{LRD_ctxt_rules}}
33              
34             #----------------
35              
36             sub configure(%)
37 7     7 1 24 { my ($self, %args) = @_;
38              
39 7 50       23 if(my $config = delete $args{config})
40 0         0 { my $set = $self->readConfig($config);
41 0         0 %args = (%$set, %args);
42             }
43              
44             # 'formatter' is mainly handled by the base-class, but documented here.
45 7   50     34 my $format = $args{formatter} || 'PRINTI';
46 7 50       34 $args{formatter} = $format = {} if $format eq 'PRINTI';
47              
48 7 50       27 if(ref $format eq 'HASH')
49 7     0   34 { $format->{missing_key} = sub {$self->_reportMissingKey(@_)};
  0         0  
50             }
51              
52 7         53 $self->SUPER::configure(%args);
53              
54 7   33     532 my $transl = $args{translator} || Log::Report::Translator->new;
55 7 50       29 $transl = Log::Report::Translator->new(%$transl)
56             if ref $transl eq 'HASH';
57              
58 7 50 33     87 !blessed $transl || $transl->isa('Log::Report::Translator')
59             or panic "translator must be a Log::Report::Translator object";
60 7         20 $self->{LRD_transl} = $transl;
61              
62             my $native = $self->{LRD_native}
63 7   50     32 = $args{native_language} || 'en_US';
64              
65 7         40 my ($lang) = parse_locale $native;
66 7 50       266 defined $lang
67             or error __x"the native_language '{locale}' is not a valid locale"
68             , locale => $native;
69              
70 7 50       24 if(my $cr = $args{context_rules})
71 0         0 { my $tc = 'Log::Report::Translator::Context';
72 0 0       0 eval "require $tc"; panic $@ if $@;
  0         0  
73 0 0       0 if(blessed $cr)
    0          
74 0 0       0 { $cr->isa($tc) or panic "context_rules must be a $tc" }
75             elsif(ref $cr eq 'HASH')
76 0         0 { $cr = Log::Report::Translator::Context->new(rules => $cr) }
77             else
78 0         0 { panic "context_rules expects object or hash, not {have}", have=>$cr;
79             }
80              
81 0         0 $self->{LRD_ctxt_rules} = $cr;
82             }
83              
84 7         26 $self;
85             }
86              
87             sub _reportMissingKey($$)
88 0     0   0 { my ($self, $sp, $key, $args) = @_;
89              
90             warning
91             __x"Missing key '{key}' in format '{format}', file {use}"
92             , key => $key, format => $args->{_format}
93 0         0 , use => $args->{_use};
94              
95 0         0 undef;
96             }
97              
98              
99             sub setContext(@)
100 0     0 1 0 { my $self = shift;
101 0 0       0 my $cr = $self->contextRules # ignore context if no rules given
102             or error __x"you need to configure context_rules before setContext";
103              
104 0         0 $self->{LRD_ctxt_def} = $cr->needDecode(set => @_);
105             }
106              
107              
108             sub updateContext(@)
109 0     0 1 0 { my $self = shift;
110 0 0       0 my $cr = $self->contextRules # ignore context if no rules given
111             or return;
112              
113 0         0 my $rules = $cr->needDecode(update => @_);
114 0   0     0 my $r = $self->{LRD_ctxt_def} ||= {};
115 0         0 @{$r}{keys %$r} = values %$r;
  0         0  
116 0         0 $r;
117             }
118              
119              
120 0     0 1 0 sub defaultContext() { shift->{LRD_ctxt_def} }
121              
122              
123             sub readConfig($)
124 0     0 1 0 { my ($self, $fn) = @_;
125 0         0 my $config;
126              
127 0 0       0 if($fn =~ m/\.pl$/i)
    0          
128 0         0 { $config = do $fn;
129             }
130             elsif($fn =~ m/\.json$/i)
131 0 0       0 { eval "require JSON"; panic $@ if $@;
  0         0  
132 0 0       0 open my($fh), '<:encoding(utf8)', $fn
133             or fault __x"cannot open JSON file for context at {fn}"
134             , fn => $fn;
135 0         0 local $/;
136 0         0 $config = JSON->utf8->decode(<$fh>);
137             }
138             else
139 0         0 { error __x"unsupported context file type for {fn}", fn => $fn;
140             }
141              
142 0         0 $config;
143             }
144              
145             #-------------------
146              
147             sub translate($$)
148 87     87 1 154 { my ($self, $msg, $lang) = @_;
149 87   66     136 my $tr = $self->translator || $self->configure->translator;
150 87         161 my $msgid = $msg->msgid;
151              
152             # fast route when certainly no context is involved
153 87 50 33     272 return $tr->translate($msg, $lang) || $msgid
154             if index($msgid, '<') == -1;
155              
156 0           my $msgctxt;
157 0 0         if($msgctxt = $msg->msgctxt)
    0          
158             { # msgctxt in traditional gettext style
159             }
160             elsif(my $rules = $self->contextRules)
161 0           { ($msgid, $msgctxt)
162             = $rules->ctxtFor($msg, $lang, $self->defaultContext);
163             }
164             else
165 0           { 1 while $msgid =~
166 0 0         s/\{([^}]*)\<\w+([^}]*)\}/length "$1$2" ? "{$1$2}" : ''/e;
167             }
168              
169             # This is ugly, horrible and worse... but I do not want to mutulate
170             # the message neither to clone it for performance. We do need to get
171             # rit of {<}
172 0           local $msg->{_msgid} = $msgid;
173 0 0         $tr->translate($msg, $lang, $msgctxt) || $msgid;
174             }
175              
176             1;
177              
178             __END__