Geo-OGC-Service
view release on metacpan or search on metacpan
lib/Geo/OGC/Service.pm view on Meta::CPAN
my $config = shift;
my $had_ref;
do {
$had_ref = 0;
for my $j (keys %$config) {
$had_ref += config_ref($config->{$j}, $config);
}
} while ($had_ref);
for my $j (keys %$config) {
next if $j eq 'Common';
next if $j =~ /^BoundingBox/;
next unless ref $config->{$j} eq 'HASH';
for my $c (keys %{$config->{Common}}) {
$config->{$j}{$c} //= clone($config->{Common}{$c});
}
}
}
sub config_ref {
my ($config, $refs) = @_;
my $had_ref = 0;
if (ref $config eq 'ARRAY') {
for my $j (@$config) {
$had_ref += config_ref($j, $refs);
}
}
elsif (ref $config eq 'HASH') {
for my $j (keys %$config) {
my $r = $config->{$j};
if (ref $r) {
$had_ref += config_ref($r, $refs);
} else {
if ($r =~ /^ref:/) {
my $target = config_target($refs, $r);
croak "config reference not found: '$r'." unless $target;
$config->{$j} = clone($target);
$had_ref = 1;
}
}
}
}
return $had_ref;
}
sub config_target {
my ($config, $ref) = @_;
my @path = split /\//, $ref;
shift @path;
if (ref $config eq 'HASH') {
return $config->{$path[0]};
}
return undef;
}
=pod
=head3 call
This method is called internally by the method to_app of
Plack::Component. The method fails unless this module
is running in a psgi.streaming environment. Otherwise,
it returns a subroutine, which calls the respond method.
=cut
sub call {
my ($self, $env) = @_;
if (! $env->{'psgi.streaming'}) { # after Lyra-Core/lib/Lyra/Trait/Async/PsgiApp.pm
return [ 500, ["Content-Type" => "text/plain"], ["Internal Server Error (Server Implementation Mismatch)"] ];
}
return sub {
my $responder = shift;
$self->respond($responder, $env);
}
}
=pod
=head3 respond
This method is called for each request from the Internet. The call is
responded during the execution of the subroutine.
In the default case this method constructs a new service object using
the method 'service' and calls its process_request method with PSGI
style $responder object as a parameter.
This subroutine may fail while interpreting the request, or while
processing the request.
=cut
sub respond {
my ($self, $responder, $env) = @_;
# TODO: logging
if ($env->{REQUEST_METHOD} eq 'OPTIONS') {
$responder->([200, ['Content-Length' => 0,
'Content-Type' => 'text/plain',
Geo::OGC::Service::Common::CORS($self)]]);
} else {
my $service;
eval {
$service = $self->service($responder, $env);
};
if ($@) {
print STDERR "$@";
error($responder, { exceptionCode => 'ResourceNotFound',
ExceptionText => "Internal error while interpreting the request." } );
} elsif ($service) {
eval {
$service->process_request($responder);
};
if ($@) {
print STDERR "$@";
error($responder, { exceptionCode => 'ResourceNotFound',
ExceptionText => "Internal error while processing the request." } );
}
}
}
}
=pod
=head3 service
This method does a preliminary interpretation of the request and
converts it into a service object, which is returned.
( run in 1.550 second using v1.01-cache-2.11-cpan-140bd7fdf52 )