########################################################################## # # # Copyright 2002 Rational Software Corporation. # # All Rights Reserved. # # This software is distributed under the Common Public License Version # # 0.5 (CPL), and you may use this software if you accept that agreement. # # You should have received a copy of the CPL with this software # # in the file LICENSE.TXT. If you did not, please visit # # http://www.opensource.org/licenses/cpl.html for a copy of the license. # # # ########################################################################## =head1 NAME CC::CompositeDiff - XXX =cut use CC::CC; use CC::Activity; use CC::Baseline; use CC::Component; # use Trace; use strict; ############################################################################## package CC::CompositeDiff; ############################################################################## ############################################################################## sub new ############################################################################## { # my $trace(); my $class = shift @_; my $result = shift @_; my $vob = shift @_; my $this = { }; CC::CC::assert($result); # 'diffbl' results look like: # << MyActivity "My Activity Headline" ($this->{kind}, $this->{act}) = split(' ', $result); $this->{act} = new CC::Activity($this->{act}, $vob); my $cleartool = ClearCase::CtCmd->new; $this->{cleartool}=$cleartool; $this->{status} = 0; return bless($this, $class); } ############################################################################## sub kind ############################################################################## { my $this = shift @_; return $this->{kind}; } ############################################################################## sub activity ############################################################################## { my $this = shift @_; return $this->{act}; } ############################################################################## sub print ############################################################################## { my $this = shift @_; printf("%s %s \"%s\"\n", $this->kind(), $this->activity()->name(), $this->activity()->headline()); return 1; } ############################################################################## package CC::BaselineDiff; ############################################################################## ############################################################################## sub new ############################################################################## { # my $trace(); my $class = shift @_; my $lhs = shift @_; my $rhs = shift @_; my $this = { }; CC::CC::assert($lhs || $rhs); $this->{lhs} = $lhs; $this->{rhs} = $rhs; if ( ! $rhs) { $this->{kind} = '<<'; } elsif ( ! $lhs) { $this->{kind} = '>>'; } elsif ($lhs->equals($rhs)) { $this->{kind} = '=='; } else { $this->{kind} = '<>'; } return bless($this, $class); } ############################################################################## sub DESTROY ############################################################################## { return 1; # no-op } ############################################################################## sub lhs ############################################################################## { my $this = shift @_; return $this->{lhs}; } ############################################################################## sub rhs ############################################################################## { my $this = shift @_; return $this->{rhs}; } ############################################################################## sub kind ############################################################################## { my $this = shift @_; return $this->{kind}; } ############################################################################## sub print ############################################################################## { my $this = shift @_; my $lhs = $this->lhs(); my $rhs = $this->rhs(); my $comp = ($lhs ? $lhs->component() : $rhs->component()); printf("##### component %s:\t%20s %s %s\n", $comp->name(), ($lhs ? $lhs->name() : ''), $this->kind(), ($rhs ? $rhs->name() : '')); return 1; } ############################################################################## sub results ############################################################################## { # my $trace(); my $this = shift @_; my $lhs = $this->lhs(); my $rhs = $this->rhs(); my $vob = $lhs->vob(); my @diffs; CC::CC::assert($this->kind() eq '<>'); my @lines = $this->{cleartool}->exec('diffbl', $lhs->objsel(), $rhs->objsel()); return $this->{cleartool}->status? 0 : map { new CC::DiffResult($_, $vob); } @lines; } ############################################################################## package CC::CompositeDiff; ############################################################################## ############################################################################## sub DESTROY ############################################################################## { return 1; # no-op } ############################################################################## sub lhs ############################################################################## { my $this = shift @_; return $this->{lhs}; } ############################################################################## sub rhs ############################################################################## { my $this = shift @_; return $this->{rhs}; } ############################################################################## sub results ############################################################################## { # my $trace(); my $this = shift @_; my %lhs_hash = _component_to_operand_hash($this->lhs()); my %rhs_hash = _component_to_operand_hash($this->rhs()); my @comps = _remove_duplicates(keys(%lhs_hash), keys(%rhs_hash)); return map { new CC::BaselineDiff($lhs_hash{$_}, $rhs_hash{$_}); } @comps; } ############################################################################## sub _component_to_operand_hash ############################################################################## { my $op = shift @_; my ($dep, $comp); my %hash; if ($op->metatype() eq 'stream') { for $comp ($op->components()) { $hash{$comp->objsel()} = $op; } } elsif ($op->has_dependencies()) { for $dep ($op->dependencies()) { $hash{$dep->component()->objsel()} = $dep; } } else { $hash{$op->component()->objsel()} = $op; } return %hash; } ############################################################################## sub _remove_duplicates ############################################################################## { my %item_hash; # Initialize hash using list items as keys, which eliminates duplicates. @item_hash{@_} = 0; # Reconsitute list from hash keys. return keys(%item_hash); } 1; # Make "use" and "require" happy