TimeseriesIO.java

package de.dlr.shepard.data.timeseries.io;

import de.dlr.shepard.common.util.HasId;
import de.dlr.shepard.context.semantic.entities.SemanticAnnotation;
import de.dlr.shepard.data.timeseries.model.Timeseries;
import de.dlr.shepard.data.timeseries.model.enums.DataPointValueType;
import jakarta.validation.constraints.NotBlank;
import java.util.List;
import java.util.Objects;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema;

/**
 * IO-Object relating to a client side Timeseries.
 * It encompasses the timeseries ID, the ID of the associated container, a value type as well as the tuple identifying
 * a timeseries: measurement, device, location, symbolicName and field.
 *
 */
@Schema(name = "TimeseriesEntity")
@Data
@NoArgsConstructor(force = true) // needed for serialization
public final class TimeseriesIO {

  @NotBlank
  private final long id;

  @NotBlank
  private final long containerId;

  @NotBlank
  private final DataPointValueType valueType;

  @NotBlank
  private final String measurement;

  @NotBlank
  private final String device;

  @NotBlank
  private final String location;

  @NotBlank
  private final String symbolicName;

  @NotBlank
  private final String field;

  @Schema(readOnly = true, required = true)
  private final long[] semanticAnnotationIds;

  public TimeseriesIO(Timeseries timeseries) {
    this.id = timeseries.getTimeseriesId();
    this.containerId = timeseries.getContainer().getId();
    this.valueType = timeseries.getValueType();
    this.measurement = timeseries.getTimeseriesTuple().getMeasurement();
    this.device = timeseries.getTimeseriesTuple().getDevice();
    this.location = timeseries.getTimeseriesTuple().getLocation();
    this.symbolicName = timeseries.getTimeseriesTuple().getSymbolicName();
    this.field = timeseries.getTimeseriesTuple().getField();
    this.semanticAnnotationIds = extractIds(timeseries.getAnnotations());
  }

  private static long[] extractIds(List<SemanticAnnotation> annotations) {
    return annotations.stream().map(SemanticAnnotation::getId).mapToLong(Long::longValue).toArray();
  }

  @Override
  public boolean equals(Object o) {
    if (o == null || getClass() != o.getClass()) return false;
    TimeseriesIO that = (TimeseriesIO) o;
    return (
      id == that.id &&
      containerId == that.containerId &&
      valueType == that.valueType &&
      Objects.equals(measurement, that.measurement) &&
      Objects.equals(device, that.device) &&
      Objects.equals(location, that.location) &&
      Objects.equals(symbolicName, that.symbolicName) &&
      Objects.equals(field, that.field) &&
      Objects.deepEquals(semanticAnnotationIds, that.semanticAnnotationIds)
    );
  }

  @Override
  public int hashCode() {
    return Objects.hash(
      id,
      containerId,
      valueType,
      measurement,
      device,
      location,
      symbolicName,
      field,
      HasId.hashcodeHelper(semanticAnnotationIds)
    );
  }
}