File: //var/opt/OV/bin/instrumentation/DiscoverResult.pm
#######################
#
# Version : 11.11.025
#
#######################
# DiscoverResult.pm
# ported from vb to perl Aug 1, 2001 Frank Anderson
#--------------------- LinkNode ---------------------------
package LinkNode;
sub new {
my $this = shift;
my $class = ref( $this ) || $this;
my $self = {};
bless $self, $class;
$self->_initialize;
return $self;
}
sub _initialize {
my $self = shift;
$self->{ITEM} = "";
$self->{NEXT} = "";
}
sub item {
my $self = shift;
if (@_) { $self->{ITEM} = shift; }
return $self->{ITEM};
}
sub nxt {
my $self = shift;
if (@_) { $self->{NEXT} = shift; }
return $self->{NEXT};
}
#--------------------- LinkList ----------------------
package LinkList;
sub new {
my $this = shift;
my $class = ref( $this ) || $this;
my $self = {};
bless $self, $class;
$self->_initialize;
return $self;
}
sub _initialize {
my $self = shift;
$self->{HEAD} = LinkNode->new;
$self->{CURRENT} = LinkNode->new;
my $link = LinkNode->new;
$link->item( "" );
$link->nxt( "" );
$self->{HEAD} = $link;
$self->{CURRENT} = $self->{HEAD};
}
sub Reset {
my $self = shift;
$self->{CURRENT} = $self->{HEAD};
}
sub Add {
my $self = shift;
foreach $item ( @_ ) {
my $link = LinkNode->new;
$link->item( $item );
$link->nxt( $self->{HEAD}->nxt );
$self->{HEAD}->nxt( $link );
}
}
sub HasMoreItems {
my $self = shift;
if ( ref $self->{CURRENT}->nxt ) {
return 1;
} else {
return 0;
}
}
sub NextItem {
my $self = shift;
my $nextItem = "";
if ( ref $self->{CURRENT}->nxt ) {
$self->{CURRENT} = $self->{CURRENT}->nxt;
$nextItem = $self->{CURRENT}->item;
}
return $nextItem;
}
package InstanceDef;
#-------- Classes to hold instance and relationship data -------
sub new {
my $this = shift;
my $class = ref( $this ) || $this;
my $self = {};
bless $self, $class;
$self->_initialize;
return $self;
}
sub _initialize {
my $self = shift;
$self->{sREF} = "";
$self->{sSTD} = "";
$self->{bVIRTUAL} = 0;
$self->{sGUID} = "";
$self->{sKEY} = "";
$self->{sGRAPH_ID} = "";
$self->{sATTRS} = "";
}
sub sRef {
my $self = shift;
if (@_) { $self->{sREF} = shift; }
return $self->{sREF};
}
sub sStd {
my $self = shift;
if (@_) { $self->{sSTD} = shift; }
return $self->{sSTD};
}
sub bVirtual {
my $self = shift;
if (@_) {
my $v = shift;
$v =~ s/true/1/i;
$v =~ s/false/0/i;
$self->{bVIRTUAL} = $v;
}
return $self->{bVIRTUAL};
}
sub sGuid {
my $self = shift;
if (@_) { $self->{sGUID} = shift; }
return $self->{sGUID};
}
sub sKey {
my $self = shift;
if (@_) { $self->{sKEY} = shift; }
return $self->{sKEY};
}
sub sGraphID {
my $self = shift;
if (@_) { $self->{sGRAPH_ID} = shift; }
return $self->{sGRAPH_ID};
}
sub sAttrs {
my $self = shift;
if (@_) { $self->{sATTRS} = shift; }
return $self->{sATTRS};
}
package Instance;
sub new {
my $this = shift;
my $class = ref( $this ) || $this;
my $self = {};
bless $self, $class;
$self->_initialize;
return $self;
}
sub _initialize {
my $self = shift;
$self->{sREF} = "";
}
sub sRef {
my $self = shift;
if (@_) { $self->{sREF} = shift; }
return $self->{sREF};
}
package Relationship;
sub new {
my $this = shift;
my $class = ref( $this ) || $this;
my $self = {};
bless $self, $class;
$self->_initialize;
return $self;
}
sub _initialize {
my $self = shift;
$self->{sPARENT_REF} = "";
$self->{sCHILD_REF} = "";
}
sub sParentRef {
my $self = shift;
if (@_) { $self->{sPARENT_REF} = shift; }
return $self->{sPARENT_REF};
}
sub sChildRef {
my $self = shift;
if (@_) { $self->{sCHILD_REF} = shift; }
return $self->{sCHILD_REF};
}
##############################################
package DiscoverResult;
##############################################
# This is the class used by customers to build result service XML
#------------- publics -------------
sub new {
my $this = shift;
my $class = ref( $this ) || $this;
my $self = {};
bless $self, $class;
$self->_initialize;
return $self;
}
sub SetAssignChar {
my $self = shift;
my ( $c ) = @_;
# Do not allow changes after an InstDef exists
$self->{ll_InstDefs}->Reset;
if ( not $self->{ll_InstDefs}->HasMoreItems and length( $c ) > 0 ) {
my @ta = split( "", $c );
$self->{m_assign_char} = $ta[0];
}
}
sub GetAssignChar {
my $self = shift;
return $self->{m_assign_char};
}
sub SetDelimChar {
my $self = shift;
my ( $c ) = @_;
# Do not allow changes after an InstDef exists
$self->{ll_InstDefs}->Reset;
if ( not $self->{ll_InstDefs}->HasMoreItems and length( $c ) > 0 ) {
my @ta = split( "", $c );
$self->{m_delim_char} = $ta[0];
}
}
sub GetDelimChar {
my $self = shift;
return $self->{m_delim_char};
}
sub DefineInstance {
my $self = shift;
my ($sRef, $Std, $Virtual, $Guid, $Key, $GraphID, $attrs) = @_;
my $InstDef;
if ( not $self->_InstDefExists($sRef) ) {
# Create new InstDef
$InstDef = InstanceDef->new;
$InstDef->sRef ( $sRef );
$InstDef->sStd ( $Std );
$InstDef->bVirtual ( $Virtual );
$InstDef->sGuid ( $Guid );
$InstDef->sKey ( $Key );
$InstDef->sGraphID ( $GraphID );
$InstDef->sAttrs ( $attrs );
$self->{ll_InstDefs}->Add( $InstDef );
}
}
sub CreateService {
my $self = shift;
my ($sRef) = @_;
my $Inst;
# Check if service is already created
$self->{ll_Insts}->Reset;
while ( $self->{ll_Insts}->HasMoreItems ) {
$Inst = $self->{ll_Insts}->NextItem;
if ( $Inst->sRef eq $sRef ) {
return;
}
}
# Not already created, has it been defined?
if ( $self->_InstDefExists( $sRef ) ) {
$Inst = Instance->new;
$Inst->sRef( $sRef );
$self->{ll_Insts}->Add( $Inst );
}
}
sub CreateComponent {
my $self = shift;
my ($parentref, $childref) = @_;
my $Relship;
# Check if component is already created
$self->{ll_Comps}->Reset;
while ( $self->{ll_Comps}->HasMoreItems ) {
$Relship = $self->{ll_Comps}->NextItem;
if ( $Relship->sParentRef eq $parentref and
$Relship->sChildRef eq $childref ) {
return;
}
}
# Not alread created, is it defined?
if ( $self->_InstDefExists( $parentref) and
$self->_InstDefExists( $childref ) ) {
$Relship = Relationship->new;
$Relship->sParentRef( $parentref );
$Relship->sChildRef( $childref );
$self->{ll_Comps}->Add( $Relship );
}
}
sub CreateDependent {
my $self = shift;
my ($parentref, $childref) = @_;
my $Relship;
# Check if dependent is already created
$self->{ll_Deps}->Reset;
while ( $self->{ll_Deps}->HasMoreItems ) {
$Relship = $self->{ll_Deps}->NextItem;
if ( $Relship->sParentRef eq $parentref and
$Relship->sChildRef eq $childref ) {
return;
}
}
# Not alread created, is it defined?
if ( $self->_InstDefExists( $parentref ) and
$self->_InstDefExists( $childref ) ) {
$Relship = Relationship->new;
$Relship->sParentRef ( $parentref );
$Relship->sChildRef ( $childref );
$self->{ll_Deps}->Add ( $Relship );
}
}
sub AddAttr {
my $self = shift;
my ($sRef, $name, $value) = @_;
my $i;
my $InstDef;
my $str;
# Exit if ref not defined
if ( not $self->_InstDefExists( $sRef ) ) {
return;
}
$InstDef = $self->_GetInstDef( $sRef );
# Check if "name" attr already exists, exit if so
if ( $InstDef->sAttrs ne "" ) {
$i = 0;
while ( $self->_GetNvp( $InstDef->sAttrs, $i ) ) {
if ( $self->{m_name} eq $name ) {
return;
}
$i++;
}
}
# Made it this far, add it
if ( length( $InstDef->sAttrs ) > 0 ) {
$str = $InstDef->sAttrs . $self->{m_delim_char} . $name .
$self->{m_assign_char} . $value;
$InstDef->sAttrs( $str );
} else {
$str = $InstDef->sAttrs . $name .
$self->{m_assign_char} . $value;
$InstDef->sAttrs( $str );
}
}
sub OutputResult {
my $self = shift;
print STDOUT $self->getXml;
}
sub getXml {
my $self = shift;
my $i;
my $count;
my $InstDef;
my $Inst;
my $Parent;
my $Child;
my $rtnStr;
# Start XML
$rtnStr = "\n<Service>\n";
# First output NewInstances
$self->{ll_Insts}->Reset;
while ( $self->{ll_Insts}->HasMoreItems ) {
$Inst = $self->{ll_Insts}->NextItem;
$InstDef = $self->_GetInstDef( $Inst->sRef );
$rtnStr .= " <NewInstance ref=" . $self->_Quo( $InstDef->sRef ) . ">\n";
$rtnStr .= $self->_getInstXml( $InstDef, 1, 6 );
$rtnStr .= " </NewInstance>\n";
}
# Now new relationships
$self->{ll_Comps}->Reset;
while ( $self->{ll_Comps}->HasMoreItems ) {
$Inst = $self->{ll_Comps}->NextItem;
$Parent = $self->_GetInstDef( $Inst->sParentRef );
$Child = $self->_GetInstDef( $Inst->sChildRef );
$rtnStr .= " <NewRelationship>\n";
$rtnStr .= " <Parent>\n";
if ( $self->_InstExists($Parent->sRef) ) {
$rtnStr .= " <Instance ref=" . $self->_Quo($Parent->sRef) . "/>\n";
} else {
$rtnStr .= " <Instance>\n";
$rtnStr .= $self->_getInstXml( $Parent, 0, 12 );
$rtnStr .= " </Instance>\n";
}
$rtnStr .= " </Parent>\n";
$rtnStr .= " <Components>\n";
if ( $self->_InstExists( $Child->sRef ) ) {
$rtnStr .= " <Instance ref=" . $self->_Quo($Child->sRef) . "/>\n";
} else {
$rtnStr .= " <Instance>\n";
$rtnStr .= $self->_getInstXml( $Child, 0, 12 );
$rtnStr .= " </Instance>\n";
}
$rtnStr .= " </Components>\n";
$rtnStr .= " </NewRelationship>\n";
}
$self->{ll_Deps}->Reset;
while ( $self->{ll_Deps}->HasMoreItems ) {
$Inst = $self->{ll_Deps}->NextItem;
$Parent = $self->_GetInstDef( $Inst->sParentRef );
$Child = $self->_GetInstDef( $Inst->sChildRef );
$rtnStr .= " <NewRelationship>\n";
$rtnStr .= " <Parent>\n";
if ( $self->_InstExists( $Parent->sRef ) ) {
$rtnStr .= " <Instance ref=" . $self->_Quo( $Parent->sRef ) . "/>\n";
} else {
$rtnStr .= " <Instance>\n";
if ($Parent->sGuid ne "") {
$rtnStr .= $self->_getInstXml( $Parent, 1, 12 );
} else {
$rtnStr .= $self->_getInstXml( $Parent, 0, 12 );
}
$rtnStr .= " </Instance>\n";
}
$rtnStr .= " </Parent>\n";
$rtnStr .= " <DependentOn>\n";
if ( $self->_InstExists( $Child->sRef ) ) {
$rtnStr .= " <Instance ref=" . $self->_Quo( $Child->sRef ) . "/>\n";
} else {
$rtnStr .= " <Instance>\n";
if ($Child->sGuid ne "") {
$rtnStr .= $self->_getInstXml( $Child, 1, 12 );
} else {
$rtnStr .= $self->_getInstXml( $Child, 0, 12 );
}
$rtnStr .= " </Instance>\n";
}
$rtnStr .= " </DependentOn>\n";
$rtnStr .= " </NewRelationship>\n";
}
# End XML
$rtnStr .= "</Service>\n";
return $rtnStr;
}
#------------ privates -------------
sub _initialize {
my $self = shift;
$self->{ll_InstDefs} = LinkList->new;
$self->{ll_Insts} = LinkList->new;
$self->{ll_Comps} = LinkList->new;
$self->{ll_Deps} = LinkList->new;
$self->{m_name} = "";
$self->{m_value} = "";
$self->{m_assign_char} = "=";
$self->{m_delim_char} = ";";
}
sub _GetInstDef {
my $self = shift;
my $sRef = shift;
my $InstDef;
$self->{ll_InstDefs}->Reset;
while ( $self->{ll_InstDefs}->HasMoreItems ) {
$InstDef = $self->{ll_InstDefs}->NextItem;
if ( $InstDef->sRef eq $sRef ) {
return $InstDef;
}
}
return "";
}
sub _InstDefExists {
my $self = shift;
my $sRef = shift;
my $InstDef;
$InstDef = $self->_GetInstDef($sRef);
if ( $InstDef ne "" ) {
return 1;
}
# failure
return 0;
}
sub _InstExists {
my $self = shift;
my $sRef = shift;
my $Inst;
$self->{ll_Insts}->Reset;
while ( $self->{ll_Insts}->HasMoreItems ) {
$Inst = $self->{ll_Insts}->NextItem;
if ( $Inst->sRef eq $sRef ) {
return 1;
}
}
return 0;
}
# Given a string which contains name/value pairs and the
# index pair value (zero based), This function returns True
# when a n/v pair exists, Else returns False.
# When True the private members m_name & m_value are filled.
sub _GetNvp {
my $self = shift;
my ($str, $idx) = @_;
my $NvpStr;
my @NvpArray;
my @NvArray;
$self->{m_name} = "";
$self->{m_value} = "";
@NvpArray = split($self->{m_delim_char}, $str );
if ( $#NvpArray >= $idx ) {
$NvpStr = $NvpArray[ $idx ];
@NvArray = split( $self->{m_assign_char}, $NvpStr );
if ( $#NvArray == 1 ) {
$self->{m_name} = $NvArray[0];
$self->{m_value} = $NvArray[1];
# success
return 2;
}
elsif ( $#NvArray == 0 ) { return 1; }
}
# failure
return 0;
}
sub _getInstXml {
my $self = shift;
my ($InstDef, $bIncludeNodeGuid, $numspaces) = @_;
my $i;
my $rtnStr;
if ( $InstDef->sStd ne "") {
$rtnStr = " " x $numspaces . "<Std>" . $InstDef->sStd . "</Std>\n";
}
if ( $InstDef->bVirtual ) {
$rtnStr .= " " x $numspaces . "<Virtual/>\n";
}
if ( $bIncludeNodeGuid and $InstDef->sGuid ne "" ) {
$rtnStr .= " " x $numspaces . "<NodeGuid>" . $InstDef->sGuid . "</NodeGuid>\n";
}
if ( $InstDef->sKey ne "" ) {
$rtnStr .= " " x $numspaces . "<Key>" . $InstDef->sKey . "</Key>\n";
}
if ( $InstDef->sGraphID ne "" ) {
$rtnStr .= " " x $numspaces . "<GraphInstanceID>" .
$InstDef->sGraphID . "</GraphInstanceID>\n";
}
if ( $InstDef->sAttrs ne "" ) {
$rtnStr .= " " x $numspaces . "<Attributes>\n";
$i = 0;
while ( $self->_GetNvp($InstDef->sAttrs, $i) )
{
if ( $self->{m_name} )
{
$rtnStr .= " " x $numspaces .
" <Attribute name=" .
$self->_Quo( $self->{m_name} ) .
" value=" .
$self->_Quo( $self->{m_value} ) .
"/>\n";
}
$i++;
}
$rtnStr .= " " x $numspaces . "</Attributes>\n";
}
return $rtnStr;
}
sub _Quo {
my $self = shift;
my ($str) = @_;
# Returns str in double quotes.
return "\"$str\"";
}
1;