Author: spadkins
Date: Wed Nov  7 09:20:07 2007
New Revision: 10188

Modified:
   p5ee/trunk/App-Context/lib/App/Context.pm
   p5ee/trunk/App-Context/t/App.t

Log:
add global include support

Modified: p5ee/trunk/App-Context/lib/App/Context.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App/Context.pm   (original)
+++ p5ee/trunk/App-Context/lib/App/Context.pm   Wed Nov  7 09:20:07 2007
@@ -250,9 +250,17 @@
         $self->dbgprint(join("",@str));
     }
 
+    ##############################################################
+    # initialize conf
+    ##############################################################
     my $conf = {};
+
     eval {
+
+        # Initialize from "app.pl" or other file/source specified by the class
         $conf = App->new($conf_class, "new", \%options);
+
+        # Override any values which are supplied in "app.conf" (the 
"deployment descriptor")
         foreach my $var (keys %options) {
             if ($var =~ /^app\.(.+)/) {
                 $conf->set($1, $options{$var});
@@ -260,8 +268,53 @@
         }
     };
     $self->add_message($@) if ($@);
+
     $self->{conf} = $conf;
 
+    ##############################################################
+    # Include and Overlay $conf with additional files
+    ##############################################################
+    my ($includes);
+    $includes = $conf->{global}{include} if ($conf->{global});
+    if ($includes && ref($includes) eq "ARRAY") {
+        my $options = $self->{options};
+        my $prefix  = $options->{prefix};
+        my (@include_files, $cond, $include_files, $matches);
+        for (my $i = 0; $i <= $#$includes; $i += 2) {
+            $cond = $includes->[$i];
+            $include_files = $includes->[$i+1];
+            $matches = $self->cond_matches_options($cond, $options);
+            if ($matches) {
+                if (ref($include_files) eq "ARRAY") {
+                    @include_files = @$include_files;
+                }
+                elsif (ref($include_files) eq "") {
+                    @include_files = ( $include_files );
+                }
+                foreach my $conf_file (@include_files) {
+                    $conf_file = "$prefix/etc/app/$conf_file" if ($conf_file 
!~ m!^/!);
+                    if ($self->{conf_included}{$conf_file}) {
+                        print STDERR "Conf global include: [$cond][$conf_file] 
already included\n" if ($options{debug_conf});
+                        next;
+                    }
+                    if (-r $conf_file) {
+                        my $aux_conf = $conf_class->create({ conf_file => 
$conf_file });
+                        $conf->overlay($aux_conf);
+                        print STDERR "Conf global include: [$cond][$conf_file] 
included (overlayed)\n" if ($options{debug_conf});
+                    }
+                    else {
+                        print STDERR "Conf global include: [$cond][$conf_file] 
not readable\n" if ($options{debug_conf});
+                    }
+                    $self->{conf_included}{$conf_file} = 1;
+                }
+            }
+            print STDERR "Conf global include: [$cond] did not match 
options\n" if (!$matches && $options{debug_conf});
+        }
+    }
+
+    ##############################################################
+    # misc
+    ##############################################################
     if ($options{debug_conf} >= 2) {
         $self->dbgprint($self->{conf}->dump());
     }
@@ -288,6 +341,43 @@
     return("App::Session");
 }
 
+# NOTE: This is very similar logic to some logic in App::Options to see if 
sections
+#       of app.conf are active.
+sub cond_matches_options {
+    &App::sub_entry if ($App::trace);
+    my ($self, $cond_str, $options) = @_;
+    my ($var, $value, $regexp, $cond, $cond_value);
+    my $matches = 1;                      # assume the condition matches
+    my @cond = split(/;/,$cond_str);      # separate the conditions that must 
be satisfied
+    foreach $cond (@cond) {  # check each condition
+        if ($cond =~ /^([^=]+)=(.*)$/) {  # i.e. city=ATL or name=/[Ss]tephen/
+            $var = $1;
+            $cond_value = $2;
+        }
+        else {              # i.e. [go] matches the program (app) named "go"
+            $var = "app";
+            $cond_value = $cond;
+        }
+        if ($cond_value =~ m!^/(.*)/$!) {  # variable's value must match the 
regexp
+            $regexp = $1;
+            $value = $options->{$var};
+            $value = "" if (!defined $value);
+            $matches = ($value =~ /$regexp/) ? 1 : 0;
+        }
+        elsif ($var eq "app" && ($cond_value eq "" || $cond_value eq "ALL")) {
+            $matches = 1;   # "" and "ALL" are special wildcards for the "app" 
variable
+        }
+        else {  # a variable's value must match exactly
+            $value = $options->{$var};
+            $value = "" if (!defined $value);
+            $matches = ($value eq $cond_value) ? 1 : 0;
+        }
+        last if (!$matches);
+    }
+    &App::sub_exit($matches) if ($App::trace);
+    return($matches);
+}
+
 #############################################################################
 # PROTECTED METHODS
 #############################################################################

Modified: p5ee/trunk/App-Context/t/App.t
==============================================================================
--- p5ee/trunk/App-Context/t/App.t      (original)
+++ p5ee/trunk/App-Context/t/App.t      Wed Nov  7 09:20:07 2007
@@ -23,7 +23,7 @@
 $config = App->conf("conf_file" => "$dir/app.pl");
 ok(defined $config, "constructor ok");
 isa_ok($config, "App::Conf", "right class");
-is_deeply($conf, { %$config }, "config to depth");
+is_deeply({ %$config }, $conf, "config to depth");
 
 ########################################################
 # use()

Reply via email to