/*
* Copyright (c) 2007-2010 Concurrent, Inc. All Rights Reserved.
*
* Project and contact information: http://www.cascading.org/
*
* This file is part of the Cascading project.
*
* Cascading is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Cascading is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cascading. If not, see <http://www.gnu.org/licenses/>.
*/
package cascading.pipe;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import cascading.util.Util;
/**
* Subclasses of SubAssembly encapsulate complex assemblies of {@link Pipe}s so they my be reused in the same manner
* a Pipe is used.
* <p/>
* That is, a typical SubAssembly subclass will accept a 'previous' Pipe instance, and a few
* arguments for configuring the resulting sub-assembly.
* <p/>
* If the SubAssembly represents a split in the pipeline process,
* all the 'tails' of the assembly must be passed to {@link #setTails(Pipe...)}.
*/
public abstract class SubAssembly extends Pipe
{
/** Field assembly */
private Pipe[] tails;
/**
* Must be called by subclasses to set the final end points of the assembly the subclass represents.
*
* @param tails of type Pipe
*/
protected void setTails( Pipe... tails )
{
this.tails = tails;
}
/**
* Method getTails returns all the tails of this PipeAssembly object. These values are set by {@link #setTails(Pipe...)}.
*
* @return the tails (type Pipe[]) of this PipeAssembly object.
*/
public Pipe[] getTails()
{
return getPrevious(); // just returns a clone of tails
}
/**
* Method getTailNames returns the tailNames of this PipeAssembly object.
*
* @return the tailNames (type String[]) of this PipeAssembly object.
*/
public String[] getTailNames()
{
if( tails == null )
throw new IllegalStateException( Util.formatRawTrace( this, "setTails must be called in the constructor" ) );
String[] names = new String[tails.length];
for( int i = 0; i < tails.length; i++ )
names[ i ] = tails[ i ].getName();
return names;
}
@Override
public String getName()
{
return Util.join( getTailNames(), "+" );
}
@Override
public Pipe[] getPrevious()
{
if( tails == null )
throw new IllegalStateException( Util.formatRawTrace( this, "setTails must be called in the constructor" ) );
return Arrays.copyOf( tails, tails.length );
}
/**
* Is responsible for unwinding nested PipeAssembly instances.
*
* @param tails of type Pipe[]
* @return a Pipe[]
*/
public static Pipe[] unwind( Pipe... tails )
{
Set<Pipe> previous = new HashSet<Pipe>();
for( Pipe pipe : tails )
{
if( pipe instanceof SubAssembly )
Collections.addAll( previous, unwind( pipe.getPrevious() ) );
else
previous.add( pipe );
}
return previous.toArray( new Pipe[previous.size()] );
}
}