Added new tests, fixed a bug, and cleaned up more code: Intermediate check-in
[p5sagit/Excel-Template.git] / lib / Excel / Template / Factory.pm
CommitLineData
d0eafc11 1package Excel::Template::Factory;
2
3use strict;
4
d01e4722 5my %Manifest = (
d0eafc11 6
7# These are the instantiable nodes
8 'IF' => 'Excel::Template::Container::Conditional',
9 'LOOP' => 'Excel::Template::Container::Loop',
10 'ROW' => 'Excel::Template::Container::Row',
11 'SCOPE' => 'Excel::Template::Container::Scope',
12 'WORKBOOK' => 'Excel::Template::Container::Workbook',
13 'WORKSHEET' => 'Excel::Template::Container::Worksheet',
14
37513eae 15 'BACKREF' => 'Excel::Template::Element::Backref',
d0eafc11 16 'CELL' => 'Excel::Template::Element::Cell',
17 'FORMULA' => 'Excel::Template::Element::Formula',
37513eae 18 'RANGE' => 'Excel::Template::Element::Range',
d0eafc11 19 'VAR' => 'Excel::Template::Element::Var',
20
21 'FORMAT' => 'Excel::Template::Container::Format',
22
23# These are all the Format short-cut objects
37513eae 24# They are also instantiable
d0eafc11 25 'BOLD' => 'Excel::Template::Container::Bold',
26 'HIDDEN' => 'Excel::Template::Container::Hidden',
27 'ITALIC' => 'Excel::Template::Container::Italic',
28 'LOCKED' => 'Excel::Template::Container::Locked',
29 'OUTLINE' => 'Excel::Template::Container::Outline',
30 'SHADOW' => 'Excel::Template::Container::Shadow',
31 'STRIKEOUT' => 'Excel::Template::Container::Strikeout',
32
33# These are the helper objects
37513eae 34# They are also in here to make E::T::Factory::isa() work.
d0eafc11 35 'CONTEXT' => 'Excel::Template::Context',
36 'ITERATOR' => 'Excel::Template::Iterator',
37 'TEXTOBJECT' => 'Excel::Template::TextObject',
38
39 'CONTAINER' => 'Excel::Template::Container',
40 'ELEMENT' => 'Excel::Template::Element',
41
42 'BASE' => 'Excel::Template::Base',
43);
44
d01e4722 45my %isBuildable = map { $_ => ~~1 } qw(
46 WORKBOOK WORKSHEET
47 FORMAT BOLD HIDDEN ITALIC LOCKED OUTLINE SHADOW STRIKEOUT
48 IF ROW LOOP SCOPE
49 CELL FORMULA
50 VAR BACKREF RANGE
d0eafc11 51);
52
d0eafc11 53{
d01e4722 54 my %Loaded;
55 sub _load_class
56 {
57 my $self = shift;
58 my ($class) = @_;
59
60 unless ( exists $Loaded{$class} )
61 {
62 (my $filename = $class) =~ s!::!/!g;
63 eval {
64 require "$filename.pm";
65 }; if ($@) {
66 die "Cannot find or compile PM file for '$class' ($filename)\n";
67 }
68
69 $Loaded{$class} = ~~1;
70 }
e976988f 71
d01e4722 72 return ~~1;
73 }
e976988f 74}
75
76{
d0eafc11 77 my @param_names = qw(name class isa);
e976988f 78 sub register
d0eafc11 79 {
e976988f 80 my $self = shift;
81 my %params = @_;
82
83 for (@param_names)
d0eafc11 84 {
e976988f 85 unless ($params{$_})
86 {
87 warn "$_ was not supplied to register()\n" if $^W;
88 return;
89 }
d0eafc11 90 }
d0eafc11 91
e976988f 92 my $name = uc $params{name};
93 if (exists $Manifest{$name})
94 {
95 warn "$params{name} already exists in the manifest.\n" if $^W;
96 return;
97 }
d0eafc11 98
e976988f 99 my $isa = uc $params{isa};
100 unless (exists $Manifest{$isa})
101 {
102 warn "$params{isa} does not exist in the manifest.\n" if $^W;
103 return;
104 }
d0eafc11 105
e976988f 106 {
107 no strict 'refs';
108 unshift @{"$params{class}::ISA"}, $Manifest{$isa};
109 }
d0eafc11 110
e976988f 111 $self->_load_class( $Manifest{$isa} );
112 $self->_load_class( $params{class} );
d0eafc11 113
e976988f 114 $Manifest{$name} = $params{class};
115 $isBuildable{$name} = ~~1;
116
117 return ~~1;
118 }
d0eafc11 119}
120
6dd4c89d 121sub _create
d0eafc11 122{
e976988f 123 my $self = shift;
d0eafc11 124 my $name = uc shift;
125
126 return unless exists $Manifest{$name};
127
e976988f 128 $self->_load_class( $Manifest{$name} );
d0eafc11 129
130 return $Manifest{$name}->new(@_);
131}
132
6dd4c89d 133sub _create_node
d0eafc11 134{
e976988f 135 my $self = shift;
d0eafc11 136 my $name = uc shift;
137
138 return unless exists $isBuildable{$name};
139
e976988f 140 return $self->_create($name, @_);
d0eafc11 141}
142
143sub isa
144{
145 return unless @_ >= 2;
146 exists $Manifest{uc $_[1]}
147 ? UNIVERSAL::isa($_[0], $Manifest{uc $_[1]})
148 : UNIVERSAL::isa(@_)
149}
150
37513eae 151sub is_embedded
152{
153 return unless @_ >= 1;
154
6dd4c89d 155 isa( $_[0], $_ ) && return ~~1 for qw( VAR BACKREF RANGE );
37513eae 156 return;
157}
158
d0eafc11 1591;
160__END__
161
162=head1 NAME
163
164Excel::Template::Factory
165
166=head1 PURPOSE
167
37513eae 168To provide a common way to instantiate Excel::Template nodes
d0eafc11 169
37513eae 170=head1 USAGE
d0eafc11 171
37513eae 172=head2 register()
d0eafc11 173
37513eae 174Use this to register your own nodes.
d0eafc11 175
37513eae 176Example forthcoming.
d0eafc11 177
6dd4c89d 178=head1 METHODS
179
180=head2 isa
181
182This is a customized isa() wrapper for syntactic sugar
183
184=head2 is_embedded
185
d0eafc11 186=head1 AUTHOR
187
c09684ff 188Rob Kinyon (rob.kinyon@gmail.com)
d0eafc11 189
190=head1 SEE ALSO
191
192=cut