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