package AddressBook::Config;
=head1 NAME
AddressBook::Config - AddressBook configuration object
=head1 SYNOPSIS
The AddressBook::Config object contains the list of cannonical attribute names,
their respective backend database equivalents, attribute metadata, and backend
database attributes.
$config = AddressBook::Config->new(config_file=>$filename);
AddressBook::Config looks for a configuration file in /etc/AddressBook.conf if
no config_file parameter is present.
=head1 DESCRIPTION
Configuration is read from an XML configuration file which follows this DTD:
]>
For example,
This defines three attributes with cannonical names "firstname", "lastname", and
"fullname". These are accessed in the LDAP backend context as "givenname", "sn" and
"cn", and in the HTML backend context as "First Name", "Last Name" and "Full Name"
respectively.
The default attribute ordering is "firstname", "lastname", "fullname", however
the HTML backend overrides this and in that context attributes are ordered: "lastname",
"firstname", "fullname". All other meta-attributes may be similarily overriden by
specific backends
"fullname" is a calculated attribute. Calculation strings may reference the
names of other attributes by "$".
Backend databases may also be named and then tied to a source type by using the 'driver'
attribute. This technique is useful for defining multiple backends of the same type.
For example,
See the various backend man pages for information on the configuration
attributes. See also the sample configuration files in the 'examples' directory.
=cut
use AddressBook;
use strict;
use Carp;
use XML::DOM;
use vars qw($VERSION);
$VERSION = '0.13';
$AddressBook::Config::config_file = "/etc/AddressBook.conf";
#----------------------------------------------------------------
sub new {
my $class=shift;
my %args = @_;
my $self = {};
bless ($self,$class);
my ($parser,$config,$field,$field_name,$attr,$db_type,$db_field_name,$db,$select,$option,$value);
$self->{config_file} = $args{config_file} || $AddressBook::Config::config_file;
eval {
$parser = XML::DOM::Parser->new(ErrorContext=>1,
ParseParamEnt=>1,
ProtocolEncoding=>'UTF-8');
$config = $parser->parsefile($self->{config_file});
};
if ($@ || ! $config) {
$self->configError("Error reading config file: $@");
}
foreach $field ($config->getElementsByTagName("field")){
$field_name=$field->getAttribute("name");
foreach $attr ($field->getAttributes->getValues) {
$self->{meta}->{$field_name}->{$attr->getName} = $attr->getValue;
}
foreach $db ($field->getElementsByTagName("db")) {
$db_type=$db->getAttribute("type");
$db_field_name=$db->getAttribute("name");
$self->{generic2db}->{$field_name}->{$db_type} = $db_field_name;
$self->{db2generic}->{$db_type}->{$db_field_name} = $field_name;
foreach $attr ($db->getAttributes->getValues) {
if ($attr->getName !~ /^type|name$/) {
$self->{dbmeta}->{$db_type}->{$field_name}->{$attr->getName} = $attr->getValue;
}
}
}
}
my ($n) = $config->getElementsByTagName("databases");
my ($db_name);
if ($n) {
foreach $db ($n->getElementsByTagName("*")) {
$db_name=$db->getTagName;
foreach $attr ($db->getAttributes->getValues) {
$self->{db}->{$db_name}->{$attr->getName} = $attr->getValue;
}
}
}
foreach (keys %{$self->{db2generic}}) {
if (! exists $self->{db}->{$_}->{driver}) {
$self->{db}->{$_}->{driver} = $_;
}
}
$self->validate();
return $self;
}
#----------------------------------------------------------------
sub validate {
my $self=shift;
my $class = ref $self || croak "Not a method call.";
my ($db);
foreach $db (keys %{$self->{db}}) {
next unless ($self->{db}->{$db}->{key_fields});
foreach (split ",", $self->{db}->{$db}->{key_fields}) {
if (! exists $self->{db2generic}->{$db}->{$_}) {
$self->configError("key field \"$_\" is not a valid attribute for backend $db");
}
}
}
}
#----------------------------------------------------------------
sub configError {
my $self=shift;
my $class = ref $self || croak "Not a method call.";
my $msg = shift;
croak "Configuration File Error (".$self->{config_file}."):\n$msg\n";
}
#----------------------------------------------------------------
=head2 getMeta
%meta = %{$config->getMeta(attr=>$attr)}
%meta = %{$config->getMeta(attr=>$attr,db=>$db)}
Returns an attribute metadata hash
=cut
sub getMeta {
my $self = shift;
my $class = ref $self || croak "Not a method call.";
my %args = @_;
my %ret;
if (exists $args{attr} && exists $self->{meta}->{$args{attr}}) {
%ret = %{$self->{meta}->{$args{attr}}};
}
if ($args{db}) {
foreach (keys %{$self->{dbmeta}->{$args{db}}->{$args{attr}}}) {
$ret{$_} = $self->{dbmeta}->{$args{db}}->{$args{attr}}->{$_};
}
}
return \%ret;
}
1;
__END__
=head1 AUTHOR
David L. Leigh,
=head1 SEE ALSO
L
L
=cut