sync w/ main trunk
[bioperl-live.git] / Bio / Factory / ObjectFactory.pm
blobdc58c4d98ffd3f41ad4bb8265c63dfe8e6a9e09f
1 # $Id$
3 # BioPerl module for Bio::Factory::ObjectFactory
5 # Please direct questions and support issues to <bioperl-l@bioperl.org>
7 # Cared for by Hilmar Lapp <hlapp at gmx.net>
9 # Copyright Hilmar Lapp
11 # You may distribute this module under the same terms as perl itself
14 # (c) Hilmar Lapp, hlapp at gmx.net, 2003.
15 # (c) GNF, Genomics Institute of the Novartis Research Foundation, 2003.
17 # You may distribute this module under the same terms as perl itself.
18 # Refer to the Perl Artistic License (see the license accompanying this
19 # software package, or see http://www.perl.com/language/misc/Artistic.html)
20 # for the terms under which you may use, modify, and redistribute this module.
22 # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
23 # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
24 # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 # POD documentation - main docs before the code
29 =head1 NAME
31 Bio::Factory::ObjectFactory - Instantiates a new Bio::Root::RootI (or derived class) through a factory
33 =head1 SYNOPSIS
35 use Bio::Factory::ObjectFactory;
37 my $factory = Bio::Factory::ObjectFactory->new(-type => 'Bio::Ontology::GOterm');
38 my $term = $factory->create_object(-name => 'peroxisome',
39 -ontology => 'Gene Factory',
40 -identifier => 'GO:0005777');
43 =head1 DESCRIPTION
45 This object will build L<Bio::Root::RootI> objects generically.
47 =head1 FEEDBACK
49 =head2 Mailing Lists
51 User feedback is an integral part of the evolution of this and other
52 Bioperl modules. Send your comments and suggestions preferably to
53 the Bioperl mailing list. Your participation is much appreciated.
55 bioperl-l@bioperl.org - General discussion
56 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
58 =head2 Support
60 Please direct usage questions or support issues to the mailing list:
62 L<bioperl-l@bioperl.org>
64 rather than to the module maintainer directly. Many experienced and
65 reponsive experts will be able look at the problem and quickly
66 address it. Please include a thorough description of the problem
67 with code and data examples if at all possible.
69 =head2 Reporting Bugs
71 Report bugs to the Bioperl bug tracking system to help us keep track
72 of the bugs and their resolution. Bug reports can be submitted via the
73 web:
75 http://bugzilla.open-bio.org/
77 =head1 AUTHOR - Hilmar Lapp
79 Email hlapp at gmx.net
82 =head1 CONTRIBUTORS
84 This is mostly copy-and-paste with subsequent adaptation from
85 Bio::Seq::SeqFactory by Jason Stajich. Most credits should in fact go
86 to him.
88 =head1 APPENDIX
90 The rest of the documentation details each of the object methods.
91 Internal methods are usually preceded with a _
93 =cut
96 # Let the code begin...
99 package Bio::Factory::ObjectFactory;
100 use strict;
103 use base qw(Bio::Root::Root Bio::Factory::ObjectFactoryI);
105 =head2 new
107 Title : new
108 Usage : my $obj = Bio::Factory::ObjectFactory->new();
109 Function: Builds a new Bio::Factory::ObjectFactory object
110 Returns : Bio::Factory::ObjectFactory
111 Args : -type => string, name of a L<Bio::Root::RootI> derived class.
112 There is no default.
113 -interface => string, name of the interface or class any type
114 specified needs to at least implement.
115 The default is Bio::Root::RootI.
117 =cut
119 sub new {
120 my($class,@args) = @_;
122 my $self = $class->SUPER::new(@args);
124 my ($type,$interface) = $self->_rearrange([qw(TYPE INTERFACE)], @args);
126 $self->{'_loaded_types'} = {};
127 $self->interface($interface || "Bio::Root::RootI");
128 $self->type($type) if $type;
130 return $self;
134 =head2 create_object
136 Title : create_object
137 Usage : my $seq = $factory->create_object(<named parameters>);
138 Function: Instantiates a new object of the previously set type.
140 This object allows us to genericize the instantiation of
141 objects.
143 You must have provided -type at instantiation, or have
144 called type($mytype) before you can call this method.
146 Returns : an object of the type returned by type()
148 The return type is configurable using new(-type =>"..."),
149 or by calling $self->type("My::Fancy::Class").
150 Args : Initialization parameters specific to the type of
151 object we want. Check the POD of the class you set as type.
153 =cut
155 sub create_object {
156 my ($self,@args) = @_;
158 my $type = $self->type(); # type has already been loaded upon set
159 return $type->new(-verbose => $self->verbose, @args);
162 =head2 type
164 Title : type
165 Usage : $obj->type($newval)
166 Function: Get/set the type of object to be created.
168 This may be changed at any time during the lifetime of this
169 factory.
171 Returns : value of type (a string)
172 Args : newvalue (optional, a string)
175 =cut
177 sub type{
178 my $self = shift;
180 if(@_) {
181 my $type = shift;
182 if($type && (! $self->{'_loaded_types'}->{$type})) {
183 eval {
184 $self->_load_module($type);
186 if( $@ ) {
187 $self->throw("module for '$type' failed to load: ".
188 $@);
190 my $o = bless {},$type;
191 if(!$self->_validate_type($o)) { # this may throw an exception
192 $self->throw("'$type' is not valid for factory ".ref($self));
194 $self->{'_loaded_types'}->{$type} = 1;
196 return $self->{'type'} = $type;
198 return $self->{'type'};
201 =head2 interface
203 Title : interface
204 Usage : $obj->interface($newval)
205 Function: Get/set the interface or base class that supplied types
206 must at least implement (inherit from).
207 Example :
208 Returns : value of interface (a scalar)
209 Args : on set, new value (a scalar or undef, optional)
212 =cut
214 sub interface{
215 my $self = shift;
216 my $interface = shift;
218 if($interface) {
219 return $self->{'interface'} = $interface;
221 return $self->{'interface'};
224 =head2 _validate_type
226 Title : _validate_type
227 Usage : $factory->_validate_type($object)
228 Function: Called to let derived factories validate the type set
229 via type().
231 The default implementation here checks whether the supplied
232 object skeleton implements the interface set via -interface
233 upon factory instantiation.
235 Example :
236 Returns : TRUE if the type is to be considered valid, and FALSE otherwise.
237 Instead of returning FALSE this method may also just throw
238 an informative exception.
240 The default implementation here will throw an exception
241 if the supplied object does not inherit from the interface
242 provided by the interface() method.
244 Args : A hash reference blessed into the specified type, allowing
245 queries like isa().
248 =cut
250 sub _validate_type{
251 my ($self,$obj) = @_;
253 if(! $obj->isa($self->interface())) {
254 $self->throw("invalid type: '".ref($obj).
255 "' does not implement '".$self->interface()."'");
257 return 1;
260 #####################################################################
261 # aliases for naming consistency or other reasons #
262 #####################################################################
264 *create = \&create_object;