All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.gqlstatus.DiagnosticRecord Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [https://neo4j.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.neo4j.gqlstatus;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/** Entries/fields in this "map" must be serializable* (Bolt must be able to parse them).
 * They must either be primitive types like int, or String
 * or collections that consists of such types (like _position)
 */
public class DiagnosticRecord {

    static final Map DEFAULT_DIAGNOSTIC_RECORD = new DiagnosticRecord().asMap();

    private static final String CURRENT_SCHEMA_DEFAULT = "/";
    private static final String OPERATION_DEFAULT = "";
    private static final String OPERATION_CODE_DEFAULT = "0";
    private final Map innerDiagnosticRecord;

    public static Builder from() {
        return new Builder();
    }

    public DiagnosticRecord(
            String severity,
            GqlClassification classification,
            int offset,
            int line,
            int column,
            Map statusParameters) {
        innerDiagnosticRecord = new HashMap<>();
        innerDiagnosticRecord.put("CURRENT_SCHEMA", CURRENT_SCHEMA_DEFAULT);
        innerDiagnosticRecord.put("OPERATION", OPERATION_DEFAULT);
        innerDiagnosticRecord.put("OPERATION_CODE", OPERATION_CODE_DEFAULT);
        innerDiagnosticRecord.put("_severity", severity);
        innerDiagnosticRecord.put("_classification", String.valueOf(classification));
        innerDiagnosticRecord.put("_position", Map.of("offset", offset, "line", line, "column", column));
        innerDiagnosticRecord.put("_status_parameters", statusParameters);
    }

    public DiagnosticRecord(String severity, GqlClassification classification, int offset, int line, int column) {
        innerDiagnosticRecord = new HashMap<>();
        innerDiagnosticRecord.put("CURRENT_SCHEMA", CURRENT_SCHEMA_DEFAULT);
        innerDiagnosticRecord.put("OPERATION", OPERATION_DEFAULT);
        innerDiagnosticRecord.put("OPERATION_CODE", OPERATION_CODE_DEFAULT);
        innerDiagnosticRecord.put("_severity", severity);
        innerDiagnosticRecord.put("_classification", String.valueOf(classification));
        innerDiagnosticRecord.put("_position", Map.of("offset", offset, "line", line, "column", column));
    }

    public DiagnosticRecord() {
        innerDiagnosticRecord = new HashMap<>();
        innerDiagnosticRecord.put("CURRENT_SCHEMA", CURRENT_SCHEMA_DEFAULT);
        innerDiagnosticRecord.put("OPERATION", OPERATION_DEFAULT);
        innerDiagnosticRecord.put("OPERATION_CODE", OPERATION_CODE_DEFAULT);
    }

    private DiagnosticRecord(Map jsonMap) {
        innerDiagnosticRecord = new HashMap<>();
        var CURRENT_SCHEMA = Optional.ofNullable(jsonMap.get("CURRENT_SCHEMA"));
        var OPERATION = Optional.ofNullable(jsonMap.get("OPERATION"));
        var OPERATION_CODE = Optional.ofNullable(jsonMap.get("OPERATION_CODE"));
        var _severity = Optional.ofNullable(jsonMap.get("_severity"));
        var _classification = Optional.ofNullable(jsonMap.get("_classification"));
        var _position = Optional.ofNullable(jsonMap.get("_position"));
        var _status_parameters = Optional.ofNullable(jsonMap.get("_status_parameters"));

        // These are always put in, default value if value is missing
        innerDiagnosticRecord.put("CURRENT_SCHEMA", CURRENT_SCHEMA.orElse(CURRENT_SCHEMA_DEFAULT));
        innerDiagnosticRecord.put("OPERATION", OPERATION.orElse(OPERATION_DEFAULT));
        innerDiagnosticRecord.put("OPERATION_CODE", OPERATION_CODE.orElse(OPERATION_CODE_DEFAULT));

        // These might have been put in, but doesn't have a default value
        _severity.ifPresent((s) -> innerDiagnosticRecord.put("_severity", s));
        _classification.ifPresent((c) -> innerDiagnosticRecord.put("_classification", c));
        _position.ifPresent((p) -> innerDiagnosticRecord.put("_position", p));
        _status_parameters.ifPresent((sp) -> innerDiagnosticRecord.put("_status_parameters", sp));
    }

    public void setStatusParameters(Map statusParameters) {
        innerDiagnosticRecord.put("_status_parameters", statusParameters);
    }

    public int hashCode() {
        return innerDiagnosticRecord.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        DiagnosticRecord that = (DiagnosticRecord) o;
        return innerDiagnosticRecord.equals(that.innerDiagnosticRecord);
    }

    public Map asMap() {
        return Collections.unmodifiableMap(innerDiagnosticRecord);
    }

    // This is not used right now, but will be later when Gql is included in logs
    // This returns an Optional since this operation might fail and throw a JsonProcessingException
    // JsonProcessingException is part of the Jackson library, and to avoid other modules depending
    // on that library, we catch it here and return an Optional instead
    // We could also catch the JsonProcessingException and return a new error instead,
    // But right now we go for Optional
    public Optional asJson() {
        var mapper = new ObjectMapper();
        try {
            var json = mapper.writeValueAsString(this.innerDiagnosticRecord);
            return Optional.of(json);
        } catch (JsonProcessingException e) {
            return Optional.empty();
        }
    }

    // This is not used right now, but could be useful
    public static Optional fromJson(String json) {
        var mapper = new ObjectMapper();
        try {
            @SuppressWarnings("unchecked")
            Map parsed = mapper.readValue(json, Map.class);
            return Optional.of(new DiagnosticRecord(parsed));
        } catch (JsonProcessingException e) {
            return Optional.empty();
        }
    }

    public static class Builder {
        private final Map innerDiagnosticRecord;

        private Builder() {
            innerDiagnosticRecord = new HashMap<>();
            innerDiagnosticRecord.put("CURRENT_SCHEMA", CURRENT_SCHEMA_DEFAULT);
            innerDiagnosticRecord.put("OPERATION", OPERATION_DEFAULT);
            innerDiagnosticRecord.put("OPERATION_CODE", OPERATION_CODE_DEFAULT);
        }

        public Builder atPosition(int offset, int line, int column) {
            innerDiagnosticRecord.put("_position", Map.of("offset", offset, "line", line, "column", column));
            return this;
        }

        public Builder withClassification(GqlClassification classification) {
            innerDiagnosticRecord.put("_classification", classification.toString());
            return this;
        }

        public Builder withSeverity(String severity) {
            innerDiagnosticRecord.put("_severity", severity);
            return this;
        }

        public DiagnosticRecord build() {
            return new DiagnosticRecord(innerDiagnosticRecord);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy