    001/*
    002 * Copyright (c) 2016-2017 Chris K Wensel. 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.io.IOException;
    024import java.io.UncheckedIOException;
    025import java.util.Objects;
    026import java.util.function.Function;
    027import java.util.function.Supplier;
    028import java.util.function.ToDoubleFunction;
    029import java.util.function.ToIntFunction;
    030import java.util.function.ToLongFunction;
    031import java.util.stream.DoubleStream;
    032import java.util.stream.IntStream;
    033import java.util.stream.LongStream;
    034import java.util.stream.Stream;
    035
    036import cascading.flow.FlowProcess;
    037import cascading.tap.Tap;
    038
    039/**
    040 * TupleStream provides helper methods to create {@link Tuple} {@link Stream} instances from {@link Tap} instances.
    041 * <p>
    042 * This class is a convenience class over the methods provided on the Tap class that provide the same
    043 * functionality. This class exists to help overcome any generics compiler warnings.
    044 */
    045public class TupleStream
    046  {
    047  /**
    048   * Method tupleStream returns a {@link Stream} of {@link Tuple} instances from the given
    049   * {@link Tap} instance.
    050   * <p>
    051   * Also see {@link Tap#tupleStream(FlowProcess)}.
    052   *
    053   * @param tap         the Tap to open
    054   * @param flowProcess represents the current platform configuration
    055   * @return a Stream of Tuple instances
    056   */
    057  @SuppressWarnings("unchecked")
    058  public static Stream<Tuple> tupleStream( Tap tap, FlowProcess flowProcess )
    059    {
    060    Objects.requireNonNull( tap );
    061
    062    return tap.tupleStream( flowProcess );
    063    }
    064
    065  /**
    066   * Method tupleStreamCopy returns a {@link Stream} of {@link Tuple} instances from the given
    067   * {@link Tap} instance.
    068   * <p>
    069   * This method returns an Tuple instance suitable for caching.
    070   * <p>
    071   * Also see {@link Tap#tupleStreamCopy(FlowProcess)}.
    072   *
    073   * @param tap         the Tap to open
    074   * @param flowProcess represents the current platform configuration
    075   * @return a Stream of TupleEntry instances
    076   */
    077  @SuppressWarnings("unchecked")
    078  public static Stream<Tuple> tupleStreamCopy( Tap tap, FlowProcess flowProcess )
    079    {
    080    Objects.requireNonNull( tap );
    081
    082    return tap.tupleStreamCopy( flowProcess );
    083    }
    084
    085  /**
    086   * Method tupleStream returns a {@link Stream} of {@link Tuple} instances from the given
    087   * {@link Tap} instance.
    088   * <p>
    089   * Also see {@link Tap#tupleStream(FlowProcess)}.
    090   *
    091   * @param tap         the Tap to open
    092   * @param flowProcess represents the current platform configuration
    093   * @param selector    the fields to select from the underlying Tuple
    094   * @return a Stream of TupleE instances
    095   */
    096  @SuppressWarnings("unchecked")
    097  public static Stream<Tuple> tupleStream( Tap tap, FlowProcess flowProcess, Fields selector )
    098    {
    099    Objects.requireNonNull( tap );
    100    Objects.requireNonNull( selector );
    101
    102    return tap.tupleStream( flowProcess, selector );
    103    }
    104
    105  /**
    106   * Method tupleStreamCopy returns a {@link Stream} of {@link Tuple} instances from the given
    107   * {@link Tap} instance.
    108   * <p>
    109   * This method returns an Tuple instance suitable for caching.
    110   * <p>
    111   * Also see {@link Tap#tupleStreamCopy(FlowProcess)}.
    112   *
    113   * @param tap         the Tap to open
    114   * @param flowProcess represents the current platform configuration
    115   * @param selector    the fields to select from the underlying Tuple
    116   * @return a Stream of Tuple instances
    117   */
    118  @SuppressWarnings("unchecked")
    119  public static Stream<Tuple> tupleStreamCopy( Tap tap, FlowProcess flowProcess, Fields selector )
    120    {
    121    Objects.requireNonNull( tap );
    122    Objects.requireNonNull( selector );
    123
    124    return tap.tupleStreamCopy( flowProcess, selector );
    125    }
    126
    127  /**
    128   * Method posToObject returns the object at the given tuple position.
    129   *
    130   * @param pos the ordinal position to select from
    131   * @param <R> the object type
    132   * @return the value in the given ordinal position
    133   */
    134  @SuppressWarnings("unchecked")
    135  public static <R> Function<Tuple, ? extends R> posToObject( int pos )
    136    {
    137    return value -> (R) value.getObject( pos );
    138    }
    139
    140  /**
    141   * Method posToInt returns the int value at the given tuple position.
    142   *
    143   * @param pos the ordinal position to select from
    144   * @return the value in the given ordinal position
    145   */
    146  public static ToIntFunction<Tuple> posToInt( int pos )
    147    {
    148    return value -> value.getInteger( pos );
    149    }
    150
    151  /**
    152   * Method posToLong returns the long value at the given tuple position.
    153   *
    154   * @param pos the ordinal position to select from
    155   * @return the value in the given ordinal position
    156   */
    157  public static ToLongFunction<Tuple> posToLong( int pos )
    158    {
    159    return value -> value.getLong( pos );
    160    }
    161
    162  /**
    163   * Method posToDouble returns the double value at the given tuple position.
    164   *
    165   * @param pos the ordinal position to select from
    166   * @return the value in the given ordinal position
    167   */
    168  public static ToDoubleFunction<Tuple> posToDouble( int pos )
    169    {
    170    return value -> value.getDouble( pos );
    171    }
    172
    173  /**
    174   * Method writeTuple will add each {@link Tuple} instance to the {@link TupleEntryCollector} provided
    175   * by the given {@link Tap} instance.
    176   *
    177   * @param stream      a Stream of Tuple instances
    178   * @param into        a Supplier that returns the Tap to sink each entry into
    179   * @param flowProcess represents the current platform configuration
    180   * @return returns the given Tap
    181   */
    182  public static Tap writeTuple( Stream<Tuple> stream, Supplier<Tap> into, FlowProcess flowProcess )
    183    {
    184    return writeTuple( stream, into.get(), flowProcess );
    185    }
    186
    187  /**
    188   * Method writeTuple will add each {@link Tuple} instance to the {@link TupleEntryCollector} provided
    189   * by the given {@link Tap} instance.
    190   *
    191   * @param stream      a Stream of Tuple instances
    192   * @param into        the Tap to sink each entry into
    193   * @param flowProcess represents the current platform configuration
    194   * @return returns the given Tap
    195   */
    196  @SuppressWarnings("unchecked")
    197  public static Tap writeTuple( Stream<Tuple> stream, Tap into, FlowProcess flowProcess )
    198    {
    199    Objects.requireNonNull( into );
    200    Objects.requireNonNull( stream );
    201
    202    try
    203      {
    204      TupleEntryCollector collector = into.openForWrite( flowProcess );
    205
    206      stream.forEach( collector::add );
    207
    208      collector.close();
    209      }
    210    catch( IOException exception )
    211      {
    212      throw new UncheckedIOException( exception );
    213      }
    214
    215    return into;
    216    }
    217
    218  /**
    219   * Method writeInt will add each {@code int} instance to the {@link TupleEntryCollector} provided
    220   * by the given {@link Tap} instance.
    221   *
    222   * @param stream      a Stream of int values
    223   * @param into        a Supplier that returns the Tap to sink each value into
    224   * @param flowProcess represents the current platform configuration
    225   * @return returns the given Tap
    226   */
    227  public static Tap writeInt( IntStream stream, Supplier<Tap> into, FlowProcess flowProcess )
    228    {
    229    return writeInt( stream, into.get(), flowProcess );
    230    }
    231
    232  /**
    233   * Method writeInt will add each {@code int} instance to the {@link TupleEntryCollector} provided
    234   * by the given {@link Tap} instance.
    235   *
    236   * @param stream      a Stream of int values
    237   * @param into        the Tap to sink each value into
    238   * @param flowProcess represents the current platform configuration
    239   * @return returns the given Tap
    240   */
    241  @SuppressWarnings("unchecked")
    242  public static Tap writeInt( IntStream stream, Tap into, FlowProcess flowProcess )
    243    {
    244    Objects.requireNonNull( into );
    245    Objects.requireNonNull( stream );
    246
    247    Tuple tuple = Tuple.size( 1 );
    248
    249    try
    250      {
    251      TupleEntryCollector collector = into.openForWrite( flowProcess );
    252
    253      stream.forEach( i -> collector.add( reset( tuple, i ) ) );
    254
    255      collector.close();
    256      }
    257    catch( IOException exception )
    258      {
    259      throw new UncheckedIOException( exception );
    260      }
    261
    262    return into;
    263    }
    264
    265  /**
    266   * Method writeLong will add each {@code long} instance to the {@link TupleEntryCollector} provided
    267   * by the given {@link Tap} instance.
    268   *
    269   * @param stream      a Stream of long values
    270   * @param into        a Supplier that returns the Tap to sink each value into
    271   * @param flowProcess represents the current platform configuration
    272   * @return returns the given Tap
    273   */
    274  public static Tap writeLong( LongStream stream, Supplier<Tap> into, FlowProcess flowProcess )
    275    {
    276    return writeLong( stream, into.get(), flowProcess );
    277    }
    278
    279  /**
    280   * Method writeLong will add each {@code long} instance to the {@link TupleEntryCollector} provided
    281   * by the given {@link Tap} instance.
    282   *
    283   * @param stream      a Stream of long values
    284   * @param into        the Tap to sink each value into
    285   * @param flowProcess represents the current platform configuration
    286   * @return returns the given Tap
    287   */
    288  @SuppressWarnings("unchecked")
    289  public static Tap writeLong( LongStream stream, Tap into, FlowProcess flowProcess )
    290    {
    291    Objects.requireNonNull( into );
    292    Objects.requireNonNull( stream );
    293
    294    Tuple tuple = Tuple.size( 1 );
    295
    296    try
    297      {
    298      TupleEntryCollector collector = into.openForWrite( flowProcess );
    299
    300      stream.forEach( i -> collector.add( reset( tuple, i ) ) );
    301
    302      collector.close();
    303      }
    304    catch( IOException exception )
    305      {
    306      throw new UncheckedIOException( exception );
    307      }
    308
    309    return into;
    310    }
    311
    312  /**
    313   * Method writeDouble will add each {@code double} instance to the {@link TupleEntryCollector} provided
    314   * by the given {@link Tap} instance.
    315   *
    316   * @param stream      a Stream of double values
    317   * @param into        a Supplier that returns the Tap to sink each value into
    318   * @param flowProcess represents the current platform configuration
    319   * @return returns the given Tap
    320   */
    321  public static Tap writeDouble( DoubleStream stream, Supplier<Tap> into, FlowProcess flowProcess )
    322    {
    323    return writeDouble( stream, into.get(), flowProcess );
    324    }
    325
    326  /**
    327   * Method writeDouble will add each {@code double} instance to the {@link TupleEntryCollector} provided
    328   * by the given {@link Tap} instance.
    329   *
    330   * @param stream      a Stream of double values
    331   * @param into        the Tap to sink each value into
    332   * @param flowProcess represents the current platform configuration
    333   * @return returns the given Tap
    334   */
    335  @SuppressWarnings("unchecked")
    336  public static Tap writeDouble( DoubleStream stream, Tap into, FlowProcess flowProcess )
    337    {
    338    Objects.requireNonNull( into );
    339    Objects.requireNonNull( stream );
    340
    341    Tuple tuple = Tuple.size( 1 );
    342
    343    try
    344      {
    345      TupleEntryCollector collector = into.openForWrite( flowProcess );
    346
    347      stream.forEach( i -> collector.add( reset( tuple, i ) ) );
    348
    349      collector.close();
    350      }
    351    catch( IOException exception )
    352      {
    353      throw new UncheckedIOException( exception );
    354      }
    355
    356    return into;
    357    }
    358
    359  private static Tuple reset( Tuple tuple, Object value )
    360    {
    361    tuple.set( 0, value );
    362    return tuple;
    363    }
    364  }