Apache-AxKit-Provider-XMLDOMProvider
view release on metacpan or search on metacpan
lib/Apache/AxKit/Provider/XMLDOMProvider.pm view on Meta::CPAN
new init process exists mtime get_fh get_strref key get_styles get_ext_ent_handler
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
new init process exists mtime get_fh get_strref key get_styles get_ext_ent_handler
);
our $VERSION = '0.03';
# sub: init
# here we do some initialization stuff.
sub init {
my $self = shift;
my $r = $self->{apache};
my $mtime_element = $r->dir_config('RemoteXMLmTimeElement');
# prepare remote XML
my $url = $r->dir_config('RemoteXML');
# append query if defined
my $query = $r->args();
if ( defined $query ) {
$url .= "?" . $query;
}
# get xml with substitute request
my $ua = LWP::UserAgent->new();
$ua->timeout(10);
my $response = $ua->get($url);
# store some stuff for later use
$self->{response} = $response;
$self->{xmlfile} = $url;
$self->{id} = $url;
$self->{mtime_element} = $mtime_element;
}
# sub: get_fh
# we don't want to handle files, so we just throw an exception here.
sub get_fh {
throw Apache::AxKit::Exception::IO( -text => "Can't get filehandle for XMLDOMProvider (not yet implemented)!" );
}
# sub: get_strref
# since we refused to work with file handles, we HAVE to define this.
# returns a string containing the remote XML-DOM
sub get_strref {
my $self = shift;
my $response = $self->{response};
my $string = $response->content();
# debug
#my $h = $response->server;
#throw Apache::AxKit::Exception::Error(-text => "Last Modified Header: \"$h\"");
# some XML validation
my $parser = XML::LibXML->new();
$parser->validation(0);
$parser->load_ext_dtd(0);
$parser->expand_xinclude(0);
$parser->expand_entities(0);
my $dom;
eval {
$dom = $parser->parse_string($string);
};
if ($@) {
throw Apache::AxKit::Exception::Error( -text => "Input must be well-formed XML: $@" );
}
# if everything went fine, return xml-string-reference
return \$string;
}
# sub: mtime
# we want to cache our stuff; the mtime is determined
# from the mdate (YYYY-MM-DD hh:mm) element "<mdate></mdate>" placed
# somewhere in the remote XML-DOM;
# CAUTION: do not provide multiple mdate elements in one single XML-DOM;
# if mdate is not provided, we refuse to cache
sub mtime {
my $self = shift;
my $mtime_element = $self->{mtime_element};
# debug
#print STDERR Dumper( $self->{id} );
# return cached mtime, if this is the second call per request
return $self->{mtime}->{$self->{id}} if defined $self->{mtime}->{$self->{id}};
# mtime stuff
# twiggle out mdate from string-content
$self->{response}->content() =~ m/.*\<$mtime_element\>([^\<]*)\<\/$mtime_element\>/;
my $mdate = $1;
# debug
#print STDERR Dumper( "mdate: ", $mdate );
my $mtime;
# test if $mdate is provided in xml-dom
if ( defined $mdate ) {
# create time-piece object
# mdate format example: 2007-06-26 02:42
my $time_obj = Time::Piece->strptime( $mdate, "%Y-%m-%d %H:%M" );
$mtime = $time_obj->epoch();
# debug
#print STDERR Dumper( "mtime in secs: ", $mtime );
}
else {
# else invalidate cache
$mtime = time();
# debug
#print STDERR Dumper("now: ", $mtime );
}
# cache mtime, since mtime is called twice per request
$self->{mtime}->{$self->{id}} = $mtime;
# debug
( run in 1.467 second using v1.01-cache-2.11-cpan-5b529ec07f3 )