### ### Copyright 2000-2007 University of Illinois Board of Trustees ### All rights reserved. ### ### PSGConf::Data::Hash - hash data type for PSGConf::Data ### ### Campus Information Technologies and Educational Services ### University of Illinois at Urbana-Champaign ### package PSGConf::Data::Hash; use strict; use PSGConf::Data; our @ISA = qw(PSGConf::Data); ############################################################################### ### default method is insert() ############################################################################### sub default { my ($self, $value) = @_; $self->insert($value); } ############################################################################### ### unset method ############################################################################### sub unset { my ($self) = @_; $self->SUPER::set({}); return 1; } ############################################################################### ### set method ############################################################################### sub set { my ($self, $value) = @_; # print "==> Hash::set($value)\n"; $self->unset(); return $self->insert($value); } ############################################################################### ### insert method ############################################################################### sub insert { my ($self, $value) = @_; my ($key1, $key2); # print "==> Hash::insert($value)\n"; die "insert: method requires hash argument\n" if (ref($value) ne 'HASH'); $self->set({}) if (!defined($self->get())); foreach $key1 (keys %$value) { print "\t'$key1' => '$value->{$key1}'\n" if ($self->{'debug'}); die "key must be an absolute path\n" if ($self->{'key_abspath'} && $key1 !~ m|^/|); if (!defined($value->{$key1})) { ### FIXME: Need to clean up the abstraction here die "hash value missing\n" if (!$self->{'value_optional'}); } else { ### FIXME: Need to clean up the abstraction here die "hash value is not a $self->{'value_type'}\n" if (defined($self->{'value_type'}) && $self->{'value_type'} ne ref($value->{$key1})); ### FIXME: Need to clean up the abstraction here die "value must be an absolute path\n" if ($self->{'value_abspath'} && $value->{$key1} !~ m|^/|); } if ($self->find($key1)) { # print "key1='$key1'\n"; if (ref($self->find($key1)) eq 'HASH') { # print "key1={" . join(',', sort keys %{$self->find($key1)}) . "}\n"; foreach $key2 (keys %{$value->{$key1}}) { # print "\tkey2='$key2'\n"; ### FIXME: Need to clean up the abstraction here $self->{'value'}->{$key1}->{$key2} = $value->{$key1}->{$key2}; } # print "'$key1' => { " . join(', ', sort keys %{$self->find($key1)}) . " }\n"; next; } elsif (ref($self->find($key1)) eq 'ARRAY') { push(@{$self->find($key1)}, @{$value->{$key1}}); next; } } ### ### overwrite the existing entry or create a new one ### ### FIXME: Need to clean up the abstraction here print "OVERRIDE: $value->{$key1}\n" if ($self->{'debug'}); $self->{'value'}->{$key1} = $value->{$key1}; } return 1; } ############################################################################### ### exists method ############################################################################### sub exists { my ($self, $value) = @_; return (exists($self->{'value'}->{$value})); } ############################################################################### ### find method ############################################################################### sub find { my ($self, $value) = @_; ### FIXME: Need to clean up the abstraction here return (exists($self->{'value'}->{$value}) ? $self->{'value'}->{$value} : undef); } ############################################################################### ### delete method ############################################################################### sub delete { my ($self, $value) = @_; my ($val); $value = $self->_scalar_or_list($value); foreach $val (@$value) { ### FIXME: Need to clean up the abstraction here delete $self->{'value'}->{$val}; } return 1; } ############################################################################### ### count method ############################################################################### sub count { my ($self) = @_; return scalar keys %{$self->get()}; } ############################################################################### ### documentation ############################################################################### 1; __END__ =head1 NAME PSGConf::Data::Hash - hash data type class for PSGConf =head1 SYNOPSIS use PSGConf::Data::Hash; $psgconf->register_data( 'hashobj' => PSGConf::Data::Hash->new( 'value_abspath' => 1, ... ) ); =head1 DESCRIPTION The B module provides a class that represents a hash in an object so that it can be used with B. Its methods can be used to manipulate the encapsulated hash from the B data store(s). The B class is derived from the B class, but it defines/overrides the following methods: =over 4 =item insert() Inserts the specified values into the object's hash. The argument must be a reference to a hash, whose keys and values are copied into the object's hash. If the values are lists, inserting a key that already exists will append the new list to the existing list. If the values are hashes, inserting a key that already exists will insert the new key/value pairs into the existing value hash. If the object was created with the I attribute enabled, keys may be inserted with no defined values. If the object was created with the I attribute set to either "ARRAY" or "HASH", then the hash values must be references to the corresponding structure type. If the object was created with the I attribute enabled, the hash values must be absolute path strings. If the object was created with the I attribute enabled, the hash keys must be absolute path strings. =item set() The same as insert(), except that the existing hash is emptied by calling the unset() method before inserting the new data. =item default() Calls the insert() method. =item unset() Sets the object's value to an empty hash. =item delete() Deletes a specific hash key. The argument can be a scalar or a reference to a list, in which case all of the keys in the list are deleted. =item exists() Returns true if the hash is defined, false otherwise. =item find() If the argument is found in the hash, returns its value. Otherwise, returns false. =item count() Returns the number of keys in the hash. =back =head1 BUGS The I and I attributes should be replaced by a generic mechanism that allows the caller to supply a reference to a subroutine that will be called to validate the key and value data. =head1 SEE ALSO L L L =cut