File Coverage

lib/Hyper/Developer/Server.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package Hyper::Developer::Server;
2              
3 1     1   2262 use strict;
  1         2  
  1         42  
4 1     1   6 use warnings;
  1         1  
  1         40  
5              
6 1     1   6 use base qw(HTTP::Server::Simple::CGI HTTP::Server::Simple::Static);
  1         3  
  1         1022  
7              
8             use File::Basename;
9             use Hyper;
10             use Hyper::Singleton::Context;
11             use Hyper::Template::HTC;
12             use Hyper::Developer::Model::Viewer;
13             use Hyper::Request::Default;
14             use Module::Refresh;
15              
16             use Readonly;
17             Readonly my $PACKAGE => __PACKAGE__;
18              
19             use CGI;
20             use File::Find;
21             use Hyper::Functions;
22              
23             sub new {
24             my $class = shift;
25             my $arg_ref = shift;
26             my $config = delete $arg_ref->{$PACKAGE};
27             my $self = HTTP::Server::Simple::new($class, %{$arg_ref});
28              
29             $self->{$PACKAGE} = {
30             base_path => dirname((caller)[1]) . '/../../',
31             refresh => Module::Refresh->new(),
32             %{$config}
33             };
34              
35             return $self;
36             }
37              
38             sub handler {
39             my $self = shift;
40             my $cgi = CGI->new();
41              
42             { no warnings qw(redefine);
43             $self->{$PACKAGE}->{refresh}->refresh();
44             }
45              
46             # use server's cgi as cgi singleton
47             { no warnings qw(redefine);
48             *Hyper::Singleton::CGI::new
49             = *Hyper::Singleton::CGI::singleton
50             = sub { return $cgi; };
51             *Hyper::Error::_is_eval_context = sub {
52             return $_[3] && $_[3] eq '(eval)';
53             };
54             }
55              
56             print "HTTP/1.0 200 OK\n";
57             eval {
58             my $file = $cgi->path_info();
59             $file =~ s{//}{/}xmsg;
60             my $query_string = $cgi->query_string();
61             my $config = Hyper::Singleton::Context->new({
62             file => $self->{$PACKAGE}->{config_file},
63             })->get_config();
64             my $namespace = $config->get_namespace();
65             my $base_path = $config->get_base_path();
66              
67             if ( ! $file || $file eq '/' ) {
68             $self->_show_index();
69             }
70             elsif ( $file =~ m{/Model/Viewer/([^/]+)/([^/]+)/([^/]+)}xms ) {
71             $self->_model_viewer({
72             namespace => $namespace,
73             type => $1,
74             service => $2,
75             usecase => $3,
76             });
77             }
78             elsif ( $file eq '/cgi-bin/' . (lc $namespace) . '/index.pl' ) {
79             do "$base_path/$file";
80             }
81             else {
82             $self->serve_static($cgi, "$base_path/htdocs/");
83             }
84             Hyper::Request::Default::cleanup();
85             };
86              
87             return;
88             }
89              
90             sub _model_viewer {
91             my $self = shift;
92             my $arg_ref = shift;
93             my $class = "$arg_ref->{namespace}\::Control\::$arg_ref->{type}"
94             . "\::$arg_ref->{service}\::"
95             . ( substr $arg_ref->{type}, 0, 1 )
96             . $arg_ref->{usecase};
97              
98             eval {
99             my $svg = Hyper::Developer::Model::Viewer->new({
100             for_class => $class,
101             })->create_graph()->as_svg();
102             print <<"EOT";
103             content-type:image/svg+xml
104              
105            
106            
107            
108             xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
109             version="1.1" baseProfile="full" width="5000">$svg
110             EOT
111             };
112              
113             return;
114             }
115              
116             sub _show_index {
117             my $self = shift;
118             my $config = Hyper::Singleton::Context->singleton()->get_config();
119             my $namespace = $config->get_namespace();
120             my $base_path = $config->get_base_path();
121              
122             eval {
123             # Child
124             print "content-type:text/html; charset=utf-8\n\n";
125             my @flow_controls;
126             my @container_controls;
127             find(
128             sub {
129             m{.ini\Z} or return;
130             my ($type, $service, $last_part)
131             = (split m{/}, $File::Find::name)[-3..-1];
132             my ($usecase) = $last_part =~ m{(?: F|C)([^\.]+)\.ini}xms;
133              
134             my %value_of = (
135             service => $service,
136             usecase => $usecase,
137             is_broken => do {
138             $last_part =~ s{\.ini\Z}{}xms;
139             eval "use $namespace\::Control\::$type\::$service\::$last_part;";
140             warn "use $namespace\::Control\::$type\::$service\::$last_part;";
141             $@;
142             },
143             );
144              
145             if ( $type eq 'Flow' ) {
146             push @flow_controls, \%value_of;
147             }
148             else {
149             push @container_controls, \%value_of;
150             }
151             },
152             map {
153             "$base_path/etc/$namespace/Control/$_";
154             } qw(Container Flow)
155             );
156             my $template = Hyper::Template::HTC->new(
157             out_fh => 0,
158             for_class => __PACKAGE__,
159             path => [
160             map {
161             $_ . '/' . Hyper::Functions::get_path_for('template');
162             } $config->get_base_path(),
163             Hyper::Functions::get_path_from_file(__FILE__),
164             ]
165             );
166              
167             $template->param(
168             namespace => $namespace,
169             lc_namespace => lc $namespace,
170             flow_controls => \@flow_controls,
171             container_controls => \@container_controls,
172             );
173             print $template->output();
174             };
175              
176             return $self;
177             }
178              
179             1;
180              
181             __END__