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