SetStationConfig.java

package com.workbenchclassic;

import org.json.JSONArray;
import org.json.JSONObject;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Path("/setStationConfig")
public class SetStationConfig {

    // Nutzen Sie eine einheitliche Instanz von DBService
    private final DBService dbService = new DBService("dsMesMiiNJTA");

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response doUpdate(String jsonBody) {
        Connection conn = null;
        try {
            // 1) JSON einlesen
            JSONObject json = new JSONObject(jsonBody);
            String station = json.getString("station");
            String persIdStr = json.getString("persID"); // z. B. "1234"
            int persID = Integer.parseInt(persIdStr);
            JSONArray dataArray = json.getJSONArray("data");

            // 2) Connection holen
            conn = dbService.getConnection();
            conn.setAutoCommit(false); // Transaktion starten

            // 3) DB-Daten ermitteln (nur Code-NR + Code-Wert)
            String query = "SELECT code_nr, code_wert, stamp "
                    + "  FROM bde.txt_konfig "
                    + " WHERE code IN (SELECT kap_id FROM bde.kast WHERE KAP_NR = ? )";

            // In diesem Beispiel nutzen wir direkt PreparedStatement + das gleiche conn
            Map<Integer, String> dbCodeMap = new HashMap<>();
            Set<Integer> dbCodeNrSet = new HashSet<>();

            try (PreparedStatement ps = conn.prepareStatement(query)) {
                ps.setString(1, station);
                try (ResultSet rs = ps.executeQuery()) {
                    while (rs.next()) {
                        int codeNr = rs.getInt("code_nr");
                        String codeWert = rs.getString("code_wert");
                        dbCodeMap.put(codeNr, codeWert);
                        dbCodeNrSet.add(codeNr);
                    }
                }
            }

            // 4) SQL-Statements für Update, Insert und Delete vorbereiten
            String updateSql = "UPDATE bde.txt_konfig "
                    + "    SET code_wert = ?, user_id = ? "
                    + " WHERE code_nr = ? "
                    + "    AND code IN (SELECT DISTINCT kap_id FROM bde.kast WHERE KAP_NR = ? AND KAP_TYP = 'T')";

            String insertSql = "INSERT INTO bde.txt_konfig (code, code_nr, code_bez, code_wert, created, stamp, user_ID) "
                    + "VALUES ( (SELECT kap_id FROM bde.kast WHERE KAP_NR = ? AND KAP_TYP = 'T'), ?, ?, ?, ?, ?, ? )";

            String deleteSql = "DELETE FROM bde.txt_konfig "
                    + " WHERE code_nr = ? "
                    + "   AND code IN (SELECT kap_id FROM bde.kast WHERE KAP_NR = ? and KAP_TYP = 'T')";

            // Für das Nachhalten aller "code_nr" aus dem JSON
            Set<Integer> jsonCodeNrSet = new HashSet<>();
            LocalDateTime jetzt = LocalDateTime.now();
            Timestamp timestamp = Timestamp.valueOf(jetzt);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

            try (PreparedStatement pstmtUpdate = conn.prepareStatement(updateSql);
                    PreparedStatement pstmtInsert = conn.prepareStatement(insertSql);
                    PreparedStatement pstmtDelete = conn.prepareStatement(deleteSql)) {

                // 4a) Über JSON-Array iterieren und ggf. Updaten/Einfügen
                for (int i = 0; i < dataArray.length(); i++) {
                    JSONObject obj = dataArray.getJSONObject(i);

                    // Beispiel: JSON hat "code_nr" und "code_wert"
                    if (obj.has("code_nr") && !obj.isNull("code_nr")
                            && obj.has("code_wert") && !obj.isNull("code_wert")) {
                        Integer jsonCodeNr = obj.getInt("code_nr");
                        String jsonCodeWert = obj.getString("code_wert").trim();
                        String jsonCodeBez = obj.getString("description").trim();
                        String jsoncreated = obj.getString("timestamp").trim();
                        jsonCodeNrSet.add(jsonCodeNr);

                        // Fall A: code_nr ist in DB -> Update (nur wenn sich der Wert ändert)
                        if (dbCodeMap.containsKey(jsonCodeNr)) {
                            String dbCodeWert = dbCodeMap.get(jsonCodeNr);
                            if (!dbCodeWert.equals(jsonCodeWert)) {
                                pstmtUpdate.setString(1, jsonCodeWert);
                                pstmtUpdate.setInt(2, persID); // Set the user_id parameter
                                pstmtUpdate.setInt(3, jsonCodeNr);
                                pstmtUpdate.setString(4, station);
                                pstmtUpdate.executeUpdate();
                            }
                        }
                        // Fall B: code_nr noch nicht in DB -> Insert
                        else {
                            LocalDateTime localDateTime = LocalDateTime.parse(jsoncreated, formatter);
                            Timestamp timestampcreated = Timestamp.valueOf(localDateTime);
                            pstmtInsert.setString(1, station);
                            pstmtInsert.setInt(2, jsonCodeNr);
                            pstmtInsert.setString(3, jsonCodeBez);
                            pstmtInsert.setString(4, jsonCodeWert);
                            pstmtInsert.setTimestamp(5, timestampcreated);
                            pstmtInsert.setTimestamp(6, timestamp);
                            pstmtInsert.setInt(7, persID);
                            pstmtInsert.executeUpdate();
                        }
                    }
                }

                // 4b) Löschen der Einträge, die nicht mehr im JSON vorhanden sind
                for (Integer dbCodeNr : dbCodeNrSet) {
                    if (!jsonCodeNrSet.contains(dbCodeNr)) {
                        pstmtDelete.setInt(1, dbCodeNr);
                        pstmtDelete.setString(2, station);
                        pstmtDelete.executeUpdate();
                    }
                }
            }

            // 5) Alles erfolgreich -> commit
            conn.commit();

            // Beispiel: Werk-Daten könnten Sie ggf. noch laden
            JSONObject werkData = getWerkData(conn, station);

            // 6) Erfolgs-Response
            JSONObject response = new JSONObject();
            response.put("status", "ok");
            response.put("message", "Daten wurden erfolgreich verarbeitet.");
            response.put("werk_data", werkData); // falls Sie die Werkdaten zurückgeben möchten
            return Response.ok(response.toString()).build();

        } catch (Exception e) {
            // Fehlerfall -> Rollback, JSON-Fehlerantwort
            if (conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            e.printStackTrace();
            JSONObject error = new JSONObject();
            error.put("status", "error");
            error.put("message", e.getMessage());
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error.toString()).build();
        } finally {
            // Verbindung sauber schließen
            if (conn != null) {
                try {
                    conn.setAutoCommit(true);
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Beispielmethode: Lädt aus bde.werk die Werkdaten für eine Station.
     */
    private JSONObject getWerkData(Connection conn, String station) throws SQLException {
        String query = "SELECT ext_werk_nr, werk_nr "
                + "  FROM bde.werk "
                + " WHERE werk_id IN (SELECT werk_id FROM bde.kast WHERE kap_nr = ?)";

        try (PreparedStatement ps = conn.prepareStatement(query)) {
            ps.setString(1, station);
            try (ResultSet rs = ps.executeQuery()) {
                if (rs.next()) {
                    JSONObject result = new JSONObject();
                    result.put("ext_werk_nr", rs.getString("ext_werk_nr"));
                    result.put("werk_nr", rs.getString("werk_nr"));
                    return result;
                }
            }
        }
        return new JSONObject();
    }
}