#!perl # ########################################################################## # # Title: Stack transformer # Creation date: 2007-03-05 # Author: Michael Zedeler # Description: Represents a stack of transformers # Data Stream class # Data transformer # File: $Source: /data/cvs/lib/DSlib/lib/DS/Transformer/Stack.pm,v $ # Repository: kronhjorten # State: $State: Exp $ # Documentation: inline # Recepient: - # ########################################################################## # # TODO Make pass_row work again. # TODO Make process work again (call internal stack) package DS::Transformer::Stack; use base qw{ DS::Transformer::Opaque }; use strict; use Carp qw{ croak cluck confess }; use Carp::Assert; use DS::Target::Proxy; our ($VERSION) = $DS::VERSION; our ($REVISION) = '$Revision: 1.1 $' =~ /(\d+\.\d+)/; sub new { my( $class, $source, $stack ) = @_; my $self = $class->SUPER::new( undef, undef, $source ); foreach my $transformer (@$stack) { $self->push_transformer( $transformer ); } return $self; } sub push_transformer { my( $self, $transformer ) = @_; assert( $transformer->isa('DS::Transformer') ); if( $self->target ) { confess("Invalid use of stack. It is not possible to modify stack after target has been set."); } if( defined( $self->top() ) ) { $transformer->attach_source( $self->top() ); } else { $self->bottom( $transformer ); } $self->top( $transformer ); } # Set top transformer and check that no target has been set yet # Do NOT try to maintain links with internal transformers in stack sub top { my( $self, $top ) = @_; my $result; if( defined( $top ) ) { if( $self->target ) { confess("Invalid use of stack. It is not possible to modify stack after target has been set."); } $self->{top} = $top; $result = 1; } else { $result = $self->{top}; } return $result; } # Set bottom transformer and maintain links with source transformer (outside stack) # Do NOT try to maintain links with internal transformers in stack sub bottom { my( $self, $bottom ) = @_; my $result; if( defined( $bottom ) ) { if( defined( $self->source ) ) { $bottom->attach_source( $self->source ); } $self->{bottom} = $bottom; } else { $result = $self->{bottom}; } return $result; } sub in_type { my( $self, $in_type ) = @_; return $self->bottom()->in_type( $in_type ); } sub out_type { my( $self, $out_type ) = @_; return $self->top()->out_type( $out_type ); } sub receive_row { my( $self, $row ) = @_; return $self->bottom()->receive_row( $row ); } sub attach_source_internal { my( $self, $source ) = @_; return $self->bottom()->attach_source( $source ); } sub attach_target_internal { my( $self, $target ) = @_; return $self->top()->attach_target( $target ); } sub process { croak 'Process is not well defined on stacks, since the transformers on the stack may return more or less than one row.'; } 1;