001/*
002 * Units of Measurement Reference Implementation
003 * Copyright (c) 2005-2020, Units of Measurement project.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-385, Indriya nor the names of their contributors may be used to endorse or promote products
017 *    derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package tech.units.indriya.quantity.time;
031
032import java.time.Instant;
033import java.util.Objects;
034import java.util.function.Supplier;
035
036import tech.uom.lib.common.function.Nameable;
037
038/**
039 * TimedData is a container for a data value that keeps track of its age. This class keeps track of the birth time of a bit of data, i.e. time the
040 * object is instantiated.<br>
041 * The TimedData MUST be immutable.
042 * 
043 * @param <T>
044 *          The data value.
045 * 
046 * @author <a href="mailto:werner@units.tech">Werner Keil</a>
047 * @version 0.7
048 * @since 1.0
049 * @see <a href="http://en.wikipedia.org/wiki/Time_series"> Wikipedia: Time Series</a>
050 */
051public class TimedData<T> implements Nameable, Supplier<T> {
052  private final T value;
053  private final long timestamp;
054  private final Instant instant;
055  private final String name;
056
057  /**
058   * Construct an instance of TimedData with a value and timestamp.
059   *
060   * @param data
061   *          The value of the TimedData.
062   * @param time
063   *          The timestamp of the TimedData.
064   */
065  protected TimedData(T value, long time) {
066    this(value, time, null);
067  }
068
069  /**
070   * Construct an instance of TimedData with a value, a timestamp and a name.
071   *
072   * @param data
073   *          The value of the TimedData.
074   * @param time
075   *          The timestamp of the TimedData.
076   * @param name
077   *          The name of the TimedData.
078   */
079  protected TimedData(T value, long time, String name) {
080    this.value = value;
081    this.timestamp = time;
082    this.instant = Instant.ofEpochMilli(time);
083    this.name = name;
084  }
085
086  /**
087   * Returns a {@code TimedData} with the specified values.
088   *
089   * @param <T>
090   *          the class of the value
091   * @param val
092   *          The value for the timed data.
093   * @param time
094   *          The timestamp.
095   * @return an {@code TimedData} with the given values
096   */
097  public static <T> TimedData<T> of(T val, long time) {
098    return new TimedData<>(val, time);
099  }
100
101  /**
102   * Returns a {@code TimedData} with the specified values.
103   *
104   * @param <T>
105   *          the class of the value
106   * @param val
107   *          The value for the timed data.
108   * @param time
109   *          The timestamp.
110   * @param name
111   *          The name.
112   * @return an {@code TimedData} with the given values
113   */
114  public static <T> TimedData<T> of(T val, long time, String name) {
115    return new TimedData<>(val, time, name);
116  }
117
118  /**
119   * Returns the time with which this TimedData was created.
120   * 
121   * @return the time of creation
122   */
123  public long getTimestamp() {
124    return timestamp;
125  }
126
127  public String getName() {
128    return name;
129  }
130
131  public T get() {
132    return value;
133  }
134
135  @Override
136  public boolean equals(Object obj) {
137    if (this == obj) {
138      return true;
139    }
140    if (obj instanceof TimedData<?>) {
141      @SuppressWarnings("unchecked")
142      final TimedData<T> other = (TimedData<T>) obj;
143      return Objects.equals(get(), other.get()) && Objects.equals(getTimestamp(), other.getTimestamp()) && Objects.equals(getName(), other.getName());
144
145    }
146    return false;
147  }
148
149  @Override
150  public int hashCode() {
151    return Objects.hash(value, timestamp, name);
152  }
153
154  @Override
155  public String toString() {
156    final StringBuilder sb = new StringBuilder().append("data= ").append(get()).append(", timestamp= ").append(getTimestamp());
157    if (name != null) {
158      sb.append(", name= ").append(getName());
159    }
160    return sb.toString();
161  }
162
163  public Instant getInstant() {
164    return instant;
165  }
166
167}