org.ulyssis.ipp.snapshot.Snapshot.java Source code

Java tutorial

Introduction

Here is the source code for org.ulyssis.ipp.snapshot.Snapshot.java

Source

/*
 * Copyright (C) 2014-2015 ULYSSIS VZW
 *
 * This file is part of i++.
 * 
 * i++ is free software: you can redistribute it and/or modify
 * it under the terms of version 3 of the GNU Affero General Public License
 * as published by the Free Software Foundation. No other versions apply.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>
 */
package org.ulyssis.ipp.snapshot;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.ulyssis.ipp.updates.Status;
import org.ulyssis.ipp.utils.Serialization;

import java.io.IOException;
import java.sql.*;
import java.time.Instant;
import java.util.Optional;

public final class Snapshot {
    private static final Logger LOG = LogManager.getLogger(Snapshot.class);

    public static class Builder {
        private Snapshot snapshot;

        private Builder(Instant time, Snapshot other) {
            snapshot = new Snapshot(time);
            if (other != null) {
                snapshot.teamTagMap = other.teamTagMap;
                snapshot.startTime = other.startTime;
                snapshot.endTime = other.endTime;
                snapshot.teamStates = other.teamStates;
                snapshot.publicTeamStates = other.publicTeamStates;
                snapshot.statusMessage = other.statusMessage;
                snapshot.status = other.status;
                snapshot.updateFrequency = other.updateFrequency;
            }
        }

        public Builder withTeamTagMap(TeamTagMap teamTagMap) {
            this.snapshot.teamTagMap = teamTagMap;
            return this;
        }

        public Builder withStartTime(Instant time) {
            this.snapshot.startTime = time;
            return this;
        }

        public Builder withEndTime(Instant time) {
            this.snapshot.endTime = time;
            return this;
        }

        public Builder withTeamStates(TeamStates teamStates) {
            this.snapshot.teamStates = teamStates;
            return this;
        }

        public Builder withPublicTeamStates(TeamStates teamStates) {
            this.snapshot.publicTeamStates = teamStates;
            return this;
        }

        public Builder withStatusMessage(String message) {
            this.snapshot.statusMessage = message;
            return this;
        }

        public Builder withStatus(Status status) {
            this.snapshot.status = status;
            return this;
        }

        public Builder withUpdateFrequency(int updateFrequency) {
            this.snapshot.updateFrequency = updateFrequency;
            return this;
        }

        public Snapshot build() {
            return snapshot;
        }
    }

    @JsonIgnore
    private long id = -1;

    @JsonIgnore
    long eventId = -1;

    public Optional<Long> getId() {
        if (id != -1)
            return Optional.of(id);
        else
            return Optional.empty();
    }

    public Optional<Long> getEventId() {
        if (eventId != -1)
            return Optional.of(eventId);
        else
            return Optional.empty();
    }

    /**
     * Default constructor for Jackson
     */
    @SuppressWarnings("unused")
    private Snapshot() {
    }

    public Snapshot(Instant time) {
        snapshotTime = time;
    }

    public Instant getSnapshotTime() {
        return snapshotTime;
    }

    public TeamTagMap getTeamTagMap() {
        return teamTagMap;
    }

    public Instant getStartTime() {
        return startTime;
    }

    public Instant getEndTime() {
        return endTime;
    }

    public TeamStates getTeamStates() {
        return teamStates;
    }

    public TeamStates getPublicTeamStates() {
        return publicTeamStates;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public Status getStatus() {
        return status;
    }

    public int getUpdateFrequency() {
        return updateFrequency;
    }

    private Instant snapshotTime = Instant.MIN;
    private Instant startTime = Instant.MAX;
    private Instant endTime = Instant.MAX;
    private TeamTagMap teamTagMap = new TeamTagMap();
    private TeamStates teamStates;
    private TeamStates publicTeamStates;
    {
        teamStates = new TeamStates();
        publicTeamStates = teamStates;
    }
    private String statusMessage = "";
    private Status status = Status.NoResults;
    private int updateFrequency = 3;

    public static Builder builder(Instant time, Snapshot other) {
        return new Builder(time, other);
    }

    public static Optional<Snapshot> loadForEvent(Connection connection, Event event)
            throws SQLException, IOException {
        String statement = "SELECT \"id\", \"data\" FROM \"snapshots\" WHERE \"event\" = ?";
        try (PreparedStatement stmt = connection.prepareStatement(statement)) {
            stmt.setLong(1, event.getId().get());
            LOG.debug("executing query: {}", stmt);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                String data = rs.getString("data");
                Snapshot result = Serialization.getJsonMapper().readValue(data, Snapshot.class);
                result.id = rs.getLong("id");
                result.eventId = event.getId().get();
                return Optional.of(result);
            } else {
                return Optional.empty();
            }
        }
    }

    public static Optional<Snapshot> loadLatest(Connection connection) throws SQLException, IOException {
        String statement = "SELECT \"id\", \"data\", \"event\" FROM \"snapshots\" ORDER BY \"time\" DESC FETCH FIRST ROW ONLY";
        try (Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(statement)) {
            if (rs.next()) {
                String data = rs.getString("data");
                Snapshot result = Serialization.getJsonMapper().readValue(data, Snapshot.class);
                result.id = rs.getLong("id");
                result.eventId = rs.getLong("event");
                return Optional.of(result);
            } else {
                return Optional.empty();
            }
        }
    }

    public static Optional<Snapshot> loadBefore(Connection connection, Instant time)
            throws SQLException, IOException {
        String statement = "SELECT \"id\", \"data\", \"event\" FROM \"snapshots\" "
                + "WHERE \"time\" < ? ORDER BY \"time\" DESC, \"event\" DESC FETCH FIRST ROW ONLY";
        try (PreparedStatement stmt = connection.prepareStatement(statement)) {
            stmt.setTimestamp(1, Timestamp.from(time));
            LOG.debug("Executing query: {}", stmt);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                String data = rs.getString("data");
                Snapshot result = Serialization.getJsonMapper().readValue(data, Snapshot.class);
                result.id = rs.getLong("id");
                result.eventId = rs.getLong("event");
                return Optional.of(result);
            } else {
                return Optional.empty();
            }
        }
    }

    public void save(Connection connection) throws SQLException {
        if (id != -1)
            return;
        try (PreparedStatement statement = connection.prepareStatement(
                "INSERT INTO \"snapshots\" (\"time\",\"data\",\"event\") VALUES (?,?,?)",
                Statement.RETURN_GENERATED_KEYS)) {
            statement.setTimestamp(1, Timestamp.from(snapshotTime));
            String serialized;
            try {
                serialized = Serialization.getJsonMapper().writeValueAsString(this);
            } catch (JsonProcessingException e) {
                assert false; // TODO(Roel): Programming error
                return;
            }
            statement.setString(2, serialized);
            statement.setLong(3, eventId);
            statement.executeUpdate();
            ResultSet keys = statement.getGeneratedKeys();
            keys.next();
            this.id = keys.getLong(1);
        }
    }

    public static void deleteAfter(Connection connection, Snapshot snapshot) throws SQLException {
        String statement = "DELETE FROM \"snapshots\" WHERE \"time\" > ? OR (\"time\" = ? AND \"event\" > ?)";
        try (PreparedStatement stmt = connection.prepareStatement(statement)) {
            Timestamp timestamp = Timestamp.from(snapshot.getSnapshotTime());
            stmt.setTimestamp(1, timestamp);
            stmt.setTimestamp(2, timestamp);
            stmt.setLong(3, snapshot.getEventId().orElse(-1L));
            LOG.debug("Executing query: {}", stmt);
            int affectedRows = stmt.executeUpdate();
            LOG.debug("deleteAfter affected {} rows", affectedRows);
        }
    }
}