diff --git a/src/main/java/org/gridsuite/filter/AbstractFilter.java b/src/main/java/org/gridsuite/filter/AbstractFilter.java index 41942dd..ef9c050 100644 --- a/src/main/java/org/gridsuite/filter/AbstractFilter.java +++ b/src/main/java/org/gridsuite/filter/AbstractFilter.java @@ -6,9 +6,16 @@ */ package org.gridsuite.filter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonProperty.Access; import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import lombok.*; +import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.gridsuite.filter.expertfilter.ExpertFilter; import org.gridsuite.filter.identifierlistfilter.FilterEquipments; @@ -16,6 +23,7 @@ import org.gridsuite.filter.identifierlistfilter.IdentifiableAttributes; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; import org.gridsuite.filter.utils.EquipmentType; +import org.gridsuite.filter.utils.FilterType; import java.util.Date; import java.util.List; @@ -25,15 +33,10 @@ * @author Jacques Borsenberger * @author Franck Lecuyer */ -@JsonTypeInfo( - use = JsonTypeInfo.Id.NAME, - property = "type", - include = JsonTypeInfo.As.EXISTING_PROPERTY, - visible = true -) +@JsonTypeInfo(use = Id.NAME, property = "type", include = As.EXISTING_PROPERTY, visible = true) @JsonSubTypes({//Below, we define the names and the binding classes. - @JsonSubTypes.Type(value = IdentifierListFilter.class, name = "IDENTIFIER_LIST"), - @JsonSubTypes.Type(value = ExpertFilter.class, name = "EXPERT") + @Type(value = IdentifierListFilter.class, name = "IDENTIFIER_LIST"), + @Type(value = ExpertFilter.class, name = "EXPERT") }) @Data @NoArgsConstructor @@ -47,6 +50,10 @@ public abstract class AbstractFilter implements IFilterAttributes { private EquipmentType equipmentType; + @JsonProperty(access = Access.READ_ONLY) + @Override + public abstract FilterType getType(); + public FilterEquipments toFilterEquipments(List identifiableAttributes) { return FilterEquipments.builder() .filterId(id) diff --git a/src/main/java/org/gridsuite/filter/expertfilter/ExpertFilter.java b/src/main/java/org/gridsuite/filter/expertfilter/ExpertFilter.java index 2a9b8f3..4850645 100644 --- a/src/main/java/org/gridsuite/filter/expertfilter/ExpertFilter.java +++ b/src/main/java/org/gridsuite/filter/expertfilter/ExpertFilter.java @@ -6,7 +6,6 @@ */ package org.gridsuite.filter.expertfilter; -import com.fasterxml.jackson.annotation.JsonProperty; import com.powsybl.iidm.network.TopologyKind; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -41,7 +40,6 @@ public ExpertFilter(UUID id, Date modificationDate, EquipmentType equipmentType, this.rules = rules; } - @JsonProperty(access = JsonProperty.Access.READ_ONLY) @Override public FilterType getType() { return FilterType.EXPERT; diff --git a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/AbstractExpertRule.java b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/AbstractExpertRule.java index 72ccd07..fb9f5d9 100644 --- a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/AbstractExpertRule.java +++ b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/AbstractExpertRule.java @@ -6,10 +6,12 @@ */ package org.gridsuite.filter.expertfilter.expertrule; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty.Access; +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; +import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.powsybl.iidm.network.Identifiable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -30,20 +32,17 @@ /** * @author Antoine Bouhours */ -@JsonTypeInfo( - use = JsonTypeInfo.Id.NAME, - property = "dataType", - include = JsonTypeInfo.As.EXISTING_PROPERTY) +@JsonTypeInfo(use = Id.NAME, property = "dataType", include = As.EXISTING_PROPERTY, visible = true) @JsonSubTypes({ - @JsonSubTypes.Type(value = StringExpertRule.class, name = "STRING"), - @JsonSubTypes.Type(value = BooleanExpertRule.class, name = "BOOLEAN"), - @JsonSubTypes.Type(value = EnumExpertRule.class, name = "ENUM"), - @JsonSubTypes.Type(value = NumberExpertRule.class, name = "NUMBER"), - @JsonSubTypes.Type(value = CombinatorExpertRule.class, name = "COMBINATOR"), - @JsonSubTypes.Type(value = FilterUuidExpertRule.class, name = "FILTER_UUID"), - @JsonSubTypes.Type(value = PropertiesExpertRule.class, name = "PROPERTIES"), + @Type(value = StringExpertRule.class, name = "STRING"), + @Type(value = BooleanExpertRule.class, name = "BOOLEAN"), + @Type(value = EnumExpertRule.class, name = "ENUM"), + @Type(value = NumberExpertRule.class, name = "NUMBER"), + @Type(value = CombinatorExpertRule.class, name = "COMBINATOR"), + @Type(value = FilterUuidExpertRule.class, name = "FILTER_UUID"), + @Type(value = PropertiesExpertRule.class, name = "PROPERTIES"), }) -@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonInclude(Include.NON_NULL) @NoArgsConstructor @AllArgsConstructor @Getter @@ -61,6 +60,7 @@ public abstract class AbstractExpertRule { public abstract boolean evaluateRule(Identifiable identifiable, FilterLoader filterLoader, Map cachedUuidFilters); + @JsonProperty(access = Access.READ_ONLY) public abstract DataType getDataType(); @JsonIgnore diff --git a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/BooleanExpertRule.java b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/BooleanExpertRule.java index 2687960..b6e6262 100644 --- a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/BooleanExpertRule.java +++ b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/BooleanExpertRule.java @@ -6,7 +6,6 @@ */ package org.gridsuite.filter.expertfilter.expertrule; -import com.fasterxml.jackson.annotation.JsonProperty; import com.powsybl.commons.PowsyblException; import com.powsybl.iidm.network.Identifiable; import lombok.AllArgsConstructor; @@ -42,7 +41,6 @@ public String getStringValue() { } @Override - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public DataType getDataType() { return DataType.BOOLEAN; } diff --git a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/CombinatorExpertRule.java b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/CombinatorExpertRule.java index c869828..9d1d09c 100644 --- a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/CombinatorExpertRule.java +++ b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/CombinatorExpertRule.java @@ -6,7 +6,6 @@ */ package org.gridsuite.filter.expertfilter.expertrule; -import com.fasterxml.jackson.annotation.JsonProperty; import com.powsybl.commons.PowsyblException; import com.powsybl.iidm.network.Identifiable; import lombok.NoArgsConstructor; @@ -26,7 +25,6 @@ @SuperBuilder public class CombinatorExpertRule extends AbstractExpertRule { @Override - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public DataType getDataType() { return DataType.COMBINATOR; } diff --git a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/EnumExpertRule.java b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/EnumExpertRule.java index 332425e..de77c91 100644 --- a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/EnumExpertRule.java +++ b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/EnumExpertRule.java @@ -6,7 +6,6 @@ */ package org.gridsuite.filter.expertfilter.expertrule; -import com.fasterxml.jackson.annotation.JsonProperty; import com.powsybl.commons.PowsyblException; import com.powsybl.iidm.network.Identifiable; import lombok.NoArgsConstructor; @@ -27,7 +26,6 @@ @SuperBuilder public class EnumExpertRule extends StringExpertRule { @Override - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public DataType getDataType() { return DataType.ENUM; } diff --git a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/FilterUuidExpertRule.java b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/FilterUuidExpertRule.java index d551edd..83a8d6a 100644 --- a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/FilterUuidExpertRule.java +++ b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/FilterUuidExpertRule.java @@ -6,7 +6,6 @@ */ package org.gridsuite.filter.expertfilter.expertrule; -import com.fasterxml.jackson.annotation.JsonProperty; import com.powsybl.commons.PowsyblException; import com.powsybl.iidm.network.Identifiable; import lombok.NoArgsConstructor; @@ -28,7 +27,6 @@ @SuperBuilder public class FilterUuidExpertRule extends StringExpertRule { @Override - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public DataType getDataType() { return DataType.FILTER_UUID; } diff --git a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/NumberExpertRule.java b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/NumberExpertRule.java index 72b8760..c3910d9 100644 --- a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/NumberExpertRule.java +++ b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/NumberExpertRule.java @@ -6,7 +6,6 @@ */ package org.gridsuite.filter.expertfilter.expertrule; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.powsybl.commons.PowsyblException; import com.powsybl.iidm.network.Identifiable; @@ -45,7 +44,6 @@ public static Double getNumberValue(String value) { } @Override - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public DataType getDataType() { return DataType.NUMBER; } diff --git a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/StringExpertRule.java b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/StringExpertRule.java index 82feea3..5baaf5d 100644 --- a/src/main/java/org/gridsuite/filter/expertfilter/expertrule/StringExpertRule.java +++ b/src/main/java/org/gridsuite/filter/expertfilter/expertrule/StringExpertRule.java @@ -6,7 +6,6 @@ */ package org.gridsuite.filter.expertfilter.expertrule; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.powsybl.commons.PowsyblException; import com.powsybl.iidm.network.Identifiable; @@ -53,7 +52,6 @@ public String getStringValue() { } @Override - @JsonProperty(access = JsonProperty.Access.READ_ONLY) public DataType getDataType() { return DataType.STRING; } diff --git a/src/main/java/org/gridsuite/filter/utils/FilterServiceUtils.java b/src/main/java/org/gridsuite/filter/utils/FilterServiceUtils.java index c37726f..a77a921 100644 --- a/src/main/java/org/gridsuite/filter/utils/FilterServiceUtils.java +++ b/src/main/java/org/gridsuite/filter/utils/FilterServiceUtils.java @@ -6,15 +6,17 @@ */ package org.gridsuite.filter.utils; +import com.powsybl.iidm.network.Identifiable; import com.powsybl.iidm.network.Network; -import org.gridsuite.filter.FilterLoader; import org.gridsuite.filter.AbstractFilter; +import org.gridsuite.filter.FilterLoader; import org.gridsuite.filter.identifierlistfilter.FilterEquipments; import org.gridsuite.filter.identifierlistfilter.IdentifiableAttributes; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; import java.util.List; import java.util.UUID; +import java.util.function.Function; /** * @author Franck Lecuyer @@ -25,25 +27,15 @@ private FilterServiceUtils() { } public static List getIdentifiableAttributes(AbstractFilter filter, Network network, FilterLoader filterLoader) { - if (filter instanceof IdentifierListFilter identifierListFilter && - (filter.getEquipmentType() == EquipmentType.GENERATOR || - filter.getEquipmentType() == EquipmentType.LOAD)) { - return FiltersUtils.getIdentifiables(filter, network, filterLoader) - .stream() - .map(identifiable -> new IdentifiableAttributes(identifiable.getId(), - identifiable.getType(), - identifierListFilter.getDistributionKey(identifiable.getId()))) - .toList(); - } else { - return FiltersUtils.getIdentifiables(filter, network, filterLoader).stream() - .map(identifiable -> new IdentifiableAttributes(identifiable.getId(), identifiable.getType(), null)) - .toList(); - } + final Function, IdentifiableAttributes> mapper = (filter instanceof IdentifierListFilter identifierListFilter && + (filter.getEquipmentType() == EquipmentType.GENERATOR || filter.getEquipmentType() == EquipmentType.LOAD)) + ? (identifiable -> new IdentifiableAttributes(identifiable.getId(), identifiable.getType(), identifierListFilter.getDistributionKey(identifiable.getId()))) + : (identifiable -> new IdentifiableAttributes(identifiable.getId(), identifiable.getType(), null)); + return FiltersUtils.getIdentifiables(filter, network, filterLoader).stream().map(mapper).toList(); } public static List getFilterEquipmentsFromUuid(Network network, UUID uuid, FilterLoader filterLoader) { - List filters = filterLoader.getFilters(List.of(uuid)); - return filters.stream() + return filterLoader.getFilters(List.of(uuid)).stream() .map(filter -> filter.toFilterEquipments(FilterServiceUtils.getIdentifiableAttributes(filter, network, filterLoader))) .toList(); } diff --git a/src/main/java/org/gridsuite/filter/utils/FiltersUtils.java b/src/main/java/org/gridsuite/filter/utils/FiltersUtils.java index 77255fe..55dfc64 100644 --- a/src/main/java/org/gridsuite/filter/utils/FiltersUtils.java +++ b/src/main/java/org/gridsuite/filter/utils/FiltersUtils.java @@ -6,16 +6,21 @@ */ package org.gridsuite.filter.utils; -import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.Identifiable; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.TopologyKind; +import com.powsybl.iidm.network.VoltageLevel; import org.gridsuite.filter.AbstractFilter; import org.gridsuite.filter.FilterLoader; import org.gridsuite.filter.expertfilter.ExpertFilter; +import org.gridsuite.filter.expertfilter.expertrule.AbstractExpertRule; import org.gridsuite.filter.identifierlistfilter.FilterEquipments; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; import java.util.*; -import java.util.function.Predicate; +import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -26,215 +31,70 @@ private FiltersUtils() { throw new AssertionError("Utility class should not be instantiated"); } - private static List getIdentifierListFilterEquipmentIds(IdentifierListFilter identifierListFilter) { - return identifierListFilter.getFilterEquipmentsAttributes() - .stream() - .map(IdentifierListFilterEquipmentAttributes::getEquipmentID) - .toList(); - } - - private static > Stream> getInjectionList(Stream> stream, AbstractFilter filter, FilterLoader filterLoader) { - if (filter instanceof IdentifierListFilter identifierListFilter) { - List equipmentIds = getIdentifierListFilterEquipmentIds(identifierListFilter); - return stream.filter(injection -> equipmentIds.contains(injection.getId())); - } else if (filter instanceof ExpertFilter expertFilter) { - var rule = expertFilter.getRules(); - Map cachedUuidFilters = new HashMap<>(); - return stream.filter(ident -> rule.evaluateRule(ident, filterLoader, cachedUuidFilters)); - } else { - return Stream.empty(); - } - } - - private static List> getGeneratorList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - if (filter instanceof IdentifierListFilter || filter instanceof ExpertFilter) { - Stream> stream = getInjectionList(network.getGeneratorStream().map(generator -> generator), filter, filterLoader); - return new ArrayList<>(stream.toList()); - } else { - return List.of(); - } - } - - private static List> getLoadList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - Stream> stream = getInjectionList(network.getLoadStream().map(load -> load), filter, filterLoader); - return new ArrayList<>(stream.toList()); - } - - private static List> getBatteryList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - Stream> stream = getInjectionList(network.getBatteryStream().map(battery -> battery), filter, filterLoader); - return new ArrayList<>(stream.toList()); - } - - private static List> getStaticVarCompensatorList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - Stream> stream = getInjectionList(network.getStaticVarCompensatorStream().map(svc -> svc), filter, filterLoader); - return new ArrayList<>(stream.toList()); - } - - private static List> getShuntCompensatorList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - Stream> stream = getInjectionList(network.getShuntCompensatorStream().map(sc -> sc), filter, filterLoader); - return new ArrayList<>(stream.toList()); - } - - private static List> getDanglingLineList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - Stream> stream = getInjectionList(network.getDanglingLineStream().map(dl -> dl), filter, filterLoader); - return new ArrayList<>(stream.toList()); - } - - private static List> getLccConverterStationList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - Stream> stream = getInjectionList(network.getLccConverterStationStream().map(lcc -> lcc), filter, filterLoader); - return new ArrayList<>(stream.toList()); - } - - private static List> getVscConverterStationList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - Stream> stream = getInjectionList(network.getVscConverterStationStream().map(vsc -> vsc), filter, filterLoader); - return new ArrayList<>(stream.toList()); - } - - private static List> getBusList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - if (filter instanceof ExpertFilter expertFilter) { - // topologyKind is an optional info attached into expert filter when filtering bus for optimizing the perf - // note that with voltage levels of kind TopologyKind.NODE_BREAKER, buses are computed on-the-fly => expensive - var topologyKind = expertFilter.getTopologyKind(); - Predicate voltageLevelFilter = vl -> topologyKind == null || vl.getTopologyKind() == topologyKind; - - Stream> stream = network.getVoltageLevelStream() - .filter(voltageLevelFilter) - .map(VoltageLevel::getBusBreakerView) - .flatMap(VoltageLevel.BusBreakerView::getBusStream); - - var rule = expertFilter.getRules(); - Map cachedUuidFilters = new HashMap<>(); - return stream.filter(ident -> rule.evaluateRule(ident, filterLoader, cachedUuidFilters)).toList(); - } else { - return List.of(); - } - } - - private static List> getBusbarSectionList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - Stream> stream = getInjectionList(network.getBusbarSectionStream().map(bbs -> bbs), filter, filterLoader); - return new ArrayList<>(stream.toList()); - } - - private static List> getLineList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - if (filter instanceof IdentifierListFilter identifierListFilter) { - List equipmentIds = getIdentifierListFilterEquipmentIds(identifierListFilter); - Stream stream = network.getLineStream() - .filter(line -> equipmentIds.contains(line.getId())); - return new ArrayList<>(stream.toList()); - } else if (filter instanceof ExpertFilter expertFilter) { - var rule = expertFilter.getRules(); - Map cachedUuidFilters = new HashMap<>(); - Stream stream = network.getLineStream() - .filter(ident -> rule.evaluateRule(ident, filterLoader, cachedUuidFilters)); - return new ArrayList<>(stream.toList()); - } else { - return List.of(); - } - } - - private static List> get2WTransformerList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - if (filter instanceof IdentifierListFilter identifierListFilter) { - List equipmentIds = getIdentifierListFilterEquipmentIds(identifierListFilter); - Stream stream = network.getTwoWindingsTransformerStream() - .filter(twoWindingsTransformer -> equipmentIds.contains(twoWindingsTransformer.getId())); - return new ArrayList<>(stream.toList()); - } else if (filter instanceof ExpertFilter expertFilter) { - var rule = expertFilter.getRules(); - Map cachedUuidFilters = new HashMap<>(); - Stream stream = network.getTwoWindingsTransformerStream() - .filter(ident -> rule.evaluateRule(ident, filterLoader, cachedUuidFilters)); - return new ArrayList<>(stream.toList()); - } else { - return List.of(); - } - } - - private static List> get3WTransformerList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - if (filter instanceof IdentifierListFilter identifierListFilter) { - List equipmentIds = getIdentifierListFilterEquipmentIds(identifierListFilter); - Stream stream = network.getThreeWindingsTransformerStream() - .filter(threeWindingsTransformer -> equipmentIds.contains(threeWindingsTransformer.getId())); - return new ArrayList<>(stream.toList()); - } else if (filter instanceof ExpertFilter expertFilter) { - var rule = expertFilter.getRules(); - Map cachedUuidFilters = new HashMap<>(); - Stream stream = network.getThreeWindingsTransformerStream() - .filter(ident -> rule.evaluateRule(ident, filterLoader, cachedUuidFilters)); - return new ArrayList<>(stream.toList()); - } else { - return List.of(); - } - } - - private static List> getHvdcList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - if (filter instanceof IdentifierListFilter identifierListFilter) { - List equipmentsIds = getIdentifierListFilterEquipmentIds(identifierListFilter); - Stream stream = network.getHvdcLineStream() - .filter(hvdcLine -> equipmentsIds.contains(hvdcLine.getId())); - return new ArrayList<>(stream.toList()); - } else if (filter instanceof ExpertFilter expertFilter) { - var rule = expertFilter.getRules(); - Map cachedUuidFilters = new HashMap<>(); - Stream stream = network.getHvdcLineStream() - .filter(ident -> rule.evaluateRule(ident, filterLoader, cachedUuidFilters)); - return new ArrayList<>(stream.toList()); - } else { - return List.of(); - } - } - - private static List> getVoltageLevelList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - if (filter instanceof IdentifierListFilter identifierListFilter) { - List equipmentIds = getIdentifierListFilterEquipmentIds(identifierListFilter); - Stream stream = network.getVoltageLevelStream() - .filter(voltageLevel -> equipmentIds.contains(voltageLevel.getId())); - return new ArrayList<>(stream.toList()); - } else if (filter instanceof ExpertFilter expertFilter) { - var rule = expertFilter.getRules(); - Map cachedUuidFilters = new HashMap<>(); - Stream stream = network.getVoltageLevelStream() - .filter(ident -> rule.evaluateRule(ident, filterLoader, cachedUuidFilters)); - return new ArrayList<>(stream.toList()); - } else { - return List.of(); - } - } - - private static List> getSubstationList(Network network, AbstractFilter filter, FilterLoader filterLoader) { - if (filter instanceof IdentifierListFilter identifierListFilter) { - List equipmentIds = getIdentifierListFilterEquipmentIds(identifierListFilter); - Stream stream = network.getSubstationStream() - .filter(substation -> equipmentIds.contains(substation.getId())); - return new ArrayList<>(stream.toList()); - } else if (filter instanceof ExpertFilter expertFilter) { - var rule = expertFilter.getRules(); - Map cachedUuidFilters = new HashMap<>(); - Stream stream = network.getSubstationStream() - .filter(ident -> rule.evaluateRule(ident, filterLoader, cachedUuidFilters)); - return new ArrayList<>(stream.toList()); - } else { - return List.of(); - } + private static List> filterById(@Nonnull final Network network, @Nonnull final IdentifierListFilter filter, + @Nonnull final Function>> extractor) { + final List equipmentIds = filter.getFilterEquipmentsAttributes() + .stream() + .map(IdentifierListFilterEquipmentAttributes::getEquipmentID) + .toList(); + return extractor.apply(network) + .filter(ident -> equipmentIds.contains(ident.getId())) + .collect(Collectors.toCollection(ArrayList::new)); + } + + private static List> filterByRules(@Nonnull final Network network, + @Nonnull final ExpertFilter filter, final FilterLoader filterLoader, + @Nonnull final Function>> extractor) { + final AbstractExpertRule rule = filter.getRules(); + final Map cachedUuidFilters = new HashMap<>(); + return extractor.apply(network) + .filter(ident -> rule.evaluateRule(ident, filterLoader, cachedUuidFilters)) + .collect(Collectors.toCollection(ArrayList::new)); + } + + private static List> getIdentifiableList(@Nonnull final Network network, + @Nonnull final AbstractFilter filter, final FilterLoader filterLoader, + @Nonnull final Function>> extractor) { + return switch (filter) { + case final IdentifierListFilter identifierListFilter -> filterById(network, identifierListFilter, extractor); + case final ExpertFilter expertFilter -> filterByRules(network, expertFilter, filterLoader, extractor); + default -> List.of(); + }; } - public static List> getIdentifiables(AbstractFilter filter, Network network, FilterLoader filterLoader) { - return switch (filter.getEquipmentType()) { - case GENERATOR -> getGeneratorList(network, filter, filterLoader); - case LOAD -> getLoadList(network, filter, filterLoader); - case BATTERY -> getBatteryList(network, filter, filterLoader); - case STATIC_VAR_COMPENSATOR -> getStaticVarCompensatorList(network, filter, filterLoader); - case SHUNT_COMPENSATOR -> getShuntCompensatorList(network, filter, filterLoader); - case LCC_CONVERTER_STATION -> getLccConverterStationList(network, filter, filterLoader); - case VSC_CONVERTER_STATION -> getVscConverterStationList(network, filter, filterLoader); - case HVDC_LINE -> getHvdcList(network, filter, filterLoader); - case DANGLING_LINE -> getDanglingLineList(network, filter, filterLoader); - case LINE -> getLineList(network, filter, filterLoader); - case TWO_WINDINGS_TRANSFORMER -> get2WTransformerList(network, filter, filterLoader); - case THREE_WINDINGS_TRANSFORMER -> get3WTransformerList(network, filter, filterLoader); - case BUS -> getBusList(network, filter, filterLoader); - case BUSBAR_SECTION -> getBusbarSectionList(network, filter, filterLoader); - case VOLTAGE_LEVEL -> getVoltageLevelList(network, filter, filterLoader); - case SUBSTATION -> getSubstationList(network, filter, filterLoader); + public static List> getIdentifiables(@Nonnull final AbstractFilter filter, @Nonnull final Network network, + final FilterLoader filterLoader) { + final Function>> getter = switch (filter.getEquipmentType()) { + case null -> throw new NullPointerException("Equipment type cannot be null"); + case BATTERY -> Network::getBatteryStream; + case BUS -> network1 -> { + if (filter instanceof final ExpertFilter expertFilter) { + // topologyKind is an optional info attached into an expert filter when filtering bus for optimizing the perf + // note that with voltage levels of kind TopologyKind.NODE_BREAKER, buses are computed on-the-fly => expensive + final TopologyKind topologyKind = expertFilter.getTopologyKind(); + return network.getVoltageLevelStream() + .filter(vl -> topologyKind == null || vl.getTopologyKind() == topologyKind) + .map(VoltageLevel::getBusBreakerView) + .flatMap(VoltageLevel.BusBreakerView::getBusStream); + } + // Note: the webapps don't permit filtering a BUS by ID, so this case will not happen in reality + return Stream.empty(); + }; + case BUSBAR_SECTION -> Network::getBusbarSectionStream; + case DANGLING_LINE -> Network::getDanglingLineStream; + case GENERATOR -> Network::getGeneratorStream; + case HVDC_LINE -> Network::getHvdcLineStream; + case LCC_CONVERTER_STATION -> Network::getLccConverterStationStream; + case LINE -> Network::getLineStream; + case LOAD -> Network::getLoadStream; + case SHUNT_COMPENSATOR -> Network::getShuntCompensatorStream; + case STATIC_VAR_COMPENSATOR -> Network::getStaticVarCompensatorStream; + case SUBSTATION -> Network::getSubstationStream; + case THREE_WINDINGS_TRANSFORMER -> Network::getThreeWindingsTransformerStream; + case TWO_WINDINGS_TRANSFORMER -> Network::getTwoWindingsTransformerStream; + case VOLTAGE_LEVEL -> Network::getVoltageLevelStream; + case VSC_CONVERTER_STATION -> Network::getVscConverterStationStream; }; + return getIdentifiableList(network, filter, filterLoader, getter); } }