/* * Copyright (c) 2015-2019, Cloudera, Inc. All Rights Reserved. * * Cloudera, Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"). You may not use this file except in * compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * This software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for * the specific language governing permissions and limitations under the * License. */ package com.cloudera.labs.envelope.plan.time; import com.cloudera.labs.envelope.component.ProvidesAlias; import com.cloudera.labs.envelope.spark.RowWithSchema; import com.cloudera.labs.envelope.utils.RowUtils; import com.cloudera.labs.envelope.validate.ProvidesValidations; import com.cloudera.labs.envelope.validate.Validations; import com.google.common.collect.Lists; import com.typesafe.config.Config; import com.typesafe.config.ConfigValueType; import org.apache.spark.sql.Row; import org.apache.spark.sql.types.DataTypes; import org.apache.spark.sql.types.StructField; import org.apache.spark.sql.types.StructType; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.List; public class StringDateTimeModel implements TimeModel, ProvidesAlias, ProvidesValidations { public static final String DATETIME_FORMAT_CONFIG = "format"; private StructField field; private DateFormat format; private Date current; private Date farFuture = new Date(253402214400000L); @Override public void configure(Config config) { if (config.hasPath(DATETIME_FORMAT_CONFIG)) { this.format = new SimpleDateFormat(config.getString(DATETIME_FORMAT_CONFIG)); } else { this.format = new SimpleDateFormat("yyyy-MM-dd"); } } @Override public void configureFieldNames(List<String> fieldNames) { this.field = DataTypes.createStructField(fieldNames.get(0), DataTypes.StringType, true); } @Override public void configureCurrentSystemTime(long currentSystemTimeMillis) { this.current = new Date(currentSystemTimeMillis); } @Override public int compare(Row first, Row second) { Date firstDate; Date secondDate; try { firstDate = format.parse(first.<String>getAs(field.name())); secondDate = format.parse(second.<String>getAs(field.name())); } catch (ParseException e) { throw new RuntimeException(e); } return firstDate.compareTo(secondDate); } @Override public StructType getSchema() { return DataTypes.createStructType(Lists.newArrayList(field)); } @Override public Row setFarFutureTime(Row row) { return RowUtils.set(row, field.name(), format.format(farFuture)); } @Override public Row setCurrentSystemTime(Row row) { return RowUtils.set(row, field.name(), format.format(current)); } @Override public Row setPrecedingSystemTime(Row row) { return RowUtils.set(row, field.name(), format.format(precedingDate(current))); } @Override public Row appendFields(Row row) { return RowUtils.append(row, field.name(), field.dataType(), true, null); } private Date precedingDate(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.DATE, -1); return cal.getTime(); } @Override public Row getTime(Row row) { return new RowWithSchema(getSchema(), row.getAs(field.name())); } @Override public Row getPrecedingTime(Row row) { Date date; try { date = format.parse(row.<String>getAs(field.name())); } catch (ParseException e) { throw new RuntimeException(e); } String precedingDateString = format.format(precedingDate(date)); return new RowWithSchema(getSchema(), precedingDateString); } @Override public String getAlias() { return "stringdate"; } @Override public Validations getValidations() { return Validations.builder() .optionalPath(DATETIME_FORMAT_CONFIG, ConfigValueType.STRING) .build(); } }