SecurityAnalysisResultDeserializer.java
/**
* Copyright (c) 2017, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.security.json;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.google.common.base.Suppliers;
import com.powsybl.action.json.ActionJsonModule;
import com.powsybl.commons.extensions.*;
import com.powsybl.commons.json.JsonUtil;
import com.powsybl.loadflow.LoadFlowResult;
import com.powsybl.security.LimitViolationsResult;
import com.powsybl.security.NetworkMetadata;
import com.powsybl.security.results.*;
import com.powsybl.security.SecurityAnalysisResult;
import com.powsybl.security.results.OperatorStrategyResult;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
import static com.powsybl.security.json.LimitViolationDeserializer.VIOLATION_LOCATION_SUPPORT;
/**
* @author Massimo Ferraro {@literal <massimo.ferraro@techrain.it>}
*/
public class SecurityAnalysisResultDeserializer extends StdDeserializer<SecurityAnalysisResult> {
private static final String CONTEXT_NAME = "SecurityAnalysisResult";
private static final Supplier<ExtensionProviders<ExtensionJsonSerializer>> SUPPLIER =
Suppliers.memoize(() -> ExtensionProviders.createProvider(ExtensionJsonSerializer.class, "security-analysis"));
public static final String SOURCE_VERSION_ATTRIBUTE = "sourceVersionAttribute";
public SecurityAnalysisResultDeserializer() {
super(SecurityAnalysisResult.class);
}
@Override
public SecurityAnalysisResult deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
String version = null;
NetworkMetadata networkMetadata = null;
LimitViolationsResult limitViolationsResult = null;
List<PostContingencyResult> postContingencyResults = Collections.emptyList();
List<Extension<SecurityAnalysisResult>> extensions = Collections.emptyList();
PreContingencyResult preContingencyResult = null;
List<OperatorStrategyResult> operatorStrategyResults = Collections.emptyList();
while (parser.nextToken() != JsonToken.END_OBJECT) {
switch (parser.currentName()) {
case "version":
parser.nextToken(); // skip
version = parser.getValueAsString();
JsonUtil.setSourceVersion(ctx, version, SOURCE_VERSION_ATTRIBUTE);
ctx.setAttribute(VIOLATION_LOCATION_SUPPORT, version.compareTo("1.7") >= 0);
break;
case "network":
parser.nextToken();
networkMetadata = JsonUtil.readValue(ctx, parser, NetworkMetadata.class);
break;
case "preContingencyResult":
parser.nextToken();
if (version != null && version.equals("1.0")) {
limitViolationsResult = JsonUtil.readValue(ctx, parser, LimitViolationsResult.class);
} else {
preContingencyResult = JsonUtil.readValue(ctx, parser, PreContingencyResult.class);
}
break;
case "postContingencyResults":
parser.nextToken();
postContingencyResults = JsonUtil.readList(ctx, parser, PostContingencyResult.class);
break;
case "operatorStrategyResults":
JsonUtil.assertGreaterOrEqualThanReferenceVersion(CONTEXT_NAME, "Tag: operatorStrategyResults", version, "1.2");
parser.nextToken();
operatorStrategyResults = JsonUtil.readList(ctx, parser, OperatorStrategyResult.class);
break;
case "extensions":
parser.nextToken();
extensions = JsonUtil.readExtensions(parser, ctx, SUPPLIER.get());
break;
default:
throw new IllegalStateException("Unexpected field: " + parser.currentName());
}
}
SecurityAnalysisResult result = null;
if (preContingencyResult == null) {
LoadFlowResult.ComponentResult.Status status = null;
if (limitViolationsResult != null && version.equals("1.0")) {
status = limitViolationsResult.isComputationOk() ? LoadFlowResult.ComponentResult.Status.CONVERGED : LoadFlowResult.ComponentResult.Status.FAILED;
} else {
status = LoadFlowResult.ComponentResult.Status.CONVERGED;
}
result = new SecurityAnalysisResult(limitViolationsResult, status, postContingencyResults, Collections.emptyList(),
Collections.emptyList(), Collections.emptyList(), operatorStrategyResults);
} else {
result = new SecurityAnalysisResult(preContingencyResult, postContingencyResults, operatorStrategyResults);
}
result.setNetworkMetadata(networkMetadata);
SUPPLIER.get().addExtensions(result, extensions);
return result;
}
public static SecurityAnalysisResult read(Path jsonFile) {
try (InputStream is = Files.newInputStream(jsonFile)) {
return read(is);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public static SecurityAnalysisResult read(InputStream is) {
Objects.requireNonNull(is);
ObjectMapper objectMapper = JsonUtil.createObjectMapper()
.registerModule(new SecurityAnalysisJsonModule())
.registerModule(new ActionJsonModule());
try {
return objectMapper.readValue(is, SecurityAnalysisResult.class);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}