############################################################################### # CLASS Clearcase::CmdProc # Derived Class of CCCmd that provides the basic framework for storing the results # of executing the command in the base class. It also provides the framework # to allow further processing of the stored data. # Derived classes should override the CCCmd base classes CCProcess member to # allow the derived class to process the result of the Cmd and use the framework # provided to store information about the files produced by the CCCmd output. # # The class stores information in a member called FILEINFO that is an array of # annonymous hashes. The contents of the hash's store information about each file. # A Hash FILEINDEX is used to as an index into the array the hash is keyed by the # file name and each key stores the index number of that file in the array. # A CURRENTFILEINDEX element hold the index of the current element being processed # # A new element is added to the array by using the addToFileList member. It sets # the array element hash to contain the file name and also updates the index & # sets the CURRENTFILEINDEX to the index of the file in the array. # # The updateCurrentFile member allows additional fields to be added to the current # elements hash by supplying hash key & value to be added. ############################################################################### package Clearcase::CmdProc; use strict; use DeployUtils::Logger; use Clearcase::Cmd; # Inherits from CCCmd use vars qw( @ISA ); @ISA = qw( Clearcase::Cmd ); #============================================================================== # Constructor #============================================================================== sub new { my $obclass = shift; my $class = ref($obclass) || $obclass; LogDebug("Clearcase::CmdProc::new Instantiating new object of class $class"); # Call base class's constructor my $self = $class->SUPER::new(); # Add this class's data to the class object $self->{FILEINFO} = []; # array whose elements are hashes used to hold information about CC files $self->{FILEINDEX} = { }; # hash on file names storing position of file in array above $self->{CURRENTFILEINDEX} = undef; # holds the index of the current element in the array, bless($self, $class); # reconsecrate return($self); } # new #============================================================================== # FileInfoDump prints the contents of the FILEINFO array # It simply uses the Data::Dumper to dump the contents of the array #============================================================================== sub FileInfoDump { use Data::Dumper; my $self = shift; print Data::Dumper->Dump([$self->{FILEINFO}], ["FileList"]); } # CCprint #============================================================================== # addToFileList adds the information to the File list # The 1st parameter is the file to add. # If the name is not in the list it pushes a hash containing the file name # onto array and adds it to the index hash with the array element number. # The contents of the array element can be updated as needed # If name is in hash it does nothing. # Regardless it returns the array element number for name and is stored locally # in the class hash to allow additional changes to element #============================================================================== sub addToFileList { my $self = shift; my $name = shift; if ( ! defined($self->{FILEINDEX}{$name}) ) { push(@{$self->{FILEINFO}}, { NAME => $name } ); $self->{CURRENTFILEINDEX} = $#{$self->{FILEINFO}}; $self->{FILEINDEX}{$name} = $self->{CURRENTFILEINDEX}; LogDebug("Clearcase::CmdProc::addToFileList Added $name to list at index $self->{CURRENTFILEINDEX}"); } else { $self->{CURRENTFILEINDEX} = $self->{FILEINDEX}{$name}; LogDebug("Clearcase::CmdProc::addToFileList File $name exists in list just return index $self->{CURRENTFILEINDEX}"); } return $self->{CURRENTFILEINDEX}; } # addToFileList #============================================================================== # updateCurrentFile # Updates/adds fields to the current FILEINFO element $self->{CURRENTFILEINDEX}. # The paramaters should be passed in groups of 2 so that each group of 2 contains # The Hash key Name and its value # eg updateCurrentFileListElement("STATE", "CHECKEDOUT", "VERSION", 2); #============================================================================== sub updateCurrentFile { my $self = shift; # correct number of parameters? if ( ($#_+1)%2 != 0 ) { LogError("Clearcase::CmdProc::updateCurrentFile Incorrect number of params passed to function."); } my $index = $self->{CURRENTFILEINDEX}; LogError("Clearcase::CmdProc::updateCurrentFile Calling this member when CurrentFileIndex is undefined") if ( !defined($index) ); for ( my $i=0; $i < $#_; $i+=2 ) { $self->{FILEINFO}[$index]{$_[$i]} = $_[$i+1]; } } # updateCurrentFile #============================================================================== # getNumElements # Returns the number of elements in the FILEINFO ARRAY #============================================================================== sub getNumElements { my $self = shift; return ($#{$self->{FILEINFO}} + 1 ); } # getNumElements #============================================================================== # getFirstElement # Returns a reference to the hash in the first element of the array & sets # $self->{CURRENTFILEINDEX} to 0. Returns undef if array is empty #============================================================================== sub getFirstElement { my $self = shift; if ( $#{$self->{FILEINFO}} >= 0 ) { $self->{CURRENTFILEINDEX} = 0; return \%{$self->{FILEINFO}[$self->{CURRENTFILEINDEX}]}; } else { $self->{CURRENTFILEINDEX} = undef; return undef; } } # getFirstElement #============================================================================== # getNextElement # Increments $self->{CURRENTFILEINDEX} and returns a reference to the hash in # that element of the array, returns undef at end of array #============================================================================== sub getNextElement { my $self = shift; if ( $self->{CURRENTFILEINDEX} < $#{$self->{FILEINFO}} ) { return \%{$self->{FILEINFO}[++$self->{CURRENTFILEINDEX}]}; } else { $self->{CURRENTFILEINDEX} = undef; return undef; } } # getNextElement #============================================================================== # getElement # Returns a reference to the hash located at the index supplied. Returns undef # if that index is invalid or does not exist. Sets $self->{CURRENTFILEINDEX} # to index if successfull #============================================================================== sub getElement { my $self = shift; my $index = shift; if ( $index >= 0 && $index <= $#{$self->{FILEINFO}} ) { $self->{CURRENTFILEINDEX} = $index; return \%{$self->{FILEINFO}[$self->{CURRENTFILEINDEX}]}; } else { LogWarn("Clearcase::CmdProc::getElement Index out of range"); $self->{CURRENTFILEINDEX} = undef; return undef; } } # getElement #============================================================================== # findName # Seaches for element defined by name supplied. # if found returns a reference to the hash for that element, otherwise undef #============================================================================== sub findName { my $self = shift; my $name = shift; LogError("CmdProc::findName must supply name to find") if ( ! defined($name) ); if ( defined($self->{FILEINDEX}{$name}) ) { return \%{$self->{FILEINFO}[$self->{FILEINDEX}{$name}]}; } else { return undef; } } # findName 1;