GraphMetadata.java
/**
* Copyright (c) 2019, 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.sld.svg;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.powsybl.commons.json.JsonUtil;
import com.powsybl.diagram.metadata.AbstractMetadata;
import com.powsybl.sld.layout.LayoutParameters;
import com.powsybl.sld.library.*;
import com.powsybl.sld.model.coordinate.Direction;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
/**
* @author Benoit Jeanson {@literal <benoit.jeanson at rte-france.com>}
* @author Nicolas Duchene
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
* @author Franck Lecuyer {@literal <franck.lecuyer at rte-france.com>}
*/
public class GraphMetadata extends AbstractMetadata {
@JsonInclude(JsonInclude.Include.NON_NULL)
// On some systems, the export order is determined by the order of the 1st encountered JsonCreator's attributes
// and "unescapedId" is put in last place. But on other systems, the export order is determined by the getters' order
// and "unescapedId" is put in 1st place, which leads to comparison errors in the unit tests.
// To prevent this discrepancy, the order is manually fixed.
@JsonPropertyOrder(value = {"unescapedId", "id", "vid", "nextVId", "componentType", "open", "direction", "vlabel", "equipmentId", "labels"})
public static class NodeMetadata {
private final String unescapedId;
private final String id;
private final String componentType;
private final boolean open;
private final String vId;
private final String nextVId;
private final Direction direction;
private final boolean vLabel;
private final String equipmentId;
private final List<NodeLabelMetadata> labels;
/**
* @deprecated use {@link NodeMetadata#NodeMetadata(String, String, String, String, String, boolean, Direction, boolean, String, List)} instead.
*/
@Deprecated(since = "4.0.0", forRemoval = true)
public NodeMetadata(@JsonProperty("id") String escapedId,
@JsonProperty("vid") String vId,
@JsonProperty("nextVId") String nextVId,
@JsonProperty("componentType") String componentType,
@JsonProperty("open") boolean open,
@JsonProperty("direction") Direction direction,
@JsonProperty("vlabel") boolean vLabel,
@JsonProperty("equipmentId") String equipmentId,
@JsonProperty("labels") List<NodeLabelMetadata> labels) {
this(null, escapedId, vId, nextVId, componentType, open, direction, vLabel, equipmentId, labels);
}
@JsonCreator
public NodeMetadata(@JsonProperty("unescapedId") String unescapedId,
@JsonProperty("id") String escapedId,
@JsonProperty("vid") String vId,
@JsonProperty("nextVId") String nextVId,
@JsonProperty("componentType") String componentType,
@JsonProperty("open") boolean open,
@JsonProperty("direction") Direction direction,
@JsonProperty("vlabel") boolean vLabel,
@JsonProperty("equipmentId") String equipmentId,
@JsonProperty("labels") List<NodeLabelMetadata> labels) {
this.unescapedId = unescapedId;
this.id = Objects.requireNonNull(escapedId);
this.vId = Objects.requireNonNull(vId);
this.nextVId = nextVId;
this.componentType = componentType;
this.open = Objects.requireNonNull(open);
this.direction = direction;
this.vLabel = vLabel;
this.equipmentId = equipmentId;
this.labels = Objects.requireNonNull(labels);
}
public String getUnescapedId() {
return unescapedId;
}
public String getId() {
return id;
}
public String getVId() {
return vId;
}
public String getNextVId() {
return nextVId;
}
public String getComponentType() {
return componentType;
}
public boolean isOpen() {
return open;
}
public Direction getDirection() {
return direction;
}
@JsonProperty("direction")
public Direction getNullableDirection() {
return direction == Direction.UNDEFINED ? null : direction;
}
public boolean isVLabel() {
return vLabel;
}
public String getEquipmentId() {
return equipmentId;
}
public List<NodeLabelMetadata> getLabels() {
return labels;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class NodeLabelMetadata {
private final String id;
private final String positionName;
private final String userDefinedId;
@JsonCreator
public NodeLabelMetadata(@JsonProperty("id") String id,
@JsonProperty("positionName") String positionName,
@JsonProperty("userDefinedId") String userDefinedId) {
this.id = Objects.requireNonNull(id);
this.positionName = Objects.requireNonNull(positionName);
this.userDefinedId = userDefinedId;
}
public String getId() {
return id;
}
public String getUserDefinedId() {
return userDefinedId;
}
public String getPositionName() {
return positionName;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class WireMetadata {
private final String id;
private final String nodeId1;
private final String nodeId2;
private final boolean straight;
private final boolean snakeLine;
@JsonCreator
public WireMetadata(@JsonProperty("id") String id,
@JsonProperty("nodeId1") String nodeId1,
@JsonProperty("nodeId2") String nodeId2,
@JsonProperty("straight") boolean straight,
@JsonProperty("snakeline") boolean snakeline) {
this.id = Objects.requireNonNull(id);
this.nodeId1 = Objects.requireNonNull(nodeId1);
this.nodeId2 = Objects.requireNonNull(nodeId2);
this.straight = straight;
this.snakeLine = snakeline;
}
public String getId() {
return id;
}
public String getNodeId1() {
return nodeId1;
}
public String getNodeId2() {
return nodeId2;
}
public boolean isStraight() {
return straight;
}
public boolean isSnakeLine() {
return snakeLine;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class LineMetadata {
private final String id;
private final String nodeId1;
private final String nodeId2;
@JsonCreator
public LineMetadata(@JsonProperty("id") String id,
@JsonProperty("nodeId1") String nodeId1,
@JsonProperty("nodeId2") String nodeId2) {
this.id = Objects.requireNonNull(id);
this.nodeId1 = Objects.requireNonNull(nodeId1);
this.nodeId2 = Objects.requireNonNull(nodeId2);
}
public String getId() {
return id;
}
public String getNodeId1() {
return nodeId1;
}
public String getNodeId2() {
return nodeId2;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class FeederInfoMetadata {
private final String id;
private final String equipmentId;
private final String side;
private final String userDefinedId;
private final String componentType;
@JsonCreator
public FeederInfoMetadata(@JsonProperty("id") String id, @JsonProperty("equipmentId") String equipmentId, @JsonProperty("side") String side, @JsonProperty("componentType") String componentType, @JsonProperty("userDefinedId") String userDefinedId) {
this.id = Objects.requireNonNull(id);
this.equipmentId = Objects.requireNonNull(equipmentId);
this.side = side;
this.componentType = componentType;
this.userDefinedId = userDefinedId;
}
public String getId() {
return id;
}
public String getEquipmentId() {
return equipmentId;
}
public String getSide() {
return side;
}
public String getComponentType() {
return componentType;
}
public String getUserDefinedId() {
return userDefinedId;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class BusInfoMetadata {
private final String id;
private final String busNodeId;
private final String userDefinedId;
@JsonCreator
public BusInfoMetadata(@JsonProperty("id") String id, @JsonProperty("busNodeId") String busNodeId, @JsonProperty("userDefinedId") String userDefinedId) {
this.id = Objects.requireNonNull(id);
this.busNodeId = Objects.requireNonNull(busNodeId);
this.userDefinedId = userDefinedId;
}
public String getId() {
return id;
}
public String getBusNodeId() {
return busNodeId;
}
public String getUserDefinedId() {
return userDefinedId;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class BusLegendInfoMetadata {
private final String id;
@JsonCreator
public BusLegendInfoMetadata(@JsonProperty("id") String id) {
this.id = Objects.requireNonNull(id);
}
public String getId() {
return id;
}
}
private final Map<String, Component> componentByType = new HashMap<>();
private final Map<String, NodeMetadata> nodeMetadataMap = new HashMap<>();
private final Map<String, WireMetadata> wireMetadataMap = new HashMap<>();
private final Map<String, LineMetadata> lineMetadataMap = new HashMap<>();
private final LayoutParameters layoutParameters;
private final SvgParameters svgParameters;
private final Map<String, FeederInfoMetadata> feederInfoMetadataMap = new HashMap<>();
private final Map<String, BusLegendInfoMetadata> busLegendInfoMetadataMap = new HashMap<>();
private final Map<String, BusInfoMetadata> busInfoMetadataMap = new HashMap<>();
public GraphMetadata(LayoutParameters layoutParameters, SvgParameters svgParameters) {
this(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), layoutParameters, svgParameters);
}
@JsonCreator
public GraphMetadata(@JsonProperty("components") List<Component> componentList,
@JsonProperty("nodes") List<NodeMetadata> nodeMetadataList,
@JsonProperty("wires") List<WireMetadata> wireMetadataList,
@JsonProperty("lines") List<LineMetadata> lineMetadataList,
@JsonProperty("feederInfos") List<FeederInfoMetadata> feederInfoMetadataList,
@JsonProperty("busLegendInfos") List<BusLegendInfoMetadata> busLegendInfoMetadataList,
@JsonProperty("busInfos") List<BusInfoMetadata> busInfoMetadataList,
@JsonProperty("layoutParams") LayoutParameters layoutParams,
@JsonProperty("svgParams") SvgParameters svgParams) {
for (Component component : componentList) {
addComponent(component);
}
for (NodeMetadata nodeMetadata : nodeMetadataList) {
addNodeMetadata(nodeMetadata);
}
for (WireMetadata wireMetadata : wireMetadataList) {
addWireMetadata(wireMetadata);
}
for (LineMetadata lineMetadata : lineMetadataList) {
addLineMetadata(lineMetadata);
}
for (FeederInfoMetadata feederInfoMetadata : feederInfoMetadataList) {
addFeederInfoMetadata(feederInfoMetadata);
}
for (BusLegendInfoMetadata busLegendInfoMetadata : busLegendInfoMetadataList) {
addBusLegendInfoMetadata(busLegendInfoMetadata);
}
for (BusInfoMetadata busInfoMetadata : busInfoMetadataList) {
addBusInfoMetadata(busInfoMetadata);
}
layoutParameters = layoutParams;
svgParameters = svgParams;
}
public static GraphMetadata parseJson(Path file) {
try (Reader reader = Files.newBufferedReader(file)) {
return parseJson(reader);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public static GraphMetadata parseJson(InputStream inputStream) {
Objects.requireNonNull(inputStream);
ObjectMapper objectMapper = JsonUtil.createObjectMapper();
try {
return objectMapper.readValue(inputStream, GraphMetadata.class);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public static GraphMetadata parseJson(Reader reader) {
Objects.requireNonNull(reader);
ObjectMapper objectMapper = JsonUtil.createObjectMapper();
try {
return objectMapper.readValue(reader, GraphMetadata.class);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public void addComponent(Component component) {
Objects.requireNonNull(component);
componentByType.put(component.getType(), component);
}
public Component getComponentMetadata(String componentType) {
return componentType != null ? componentByType.get(componentType) : null;
}
public List<AnchorPoint> getAnchorPoints(String type) {
Component component = getComponentMetadata(type);
return component != null ? component.getAnchorPoints()
: Collections.singletonList(new AnchorPoint(0, 0, AnchorOrientation.NONE));
}
@JsonProperty("components")
public List<Component> getComponentMetadata() {
return ImmutableList.copyOf(componentByType.values());
}
public void addNodeMetadata(NodeMetadata metadata) {
Objects.requireNonNull(metadata);
nodeMetadataMap.put(metadata.getId(), metadata);
}
public NodeMetadata getNodeMetadata(String id) {
Objects.requireNonNull(id);
return nodeMetadataMap.get(id);
}
@JsonProperty("nodes")
public List<NodeMetadata> getNodeMetadata() {
return ImmutableList.copyOf(nodeMetadataMap.values());
}
public void addWireMetadata(WireMetadata metadata) {
Objects.requireNonNull(metadata);
wireMetadataMap.put(metadata.getId(), metadata);
}
public WireMetadata getWireMetadata(String id) {
Objects.requireNonNull(id);
return wireMetadataMap.get(id);
}
@JsonProperty("wires")
public List<WireMetadata> getWireMetadata() {
return ImmutableList.copyOf(wireMetadataMap.values());
}
public void addLineMetadata(LineMetadata metadata) {
Objects.requireNonNull(metadata);
lineMetadataMap.put(metadata.getId(), metadata);
}
public LineMetadata getLineMetadata(String id) {
Objects.requireNonNull(id);
return lineMetadataMap.get(id);
}
@JsonProperty("lines")
public List<LineMetadata> getLineMetadata() {
return ImmutableList.copyOf(lineMetadataMap.values());
}
public void addFeederInfoMetadata(FeederInfoMetadata metadata) {
Objects.requireNonNull(metadata);
feederInfoMetadataMap.put(metadata.getId(), metadata);
}
public FeederInfoMetadata getFeederInfoMetadata(String id) {
Objects.requireNonNull(id);
return feederInfoMetadataMap.get(id);
}
@JsonProperty("feederInfos")
public List<FeederInfoMetadata> getFeederInfoMetadata() {
return ImmutableList.copyOf(feederInfoMetadataMap.values());
}
public void addBusInfoMetadata(BusInfoMetadata metadata) {
Objects.requireNonNull(metadata);
busInfoMetadataMap.put(metadata.getId(), metadata);
}
public BusInfoMetadata getBusInfoMetadata(String id) {
Objects.requireNonNull(id);
return busInfoMetadataMap.get(id);
}
@JsonProperty("busInfos")
public List<BusInfoMetadata> getBusInfoMetadata() {
return ImmutableList.copyOf(busInfoMetadataMap.values());
}
public void addBusLegendInfoMetadata(BusLegendInfoMetadata metadata) {
Objects.requireNonNull(metadata);
busLegendInfoMetadataMap.put(metadata.getId(), metadata);
}
public BusLegendInfoMetadata getBusLegendInfoMetadata(String id) {
Objects.requireNonNull(id);
return busLegendInfoMetadataMap.get(id);
}
@JsonProperty("busLegendInfos")
public List<BusLegendInfoMetadata> getBusLegendInfoMetadata() {
return ImmutableList.copyOf(busLegendInfoMetadataMap.values());
}
@JsonProperty("layoutParams")
public LayoutParameters getLayoutParameters() {
return layoutParameters;
}
@JsonProperty("svgParams")
public SvgParameters getSvgParameters() {
return svgParameters;
}
}