/usr/local/CPAN/DSlib/DS/Transformer/Stack.pm
#!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;