Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

andreychek's scratchpad

by andreychek (Parson)
on Jun 03, 2004 at 20:02 UTC ( #360444=scratchpad: print w/ replies, xml ) Need Help??

There is currently no interesting information to see in my scratchpad. But since you dropped by, I didn't want to dissapoint. Check out this most amusing link regarding how to drive: http://fun.from.hell.pl/2002-05-28/naukajazdy.html
#################################################### # Sample Usage (under mod_perl) #################################################### use OpenPlugin(); my $r = shift; my $OP = OpenPlugin->new( config => { src => '/etc/myconf.conf' }, request => { apache => $r } ); my $hair_color = $OP->param->get_incoming('hair'); my $eye_color = $OP->param->get_incoming('eyes'); my $credit_card = $OP->param->get_incoming('credit'); $OP->session->save({ credit => $credit_card }); $OP->httpheader->set_outgoing({ content-type => text/html }); $OP->httpheader->send_outgoing(); print "We got your number!<br>"; #################################################### # Sample Config #################################################### # Portions of OpenPlugin.conf <plugin authenticate> load = Startup driver = DBI datasource = rwcsql </plugin> <plugin param> load = Startup driver = Apache </plugin> <plugin cache> load = Auto driver = File expires = +3h </plugin> # Portions of OpenPlugin-drivermap.conf <drivermap authenticate> DBI = OpenPlugin::Authenticate::DBI Htpasswd = OpenPlugin::Authenticate::Htpasswd LDAP = OpenPlugin::Authenticate::LDAP SMB = OpenPlugin::Authenticate::SMB PAM = OpenPlugin::Authenticate::PAM </drivermap> <drivermap param> Apache = OpenPlugin::Param::Apache CGI = OpenPlugin::Param::CGI </drivermap> <drivermap cache> File = OpenPlugin::Cache::File </drivermap> #################################################### # OpenPlugin Class #################################################### package OpenPlugin; use strict; use vars qw( $AUTOLOAD ); use base qw( Class::Factory ); use OpenPlugin::Plugin qw(); use OpenPlugin::Utility qw(); use Log::Log4perl qw( get_logger ); use constant STATE => '_state'; use constant TOGGLE => '_toggle'; use constant PLUGIN => '_plugin'; use constant PLUGINCONF => '_pluginconf'; use constant INSTANCE => '_instance'; $OpenPlugin::VERSION = '0.06.6'; ########################## # Bootstrap related code # TODO: We should be able to override this by passing in arguments my $log_conf = q( log4perl.rootLogger = WARN, stderr log4perl.appender.stderr = Log::Dispatch::Screen log4perl.appender.stderr.layout = org.apache.log4j.PatternLayout log4perl.appender.stderr.layout.ConversionPattern = %C (%L) %m%n ); Log::Log4perl::init( \$log_conf ); my $logger = get_logger(); # End bootstrap code ######################### sub new { my $pkg = shift; my $params = { @_ }; my $class = ref $pkg || $pkg; my $self = bless( {}, $class ); $self->state("command_line", $params); # Read configuration from file if given $params->{config}{src} ||= $OpenPlugin::Config::Src; if ( $params->{config}{src} ) { $logger->info( "Given config source of [$params->{config}{src} +]" ); $self->load_config( $params ); } # Quit if we haven't been given some sort of config to use unless (( $params->{config}{src} ) || ( $params->{config}{config} +)) { die "No configuration given! You need to pass in the location + ", "to your configuration file, or pass in a hashref containi +ng ", "your configuration data."; } $self->register_plugins; return $self; } ######################################## # Public methods ######################################## # This gets and sets state information for user requests. For instanc +e, we can # maintain the current user and group, whether the user is an administ +rator, # etc. sub state { my ( $self, $key, $value ) = @_; if(( defined $key ) && ( not defined $value )) { $logger->info("Calling state() with key [$key]."); # Just a key passed in, return a single value return $self->{ STATE() }{ $key }; } elsif(( defined $key ) && ( defined $value )) { $logger->info("Calling state() with key [$key] and value [$val +ue]."); # We have a key and value, so assign the value to the key return $self->{ STATE() }{ $key } = $value; } else { $logger->info("Calling state() with no parameters."); # No key or value, return the entire state hash return $self->{ STATE() }; } } # Cleans up the current state in this object and sends a message to # all plugins to cleanup their state as well. sub cleanup { my ( $self ) = @_; $logger->info( "Running cleanup()" ); # Allow plugins to clean up their own state foreach my $plugin ( $self->loaded_plugins ) { $self->$plugin()->cleanup; } # Completely erase all state related information $self->{ STATE() } = {}; # Recreate a hash key for each plugin foreach my $plugin ( $self->loaded_plugins ) { $self->$plugin()->state("Init", 1); } } # This should be called before the object is taken out of scope and # should probably incorporated into a DESTROY() method. sub shutdown { my ( $self ) = @_; $logger->info( "Calling shutdown() from OP" ); $self->cleanup(); # ... do any additional cleanup so we don't have dangling/circular # references, etc.... } ######################################## # Accessor methods ######################################## # Get a list of all plugins which the config plugin knows about sub get_plugins { my $self = shift; return sort keys %{ $self->config->{plugin} }; } # Save any info that we have relating the a plugins configuration sub set_plugin_info { my ( $self, $plugin ) = @_; # $plugin_info contains all the information about a given plugin t +hat was # found in the configuration file my $plugin_info = $self->config->{plugin}{ $plugin }; # We definitely cannot load a plugin without a driver. Warn and s +kip if # that is the case. unless ( ref $plugin_info eq 'HASH' and $plugin_info->{driver} ) { $logger->warn("Invalid driver listed for [$plugin]: ", "[$plugin_info->{driver}]. Skipping." ); } $logger->info( "Driver type found for [$plugin]: ", "[$plugin_info->{driver}]" ); # Store this configuration for whenever we need it $self->{ PLUGINCONF() }{ $plugin } = $plugin_info; } # Get the name of the class name to use for a given driver sub get_plugin_class { my ( $self, $plugin ) = @_; # Get the driver for this plugin, as defined in the config file my $driver = $self->{ PLUGINCONF() }{ $plugin }{driver}; # Get the class name for the driver, as defined in the drivermap f +ile my $plugin_class = $self->config->{drivermap}{ $plugin }{ $driver +}; $logger->info( "Plugin class found for [$plugin]: [$plugin_class]" + ); return $plugin_class; } # Retrieve a list of plugins which are currently loaded, return the va +lue we # received when we called it's load() function earlier sub loaded_plugins { my $self = shift; unless ( ref $self->{ PLUGIN() } eq 'HASH' ) { return (); } return sort keys %{ $self->{ PLUGIN() } }; } # Save the plugin instance (object) that we received by calling its ne +w() # function sub set_plugin_instance { my ( $self, $plugin_type, $instance ) = @_; $self->{ INSTANCE() }{ $plugin_type } = $instance; } ######################################## # Plugin Instanciation ######################################## # Decide how and when to load each plugin sub register_plugins { my $self = shift; foreach my $plugin ( $self->get_plugins ) { $self->set_plugin_info( $plugin ); # These plugins have a "load" time of "Startup", meaning they +are # loaded when the main OpenPlugin module is if( $self->{ PLUGINCONF() }{ $plugin }{ load } eq "Startup" ) +{ unless( OpenPlugin::Plugin->get_factory_map->{$plugin} ) { # Tell OpenPlugin::Plugin that we have a new class tha +t we wish # to load now OpenPlugin::Plugin->add_factory_type( $plugin => $self->get_plugin_class( $plugi +n )); } $self->init_plugin( $plugin ); } # These plugins have a "load" time of "Auto", meaning they are # loaded on demand. If they aren't ever used, they'll never b +e loaded elsif ( $self->{ PLUGINCONF() }{ $plugin }{ load } eq "Auto" ) + { unless( OpenPlugin::Plugin->get_register_map->{$plugin} ) +{ # Tell OpenPlugin::Plugin about a class, so it can lo +ad it if # and when we finally decide to use it OpenPlugin::Plugin->register_factory_type( $plugin => $self->get_plugin_class( $plugi +n )); } } # We need to know how to load a plugin, it doesn't seem approp +riate to # guess. If the configuration isn't correct, give a warning m +essage, # but skip loading it. else { $logger->warn("Invalid load time listed for [$plugin]: [", $self->{ PLUGINCONF() }{ $plugin }{ load }, "]. Skipping." ); } } } # Make a plugin available to programs using us sub init_plugin { my ( $self, $plugin_type ) = @_; # TODO: Eventually, instead of passing the entire command line to +each # plugin, we should just pass items directly related to that plugi +n my $instance = OpenPlugin::Plugin->new( $plugin_type, $self, $self->state->{command_line} ); $self->{ INSTANCE() }{ $plugin_type } = $instance; $self->generate_plugin_method_call( $plugin_type ); $self->{ PLUGIN() }{ $plugin_type } = $self->$plugin_type()->load( +); } # Build a method call for a given plugin sub generate_plugin_method_call { my ( $self, $plugin_type ) = @_; my $class = ref $self; my $method = $class . '::' . $plugin_type; no strict 'refs'; unless ( defined &{ $method } ) { $logger->info("Generating method [$method]"); *{ $method } = sub { my $self = shift; return $self->{ INSTANCE() }{ $plugin_type }; } } } ######################################## # AUTOLOAD # (so great it gets its own section!) ######################################## sub AUTOLOAD { my ( $self, $params ) = @_; my $request = $AUTOLOAD; $request =~ s/.*://; $logger->info( "Autoload request: [$request]\n" ); $self->init_plugin( $request ); $self->$request( $params ); } # Lets not go looking for DESTROY via AUTOLOAD sub DESTROY { } ######################################## # CONFIGURATION ######################################## # Configuration is different from other plugins because of the bootstr +apping # issue. sub load_config { my ( $self, $params ) = @_; unless( OpenPlugin::Plugin->get_factory_map->{config} ) { OpenPlugin::Plugin->add_factory_type( config => 'OpenPlugin::Config' ); } my $config = OpenPlugin::Plugin->new( 'config', $self, $params->{c +onfig} ); $self->set_plugin_instance( "config", $config->read ); $self->generate_plugin_method_call( "config" ); } 1; __END__ =head1 NAME OpenPlugin - Plugin manager for web applications =head1 SYNOPSIS use OpenPlugin(); my $r = shift; my $OP = OpenPlugin->new( config => { src => '/etc/myconf.conf' +}, request => { apache => $r } ); my $is_authenticated = $OP->authenticate->authenticate({ username => + 'badguy', password => + 'scylla' }); unless ( $is_authenticated ) { $OP->exception->throw( "Login incorrect!" ); } $session = $OP->session->fetch( $session_id ); $session->{ 'hair' } = $OP->param->get_incoming( 'hair' ); $session->{ 'eyes' } = $OP->param->get_incoming( 'eyes' ); $OP->session->save( $session ); $OP->httpheader->send_outgoing(); print "You have $session->{'hair'} hair and $session->{'eyes'} eyes< +br>"; =head1 DESCRIPTION OpenPlugin is an architecture which manages plugins for web applicatio +ns. It allows you to incorporate any number of plugins and drivers into your +web application, offering a powerful user environment. OpenPlugin comes with numerous plugins, including Session Support, Use +r Authentication, Datasource Management, and Logging. With OpenPlugin's + driver support, you can do things like change your logging facility from STDE +RR to Syslog by changing one line in a config file. OpenPlugin also offers plugins which abstract Apache::Request and CGI, + allowing you to switch between the two by only changing a setting in a config f +ile. Each plugin is written in a way to allow any number of drivers which c +an manipulate how the plugin functions, or where it can find it's data. =head1 BACKGROUND Currently, there are a number of web application frameworks available. And while each one is unique, there is a certain amount of functionali +ty that each shares. Often, that functionality is built in to the particular framework, instead of being a seperate component.ÜÜ OpenPlugin offers this functionality that is common between frameworks +, but it is designed to be a reusable component, which can be used within any f +ramework or standalone web application. This allows OpenPlugin to grow beyond +the abilities of any one developer, and beyond the scope of any one framew +ork. OpenPlugin has developed into a powerful architecture allowing for ext +ensible applications. =head1 FUNCTIONS While the main OpenPlugin class does provide some publicaly available functions, you'll find the majority of OpenPlugin's funcionality in it +'s plugins. =over 4 =item B<$OP = OpenPlugin->new( %params )> You can pass a number of parameters into the B<new()> method. Each of + those parameters can effect how a given plugin, or OpenPlugin as a whole, fu +nctions. The parameters in %params will be available to each plugin as they are loaded. The syntax for the %params hash is: %params = qw( plugin_name => { plugin_param => plugin_value }, other_plugin => { plugin_param => plugin_value }, For example: %params = qw( config => { src => /path/to/config.conf }, request => { apache => $r }, ); This returns an OpenPlugin object. =item B<state( [ key ], [ value ] )> This function is for storing and retrieving state information. This information is destroyed when the script exits (see the L<Session|OpenPlugin::Session> and L<Cache|OpenPlugin::Cache> plugins for storing information across requests). This returns the full state hash if passed no parameters, a value if p +assed one parameter (a key), or sets a key equal to a given value if sent two pa +rameters. =item B<cleanup()> This function tells the main OpenPlugin module, and all of it's plugin +s, to perform a "cleanup". This is typically called by you when your applic +ation is exiting, perhaps even from a DESTROY() method. This is important when + running under mod_perl, as it clears out all the state information created dur +ing the current request. If not cleared out, mod_perl will happily keep this information for the next request too -- this is not what you want! Be + sure to run cleanup() at the end of your application. If you are using L<Open +Thought>, OpenThought does call this method for you. =back =head1 PLUGINS The API for individual plugins is available by looking at that particu +lar plugin's documentation. The following plugins are available: =over 4 =item * L<Application|OpenPlugin::Application> =item * L<Authentication|OpenPlugin::Authentication> =item * L<Cache|OpenPlugin::Cache> =item * L<Config|OpenPlugin::Config> =item * L<Cookie|OpenPlugin::Cookie> =item * L<Datasource|OpenPlugin::Datasource> =item * L<Exception|OpenPlugin::Exception> =item * L<Httpheader|OpenPlugin::Httpheader> =item * L<Log|OpenPlugin::Log> =item * L<Param|OpenPlugin::Param> =item * L<Session|OpenPlugin::Session> =item * L<Upload|OpenPlugin::Upload> =back Many of these plugins accept parameters passed into OpenPlugin's B<new +()> constructor, and a few even require it. You can obtain a list of what parameters a plugin recognizes by reading the documentation for the pl +ugin and driver which you are using. Generally speaking, the documentation for + a plugin shows how to program it's interface, and the documentation for the dri +ver shows how to configure it, along with what parameters you can pass into it. =head1 TO DO All kinds of stuff! This module has plenty of room for improvement. +The API is not complete. See the TO DO list for the individual plugins to see + a few of the ideas that I've written down. There's also plenty of room for more documentation. =head1 COPYRIGHT Copyright (c) 2001-2002 Eric Andreychek. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHORS Eric Andreychek <eric@openthought.net> =head1 CONTRIBUTORS Chris Winters initially helped get things rolling. OpenPlugin also ma +kes use of his Class::Factory module, and I occasionally borrow code from OpenInteract/SPOPS. =head1 SEE ALSO Web applications which make use of OpenPlugin: =over 4 =item * L<OpenThought|OpenThought> =back =cut
Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (4)
As of 2014-08-30 16:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (293 votes), past polls