# $Id$
package XML::Atom::Thing;
use strict;
use base qw( XML::Atom::Base );
use XML::Atom;
use base qw( XML::Atom::ErrorHandler );
use XML::Atom::Util qw( first nodelist childlist create_element );
use XML::Atom::Category;
use XML::Atom::Link;
use LWP::UserAgent;
BEGIN {
if (LIBXML) {
*init = \&init_libxml;
} else {
*init = \&init_xpath;
}
}
sub init_libxml {
my $atom = shift;
my %param = @_ == 1 ? (Stream => $_[0]) : @_;
if (my $stream = delete $param{Stream}) {
my $parser = delete $param{Parser} || XML::Atom->libxml_parser;
my $doc;
if (ref($stream) eq 'SCALAR') {
$doc = $parser->parse_string($$stream);
} elsif (ref($stream)) {
$doc = $parser->parse_fh($stream);
} else {
$doc = $parser->parse_file($stream);
}
$param{Elem} = $doc->getDocumentElement;
} elsif (my $doc = delete $param{Doc}) {
$param{Elem} = $doc->getDocumentElement;
}
$atom->SUPER::init(%param);
$atom->fixup_ns;
return $atom;
}
sub fixup_ns {
my $obj = shift;
$obj->{ns} = $obj->elem->namespaceURI;
}
sub init_xpath {
my $atom = shift;
my %param = @_ == 1 ? (Stream => $_[0]) : @_;
my $elem_name = $atom->element_name;
if (my $stream = delete $param{Stream}) {
my $parser = delete $param{Parser} || XML::Atom->expat_parser;
my $xp;
if (ref($stream) eq 'SCALAR') {
$xp = XML::XPath->new(xml => $$stream, parser => $parser);
} elsif (ref($stream)) {
$xp = XML::XPath->new(ioref => $stream, parser => $parser);
} else {
$xp = XML::XPath->new(filename => $stream, parser => $parser);
}
my $set = $xp->find('/' . $elem_name);
unless ($set && $set->size) {
$set = $xp->find('/');
}
$param{Elem} = ($set->get_nodelist)[0];
} elsif (my $doc = delete $param{Doc}) {
$param{Elem} = $doc;
} elsif (my $elem = $param{Elem}) {
my $xp = XML::XPath->new(context => $elem);
my $set = $xp->find('/' . $elem_name);
unless ($set && $set->size) {
$set = $xp->find('/');
}
$param{Elem} = ($set->get_nodelist)[0];
}
$atom->SUPER::init(%param);
$atom;
}
sub set {
my $atom = shift;
my($ns, $name, $val, $attr, $add) = @_;
if (ref($val) =~ /Element$/) {
$atom->elem->appendChild($val);
return $val;
} else {
return $atom->SUPER::set(@_);
}
}
# common elements
__PACKAGE__->mk_elem_accessors(qw( icon id logo title )); # updated & rights are in renamed
# common multiple elements
__PACKAGE__->mk_object_list_accessor('link' => 'XML::Atom::Link', 'links');
__PACKAGE__->mk_object_list_accessor('category' => 'XML::Atom::Category', 'categories');
__PACKAGE__->mk_object_list_accessor('author' => 'XML::Atom::Person', 'authors');
__PACKAGE__->mk_object_list_accessor('contributor' => 'XML::Atom::Person', 'contributors');
__PACKAGE__->_rename_elements('copyright' => 'rights');
# 0.3 -> 1.0 elements aliasing
sub _rename_elements {
my($class, $atom03, $atom10) = @_;
no strict 'refs';
*{"$class\::$atom03"} = sub {
my $self = shift;
if ($self->version eq "1.0") {
return $self->$atom10(@_);
}
@_ > 0 ? $self->set($self->ns, $atom03, @_) : $self->get($self->ns, $atom03);
};
*{"$class\::$atom10"} = sub {
my $self = shift;
if ($self->version eq "0.3") {
return $self->$atom03(@_);
}
@_ > 0 ? $self->set($self->ns, $atom10, @_) : $self->get($self->ns, $atom10);
};
}
1;