    001    /*
    002     * Copyright (c) 2007-2014 Concurrent, Inc. All Rights Reserved.
    003     *
    004     * Project and contact information: http://www.cascading.org/
    005     *
    006     * This file is part of the Cascading project.
    007     *
    008     * Licensed under the Apache License, Version 2.0 (the "License");
    009     * you may not use this file except in compliance with the License.
    010     * You may obtain a copy of the License at
    011     *
    012     *     http://www.apache.org/licenses/LICENSE-2.0
    013     *
    014     * Unless required by applicable law or agreed to in writing, software
    015     * distributed under the License is distributed on an "AS IS" BASIS,
    016     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    017     * See the License for the specific language governing permissions and
    018     * limitations under the License.
    019     */
    020
    021    package cascading.pipe.assembly;
    022
    023    import java.beans.ConstructorProperties;
    024
    025    import cascading.operation.Identity;
    026    import cascading.pipe.Each;
    027    import cascading.pipe.Pipe;
    028    import cascading.pipe.SubAssembly;
    029    import cascading.tuple.Fields;
    030
    031    /**
    032     * Class Coerce is a {@link SubAssembly} that will coerce all incoming {@link cascading.tuple.Tuple} values to
    033     * the given types.
    034     * <p/>
    035     * If the given type is a primitive ({@code long}), and the tuple value is null, {@code 0} is returned.
    036     * If the type is an Object ({@code java.lang.Long}), and the tuple value is {@code null}, {@code null} is returned.
    037     * <p/>
    038     * Coerce encapsulates the {@link Identity} function.
    039     *
    040     * @see cascading.pipe.SubAssembly
    041     * @see cascading.operation.Identity
    042     */
    043    public class Coerce extends SubAssembly
    044      {
    045      /**
    046       * Constructor Coerce creates a new Coerce instance that will coerce all input Tuple values.
    047       *
    048       * @param previous of type Pipe
    049       * @param types    of type Class...
    050       */
    051      @ConstructorProperties({"previous", "types"})
    052      public Coerce( Pipe previous, Class... types )
    053        {
    054        super( previous );
    055
    056        if( types.length > 0 )
    057          throw new IllegalArgumentException( "given types array may not be zero length" );
    058
    059        setTails( new Each( previous, new Identity( types ) ) );
    060        }
    061
    062      /**
    063       * Constructor Coerce creates a new Coerce instance that will only coerce the given coerceFields Tuple values.
    064       * <p/>
    065       * Note the resulting output Tuple will contain all the original incoming Fields.
    066       *
    067       * @param previous     of type Pipe
    068       * @param coerceFields of type Fields
    069       * @param types        of type Class...
    070       */
    071      @ConstructorProperties({"previous", "coerceFields", "types"})
    072      public Coerce( Pipe previous, Fields coerceFields, Class... types )
    073        {
    074        super( previous );
    075
    076        if( coerceFields == null )
    077          throw new IllegalArgumentException( "coerceFields may not be null" );
    078
    079        setTails( new Each( previous, coerceFields, new Identity( types ), Fields.REPLACE ) );
    080        }
    081
    082      /**
    083       * Constructor Coerce creates a new Coerce instance that will only coerce the given coerceFields Tuple values.
    084       * <p/>
    085       * The given {@code coerceFields} instance must contain field type information, otherwise an
    086       * {@link IllegalArgumentException} will be thrown.
    087       * <p/>
    088       * Note the resulting output Tuple will contain all the original incoming Fields.
    089       *
    090       * @param previous     of type Pipe
    091       * @param coerceFields of type Fields
    092       */
    093      @ConstructorProperties({"previous", "coerceFields"})
    094      public Coerce( Pipe previous, Fields coerceFields )
    095        {
    096        super( previous );
    097
    098        if( coerceFields == null )
    099          throw new IllegalArgumentException( "coerceFields may not be null" );
    100
    101        if( !coerceFields.hasTypes() )
    102          throw new IllegalArgumentException( "coerceFields must have field types declared" );
    103
    104        setTails( new Each( previous, coerceFields, new Identity( coerceFields ), Fields.REPLACE ) );
    105
    106        if( coerceFields.getTypes().length == 0 )
    107          throw new IllegalArgumentException( "number of types must not be zero" );
    108        }
    109      }