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