io.horizondb.model.core.fields.TimestampField.java Source code

Java tutorial

Introduction

Here is the source code for io.horizondb.model.core.fields.TimestampField.java

Source

/**
 * Licensed 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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 io.horizondb.model.core.fields;

import io.horizondb.io.ByteReader;
import io.horizondb.io.ByteWriter;
import io.horizondb.io.encoding.VarInts;
import io.horizondb.model.core.Field;
import io.horizondb.model.core.util.TimeUtils;
import io.horizondb.model.schema.FieldType;

import java.io.IOException;
import java.io.PrintStream;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

import com.google.common.collect.ImmutableRangeSet;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;

import static org.apache.commons.lang.Validate.notNull;

/**
 * A <code>Field</code> representing a timestamp
 */
public final class TimestampField extends AbstractField {

    /**
     * The field maximum value: 9999-12-31 23:59:59.999 GMT
     */
    public static final Field MAX_VALUE = ImmutableField
            .of(new TimestampField(253402300799999L, TimeUnit.MILLISECONDS));

    /**
     * The field minimum value: 0000-01-01 00:00:00.000 GMT
     */
    public static final Field MIN_VALUE = ImmutableField
            .of(new TimestampField(-62167392000000L, TimeUnit.MILLISECONDS));

    /**
     * The range of field going from minimum value to maximum value.
     */
    public static final RangeSet<Field> ALL = ImmutableRangeSet.of(Range.closed(MIN_VALUE, MAX_VALUE));

    /**
     * The time unit.
     */
    private final TimeUnit sourceUnit;

    /**
     * The timestamp.
     */
    private long sourceTimestamp;

    /**
     * {@inheritDoc}
     */
    @Override
    public FieldType getType() {

        if (this.sourceUnit.equals(TimeUnit.NANOSECONDS)) {

            return FieldType.NANOSECONDS_TIMESTAMP;
        }

        if (this.sourceUnit.equals(TimeUnit.MICROSECONDS)) {

            return FieldType.MICROSECONDS_TIMESTAMP;
        }

        if (this.sourceUnit.equals(TimeUnit.MILLISECONDS)) {

            return FieldType.MILLISECONDS_TIMESTAMP;
        }

        return FieldType.SECONDS_TIMESTAMP;
    }

    /**
     * Returns the time unit.
     * @return the time unit
     */
    public TimeUnit getTimeUnit() {
        return this.sourceUnit;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Field newInstance() {

        return new TimestampField(this.sourceTimestamp, this.sourceUnit);
    }

    /**
    * 
    */
    public TimestampField(TimeUnit unit) {

        notNull(unit, "the unit parameter must not be null.");
        this.sourceUnit = unit;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isZero() {
        return this.sourceTimestamp == 0;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Field setValueToZero() {
        this.sourceTimestamp = 0;
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Field add(Field field) {

        TimestampField timestampField = (TimestampField) field;

        this.sourceTimestamp += this.sourceUnit.convert(timestampField.sourceTimestamp, timestampField.sourceUnit);
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Field subtract(Field field) {

        TimestampField timestampField = (TimestampField) field;

        this.sourceTimestamp -= this.sourceUnit.convert(timestampField.sourceTimestamp, timestampField.sourceUnit);
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void copyTo(Field field) {
        field.setTimestamp(this.sourceTimestamp, this.sourceUnit);
    }

    /**    
     * {@inheritDoc}
     */
    @Override
    public Field setValueFromString(TimeZone timeZone, String s) {

        if (s.startsWith("'") && s.endsWith("'")) {

            String dateTime = s.substring(1, s.length() - 1);
            long timeInMillis = TimeUtils.parseDateTime(timeZone, dateTime);
            setTimestampInMillis(timeInMillis);

        } else {

            int length = s.length();
            int index = length - 1;

            while (Character.isLetter(s.charAt(index))) {

                index--;
            }

            String symbol = s.substring(index + 1);
            String t = s.substring(0, index + 1);

            setTimestamp(Long.parseLong(t), getTimeUnit(symbol));
        }

        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void writeTo(ByteWriter writer) throws IOException {
        VarInts.writeLong(writer, this.sourceTimestamp);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void readFrom(ByteReader reader) throws IOException {
        this.sourceTimestamp = VarInts.readLong(reader);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int computeSerializedSize() {
        return VarInts.computeLongSize(this.sourceTimestamp);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public long getTimestampIn(TimeUnit unit) {
        return unit.convert(this.sourceTimestamp, this.sourceUnit);
    }

    /**    
     * {@inheritDoc}
     */
    @Override
    public void writePrettyPrint(PrintStream stream) {

        stream.print(this.sourceTimestamp);
        stream.print(' ');
        stream.print(getTimeUnitSymbol(this.sourceUnit));
    }

    /**
     * Returns the symbol for the specified unit of time.
     * 
     * @param timeUnit the time unit
     * @return the symbol for the specified unit of time
     */
    private static String getTimeUnitSymbol(TimeUnit timeUnit) {

        switch (timeUnit) {

        case NANOSECONDS:
            return "ns";
        case MICROSECONDS:
            return "s";
        case MILLISECONDS:
            return "ms";
        case SECONDS:
            return "s";
        default:
            return timeUnit.toString().toLowerCase();
        }
    }

    /**
     * Returns the unit of time for the specified symbol.
     * 
     * @param timeUnit the time unit
     * @return the unit of time for the specified symbol
     */
    private TimeUnit getTimeUnit(String symbol) {

        switch (symbol) {

        case "":
            return this.sourceUnit;
        case "ns":
            return TimeUnit.NANOSECONDS;
        case "s":
            return TimeUnit.MICROSECONDS;
        case "ms":
            return TimeUnit.MILLISECONDS;
        case "s":
            return TimeUnit.SECONDS;
        default:
            throw new IllegalStateException("Unknown time unit: " + symbol);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Field setTimestamp(long sourceTimestamp, TimeUnit unit) {

        if (unit.compareTo(this.sourceUnit) < 0) {

            throw new TypeConversionException("A timestamp in " + unit.toString().toLowerCase()
                    + " cannot be stored in a field of type: " + getType() + ".");
        }

        this.sourceTimestamp = this.sourceUnit.convert(sourceTimestamp, unit);
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int compareTo(Field other) {
        return Long.compare(this.sourceTimestamp, other.getTimestampIn(this.sourceUnit));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {

        return this.sourceTimestamp + getSymbol();
    }

    /**
     * Return the symbol associated to the time unit.
     * @return the symbol associated to the time unit.
     */
    private String getSymbol() {

        switch (this.sourceUnit) {

        case NANOSECONDS:
            return "ns";
        case MICROSECONDS:
            return "s";
        case MILLISECONDS:
            return "ms";
        case SECONDS:
            return "s";
        default:
            return this.sourceUnit.toString();
        }
    }

    /**
     * 
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object object) {
        if (object == this) {
            return true;
        }
        if (!(object instanceof TimestampField)) {
            return false;
        }
        Field rhs = (Field) object;
        return new EqualsBuilder().append(getTimestampInNanos(), rhs.getTimestampInNanos()).isEquals();
    }

    /**
     * 
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return new HashCodeBuilder(773109111, 83366071).append(this.sourceTimestamp).append(this.sourceUnit)
                .toHashCode();
    }

    /**    
     * {@inheritDoc}
     */
    @Override
    public Field maxValue() {
        return MAX_VALUE;
    }

    /**    
     * {@inheritDoc}
     */
    @Override
    public Field minValue() {
        return MIN_VALUE;
    }

    /**
     * Creates a <code>TimestampField</code> with the specified value.
     * 
     * @param timestamp the timestamp
     * @param unit the timestamp unit
     */
    private TimestampField(long timestamp, TimeUnit unit) {

        notNull(unit, "the unit parameter must not be null.");
        this.sourceTimestamp = timestamp;
        this.sourceUnit = unit;
    }
}