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.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  }