- Fixed Makefile.PL so that it uses PM_FILTER instead of rolling its own
[p5sagit/Excel-Template.git] / lib / Excel / Template / Factory.pm
1 package Excel::Template::Factory;
2
3 use strict;
4
5 BEGIN {
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
19     'BACKREF'   => 'Excel::Template::Element::Backref',
20     'CELL'      => 'Excel::Template::Element::Cell',
21     'FORMULA'   => 'Excel::Template::Element::Formula',
22     'RANGE'     => 'Excel::Template::Element::Range',
23     'VAR'       => 'Excel::Template::Element::Var',
24
25     'FORMAT'    => 'Excel::Template::Container::Format',
26
27 # These are all the Format short-cut objects
28 # They are also instantiable
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
38 # They are also in here to make E::T::Factory::isa() work.
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
49 %isBuildable = map { $_ => 1 } qw(
50     BOLD
51     CELL
52     FORMAT
53     FORMULA
54     IF
55     HIDDEN
56     ITALIC
57     LOCKED
58     OUTLINE
59     LOOP
60     BACKREF
61     RANGE
62     ROW
63     SHADOW
64     STRIKEOUT
65     VAR
66     WORKBOOK
67     WORKSHEET
68 );
69
70 sub register
71 {
72     my %params = @_;
73
74     my @param_names = qw(name class isa);
75     for (@param_names)
76     {
77         unless ($params{$_})
78         {
79             warn "$_ was not supplied to register()\n";
80             return 0;
81         }
82     }
83
84     my $name = uc $params{name};
85     if (exists $Manifest{$name})
86     {
87         warn "$params{name} already exists in the manifest.\n";
88         return 0;
89     }
90
91     my $isa = uc $params{isa};
92     unless (exists $Manifest{$isa})
93     {
94         warn "$params{isa} does not exist in the manifest.\n";
95         return 0;
96     }
97
98     $Manifest{$name} = $params{class};
99     $isBuildable{$name} = 1;
100
101     {
102         no strict 'refs';
103         unshift @{"$params{class}::ISA"}, $Manifest{$isa};
104     }
105
106     return 1;
107 }
108
109 sub create
110 {
111     my $class = shift;
112     my $name = uc shift;
113
114     return unless exists $Manifest{$name};
115
116     (my $filename = $Manifest{$name}) =~ s!::!/!g;
117  
118     eval {
119         require "$filename.pm";
120     }; if ($@) {
121         die "Cannot find or compile PM file for '$name' ($filename)\n";
122     }
123  
124     return $Manifest{$name}->new(@_);
125 }
126
127 sub create_node
128 {
129     my $class = shift;
130     my $name = uc shift;
131
132     return unless exists $isBuildable{$name};
133
134     return $class->create($name, @_);
135 }
136
137 sub isa
138 {
139     return unless @_ >= 2;
140     exists $Manifest{uc $_[1]}
141         ? UNIVERSAL::isa($_[0], $Manifest{uc $_[1]})
142         : UNIVERSAL::isa(@_)
143 }
144
145 sub is_embedded
146 {
147     return unless @_ >= 1;
148
149     isa( $_[0], $_ ) && return !!1 for qw( VAR BACKREF RANGE );
150     return;
151 }
152
153 1;
154 __END__
155
156 =head1 NAME
157
158 Excel::Template::Factory
159
160 =head1 PURPOSE
161
162 To provide a common way to instantiate Excel::Template nodes
163
164 =head1 USAGE
165
166 =head2 register()
167
168 Use this to register your own nodes.
169
170 Example forthcoming.
171
172 =head1 AUTHOR
173
174 Rob Kinyon (rob.kinyon@gmail.com)
175
176 =head1 SEE ALSO
177
178 =cut