package UR::Namespace::View::SchemaBrowser::CgiApp;
use strict;
use warnings;
require UR;
our $VERSION = "0.41"; # UR $VERSION;
UR::Object::Type->define(
class_name => 'UR::Namespace::View::SchemaBrowser::CgiApp',
is => 'UR::Object::View',
properties => [
http_server => {},
port => { type => 'integer' },
hostname => { type => 'string' },
data_dir => { type => 'string' },
timeout => { type => 'integer' },
],
);
use File::Temp;
use Sys::Hostname qw();
use Net::HTTPServer;
use Class::Autouse \&dynamically_load_page_class;
sub create {
my($class, %params) = @_;
##$DB::single = 1;
my $port = delete $params{'port'};
my $data_dir = delete $params{'data_dir'};
my $sessions = delete $params{'sessions'};
my $server_type = delete $params{'server_type'};
my $timeout = delete $params{'timeout'};
my $self = $class->SUPER::create(%params);
$data_dir ||= File::Temp::tempdir('schemabrowserXXXXX', CLEANUP => 1);
my $server = Net::HTTPServer->new( chroot => 1,
datadir => $data_dir,
docroot => undef,
index => 'index.html',
ssl => 0,
port => $port || 'scan',
sessions => $sessions || 0,
type => $server_type || 'single',
);
unless ($server) {
$self->error_message("Can't create HTTPServer object: $!");
return;
}
$server->RegisterRegex('.*', sub { $self->render_page(@_) });
$port = $server->Start();
unless ($port) {
$self->error_message("HTTPServer couldn't start: $!");
return;
}
$self->port($port);
$self->data_dir($data_dir);
$self->hostname(Sys::Hostname::hostname());
$self->timeout($timeout);
$self->http_server($server);
return $self;
}
sub show {
my $self = shift;
#$DB::single = 1;
my $server = $self->http_server;
my $timeout = $self->timeout;
our $LAST_PAGE_TIME = time();
while($server->Process($timeout)) {
last if ((time() - $LAST_PAGE_TIME) > $self->timeout);
}
$server->Stop();
return 1;
}
sub render_page {
my $self = shift;
my $req = shift;
#$DB::single = 1;
my $resp = $req->Response;
our $LAST_PAGE_TIME = time;
my($page) = ($req->Path =~ m/\/?(.*)\.html$/);
$page ||= 'Index';
$page = ucfirst $page;
my $page_class = $self->__meta__->class_name . '::' . $page;
our %PAGE_OBJ_CACHE;
my $page_obj = $PAGE_OBJ_CACHE{$page_class} ||= eval { $page_class->new(ur_namespace => $self->subject_class_name) };
if (!$page_obj and $@) {
print "Exception when calling new() on $page_class: $@\n";
$resp->Print("Exception when calling new() on $page_class: $@\n");
$resp->Code(500);
return $resp;
}
my $output;
if ($page_obj) {
$page_obj->request($req);
$page_obj->response($resp);
$output = eval { $page_obj->run() };
if (!$output and $@) {
my $error = $@;
$error =~ s/\n/
/;
$output = "Exception when calling run() on an instance of $page_class: $@";
$resp->Code(500);
} else {
$resp->Code(200);
}
} else {
$output = q(