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  }