package Graph::Template::Factory;
use strict;
BEGIN {
use vars qw(%Manifest %isBuildable);
}
%Manifest = (
# These are the instantiable nodes
# 'IF' => 'Graph::Template::Container::Conditional',
# 'LOOP' => 'Graph::Template::Container::Loop',
'DATA' => 'Graph::Template::Container::Data',
'GRAPH' => 'Graph::Template::Container::Graph',
'SCOPE' => 'Graph::Template::Container::Scope',
'DATAPOINT' => 'Graph::Template::Element::DataPoint',
'TITLE' => 'Graph::Template::Element::Title',
'VAR' => 'Graph::Template::Element::Var',
'XLABEL' => 'Graph::Template::Element::XLabel',
'YLABEL' => 'Graph::Template::Element::YLabel',
# 'FONT' => 'Graph::Template::Container::Font',
# These are the helper objects
'CONTEXT' => 'Graph::Template::Context',
'ITERATOR' => 'Graph::Template::Iterator',
'TEXTOBJECT' => 'Graph::Template::TextObject',
'CONTAINER' => 'Graph::Template::Container',
'ELEMENT' => 'Graph::Template::Element',
'BASE' => 'Graph::Template::Base',
);
while (my ($k, $v) = each %Manifest)
{
(my $n = $v) =~ s!::!/!g;
$n .= '.pm';
$Manifest{$k} = {
package => $v,
filename => $n,
};
}
%isBuildable = map { $_ => undef } qw(
DATA
DATAPOINT
GRAPH
SCOPE
TITLE
VAR
XLABEL
YLABEL
);
sub register
{
my %params = @_;
my @param_names = qw(name class isa);
for (@param_names)
{
unless ($params{$_})
{
warn "$_ was not supplied to register()\n";
return 0;
}
}
my $name = uc $params{name};
if (exists $Manifest{$name})
{
warn "$params{name} already exists in the manifest.\n";
return 0;
}
my $isa = uc $params{isa};
unless (exists $Manifest{$isa})
{
warn "$params{isa} does not exist in the manifest.\n";
return 0;
}
$Manifest{$name} = $params{class};
$isBuildable{$name} = undef;
{
no strict 'refs';
unshift @{"$params{class}::ISA"}, $Manifest{$isa};
}
return 1;
}
sub create
{
my $class = shift;
my $name = uc shift;
return unless exists $Manifest{$name};
eval {
require $Manifest{$name}{filename};
}; if ($@) {
print "$@\n";
die "Cannot find PM file for '$name' ($Manifest{$name}{filename})\n";
}
return $Manifest{$name}{package}->new(@_);
}
sub create_node
{
my $class = shift;
my $name = uc shift;
return unless exists $isBuildable{$name};
return $class->create($name, @_);
}
sub isa
{
return unless @_ >= 2;
exists $Manifest{uc $_[1]}
? UNIVERSAL::isa($_[0], $Manifest{uc $_[1]}{package})
: UNIVERSAL::isa(@_)
}
1;
__END__