cvsuser     01/11/16 20:56:11

  Modified:    P5EEx/Blue MANIFEST
               P5EEx/Blue/P5EEx/Blue Config.pm Context.pm P5EE.pm
  Added:       P5EEx/Blue/examples Config.1 config.pl
  Log:
  first version demonstrating Config classes
  
  Revision  Changes    Path
  1.2       +1 -4      p5ee/P5EEx/Blue/MANIFEST
  
  Index: MANIFEST
  ===================================================================
  RCS file: /cvs/public/p5ee/P5EEx/Blue/MANIFEST,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- MANIFEST  2001/11/16 23:21:38     1.1
  +++ MANIFEST  2001/11/17 04:56:10     1.2
  @@ -4,11 +4,8 @@
   README
   TODO
   P5EEx/Blue/styleguide.pod
  -P5EEx/Blue/design.pod
  -P5EEx/Blue.pm
  +P5EEx/Blue/P5EE.pm
   P5EEx/Blue/Config.pm
   P5EEx/Blue/Context.pm
   P5EEx/Blue/Context/CGI.pm
   P5EEx/Blue/Config/XML.pm
  -P5EEx/Blue/Utils/Date.pm
  -P5EEx/Blue/Utils/HTML.pm
  
  
  
  1.2       +51 -17    p5ee/P5EEx/Blue/P5EEx/Blue/Config.pm
  
  Index: Config.pm
  ===================================================================
  RCS file: /cvs/public/p5ee/P5EEx/Blue/P5EEx/Blue/Config.pm,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- Config.pm 2001/11/16 23:21:38     1.1
  +++ Config.pm 2001/11/17 04:56:10     1.2
  @@ -1,10 +1,10 @@
   
   ######################################################################
  -## $Id: Config.pm,v 1.1 2001/11/16 23:21:38 spadkins Exp $
  +## $Id: Config.pm,v 1.2 2001/11/17 04:56:10 spadkins Exp $
   ######################################################################
   
   package P5EEx::Blue::Config;
  -$VERSION = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r};
  +$VERSION = do { my @r=(q$Revision: 1.2 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r};
   
   use strict;
   
  @@ -26,19 +26,40 @@
   ######################################################################
   
   sub new {
  -    my ($this) = @_;
  -    my ($class, $self);
  -    $class = ref($this) || $this;
  +    my $this = shift;
  +    my $class = ref($this) || $this;
   
  +    my ($name, $args, $i);
  +    if ($#_ == -1) {
  +        $args = {};
  +        $name = "default";
  +    }
  +    else {
  +        if (ref($_[0]) eq "HASH") {
  +            $args = shift;
  +            $name = shift if ($#_ % 2 == 0);
  +            for ($i = 0; $i < $#_; $i++) {
  +                $args->{$_[$i]} = $_[$i+1];
  +            }
  +        }
  +        else {
  +            $name = shift if ($#_ % 2 == 0);
  +            $args = ($#_ > -1) ? { @_ } : {};
  +        }
  +        $name = $args->{name} if (!$name);
  +        $name = "default" if (!$name);
  +    }
  +
       # bootstrap phase: bless an empty hash
  -    $self = {};
  +    my $self = {};
       bless $self, $class;
   
  -    # load phase: replace empty hash with loaded hash
  -    $self = $self->load();
  +    # load phase: replace empty hash with loaded hash, bless again
  +    $self = $self->load($args);
       bless $self, $class;
  +
  +    $self->init($args);  # allows a subclass to override this portion
   
  -    $self->init();  # allows a subclass to override this portion
       return $self;
   }
   
  @@ -48,23 +69,36 @@
   }
   
   sub load {
  +    my ($self, $args) = @_;
       local(*FILE);
   
       my ($file, @perl, $perl, $conf, $open);
  +    if (defined $args && $args->{configFile}) {
  +        $file = $args->{configFile};
  +        $open = open(main::FILE,"< $file");
  +    }
  +    else {
       $file = $0;
       $file =~ s!\.[^/]*$!!;
       $file .= ".pl";
  +        $open = open(main::FILE,"< $file");
  +        $open = open(main::FILE,"< config.pl") if (!$open);
  +    }
   
       $conf = {};
  -    $open = open(main::FILE,"< $file");
  -    $open = open(main::FILE,"< widget.pl") if (!$open);
       if ($open) {
           @perl = <main::FILE>;
           close(main::FILE);
           $perl = join("",@perl);
  +        if ($perl =~ /^(\$conf = \{.*\};[ \n]*)$/s) {
  +            $perl = $1;   # untainted now
           eval($perl);
           print STDERR "CONFIGURATION SYNTAX ERROR: $@\n" if ($@);
       }
  +        else {
  +            print STDERR "CONFIGURATION SYNTAX ERROR: File didn't have \$conf in 
it\n";
  +        }
  +    }
       $conf;
   }
   
  @@ -76,7 +110,7 @@
   
   sub dump {
       my $self = shift;
  -    my $d = Data::Dumper->new([ $self ], [ "data" ]);
  +    my $d = Data::Dumper->new([ $self ], [ "conf" ]);
       $d->Indent(1);
       return $d->Dump();
   }
  
  
  
  1.2       +77 -666   p5ee/P5EEx/Blue/P5EEx/Blue/Context.pm
  
  Index: Context.pm
  ===================================================================
  RCS file: /cvs/public/p5ee/P5EEx/Blue/P5EEx/Blue/Context.pm,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- Context.pm        2001/11/16 23:21:38     1.1
  +++ Context.pm        2001/11/17 04:56:10     1.2
  @@ -1,114 +1,110 @@
   
  -######################################################################
  -## $Id: Context.pm,v 1.1 2001/11/16 23:21:38 spadkins Exp $
  -######################################################################
  +#############################################################################
  +## $Id: Context.pm,v 1.2 2001/11/17 04:56:10 spadkins Exp $
  +#############################################################################
   
   package P5EEx::Blue::Context;
   
   use strict;
   
  -use Widget;
  -use CGI;
  +use P5EEx::Blue::P5EE;
   
   =head1 NAME
   
  -P5EEx::Blue::Context - Controller for sets of widgets in a CGI environment
  +P5EEx::Blue::Context - context in which we are currently running
   
   =head1 SYNOPSIS
   
  -   my ($wc, $widget, @widgets);
  +   my ($c);
   
  -   # ... official way to get a Controller object ...
  -   use Widget;
  -   $wc = Widget->controller();                      # make factory which knows the 
config info
  -   $wc->dispatch_events();
  +   # ... official way to get a Context object ...
  +   use P5EEx::Blue::P5EE;
  +   my $ctx = P5EEx::Blue::P5EE->context();
  +   $config = $ctx->config();   # get the configuration
   
  -   $wc = Widget->controller("P5EEx::Blue::Context");  # use other than the 
autodetected controller
  -   print "wc is of type: ", ref($wc), "\n";         # should be the Controller 
class instantiated
  -
      # ... alternative way (used internally) ...
      use P5EEx::Blue::Context;
  -   $wc = P5EEx::Blue::Context->new();
  -   print "wc is of type: ", ref($wc), "\n";         # should be the Controller 
class instantiated
  +   my $ctx = P5EEx::Blue::Context->new();
   
  -   # the rest represents what might be done with the resulting widget controller
  -   $widget = $wc->widget("birth_dt");           # gets a widget
  -   print $widget->html(), "\n";                 # this works for an HTML widget
  -
  -   # or more generally... (maybe one day we will have Widget::Tk, Widget::Curses, 
etc.?)
  -   push(@widgets, $widget);                     # add widget to a list of widgets
  -   $wc->display(@widgets);                      # controller renders list of 
widgets on display
  +   # any of the following named parameters may be specified
  +   my $ctx = P5EEx::Blue::P5EE->context(
  +       contextClass => "P5EEx::Blue::Context::CGI",
  +       configClass => "P5EEx::Blue::Config::XML",   # or any Config args
  +   );
   
   =cut
   
  -######################################################################
  +#############################################################################
   # CONSTANTS
  -######################################################################
  -
  -######################################################################
  -# ATTRIBUTES
  -######################################################################
  -
  -#   $self->{widget}              # {} cache of widgets (by widgetName)
  -#   $self->{widgetconfig}        # {} cache of widget configuration information (by 
widgetName)
  -#   $self->{messages}            # "" HTML text (?) derived from the event handling
  -#
  -# MAJOR SECTIONS OF THE config STRUCTURE
  -#   $self->{config}              # {} global, read-only, config information
  -#   $self->{config}{repository}  # {} accessible repositories for data retrieval
  -#   $self->{config}{domain}      # {} domains of value/label pairs
  -#   $self->{config}{widgetType}  # {} widget configs ready for use in a widget
  -#   $self->{config}{widget}      # {} widget config info
  -#
  -# MAJOR SECTIONS OF THE state STRUCTURE
  -#   $self->{state}               # {} dynamic state
  -#   $self->{state}{org}          # {} dynamic state (for the user's current org)
  -#   $self->{state}{user}         # {} dynamic state (for the current user)
  -#   $self->{state}{widget}       # {} dynamic state (for the current state for each 
widget)
  +#############################################################################
   
  -# INPUTS FROM THE ENVIRONMENT
  -
   =head1 DESCRIPTION
  +
  +A Context class models the environment in which the current process is
  +running. Examples might be
   
  -This is a controller class for widgets running in a CGI environment.
  +   P5EEx::Blue::Context::CGI
  +   P5EEx::Blue::Context::ModPerl
  +   P5EEx::Blue::Context::ModPerlRegistry
  +   P5EEx::Blue::Context::PPerl
  +   P5EEx::Blue::Context::Cmd
  +   P5EEx::Blue::Context::Daemon
  +   P5EEx::Blue::Context::Gtk
  +   P5EEx::Blue::Context::WxPerl
  +
  +The role of the Context class is to abstract the details of the
  +various runtime environments (or Platforms) so that the basic programming
  +model for the developer is uniform.
  +
  +The main function of the Context class is to load the Config data
  +and manage Session data.
  +
  +The Context object is always a singleton per process (except in rare cases
  +like debugging).  Conceptually, the Context may be associated with many
  +Config's and Sessions in a single process (ModPerl), whereas it frequently
  +is associated with only one Config or Session throughout the lifetime of
  +the process (CGI, Cmd).
   
   =cut
   
  -######################################################################
  +#############################################################################
   # CONSTRUCTOR
  -######################################################################
  +#############################################################################
   
   sub new {
  -    my ($this, $args) = @_;
  +    my $this = shift;
       my $class = ref($this) || $this;
       my $self = {};
       bless $self, $class;
  -    Widget->dbgprint("$class->new(" . join(", ",%$args) . ")")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"new"));
   
  -    $self->{widget} = {};        # initialize empty cache of widgets
  -    $self->{widgetconfig} = {};  # initialize empty cache of their effective config
  -
  -    my ($config_class, $state_class);
  -
  -    $config_class   = $args->{config};
  -    $config_class   = "Widget::Config" if (!defined $config_class || $config_class 
eq "");
  -
  -    $state_class    = $args->{state};
  -    $state_class    = "Widget::State" if (!defined $state_class || $state_class eq 
"");
  +    my ($name, $args, $i);
  +    if ($#_ == -1) {
  +        $args = {};
  +        $name = "default";
  +    }
  +    else {
  +        if (ref($_[0]) eq "HASH") {
  +            $args = shift;
  +            $name = shift if ($#_ % 2 == 0);
  +            for ($i = 0; $i < $#_; $i++) {
  +                $args->{$_[$i]} = $_[$i+1];
  +            }
  +        }
  +        else {
  +            $name = shift if ($#_ % 2 == 0);
  +            $args = ($#_ > -1) ? { @_ } : {};
  +        }
  +        $name = $args->{name} if (!$name);
  +        $name = "default" if (!$name);
  +    }
   
  -    $self->{config} = Widget->create($config_class, $args);
  -    $self->{state}  = Widget->create($state_class, $args);
  +    my ($config_class);
   
  -    # create the pseudo-widget "global" only as a widgetconfig
  -    $self->{widgetconfig}{global}{lang} = "en_us";
  +    $config_class   = $args->{configClass};
  +    $config_class   = $ENV{P5EE_CONFIG_CLASS} if (! $config_class);
  +    $config_class   = "P5EEx::Blue::Config" if (! $config_class);
   
  -    # create the pseudo-widget "session"
  -    $self->widget(
  -        -name => "session",
  -        -widgetClass => "Widget::Base",
  -        -container => "global",
  -    );
  +    $self->{config} = P5EEx::Blue::P5EE->create($config_class, $args);
   
       $self->init($args);
   
  @@ -120,608 +116,23 @@
       my ($self, $args) = @_;
   }
   
  -######################################################################
  +#############################################################################
   # METHODS
  -######################################################################
  -
  -sub add_message {
  -    my ($self, $msg) = @_;
  -    if (defined $self->{messages}) {
  -        $self->{messages} .= "<br>" . $msg;
  -    }
  -    else {
  -        $self->{messages} = $msg;
  -    }
  -}
  -
  -# NOTE: This is a key method to override in the driver classes
  -sub dispatch_events {
  -    my ($self, $eventarray) = @_;
  -    # TODO: implement a default handler here
  -    # $self->widget($name)->handle_event($ename, $event, @args);
  -}
  +#############################################################################
   
  -# NOTE: This is a key method to override in the driver classes
  -sub display {
  +sub log {
       my $self = shift;
  -    my ($widget);
  -    foreach $widget (@_) {
  -        $widget->display();
  -    }
  +    print STDERR @_, "\n";
   }
   
   sub user {
       my $self = shift;
  -    "guest";      # improve this over time
  -}
  -
  -sub state {
  -    $_[0]->{state};
  -}
  -
  -sub repository {
  -    my ($self, $repname) = @_;
  -    my ($config, $repdef, $instance, $key, $global, $var);
  -    my ($class, $method, $args, @args, $argidx);
  -
  -    $repname = "db" if (!defined $repname || $repname eq "");
  -    Widget->dbgprint("P5EEx::Blue::Context->repository($repname)")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"repository"));
  -
  -    $config = $self->{config};
  -    $repdef = $config->{repository}{$repname};
  -    return undef if (!defined $repdef);
  -
  -    $instance = $self->{repository}{$repname};
  -    if (! defined $instance) {
  -        if ($repdef->{import}) {
  -            $global = $self->{widgetconfig}{global};
  -            foreach $key (keys %$repdef) {
  -                $repdef->{$key} = $global->{$key} if (defined $global->{$key});
  -            }
  -        }
  -        $class = $repdef->{class};
  -        if (defined $class) {
  -            $method = $repdef->{newmethod};
  -            $method = "new" if (!defined $method);
  -            $args   = $repdef->{newmethod_args};
  -            $args   = [] if (!defined $args || ref($args) ne "ARRAY");
  -            @args   = @$args;
  -            for ($argidx = 0; $argidx <= $#$args; $argidx++) {
  -                if ($args->[$argidx] =~ /^\{(.+)\}$/) {
  -                    $var = $1;
  -                    if ($var eq "config") {
  -                        $args[$argidx] = $config;
  -                    }
  -                    elsif ($var eq "repconfig") {
  -                        $args[$argidx] = $repdef;
  -                    }
  -                    elsif (defined $repdef->{$var}) {
  -                        $args[$argidx] = $repdef->{$var};
  +    "guest";
                       }
  -                }
  -            }
  -
  -            Widget->dbgprint("P5EEx::Blue::Context->repository($repname): 
$class->$method(@$args)")
  -                if ($Widget::DEBUG && Widget->dbg(ref($self),"repository"));
   
  -            Widget->use($class);
  -            $instance = $class->$method(@args);
  -            $self->{repository}{$repname} = $instance;
  -        }
  -    }
  -    $instance;
  -}
  -
  -sub shutdown {
  +sub config {
       my $self = shift;
  -    my ($config, $repdef, $repname, $instance);
  -    my ($class, $method, $args, $argidx);
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->shutdown()")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"shutdown"));
  -
  -    $config = $self->{config};
  -    if (defined $self->{repository} && ref($self->{repository}) eq "HASH") {
  -        foreach $repname (keys %{$self->{repository}}) {
  -            $instance = $self->{repository}{$repname};
  -            $repdef = $config->{repository}{$repname};
  -            $method = $repdef->{finishmethod};
  -            $method = "disconnect" if (!defined $method);
  -       
  -            Widget->dbgprint("P5EEx::Blue::Context->shutdown(): 
$instance->$method()")
  -                if ($Widget::DEBUG && Widget->dbg(ref($self),"shutdown"));
  -     
  -            $instance->$method();
  -            delete $self->{repository}{$repname};
  -        }
  -    }
  -}
  -
  -sub domain {
  -    my ($self, $domain) = @_;
  -    my ($config, $domainref, $repository, $rep);
  -    my ($values, $labels, $needs_loading, $time_to_live, $time);
  -    my ($class, $method, $args, $rows, $row);
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->domain($domain)")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"domain"));
  -
  -    $config = $self->{config};
  -    $domainref = $config->{domain}{$domain};
  -    if (defined $domainref) {
  -        $values = $domainref->{values};
  -        $labels = $domainref->{labels};
  -
  -        $needs_loading = 0;
  -        $repository = $domainref->{repository};
  -        if (defined $repository && $repository ne "") {
  -            if (!defined $values || !defined $labels) {
  -                $needs_loading = 1;
  -            }
  -            else {
  -                $time_to_live = $domainref->{time_to_live};
  -                if (defined $time_to_live && $time_to_live ne "" && $time_to_live 
>= 0) {
  -                    if ($time_to_live == 0) {
  -                        $needs_loading = 1;
  -                    }
  -                    else {
  -                        if (time() >= $domainref->{time} + $time_to_live) {
  -                            $needs_loading = 1;
  -                        }
  -                    }
  -                }
  -            }
  -        }
  -
  -        Widget->dbgprint("P5EEx::Blue::Context->domain($domain): 
needs_loading=$needs_loading")
  -            if ($Widget::DEBUG && Widget->dbg(ref($self),"domain"));
  -
  -        if ($needs_loading) {
  -            $rep = $self->repository($repository);
  -            if (defined $rep) {
  -                $method = $domainref->{getmethod};
  -                $method = "get" if (!defined $method);
  -                $args   = $domainref->{getmethod_args};
  -                $args   = [ $domain ] if (!defined $args);
  -
  -                Widget->dbgprint("P5EEx::Blue::Context->domain($domain): 
$rep->$method(@$args)")
  -                    if ($Widget::DEBUG && Widget->dbg(ref($self),"domain"));
  -
  -                $rows   = ${rep}->${method}(@$args);
  -                $values = [];
  -                $labels = {};
  -                foreach $row (@$rows) {
  -                    push(@$values, $row->[0]);
  -                    $labels->{$row->[0]} = $row->[1];
  -                }
  -                $domainref->{values} = $values;
  -                $domainref->{labels} = $labels;
  -                $time = time();
  -                $domainref->{time} = $time;
  -            }
  -        }
  -
  -        $values = $domainref->{values};
  -        $labels = $domainref->{labels};
  -    }
  -    $values = [] if (! defined $values);
  -    $labels = {} if (! defined $labels);
  -    return ($values, $labels);
  -}
  -
  -# The widget config is a simple hash which is the result of several
  -# complementary sources:
  -#   1. config of the widget (in Config) (which override widgetType)
  -#   2. optional config of the widget's widgetType (in Config)
  -#   3. config of container widget
  -#   4. args to the widget_config() call, usually coming from the widget constructor
  -#      some of these are defaults, other are overrides
  -# NOTES;
  -#   * we don't want to copy *all* attributes of container config, so
  -#     we need a list of "absorbable" attributes
  -#   * all widget configuration happens before instantiation
  -#     this allows you to override the widgetClass in time for instantiation
  -#   * widget_config's are cached in the Controller because the controller
  -#     needs to know the configuration before it can instantiate the widget.
  -#   * A reference to this config is kept by the widget for its own convenience.
  -
  -# Usage: $config = $wc->widget_config("last_name");
  -sub widget_config {
  -    my ($self, $name, $args) = @_;
  -    my ($confroot, $config, $readonly_config, $state, $widgetType, $attrib, 
$override);
  -    my ($new_config);
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->widget_config($name, " . join(", 
",(defined $args)?%$args:"") . ")")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"widget_config",3));
  -
  -    if (defined $self->{widgetconfig}{$name}) {
  -        $config = $self->{widgetconfig}{$name};
  -        $new_config = 0;
  -
  -        $state = $self->{state}{widget}{$name};
  -        $state = {} if (!defined $state);
  -    }
  -    else {
  -        ################################################################
  -        # set up the {config} and {state} hashrefs
  -        ################################################################
  -        $config = {};
  -        $self->{widgetconfig}{$name} = $config;
  -        $new_config = 1;
  -
  -        $state = $self->{state}{widget}{$name};
  -        $state = {} if (!defined $state);
  -
  -        ################################################################
  -        # start with runtime state for the widget from the state data
  -        ################################################################
  -        %$config = %$state;
  -        $config->{name} = $name;
  -
  -        ################################################################
  -        # overlay with attributes from the (read-only) config file
  -        ################################################################
  -        $confroot = $self->{config};
  -        $readonly_config = $confroot->{widget}{$name};
  -        foreach $attrib (keys %$readonly_config) {
  -            # include config attributes only if not provided in the state
  -            if (!defined $config->{$attrib}) {  
  -                $config->{$attrib} = $readonly_config->{$attrib};
  -            }
  -        }
  -
  -        ################################################################
  -        # overlay with attributes from the "widgetType"
  -        ################################################################
  -        $widgetType = $config->{widgetType};
  -        if ($widgetType) {
  -            $readonly_config = $confroot->{widgetType}{$widgetType};
  -            foreach $attrib (keys %$readonly_config) {
  -                # include widgetType configs only if not provided in the widget 
configs
  -                if (!defined $config->{$attrib}) {  
  -                    $config->{$attrib} = $readonly_config->{$attrib};
  -                }
  -            }
  -        }
  -    }
  -
  -    my ($lightweight);
  -    $lightweight = ($name =~ /[\[\]\{\}]/);  
  -
  -    ####################################################################
  -    # include defaults/overrides from args to $wc->widget($name, $args);
  -    ####################################################################
  -    if (defined $args && ref($args) eq "HASH") { # ... args were provided
  -        $override = $args->{override};   # don't override by default
  -
  -        ################################################################
  -        # take care of attributes associated with widgetType first
  -        ################################################################
  -        if ($args->{widgetType} &&
  -             ($override || !defined $config->{widgetType})) {
  -            $widgetType = $args->{widgetType};
  -            if (!$config->{widgetType} || $widgetType ne $config->{widgetType}) {
  -                $readonly_config = $confroot->{widgetType}{$widgetType};
  -                foreach $attrib (keys %$readonly_config) {
  -                    if (!defined $config->{$attrib} || $override) {
  -                        $config->{$attrib} = $readonly_config->{$attrib};
  -                    }
  -                }
  -            }
  -        }
  -
  -        ################################################################
  -        # take care of all %$args attributes next
  -        ################################################################
  -        foreach $attrib (keys %$args) {
  -            # don't include the entry which says whether we are overriding or not
  -            next if ($attrib eq "override");
  -
  -            # include attrib if overriding OR attrib not provided in the widget 
configs already
  -            if (!defined $config->{$attrib} ||
  -                ($override && $config->{$attrib} ne $args->{$attrib})) {  
  -                $config->{$attrib} = $args->{$attrib};
  -                # don't store state for lightweight widgets
  -                $state->{$attrib}  = $args->{$attrib} if (! $lightweight);
  -            }
  -            Widget->dbgprint("Controller->widget_config() [arg=$attrib] name=$name 
lw=$lightweight ovr=$override",
  -                " config=", $config->{$attrib},
  -                " state=", $state->{$attrib},
  -                " args=", $args->{$attrib})
  -                if ($Widget::DEBUG && Widget->dbg(ref($self),"widget_config",6));
  -        }
  -    }
  -
  -    ####################################################################
  -    # infer a container (if none supplied, by the dots in the "name")
  -    ####################################################################
  -    if (! defined $config->{container}) {
  -        if ($name =~ /^(.+)\./) {
  -            $config->{container} = $1;
  -        }
  -        elsif ($name eq "session") {
  -            $config->{container} = "global";
  -        }
  -        elsif ($name ne "global") {
  -            $config->{container} = "session";
  -        }
  -        if (defined $config->{widgetClass}) {
  -            Widget->use($config->{widgetClass}); # load the perl code
  -            $config->{absorbable_attribs} = 
$config->{widgetClass}->absorbable_attribs();
  -        }
  -    }
  -
  -    # absorb attributes of the container config if ...
  -    # TODO: sort out whether we need to absorb attributes more often
  -    #       (i.e. push model rather than a pull model)
  -    if ($new_config &&                      # ... it is the first time through
  -        $config->{container} &&             # ... a container exists
  -        $config->{absorbable_attribs}) {    # ... there are known attributes to 
absorb
  -
  -        my ($container, $container_config, $absorbable_attribs);
  -        $container = $config->{container};
  -        $container_config = $self->widget_config($container);  # notice a recursion 
here on containers
  -        $absorbable_attribs = $config->{absorbable_attribs};
  -        if (ref($absorbable_attribs) eq "") {
  -            $absorbable_attribs = [ split(/ *, */,$absorbable_attribs) ];
  -        }
  -        if (ref($absorbable_attribs) eq "ARRAY") {
  -            foreach $attrib (@$absorbable_attribs) {
  -                if (!defined $config->{$attrib}) {    # incorporate only if from no 
other source
  -                    $config->{$attrib} = $container_config->{$attrib};
  -                }
  -            }
  -        }
  -    }
  -
  -    if (!defined $self->{state}{widget}{$name} && !$lightweight && (%$state)) {
  -        $self->{state}{widget}{$name} = $state;
  -    }
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->widget_config($name) = [" . join(", 
",(defined $config)?%$config:"") . "]")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"widget_config",3));
  -
  -    return $config;
  -}
  -
  -# Usage: $widget = $wc->widget("first_name");
  -sub widget {
  -    my $self = shift;
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->widget(" . join(", ",@_) . ")")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"widget",3));
  -
  -    my ($args);
  -    my ($name, $widget, $config, $class, $oldclass);
  -
  -    if ($#_ == -1) {
  -        return undef;  # we need at least a name
  -    }
  -    elsif (ref($_[0]) eq "HASH") {
  -        $args = shift;
  -        $name = $args->{name};
  -    }
  -    elsif ($_[0] =~ /^-/) {
  -        $args = {};
  -        my ($i, $var);
  -        for ($i = 0; $i < $#_; $i += 2) {
  -            $var = $_[$i];
  -            $var =~ s/^-//;
  -            $args->{$var} = $_[$i+1];
  -        }
  -        $name = $args->{name};
  -    }
  -    else {
  -        $name = $_[0];
  -        $args = $_[1];
  -        # no other positional args for this class
  -    }
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->widget: name=[$name]")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"widget",3));
  -
  -    return undef if (! defined $name);    # we need a name!
  -    $config = $self->widget_config($name, $args);
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->widget: returned from widget_config()")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"widget",3));
  -
  -    $class = $config->{"widgetClass"};
  -    if (!defined $class || $class eq "") {
  -        if ($name ne "global") {
  -            $class = "Widget::HTML::TextField";
  -            $config->{"widgetClass"} = $class;
  -            $config->{backgroundColor} = "#ffcccc";
  -        }
  -    }
  -
  -    # NOTE: This does not allow widgets to change their class during execution
  -    # i.e. once the widget is instantiated as a particular class, it is stored
  -    # in the cache and never instantiated again.  I think this is what we want.
  -    # I could conceivably allow a widget to change its class.  Then it would
  -    # need to get reinstantiated as the new class, but I don't think this is 
  -    # what we want.
  -
  -    $widget = $self->{widget}{$name};    # check the cache
  -    if (!defined $widget) {
  -
  -        Widget->dbgprint("P5EEx::Blue::Context->widget(): creating new widget (not 
in cache)")
  -            if ($Widget::DEBUG && Widget->dbg(ref($self),"widget",3));
  -
  -        if (defined $class && $class ne "") {
  -            Widget->use($class);
  -            $widget = $class->new($name,$self,1);
  -        }
  -        else {
  -            $widget = {};
  -            $widget->{name} = $name;
  -            $widget->{controller} = $self;
  -        }
  -
  -        $self->{widget}{$name} = $widget;
  -    }
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->widget() = $widget")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"widget",3));
  -
  -    return $widget;
  -}
  -
  -sub get_table_cell {
  -    my ($self, $table, $rowkey, $colname) = @_;
  -    my ($tablehash, $rowidx, $colidx);
  -    $tablehash = $self->{config}{table}{$table};
  -    return undef if (!defined $tablehash);
  -    $rowidx = $tablehash->{rowindex}{$rowkey};
  -    $colidx = $tablehash->{colindex}{$colname};
  -    return "" if (!defined $rowidx || !defined $colidx);
  -    return $tablehash->{data}[$rowidx][$colidx];
  -}
  -
  -# $self->set("{arr}[1][2]",        14);
  -# $self->set("{arr.totals}[1][2]", 14);
  -#sub set {
  -#    my ($self, $var, $value) = @_;
  -#    my ($perl);
  -#
  -#    if ($var !~ /[\[\]\{\}]/) {         # no special chars, "foo.bar"
  -#        $self->{$var} = $value;
  -#        return;
  -#    } # match {
  -#    elsif ($var =~ /^\{([^\}]+)\}$/) {  # a simple "{foo.bar}"
  -#        $var = $1;
  -#        $self->{$var} = $value;
  -#        return;
  -#    } # match {
  -#
  -#    $var =~ s/\{([^\}]+)\}/\{"$1"\}/g;
  -#    $perl = "\$self->$var = \$value;";
  -#    eval $perl;
  -#    print STDERR "ERROR: P5EEx::Blue::Context->set($var,$value): eval ($perl): 
$@\n" if ($@);
  -#    return $value;
  -#}
  -
  -sub wget_value {
  -    my ($self, $name, $default, $setdefault) = @_;
  -    my ($wname, $var, $value);
  -    if ($name =~ /^(.+)\.([^\.]+)$/) {
  -        $wname = $1;
  -        $var = $2;
  -        $value = $self->{widgetconfig}{$wname}{$var};
  -        if (!defined $value && defined $default) {
  -            $value = $default;
  -            if ($setdefault) {
  -                $self->{state}{widget}{$wname}{$var} = $value;
  -                $self->widget_config($wname) if (!defined 
$self->{widgetconfig}{$wname});
  -                $self->{widgetconfig}{$wname}{$var} = $value;
  -            }
  -        }
  -    }
  -    else {
  -        $value = $self->{widgetconfig}{session}{$name};
  -        if (!defined $value && defined $default) {
  -            $value = $default;
  -            if ($setdefault) {
  -                $self->{state}{widget}{session}{$name} = $value;
  -                $self->{widgetconfig}{session}{$name} = $value;
  -            }
  -        }
  -    }
  -    return $value;
  -}
  -
  -sub wset_value {
  -    my ($self, $name, $value) = @_;
  -    my ($wname, $var);
  -
  -    if ($name =~ /^(.+)\.([^\.]+)$/) {
  -        $wname = $1;
  -        $var = $2;
  -        $self->{state}{widget}{$wname}{$var} = $value;
  -        $self->widget_config($wname) if (!defined $self->{widgetconfig}{$wname});
  -        $self->{widgetconfig}{$wname}{$var} = $value;
  -    }
  -    else {
  -        $self->{state}{widget}{session}{$name} = $value;
  -        $self->{widgetconfig}{session}{$name} = $value;
  -    }
  -}
  -
  -# $self->set("{arr}[1][2]",        14);
  -# $self->set("{arr.totals}[1][2]", 14);
  -sub wset {
  -    my ($self, $name, $var, $value) = @_;
  -    my ($perl, $multiple);
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->wget($name,$var,$value)")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"wset",3));
  -
  -    if ($var !~ /[\[\]\{\}]/) {         # no special chars, "foo.bar"
  -        $self->{state}{widget}{$name}{$var} = $value;
  -        $self->widget_config($name) if (!defined $self->{widgetconfig}{$name});
  -        $self->{widgetconfig}{$name}{$var} = $value;
  -        return;
  -    } # match {
  -    elsif ($var =~ /^\{([^\}]+)\}$/) {  # a simple "{foo.bar}"
  -        $var = $1;
  -        $self->{state}{widget}{$name}{$var} = $value;
  -        $self->widget_config($name) if (!defined $self->{widgetconfig}{$name});
  -        $self->{widgetconfig}{$name}{$var} = $value;
  -        return;
  -    } # match {
  -
  -    $self->widget_config($name) if (!defined $self->{widgetconfig}{$name});
  -    $var =~ s/\{([^\}]+)\}/\{"$1"\}/g;  # put quotes around hash keys
  -    $perl = "\$self->{state}{widget}{\$name}$var = \$value; 
\$self->{widgetconfig}{\$name}$var = \$value;";
  -    eval $perl;
  -    print STDERR "ERROR: P5EEx::Blue::Context->wset($name,$var,$value): eval 
($perl): $@\n" if ($@);
  -    return $value;
  -}
  -
  -sub wget {
  -    my ($self, $name, $var, $default, $setdefault) = @_;
  -    my ($perl, $value);
  -
  -    if ($var !~ /[\[\]\{\}]/) {         # no special chars, "foo.bar"
  -        $value = $self->{widgetconfig}{$name}{$var};
  -        if (!defined $value && defined $default) {
  -            $value = $default;
  -            if ($setdefault) {
  -                $self->{state}{widget}{$name}{$var} = $value;
  -                $self->widget_config($name) if (!defined 
$self->{widgetconfig}{$name});
  -                $self->{widgetconfig}{$name}{$var} = $value;
  -            }
  -        }
  -        Widget->dbgprint("P5EEx::Blue::Context->wget($name,$var) (value) = 
[$value]")
  -            if ($Widget::DEBUG && Widget->dbg(ref($self),"wget",3));
  -        return $value;
  -    } # match {
  -    elsif ($var =~ /^\{([^\}]+)\}$/) {  # a simple "{foo.bar}"
  -        $var = $1;
  -        $value = $self->{widgetconfig}{$name}{$var};
  -        if (!defined $value && defined $default) {
  -            $value = $default;
  -            if ($setdefault) {
  -                $self->{state}{widget}{$name}{$var} = $value;
  -                $self->widget_config($name) if (!defined 
$self->{widgetconfig}{$name});
  -                $self->{widgetconfig}{$name}{$var} = $value;
  -            }
  -        }
  -        Widget->dbgprint("P5EEx::Blue::Context->wget($name,$var) (attrib) = 
[$value]")
  -            if ($Widget::DEBUG && Widget->dbg(ref($self),"wget",3));
  -        return $value;
  -    } # match {
  -
  -    $self->widget_config($name) if (!defined $self->{widgetconfig}{$name});
  -    $var =~ s/\{([^\}]+)\}/\{"$1"\}/g;
  -    $perl = "\$value = \$self->{widgetconfig}{\$name}$var;";
  -    eval $perl;
  -    print STDERR "ERROR: Widget::Base->get($var): eval ($perl): $@\n" if ($@);
  -
  -    Widget->dbgprint("P5EEx::Blue::Context->wget($name,$var) (indexed) = [$value]")
  -        if ($Widget::DEBUG && Widget->dbg(ref($self),"wget",3));
  -    return $value;
  +    $self->{config};
   }
   
   1;
  
  
  
  1.2       +63 -49    p5ee/P5EEx/Blue/P5EEx/Blue/P5EE.pm
  
  Index: P5EE.pm
  ===================================================================
  RCS file: /cvs/public/p5ee/P5EEx/Blue/P5EEx/Blue/P5EE.pm,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- P5EE.pm   2001/11/16 23:21:38     1.1
  +++ P5EE.pm   2001/11/17 04:56:10     1.2
  @@ -1,6 +1,6 @@
   
   #############################################################################
  -## $Id: P5EE.pm,v 1.1 2001/11/16 23:21:38 spadkins Exp $
  +## $Id: P5EE.pm,v 1.2 2001/11/17 04:56:10 spadkins Exp $
   #############################################################################
   
   package P5EEx::Blue::P5EE;
  @@ -83,44 +83,44 @@
       $self->context(@_);
   }
   
  -my ($default_context);  # singleton
  +my (%context);  # singleton classes per name
   
   sub context {
       my $self = shift;
   
  -    my ($args, $context);
  +    my ($name, $args, $i);
       if ($#_ == -1) {
           $args = {};
  +        $name = "default";
       }
  -    elsif (ref($_[0]) eq "HASH") {
  +    else {
  +        if (ref($_[0]) eq "HASH") {
           $args = shift;
  -    }
  -    elsif ($_[0] =~ /^-/) {
  -        $args = {};
  -        my ($i, $var);
  -        for ($i = 0; $i < $#_; $i += 2) {
  -            $var = $_[$i];
  -            $var =~ s/^-//;
  -            $args->{$var} = $_[$i+1];
  +            $name = shift if ($#_ % 2 == 0);
  +            for ($i = 0; $i < $#_; $i++) {
  +                $args->{$_[$i]} = $_[$i+1];
           }
       }
       else {
  -        $args = {};
  -        # no positional args for this method
  +            $name = shift if ($#_ % 2 == 0);
  +            $args = ($#_ > -1) ? { @_ } : {};
       }
  +        $name = $args->{name} if (!$name);
  +        $name = "default" if (!$name);
  +    }
  +    return ($context{$name}) if (defined $context{$name});
       
  -    if (! $args->{context}) {
  +    if (! $args->{contextClass}) {
           if (defined $ENV{"P5EE_CONTEXT_CLASS"}) {     # env variable set?
  -            $args->{context} = $ENV{"P5EE_CONTEXT_CLASS"};
  +            $args->{contextClass} = $ENV{"P5EE_CONTEXT_CLASS"};
           }
           else {   # try autodetection ...
               my $gateway = $ENV{"GATEWAY_INTERFACE"};
               if (defined $gateway && $gateway =~ /CGI-Perl/) {  # running under 
mod_perl?
  -                $args->{context} = "P5EEx::Blue::Context::Modperl";
  +                $args->{contextClass} = "P5EEx::Blue::Context::Modperl";
               }
               elsif ($ENV{"HTTP_USER_AGENT"}) {  # running as CGI script?
  -                $args->{context} = "P5EEx::Blue::Context::CGI";
  -                $args->{state}      = "P5EEx::Blue::State::CGI";
  +                $args->{contextClass} = "P5EEx::Blue::Context::CGI";
               }
               # let's be real... these next two are not really critical right now
               #elsif ($ENV{"DISPLAY"}) {         # running with an X DISPLAY var set?
  @@ -130,51 +130,65 @@
               #    $args->{context} = "P5EEx::Blue::Context::Curses";
               #}
               else {                             # fall back to CGI, because it works 
OK in command mode
  -                $args->{context} = "P5EEx::Blue::Context::CGI";
  -                $args->{state}      = "P5EEx::Blue::State::CGI";
  +                $args->{contextClass} = "P5EEx::Blue::Context::CGI";
               }
           }
       }
   
  -    if (!defined $args->{config} || $args->{config} eq "") {
  -        if (defined $ENV{"P5EE_CONFIG_CLASS"}) {
  -            $args->{config} = $ENV{"P5EE_CONFIG_CLASS"};
  -        }
  +    $context{$name} = $self->create($args->{contextClass}, $args);
  +    return $context{$name};
       }
   
  -    $context = $self->create($args->{context}, $args);
  -    $default_context = $context if (!defined $default_context);
  -    return $context;
  +sub config {
  +    my $self = shift;
  +
  +    my ($name, $args, $i);
  +    if ($#_ == -1) {
  +        $args = {};
  +        $name = "default";
  +    }
  +    else {
  +        if (ref($_[0]) eq "HASH") {
  +            $args = shift;
  +            $name = shift if ($#_ % 2 == 0);
  +            for ($i = 0; $i < $#_; $i++) {
  +                $args->{$_[$i]} = $_[$i+1];
   }
  +        }
  +        else {
  +            $name = shift if ($#_ % 2 == 0);
  +            $args = ($#_ > -1) ? { @_ } : {};
  +        }
  +        $name = $args->{name} if (!$name);
  +        $name = "default" if (!$name);
  +    }
   
  -sub default_context {
  -    my $self = shift;
  -    return ($default_context) if (defined $default_context);
  -    return P5EEx::Blue->context(@_);
  +    $self->context($args)->config();
   }
   
  +my (%used);
  +
   sub create {
       my $self = shift;
       my $class = shift;
  +    if ($class =~ /^([A-Za-z0-9:_]+)$/) {
  +        $class = $1;
  +        if (! $used{$class}) {
       eval("use $class;");
  -    return undef if ($@);
  +            if ($@) {
  +                print STDERR "Error creating object: $@\n";
  +                return undef;
  +            }
  +            $used{$class} = 1;
  +        }
       return $class->new(@_);
   }
  +    return undef;
  +}
   
   #############################################################################
   # METHODS
   #############################################################################
  -
  -sub current_directory {
  -    eval("use Cwd;");
  -    cwd();
  -}
  -
  -sub command {
  -    my $cmd = $0;
  -    $cmd =~ s!^\.\/!!;
  -    return $cmd;
  -}
   
   #############################################################################
   # DEBUG SUPPORT
  
  
  
  1.1                  p5ee/P5EEx/Blue/examples/Config.1
  
  Index: Config.1
  ===================================================================
  #!/usr/local/bin/perl -wT
  
  use lib "..";
  use P5EEx::Blue::P5EE;
  
  $config = P5EEx::Blue::P5EE->config();
  print "FROM PERL: ", $config->dump(), "\n";
  
  $config = P5EEx::Blue::P5EE->config(
      configClass => "P5EEx::Blue::Config::XML",
  );
  print "FROM XML: ", $config->dump(), "\n";
  
  $config = P5EEx::Blue::P5EE->config(
      configClass => "P5EEx::Blue::Config::Inifiles",
  );
  print "FROM INI: ", $config->dump(), "\n";
  
  
  
  
  1.1                  p5ee/P5EEx/Blue/examples/config.pl
  
  Index: config.pl
  ===================================================================
  $conf = {
    Session => {
      default => {
        sessionClass => "P5EE::Blue::Session::CGI",
      },
    },
    Standard => {
      'Log-Dispatch' => {
        logdir => '/var/p5ee',
      }
    },
    Authen => {
      passwd => '/etc/passwd',
      seed => 303292,
    },
  };
  
  
  
  


Reply via email to