    001/*
    002 * Copyright (c) 2007-2016 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
    021package cascading.operation.text;
    022
    023import java.beans.ConstructorProperties;
    024import java.text.SimpleDateFormat;
    025import java.util.Calendar;
    026import java.util.Locale;
    027import java.util.TimeZone;
    028
    029import cascading.flow.FlowProcess;
    030import cascading.operation.BaseOperation;
    031import cascading.operation.OperationCall;
    032import cascading.tuple.Fields;
    033import cascading.tuple.Tuple;
    034import cascading.util.Pair;
    035
    036/** Class DateOperation is the base class for {@link DateFormatter} and {@link DateParser}. */
    037public class DateOperation extends BaseOperation<Pair<SimpleDateFormat, Tuple>>
    038  {
    039  /** Field zone */
    040  protected TimeZone zone;
    041  /** Field locale */
    042  protected Locale locale;
    043  /** Field dateFormatString */
    044  final String dateFormatString;
    045
    046  /**
    047   * Constructor DateOperation creates a new DateOperation instance.
    048   *
    049   * @param numArgs          of type int
    050   * @param fieldDeclaration of type Fields
    051   * @param dateFormatString of type String
    052   */
    053  @ConstructorProperties({"numArgs", "fieldDeclaration", "dateFormatString"})
    054  public DateOperation( int numArgs, Fields fieldDeclaration, String dateFormatString )
    055    {
    056    super( numArgs, fieldDeclaration );
    057    this.dateFormatString = dateFormatString;
    058
    059    if( !fieldDeclaration.isSubstitution() && fieldDeclaration.size() != 1 )
    060      throw new IllegalArgumentException( "fieldDeclaration may only declare one field name, got " + fieldDeclaration.print() );
    061    }
    062
    063  /**
    064   * Constructor DateOperation creates a new DateOperation instance.
    065   *
    066   * @param numArgs          of type int
    067   * @param fieldDeclaration of type Fields
    068   * @param dateFormatString of type String
    069   * @param zone             of type TimeZone
    070   * @param locale           of type Locale
    071   */
    072  @ConstructorProperties({"numArgs", "fieldDeclaration", "dateFormatString", "zone", "locale"})
    073  public DateOperation( int numArgs, Fields fieldDeclaration, String dateFormatString, TimeZone zone, Locale locale )
    074    {
    075    super( numArgs, fieldDeclaration );
    076    this.dateFormatString = dateFormatString;
    077    this.zone = zone;
    078    this.locale = locale;
    079    }
    080
    081  public String getDateFormatString()
    082    {
    083    return dateFormatString;
    084    }
    085
    086  /**
    087   * Method getDateFormat returns the dateFormat of this DateParser object.
    088   *
    089   * @return the dateFormat (type SimpleDateFormat) of this DateParser object.
    090   */
    091  public SimpleDateFormat getDateFormat()
    092    {
    093    SimpleDateFormat dateFormat = new SimpleDateFormat( dateFormatString, getLocale() );
    094
    095    dateFormat.setTimeZone( getZone() );
    096
    097    return dateFormat;
    098    }
    099
    100  private Locale getLocale()
    101    {
    102    if( locale != null )
    103      return locale;
    104
    105    return Locale.getDefault();
    106    }
    107
    108  private TimeZone getZone()
    109    {
    110    if( zone != null )
    111      return zone;
    112
    113    return TimeZone.getTimeZone( "UTC" );
    114    }
    115
    116  protected Calendar getCalendar()
    117    {
    118    return Calendar.getInstance( TimeZone.getTimeZone( "UTC" ), getLocale() );
    119    }
    120
    121  @Override
    122  public void prepare( FlowProcess flowProcess, OperationCall<Pair<SimpleDateFormat, Tuple>> operationCall )
    123    {
    124    operationCall.setContext( new Pair<SimpleDateFormat, Tuple>( getDateFormat(), Tuple.size( 1 ) ) );
    125    }
    126
    127  @Override
    128  public boolean equals( Object object )
    129    {
    130    if( this == object )
    131      return true;
    132    if( !( object instanceof DateOperation ) )
    133      return false;
    134    if( !super.equals( object ) )
    135      return false;
    136
    137    DateOperation that = (DateOperation) object;
    138
    139    if( dateFormatString != null ? !dateFormatString.equals( that.dateFormatString ) : that.dateFormatString != null )
    140      return false;
    141    if( locale != null ? !locale.equals( that.locale ) : that.locale != null )
    142      return false;
    143    if( zone != null ? !zone.equals( that.zone ) : that.zone != null )
    144      return false;
    145
    146    return true;
    147    }
    148
    149  @Override
    150  public int hashCode()
    151    {
    152    int result = super.hashCode();
    153    result = 31 * result + ( zone != null ? zone.hashCode() : 0 );
    154    result = 31 * result + ( locale != null ? locale.hashCode() : 0 );
    155    result = 31 * result + ( dateFormatString != null ? dateFormatString.hashCode() : 0 );
    156    return result;
    157    }
    158  }