Apache::Admin::Config Include loop

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Hey all,

I am trying to subclass Apache::Admin::Config in order to add some
properties and a method that will parse the config tree looking for
Apache 'Include' directives. When it encounters the 'Include' directive
I want the method to create and new object around the file specified by
the directive and then add that files directives to the current tree.

The problem is that I need it to be recursive so that it will
find/parse 'Include' directives throughout the config tree. Ultimately,
I want a single config tree that contains all the directives that were
in seperate files specified by 'Include' directives.

For example:

# in a file, main.conf
ServerName test.me.com
DocumentRoot /var/www/html
Include sub.conf

# in another file, sub.conf
<VirtualHost *>
    ServerName sub1.me.com
    DocumentRoot /var/www/html/sub1

# I then instaniate my subclass of Apache::Admin::Config

my $conf = MyConfigSubclass->new('main.conf')

# And call the method I'm trying to write

# And now I have the $conf object whose tree looks like:
ServerName test.me.com
DocumentRoot /var/www/html

<VirtualHost *>
    ServerName sub1.me.com
    DocumentRoot /var/www/html/sub1

# Notice that the 'Include' directive has been replaced with
# the contents of sub.conf

Here is want I've been working with, which appears to be working on a
sample set of Apache
config files:

package MyConfigSubclass;

use base qw(Apache::Admin::Config)


sub parse_includes {
    my $self = shift;

    # Instance method
    return unless ref($self);

    # Loop through all
    foreach my $conf ($self->select()) {
        # Handle includes
        if ($conf->type() eq 'directive' &&
            $conf->name() =~ m/include/i) {

            # Use glob to handle wildcard Include directive
            my @dir = glob($conf->value());

            # Establish target directive for adding directives.
            # We want to add the include files in alphabetical order
            # so we sort the file list and then set our target to the
            # last added directive
            @dir = sort(@dir);
            my $target = $conf;

            # Loop through files
            foreach my $f (@dir) {
                # Create new instance for include file
                my $inc_conf = __PACKAGE__->new($f) ||
                    die $__PACKAGE__::ERROR;

                # Parse new conf

                # Add new config object after the 'Include' directive
                $target = $self->add(
                                      "\nBEGIN " . $f,
                                      -after=> $target )
                    || die $self->error();
                $target = $self->add(
                                      -after => $target )
                    || die $self->error();
                $target = $self->add(
                                      "\nEND " . $f,
                                      -after => $target )
                    || die $self->error();

            #Delete the Include directive
            $conf->delete() || die $self->error();

        # Recursive parse for sections
        elsif ($conf->type() eq 'section') {
            # Create new object container
            my $con_conf = __PACKAGE__->new() ||
                die $__PACKAGE__::ERROR;

            # Manually assign tree by reference so changes propogate up
            $con_conf-> = $conf;

            # Parse it

As I said before, this seems to work on a sample set of Apache config
files, but I wanted to get some opinions on it. Does this look ok? Any
suggestions/ideas to do it better? This recursive OO loop stuff is
really messing with my head.
Thanks very much in advance for any help.

Matt Pitts

Site Timeline