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        setTails( new Each( previous, new Identity( types ) ) );
057        }
058    
059      /**
060       * Constructor Coerce creates a new Coerce instance that will only coerce the given coerceFields Tuple values.
061       * <p/>
062       * Note the resulting output Tuple will contain all the original incoming Fields.
063       *
064       * @param previous     of type Pipe
065       * @param coerceFields of type Fields
066       * @param types        of type Class...
067       */
068      @ConstructorProperties({"previous", "coerceFields", "types"})
069      public Coerce( Pipe previous, Fields coerceFields, Class... types )
070        {
071        super( previous );
072    
073        setTails( new Each( previous, coerceFields, new Identity( types ), Fields.REPLACE ) );
074        }
075    
076      /**
077       * Constructor Coerce creates a new Coerce instance that will only coerce the given coerceFields Tuple values.
078       * <p/>
079       * The given {@code coerceFields} instance must contain field type information, otherwise an
080       * {@link IllegalArgumentException} will be thrown.
081       * <p/>
082       * Note the resulting output Tuple will contain all the original incoming Fields.
083       *
084       * @param previous     of type Pipe
085       * @param coerceFields of type Fields
086       */
087      @ConstructorProperties({"previous", "coerceFields"})
088      public Coerce( Pipe previous, Fields coerceFields )
089        {
090        super( previous );
091    
092        setTails( new Each( previous, coerceFields, new Identity( coerceFields ), Fields.REPLACE ) );
093    
094        if( coerceFields.getTypes().length == 0 )
095          throw new IllegalArgumentException( "number of types must not be zero" );
096        }
097      }