File Coverage

blib/lib/POE/Component/WebService/Validator/CSS/W3C.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package POE::Component::WebService::Validator::CSS::W3C;
2              
3 2     2   522317 use warnings;
  2         4  
  2         80  
4 2     2   10 use strict;
  2         4  
  2         91  
5              
6             our $VERSION = '1.001004'; # VERSION
7              
8 2     2   10 use Carp;
  2         4  
  2         141  
9 2     2   896 use URI;
  2         7992  
  2         63  
10 2     2   1332 use LWP::UserAgent;
  2         46006  
  2         63  
11 2     2   1053 use WebService::Validator::CSS::W3C;
  0            
  0            
12             use POE qw( Wheel::Run Filter::Reference Filter::Line );
13              
14             sub spawn {
15             my $package = shift;
16             croak "$package requires an even number of arguments"
17             if @_ & 1;
18              
19             my %params = @_;
20              
21             $params{ lc $_ } = delete $params{ $_ } for keys %params;
22              
23             delete $params{options}
24             unless ref $params{options} eq 'HASH';
25              
26             # fill in defaults
27             %params = (
28             ua => LWP::UserAgent->new( timeout => 30 ),
29             val_uri => 'http://jigsaw.w3.org/css-validator/validator',
30              
31             %params,
32             );
33              
34             my $self = bless \%params, $package;
35              
36             $self->{session_id} = POE::Session->create(
37             object_states => [
38             $self => {
39             validate => '_validate',
40             shutdown => '_shutdown',
41             },
42             $self => [
43             qw(
44             _child_error
45             _child_closed
46             _child_stdout
47             _child_stderr
48             _sig_child
49             _start
50             )
51             ]
52             ],
53             ( defined $params{options} ? ( options => $params{options} ) : () ),
54             )->ID();
55              
56             return $self;
57             }
58              
59             sub _start {
60             my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
61             $self->{session_id} = $_[SESSION]->ID();
62              
63             if ( $self->{alias} ) {
64             $kernel->alias_set( $self->{alias} );
65             }
66             else {
67             $kernel->refcount_increment( $self->{session_id} => __PACKAGE__ );
68             }
69              
70             $self->{wheel} = POE::Wheel::Run->new(
71             Program => sub { _val_wheel( @$self{ qw(ua val_uri) } ); },
72             ErrorEvent => '_child_error',
73             CloseEvent => '_child_close',
74             StdoutEvent => '_child_stdout',
75             StderrEvent => '_child_stderr',
76             StdioFilter => POE::Filter::Reference->new,
77             StderrFilter => POE::Filter::Line->new,
78             ( $^O eq 'MSWin32' ? ( CloseOnCall => 0 ) : ( CloseOnCall => 1 ) )
79             );
80              
81             $kernel->yield('shutdown')
82             unless $self->{wheel};
83              
84             $kernel->sig_child( $self->{wheel}->PID(), '_sig_child' );
85              
86             undef;
87             }
88              
89             sub _sig_child {
90             $poe_kernel->sig_handled;
91             }
92              
93             sub session_id {
94             return $_[0]->{session_id};
95             }
96              
97             sub validate {
98             my $self = shift;
99             $poe_kernel->post( $self->{session_id} => 'validate' => @_ );
100             }
101              
102             sub _validate {
103             my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
104             my $sender = $_[SENDER]->ID;
105              
106             return
107             if $self->{shutdown};
108              
109             my $args;
110             if ( ref $_[ARG0] eq 'HASH' ) {
111             $args = { %{ $_[ARG0] } };
112             }
113             else {
114             warn "First parameter must be a hashref, trying to adjust...";
115             $args = { @_[ARG0 .. $#_] };
116             }
117              
118             $args->{ lc $_ } = delete $args->{ $_ }
119             for grep { !/^_/ } keys %{ $args };
120              
121             unless ( $args->{event} ) {
122             carp "Missing 'event' parameter to validate()";
123             return;
124             }
125              
126             if ( !exists $args->{uri} and !exists $args->{string} ) {
127             carp "Must specify either `uri` or `string` validate()";
128             return;
129             }
130              
131             $args->{params}{ $_ } = $args->{ $_ }
132             for ( qw( string uri medium profile warnings language ) );
133              
134             if ( $args->{session} ) {
135             if ( my $ref = $kernel->alias_resolve( $args->{session} ) ) {
136             $args->{sender} = $ref->ID;
137             }
138             else {
139             carp "Could not resolve 'session' parameter to a valid"
140             . " POE session";
141             return;
142             }
143             }
144             else {
145             $args->{sender} = $sender;
146             }
147              
148             $kernel->refcount_increment( $args->{sender} => __PACKAGE__ );
149             $self->{wheel}->put( $args );
150              
151             undef;
152             }
153              
154             sub shutdown {
155             my $self = shift;
156             $poe_kernel->call( $self->{session_id} => 'shutdown' => @_ );
157             }
158              
159             sub _shutdown {
160             my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
161             $kernel->alarm_remove_all;
162             $kernel->alias_remove( $_ ) for $kernel->alias_list;
163             $kernel->refcount_decrement( $self->{session_id} => __PACKAGE__ )
164             unless $self->{alias};
165              
166             $self->{shutdown} = 1;
167              
168             $self->{wheel}->shutdown_stdin
169             if $self->{wheel};
170             }
171              
172             sub _child_closed {
173             my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
174              
175             warn "_child_closed called (@_[ARG0..$#_])\n"
176             if $self->{debug};
177              
178             delete $self->{wheel};
179             $kernel->yield('shutdown')
180             unless $self->{shutdown};
181              
182             undef;
183             }
184              
185             sub _child_error {
186             my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
187             warn "_child_error called: (@_[ARG0..$#_])\n"
188             if $self->{debug};
189              
190             delete $self->{wheel};
191             $kernel->yield('shutdown')
192             unless $self->{shutdown};
193              
194             undef;
195             }
196              
197             sub _child_stderr {
198             my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
199             warn "_child_stderr: $_[ARG0]\n"
200             if $self->{debug};
201              
202             undef;
203             }
204              
205             sub _child_stdout {
206             my ( $kernel, $self, $input ) = @_[ KERNEL, OBJECT, ARG0 ];
207              
208             my $session = delete $input->{sender};
209             my $event = delete $input->{event};
210             delete $input->{params};
211              
212             $kernel->post( $session, $event, $input );
213             $kernel->refcount_decrement( $session => __PACKAGE__ );
214              
215             undef;
216             }
217              
218             sub _val_wheel {
219             my ( $val_ua, $val_uri ) = @_;
220              
221             if ( $^O eq 'MSWin32' ) {
222             binmode STDIN;
223             binmode STDOUT;
224             }
225              
226             my $raw;
227             my $size = 4096;
228             my $filter = POE::Filter::Reference->new;
229              
230             while ( sysread STDIN, $raw, $size ) {
231             my $requests = $filter->get( [ $raw ] );
232             foreach my $req_ref ( @$requests ) {
233              
234             # changes $req_ref
235             _prepare_results( $req_ref, $val_ua, $val_uri );
236              
237             my $response = $filter->put( [ $req_ref ] );
238             print STDOUT @$response;
239             }
240             }
241             }
242              
243             sub _prepare_results {
244             my ( $req_ref, $val_ua, $val_uri ) = @_;
245              
246             my $val = WebService::Validator::CSS::W3C->new( $val_ua, $val_uri );
247              
248             @$req_ref{
249             qw(
250             result
251             is_valid
252             num_errors
253             errors
254             num_warnings
255             warnings
256             val_uri
257             http_response
258             request_uri
259             som
260             )
261             }
262             = (
263             $val->validate( %{ $req_ref->{params} || {} } ),
264             $val->is_valid,
265             scalar $val->errorcount,
266             [ $val->errors ],
267             scalar $val->warningcount,
268             [ $val->warnings ],
269             $val->validator_uri,
270             $val->response,
271             $val->request_uri,
272             $val->som,
273             );
274             unless ( $req_ref->{result} ) {
275             delete $req_ref->{result};
276             $req_ref->{request_error} = $req_ref->{http_response}->status_line;
277             }
278              
279             my $refer_to_uri = URI->new( $req_ref->{request_uri} );
280              
281             my %refer_to_params = $refer_to_uri->query_form;
282             delete $refer_to_params{output};
283             $refer_to_uri->query_form( %refer_to_params );
284              
285             $req_ref->{refer_to_uri} = $refer_to_uri;
286              
287             undef;
288             }
289              
290             1;
291              
292             __END__