- Fixed bugs that were:
[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     ITALIC
56     OUTLINE
57     LOOP
58     BACKREF
59     RANGE
60     ROW
61     SHADOW
62     STRIKEOUT
63     VAR
64     WORKBOOK
65     WORKSHEET
66 );
67
68 sub register
69 {
70     my %params = @_;
71
72     my @param_names = qw(name class isa);
73     for (@param_names)
74     {
75         unless ($params{$_})
76         {
77             warn "$_ was not supplied to register()\n";
78             return 0;
79         }
80     }
81
82     my $name = uc $params{name};
83     if (exists $Manifest{$name})
84     {
85         warn "$params{name} already exists in the manifest.\n";
86         return 0;
87     }
88
89     my $isa = uc $params{isa};
90     unless (exists $Manifest{$isa})
91     {
92         warn "$params{isa} does not exist in the manifest.\n";
93         return 0;
94     }
95
96     $Manifest{$name} = $params{class};
97     $isBuildable{$name} = 1;
98
99     {
100         no strict 'refs';
101         unshift @{"$params{class}::ISA"}, $Manifest{$isa};
102     }
103
104     return 1;
105 }
106
107 sub create
108 {
109     my $class = shift;
110     my $name = uc shift;
111
112     return unless exists $Manifest{$name};
113
114     (my $filename = $Manifest{$name}) =~ s!::!/!g;
115  
116     eval {
117         require "$filename.pm";
118     }; if ($@) {
119         die "Cannot find or compile PM file for '$name' ($filename)\n";
120     }
121  
122     return $Manifest{$name}->new(@_);
123 }
124
125 sub create_node
126 {
127     my $class = shift;
128     my $name = uc shift;
129
130     return unless exists $isBuildable{$name};
131
132     return $class->create($name, @_);
133 }
134
135 sub isa
136 {
137     return unless @_ >= 2;
138     exists $Manifest{uc $_[1]}
139         ? UNIVERSAL::isa($_[0], $Manifest{uc $_[1]})
140         : UNIVERSAL::isa(@_)
141 }
142
143 sub is_embedded
144 {
145     return unless @_ >= 1;
146
147     isa( $_[0], $_ ) && return !!1 for qw( VAR BACKREF RANGE );
148     return;
149 }
150
151 1;
152 __END__
153
154 =head1 NAME
155
156 Excel::Template::Factory
157
158 =head1 PURPOSE
159
160 To provide a common way to instantiate Excel::Template nodes
161
162 =head1 USAGE
163
164 =head2 register()
165
166 Use this to register your own nodes.
167
168 Example forthcoming.
169
170 =head1 AUTHOR
171
172 Rob Kinyon (rob.kinyon@gmail.com)
173
174 =head1 SEE ALSO
175
176 =cut