001/* 002 * Copyright (c) 2016-2017 Chris K Wensel. 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.tuple; 023 024import java.util.Collection; 025import java.util.Collections; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Map; 029 030import cascading.operation.OperationException; 031import cascading.tuple.type.CoercibleType; 032 033/** 034 * Class Tuples is a helper class providing common methods to manipulate {@link Tuple} and {@link TupleEntry} instances. 035 * 036 * @see Tuple 037 * @see TupleEntry 038 */ 039public class Tuples 040 { 041 /** 042 * A utility function for use with Janino expressions to get around its lack of support for varargs. 043 * 044 * @param a of type Object 045 * @return a new Tuple 046 */ 047 public static Tuple tuple( Object a ) 048 { 049 return new Tuple( a ); 050 } 051 052 /** 053 * A utility function for use with Janino expressions to get around its lack of support for varargs. 054 * 055 * @param a of type Object 056 * @param b of type Object 057 * @return a new Tuple 058 */ 059 public static Tuple tuple( Object a, Object b ) 060 { 061 return new Tuple( a, b ); 062 } 063 064 /** 065 * A utility function for use with Janino expressions to get around its lack of support for varargs. 066 * 067 * @param a of type Object 068 * @param b of type Object 069 * @param c of type Object 070 * @return a new Tuple 071 */ 072 public static Tuple tuple( Object a, Object b, Object c ) 073 { 074 return new Tuple( a, b, c ); 075 } 076 077 /** 078 * A utility function for use with Janino expressions to get around its lack of support for varargs. 079 * 080 * @param a of type Object 081 * @param b of type Object 082 * @param c of type Object 083 * @param d of type Object 084 * @return a new Tuple 085 */ 086 public static Tuple tuple( Object a, Object b, Object c, Object d ) 087 { 088 return new Tuple( a, b, c, d ); 089 } 090 091 /** 092 * A utility function for use with Janino expressions to get around its lack of support for varargs. 093 * 094 * @param a of type Object 095 * @param b of type Object 096 * @param c of type Object 097 * @param d of type Object 098 * @param e of type Object 099 * @return a new Tuple 100 */ 101 public static Tuple tuple( Object a, Object b, Object c, Object d, Object e ) 102 { 103 return new Tuple( a, b, c, d, e ); 104 } 105 106 /** 107 * A utility function for use with Janino expressions to get around its lack of support for varargs. 108 * 109 * @param a of type Object 110 * @param b of type Object 111 * @param c of type Object 112 * @param d of type Object 113 * @param e of type Object 114 * @param f of type Object 115 * @return a new Tuple 116 */ 117 public static Tuple tuple( Object a, Object b, Object c, Object d, Object e, Object f ) 118 { 119 return new Tuple( a, b, c, d, e, f ); 120 } 121 122 /** 123 * A utility function for use with Janino expressions to get around its lack of support for varargs. 124 * 125 * @param a of type Object 126 * @param b of type Object 127 * @param c of type Object 128 * @param d of type Object 129 * @param e of type Object 130 * @param f of type Object 131 * @param g of type Object 132 * @return a new Tuple 133 */ 134 public static Tuple tuple( Object a, Object b, Object c, Object d, Object e, Object f, Object g ) 135 { 136 return new Tuple( a, b, c, d, e, f, g ); 137 } 138 139 /** 140 * A utility function for use with Janino expressions to get around its lack of support for varargs. 141 * 142 * @param a of type Object 143 * @param b of type Object 144 * @param c of type Object 145 * @param d of type Object 146 * @param e of type Object 147 * @param f of type Object 148 * @param g of type Object 149 * @param h of type Object 150 * @return a new Tuple 151 */ 152 public static Tuple tuple( Object a, Object b, Object c, Object d, Object e, Object f, Object g, Object h ) 153 { 154 return new Tuple( a, b, c, d, e, f, g, h ); 155 } 156 157 /** 158 * Method asArray copies the elements of the given Tuple instance to the given Object array. 159 * 160 * @param tuple of type Tuple 161 * @param destination of type Object[] 162 * @return Object[] 163 */ 164 public static <T> T[] asArray( Tuple tuple, T[] destination ) 165 { 166 if( tuple.size() != destination.length ) 167 throw new OperationException( "number of input tuple values: " + tuple.size() + ", does not match destination array size: " + destination.length ); 168 169 return tuple.elements( destination ); 170 } 171 172 public static Object[] asArray( Tuple tuple, CoercibleType[] coercions, Class[] types, Object[] destination ) 173 { 174 if( tuple.size() != types.length ) 175 throw new OperationException( "number of input tuple values: " + tuple.size() + ", does not match number of coercion types: " + types.length ); 176 177 for( int i = 0; i < types.length; i++ ) 178 destination[ i ] = coercions[ i ].coerce( tuple.getObject( i ), types[ i ] ); 179 180 return destination; 181 } 182 183 public static Map<String, Object> asMap( Fields fields, TupleEntry arguments ) 184 { 185 Map<String, Object> result = new HashMap<>(); 186 187 for( Comparable comparable : fields ) 188 result.put( comparable.toString(), arguments.getObject( comparable ) ); 189 190 return result; 191 } 192 193 public static Map<Comparable, Object> asComparableMap( Fields fields, TupleEntry arguments ) 194 { 195 Map<Comparable, Object> result = new HashMap<>(); 196 197 for( Comparable comparable : fields ) 198 result.put( comparable, arguments.getObject( comparable ) ); 199 200 return result; 201 } 202 203 public static Collection asCollection( Tuple tuple ) 204 { 205 return Collections.unmodifiableCollection( tuple.elements ); 206 } 207 208 /** 209 * Method frequency behaves the same as {@link Collections#frequency(java.util.Collection, Object)}. 210 * <p> 211 * This method is a convenient way to test for all null values in a tuple. 212 * 213 * @param tuple of type Tuple 214 * @param value of type Object 215 * @return an int 216 */ 217 public static int frequency( Tuple tuple, Object value ) 218 { 219 return Collections.frequency( tuple.elements, value ); 220 } 221 222 /** 223 * Method frequency behaves the same as {@link Collections#frequency(java.util.Collection, Object)}. 224 * <p> 225 * This method is a convenient way to test for all null values in a tuple. 226 * 227 * @param tupleEntry of type TupleEntry 228 * @param value of type Object 229 * @return an int 230 */ 231 public static int frequency( TupleEntry tupleEntry, Object value ) 232 { 233 return Collections.frequency( tupleEntry.getTuple().elements, value ); 234 } 235 236 /** 237 * Method extractTuple returns a new Tuple based on the given selector. But sets the values of the 238 * given TupleEntry to null. 239 * 240 * @param tupleEntry of type TupleEntry 241 * @param selector of type Fields 242 * @return Tuple 243 */ 244 public static Tuple extractTuple( TupleEntry tupleEntry, Fields selector ) 245 { 246 if( selector == null || selector.isAll() ) 247 { 248 Tuple result = tupleEntry.tuple; 249 250 tupleEntry.setTuple( Tuple.size( result.size() ) ); 251 252 return result; 253 } 254 255 try 256 { 257 return extract( tupleEntry, selector ); 258 } 259 catch( Exception exception ) 260 { 261 throw new TupleException( "unable to select from: " + tupleEntry.getFields().printVerbose() + ", using selector: " + selector.printVerbose(), exception ); 262 } 263 } 264 265 /** 266 * Method extract creates a new Tuple from the given selector, but sets the values in the current tuple to null. 267 * 268 * @param tupleEntry of type TupleEntry 269 * @param selector of type Fields 270 * @return Tuple 271 */ 272 public static Tuple extract( TupleEntry tupleEntry, Fields selector ) 273 { 274 return tupleEntry.tuple.extract( tupleEntry.getFields().getPos( selector, tupleEntry.getFields().size() ) ); 275 } 276 277 public static Tuple nulledCopy( TupleEntry tupleEntry, Fields selector ) 278 { 279 return tupleEntry.tuple.nulledCopy( tupleEntry.getFields().getPos( selector, tupleEntry.getFields().size() ) ); 280 } 281 282 public static Tuple nulledCopy( Fields declarator, Tuple tuple, Fields selector ) 283 { 284 // use tuple.size() in case declarator is UNKNOWN and selector has relative pos 285 return tuple.nulledCopy( declarator.getPos( selector, tuple.size() ) ); 286 } 287 288 public static Tuple setOnEmpty( TupleEntry baseEntry, TupleEntry valuesEntry ) 289 { 290 Tuple emptyTuple = Tuple.size( baseEntry.getFields().size() ); 291 292 emptyTuple.set( baseEntry.getFields(), valuesEntry.getFields(), valuesEntry.getTuple() ); 293 294 return emptyTuple; 295 } 296 297 /** 298 * Method asUnmodifiable marks the given Tuple instance as unmodifiable. 299 * 300 * @param tuple of type Tuple 301 * @return Tuple 302 */ 303 public static <T extends Tuple> T asUnmodifiable( T tuple ) 304 { 305 tuple.isUnmodifiable = true; 306 307 return tuple; 308 } 309 310 /** 311 * Method asModifiable marks the given Tuple instance as modifiable. 312 * 313 * @param tuple of type Tuple 314 * @return Tuple 315 */ 316 public static <T extends Tuple> T asModifiable( T tuple ) 317 { 318 tuple.isUnmodifiable = false; 319 320 return tuple; 321 } 322 323 public static <T extends Tuple> T setUnmodifiable( T tuple, boolean isUnmodifiable ) 324 { 325 tuple.isUnmodifiable = isUnmodifiable; 326 327 return tuple; 328 } 329 330 public static Tuple create( List<Object> arrayList ) 331 { 332 return new Tuple( arrayList ); 333 } 334 }