001 /* 002 * Copyright (c) 2007-2015 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.tuple; 022 023 import java.util.Collection; 024 import java.util.Collections; 025 import java.util.List; 026 027 import cascading.operation.OperationException; 028 import cascading.tuple.coerce.Coercions; 029 import cascading.tuple.type.CoercibleType; 030 031 /** 032 * Class Tuples is a helper class providing common methods to manipulate {@link Tuple} and {@link TupleEntry} instances. 033 * 034 * @see Tuple 035 * @see TupleEntry 036 */ 037 public class Tuples 038 { 039 /** 040 * A utility function for use with Janino expressions to get around its lack of support for varargs. 041 * 042 * @param a of type Object 043 * @return a new Tuple 044 */ 045 public static Tuple tuple( Object a ) 046 { 047 return new Tuple( a ); 048 } 049 050 /** 051 * A utility function for use with Janino expressions to get around its lack of support for varargs. 052 * 053 * @param a of type Object 054 * @param b of type Object 055 * @return a new Tuple 056 */ 057 public static Tuple tuple( Object a, Object b ) 058 { 059 return new Tuple( a, b ); 060 } 061 062 /** 063 * A utility function for use with Janino expressions to get around its lack of support for varargs. 064 * 065 * @param a of type Object 066 * @param b of type Object 067 * @param c of type Object 068 * @return a new Tuple 069 */ 070 public static Tuple tuple( Object a, Object b, Object c ) 071 { 072 return new Tuple( a, b, c ); 073 } 074 075 /** 076 * A utility function for use with Janino expressions to get around its lack of support for varargs. 077 * 078 * @param a of type Object 079 * @param b of type Object 080 * @param c of type Object 081 * @param d of type Object 082 * @return a new Tuple 083 */ 084 public static Tuple tuple( Object a, Object b, Object c, Object d ) 085 { 086 return new Tuple( a, b, c, d ); 087 } 088 089 /** 090 * A utility function for use with Janino expressions to get around its lack of support for varargs. 091 * 092 * @param a of type Object 093 * @param b of type Object 094 * @param c of type Object 095 * @param d of type Object 096 * @param e of type Object 097 * @return a new Tuple 098 */ 099 public static Tuple tuple( Object a, Object b, Object c, Object d, Object e ) 100 { 101 return new Tuple( a, b, c, d, e ); 102 } 103 104 /** 105 * A utility function for use with Janino expressions to get around its lack of support for varargs. 106 * 107 * @param a of type Object 108 * @param b of type Object 109 * @param c of type Object 110 * @param d of type Object 111 * @param e of type Object 112 * @param f of type Object 113 * @return a new Tuple 114 */ 115 public static Tuple tuple( Object a, Object b, Object c, Object d, Object e, Object f ) 116 { 117 return new Tuple( a, b, c, d, e, f ); 118 } 119 120 /** 121 * A utility function for use with Janino expressions to get around its lack of support for varargs. 122 * 123 * @param a of type Object 124 * @param b of type Object 125 * @param c of type Object 126 * @param d of type Object 127 * @param e of type Object 128 * @param f of type Object 129 * @param g of type Object 130 * @return a new Tuple 131 */ 132 public static Tuple tuple( Object a, Object b, Object c, Object d, Object e, Object f, Object g ) 133 { 134 return new Tuple( a, b, c, d, e, f, g ); 135 } 136 137 /** 138 * A utility function for use with Janino expressions to get around its lack of support for varargs. 139 * 140 * @param a of type Object 141 * @param b of type Object 142 * @param c of type Object 143 * @param d of type Object 144 * @param e of type Object 145 * @param f of type Object 146 * @param g of type Object 147 * @param h of type Object 148 * @return a new Tuple 149 */ 150 public static Tuple tuple( Object a, Object b, Object c, Object d, Object e, Object f, Object g, Object h ) 151 { 152 return new Tuple( a, b, c, d, e, f, g, h ); 153 } 154 155 /** 156 * Method asArray copies the elements of the given Tuple instance to the given Object array. 157 * 158 * @param tuple of type Tuple 159 * @param destination of type Object[] 160 * @return Object[] 161 */ 162 public static <T> T[] asArray( Tuple tuple, T[] destination ) 163 { 164 if( tuple.size() != destination.length ) 165 throw new OperationException( "number of input tuple values: " + tuple.size() + ", does not match destination array size: " + destination.length ); 166 167 return tuple.elements( destination ); 168 } 169 170 /** 171 * Method asArray convert the given {@link Tuple} instance into an Object[]. The given Class[] array 172 * denotes the types each tuple element value should be coerced into. 173 * <p/> 174 * Coercion types are Object, String, Integer, Long, Float, Double, Short, and Boolean. 175 * <p/> 176 * If all Tuple element values are null, they will remain null for String and Object, but become zero for the numeric types. 177 * <p/> 178 * The string value 'true' can be converted to the boolean true. 179 * 180 * @param tuple of type Tuple 181 * @param types of type Class[] 182 * @return Object[] 183 */ 184 @Deprecated 185 public static Object[] asArray( Tuple tuple, Class[] types ) 186 { 187 return asArray( tuple, types, new Object[ tuple.size() ] ); 188 } 189 190 /** 191 * Method asArray convert the given {@link Tuple} instance into an Object[]. The given Class[] array 192 * denotes the types each tuple element value should be coerced into. 193 * 194 * @param tuple of type Tuple 195 * @param types of type Class[] 196 * @param destination of type Object[] 197 * @return Object[] 198 */ 199 @Deprecated 200 public static Object[] asArray( Tuple tuple, Class[] types, Object[] destination ) 201 { 202 if( tuple.size() != types.length ) 203 throw new OperationException( "number of input tuple values: " + tuple.size() + ", does not match number of coercion types: " + types.length ); 204 205 for( int i = 0; i < types.length; i++ ) 206 destination[ i ] = coerce( tuple, i, types[ i ] ); 207 208 return destination; 209 } 210 211 public static Object[] asArray( Tuple tuple, CoercibleType[] coercions, Class[] types, Object[] destination ) 212 { 213 if( tuple.size() != types.length ) 214 throw new OperationException( "number of input tuple values: " + tuple.size() + ", does not match number of coercion types: " + types.length ); 215 216 for( int i = 0; i < types.length; i++ ) 217 destination[ i ] = coercions[ i ].coerce( tuple.getObject( i ), types[ i ] ); 218 219 return destination; 220 } 221 222 public static Collection asCollection( Tuple tuple ) 223 { 224 return Collections.unmodifiableCollection( tuple.elements ); 225 } 226 227 /** 228 * Method frequency behaves the same as {@link Collections#frequency(java.util.Collection, Object)}. 229 * <p/> 230 * This method is a convenient way to test for all null values in a tuple. 231 * 232 * @param tuple of type Tuple 233 * @param value of type Object 234 * @return an int 235 */ 236 public static int frequency( Tuple tuple, Object value ) 237 { 238 return Collections.frequency( tuple.elements, value ); 239 } 240 241 /** 242 * Method frequency behaves the same as {@link Collections#frequency(java.util.Collection, Object)}. 243 * <p/> 244 * This method is a convenient way to test for all null values in a tuple. 245 * 246 * @param tupleEntry of type TupleEntry 247 * @param value of type Object 248 * @return an int 249 */ 250 public static int frequency( TupleEntry tupleEntry, Object value ) 251 { 252 return Collections.frequency( tupleEntry.getTuple().elements, value ); 253 } 254 255 /** 256 * Method coerce returns the value in the tuple at the given position to the requested type. 257 * <p/> 258 * If the given type is a primitive (long), and the tuple value is null, 0 is returned. 259 * <p/> 260 * If the type is an Object (Long), and the tuple value is null, null is returned. 261 * 262 * @param tuple of type Tuple 263 * @param pos of type int 264 * @param type of type Class 265 * @return returns the value coerced 266 */ 267 @Deprecated 268 public static Object coerce( Tuple tuple, int pos, Class type ) 269 { 270 Object value = tuple.getObject( pos ); 271 272 return coerce( value, type ); 273 } 274 275 @Deprecated 276 public static Object coerce( Object value, Class type ) 277 { 278 return Coercions.coerce( value, type ); 279 } 280 281 @Deprecated 282 public static final String toString( Object value ) 283 { 284 return Coercions.STRING.coerce( value ); 285 } 286 287 @Deprecated 288 public static final int toInteger( Object value ) 289 { 290 return Coercions.INTEGER.coerce( value ); 291 } 292 293 @Deprecated 294 public static final long toLong( Object value ) 295 { 296 return Coercions.LONG.coerce( value ); 297 } 298 299 @Deprecated 300 public static final double toDouble( Object value ) 301 { 302 return Coercions.DOUBLE.coerce( value ); 303 } 304 305 @Deprecated 306 public static final float toFloat( Object value ) 307 { 308 return Coercions.FLOAT.coerce( value ); 309 } 310 311 @Deprecated 312 public static final short toShort( Object value ) 313 { 314 return Coercions.SHORT.coerce( value ); 315 } 316 317 @Deprecated 318 public static final boolean toBoolean( Object value ) 319 { 320 return Coercions.BOOLEAN.coerce( value ); 321 } 322 323 @Deprecated 324 public static final Integer toIntegerObject( Object value ) 325 { 326 return Coercions.INTEGER_OBJECT.coerce( value ); 327 } 328 329 @Deprecated 330 public static final Long toLongObject( Object value ) 331 { 332 return Coercions.LONG_OBJECT.coerce( value ); 333 } 334 335 @Deprecated 336 public static final Double toDoubleObject( Object value ) 337 { 338 return Coercions.DOUBLE_OBJECT.coerce( value ); 339 } 340 341 @Deprecated 342 public static final Float toFloatObject( Object value ) 343 { 344 return Coercions.FLOAT_OBJECT.coerce( value ); 345 } 346 347 @Deprecated 348 public static final Short toShortObject( Object value ) 349 { 350 return Coercions.SHORT_OBJECT.coerce( value ); 351 } 352 353 @Deprecated 354 public static final Boolean toBooleanObject( Object value ) 355 { 356 return Coercions.BOOLEAN_OBJECT.coerce( value ); 357 } 358 359 /** 360 * Method coerce forces each element value in the given Tuple to the corresponding primitive type. 361 * 362 * @param tuple of type Tuple 363 * @param types of type Class[] 364 * @return Tuple 365 */ 366 @Deprecated 367 public static Tuple coerce( Tuple tuple, Class[] types ) 368 { 369 return new Tuple( (Object[]) asArray( tuple, types, new Object[ types.length ] ) ); 370 } 371 372 /** 373 * Method coerce forces each element value in the given Tuple to the corresponding primitive type. 374 * <p/> 375 * This method expects the destination Tuple was created with the same size at the types array. 376 * 377 * @param tuple of type Tuple 378 * @param types of type Class[] 379 * @param destination of type Tuple 380 * @return Tuple 381 */ 382 @Deprecated 383 public static Tuple coerce( Tuple tuple, Class[] types, Tuple destination ) 384 { 385 if( tuple.size() != types.length ) 386 throw new OperationException( "number of input tuple values: " + tuple.size() + ", does not match number of coercion types: " + types.length ); 387 388 if( destination.size() != types.length ) 389 throw new OperationException( "number of destination tuple values: " + destination.size() + ", does not match number of coercion types: " + types.length ); 390 391 for( int i = 0; i < types.length; i++ ) 392 destination.set( i, coerce( tuple, i, types[ i ] ) ); 393 394 return destination; 395 } 396 397 /** 398 * Method extractTuple returns a new Tuple based on the given selector. But sets the values of the 399 * given TupleEntry to null. 400 * 401 * @param tupleEntry of type TupleEntry 402 * @param selector of type Fields 403 * @return Tuple 404 */ 405 public static Tuple extractTuple( TupleEntry tupleEntry, Fields selector ) 406 { 407 if( selector == null || selector.isAll() ) 408 { 409 Tuple result = tupleEntry.tuple; 410 411 tupleEntry.setTuple( Tuple.size( result.size() ) ); 412 413 return result; 414 } 415 416 try 417 { 418 return extract( tupleEntry, selector ); 419 } 420 catch( Exception exception ) 421 { 422 throw new TupleException( "unable to select from: " + tupleEntry.getFields().printVerbose() + ", using selector: " + selector.printVerbose(), exception ); 423 } 424 } 425 426 /** 427 * Method extract creates a new Tuple from the given selector, but sets the values in the current tuple to null. 428 * 429 * @param tupleEntry of type TupleEntry 430 * @param selector of type Fields 431 * @return Tuple 432 */ 433 public static Tuple extract( TupleEntry tupleEntry, Fields selector ) 434 { 435 return tupleEntry.tuple.extract( tupleEntry.getFields().getPos( selector, tupleEntry.getFields().size() ) ); 436 } 437 438 public static Tuple nulledCopy( TupleEntry tupleEntry, Fields selector ) 439 { 440 return tupleEntry.tuple.nulledCopy( tupleEntry.getFields().getPos( selector, tupleEntry.getFields().size() ) ); 441 } 442 443 public static Tuple nulledCopy( Fields declarator, Tuple tuple, Fields selector ) 444 { 445 // use tuple.size() in case declarator is UNKNOWN and selector has relative pos 446 return tuple.nulledCopy( declarator.getPos( selector, tuple.size() ) ); 447 } 448 449 public static Tuple setOnEmpty( TupleEntry baseEntry, TupleEntry valuesEntry ) 450 { 451 Tuple emptyTuple = Tuple.size( baseEntry.getFields().size() ); 452 453 emptyTuple.set( baseEntry.getFields(), valuesEntry.getFields(), valuesEntry.getTuple() ); 454 455 return emptyTuple; 456 } 457 458 /** 459 * Method asUnmodifiable marks the given Tuple instance as unmodifiable. 460 * 461 * @param tuple of type Tuple 462 * @return Tuple 463 */ 464 public static Tuple asUnmodifiable( Tuple tuple ) 465 { 466 tuple.isUnmodifiable = true; 467 468 return tuple; 469 } 470 471 /** 472 * Method asModifiable marks the given Tuple instance as modifiable. 473 * 474 * @param tuple of type Tuple 475 * @return Tuple 476 */ 477 public static Tuple asModifiable( Tuple tuple ) 478 { 479 tuple.isUnmodifiable = false; 480 481 return tuple; 482 } 483 484 public static Tuple setUnmodifiable( Tuple tuple, boolean isUnmodifiable ) 485 { 486 tuple.isUnmodifiable = isUnmodifiable; 487 488 return tuple; 489 } 490 491 public static Tuple create( List<Object> arrayList ) 492 { 493 return new Tuple( arrayList ); 494 } 495 }