JsonCseCracCreationParameters.java
/*
* Copyright (c) 2021, 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/.
*/
package com.powsybl.openrao.data.crac.io.cse.parameters;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.data.crac.api.parameters.JsonCracCreationParameters;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.google.auto.service.AutoService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Baptiste Seguinot {@literal <baptiste.seguinot at rte-france.com>}
*/
@AutoService(JsonCracCreationParameters.ExtensionSerializer.class)
public class JsonCseCracCreationParameters implements JsonCracCreationParameters.ExtensionSerializer<CseCracCreationParameters> {
private static final String RANGE_ACTION_GROUPS = "range-action-groups";
private static final String BUS_BAR_CHANGE_SWITCHES = "bus-bar-change-switches";
private static final String REMEDIAL_ACTION_ID = "remedial-action-id";
private static final String SWITCH_PAIRS = "switch-pairs";
private static final String OPEN = "open";
private static final String CLOSE = "close";
private static final String UNEXPECTED_FIELD = "Unexpected field: %s";
@Override
public void serialize(CseCracCreationParameters cseParameters, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
serializeRangeActionGroups(cseParameters, jsonGenerator);
serializeBusBarChangeSwitchesSet(cseParameters, jsonGenerator);
jsonGenerator.writeEndObject();
}
@Override
public CseCracCreationParameters deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
return deserializeAndUpdate(jsonParser, deserializationContext, new CseCracCreationParameters());
}
@Override
public CseCracCreationParameters deserializeAndUpdate(JsonParser jsonParser, DeserializationContext deserializationContext, CseCracCreationParameters parameters) throws IOException {
while (!jsonParser.nextToken().isStructEnd()) {
switch (jsonParser.getCurrentName()) {
case RANGE_ACTION_GROUPS:
jsonParser.nextToken();
parameters.setRangeActionGroupsAsString(jsonParser.readValueAs(ArrayList.class));
break;
case BUS_BAR_CHANGE_SWITCHES:
jsonParser.nextToken();
parameters.setBusBarChangeSwitchesSet(deserializeBusBarChangeSwitchesSet(jsonParser));
break;
default:
throw new OpenRaoException(String.format(UNEXPECTED_FIELD, jsonParser.getCurrentName()));
}
}
return parameters;
}
@Override
public String getExtensionName() {
return "CseCracCreatorParameters";
}
@Override
public String getCategoryName() {
return "crac-creation-parameters";
}
@Override
public Class<? super CseCracCreationParameters> getExtensionClass() {
return CseCracCreationParameters.class;
}
private void serializeRangeActionGroups(CseCracCreationParameters cseParameters, JsonGenerator jsonGenerator) throws IOException {
serializeStringArray(RANGE_ACTION_GROUPS, cseParameters.getRangeActionGroupsAsString(), jsonGenerator);
}
private void serializeBusBarChangeSwitchesSet(CseCracCreationParameters cseParameters, JsonGenerator jsonGenerator) throws IOException {
jsonGenerator.writeFieldName(BUS_BAR_CHANGE_SWITCHES);
jsonGenerator.writeStartArray();
for (BusBarChangeSwitches busBarChangeSwitches : cseParameters.getBusBarChangeSwitchesSet()) {
serializeBusBarChangeSwitches(busBarChangeSwitches, jsonGenerator);
}
jsonGenerator.writeEndArray();
}
private void serializeBusBarChangeSwitches(BusBarChangeSwitches busBarChangeSwitches, JsonGenerator jsonGenerator) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField(REMEDIAL_ACTION_ID, busBarChangeSwitches.getRemedialActionId());
jsonGenerator.writeArrayFieldStart(SWITCH_PAIRS);
for (SwitchPairId switchPairId : busBarChangeSwitches.getSwitchPairs()) {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField(OPEN, switchPairId.getSwitchToOpenId());
jsonGenerator.writeStringField(CLOSE, switchPairId.getSwitchToCloseId());
jsonGenerator.writeEndObject();
}
jsonGenerator.writeEndArray();
jsonGenerator.writeEndObject();
}
private void serializeStringArray(String fieldName, List<String> content, JsonGenerator jsonGenerator) throws IOException {
if (!content.isEmpty()) {
jsonGenerator.writeArrayFieldStart(fieldName);
for (String string : content) {
jsonGenerator.writeString(string);
}
jsonGenerator.writeEndArray();
}
}
private Set<BusBarChangeSwitches> deserializeBusBarChangeSwitchesSet(JsonParser jsonParser) throws IOException {
Set<String> ids = new HashSet<>();
Set<BusBarChangeSwitches> set = new HashSet<>();
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
String remedialActionId = null;
Set<SwitchPairId> switchPairs = new HashSet<>();
while (!jsonParser.nextToken().isStructEnd()) {
switch (jsonParser.getCurrentName()) {
case REMEDIAL_ACTION_ID:
remedialActionId = jsonParser.nextTextValue();
break;
case SWITCH_PAIRS:
jsonParser.nextToken();
switchPairs = deserializeSwitchPairIds(jsonParser);
break;
default:
throw new OpenRaoException(String.format(UNEXPECTED_FIELD, jsonParser.getCurrentName()));
}
}
if (remedialActionId == null) {
throw new OpenRaoException(String.format("Missing remedial action ID in %s", BUS_BAR_CHANGE_SWITCHES));
}
if (ids.contains(remedialActionId)) {
throw new OpenRaoException(String.format("Remedial action %s has two or more associated %s lists", remedialActionId, BUS_BAR_CHANGE_SWITCHES));
}
ids.add(remedialActionId);
set.add(new BusBarChangeSwitches(remedialActionId, switchPairs));
}
return set;
}
private Set<SwitchPairId> deserializeSwitchPairIds(JsonParser jsonParser) throws IOException {
Set<SwitchPairId> switchPairs = new HashSet<>();
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
String switchToOpen = null;
String switchToClose = null;
while (!jsonParser.nextToken().isStructEnd()) {
switch (jsonParser.getCurrentName()) {
case OPEN:
switchToOpen = jsonParser.nextTextValue();
break;
case CLOSE:
switchToClose = jsonParser.nextTextValue();
break;
default:
throw new OpenRaoException(String.format(UNEXPECTED_FIELD, jsonParser.getCurrentName()));
}
}
if (switchToOpen == null || switchToClose == null) {
throw new OpenRaoException("Missing switch to open or switch to close in switch pair");
}
switchPairs.add(new SwitchPairId(switchToOpen, switchToClose));
}
return switchPairs;
}
}