Skip to content

Commit

Permalink
Merge branch 'main' into organize-by-filter
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinebhs authored Nov 2, 2023
2 parents 3fb9daa + a80cb59 commit ba8e65e
Show file tree
Hide file tree
Showing 17 changed files with 824 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/**
* Copyright (c) 2023, 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 org.gridsuite.filter.server;

import com.powsybl.commons.PowsyblException;
import org.gridsuite.filter.server.dto.*;
import org.gridsuite.filter.server.dto.expertrule.*;
import org.gridsuite.filter.server.entities.*;
import org.gridsuite.filter.server.repositories.ExpertFilterRepository;
import org.gridsuite.filter.server.utils.EquipmentType;
import org.gridsuite.filter.server.utils.FilterType;

import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
*/
public class ExpertFilterRepositoryProxy extends AbstractFilterRepositoryProxy<ExpertFilterEntity, ExpertFilterRepository> {
private final ExpertFilterRepository expertFilterRepository;

public ExpertFilterRepositoryProxy(ExpertFilterRepository expertFilterRepository) {
this.expertFilterRepository = expertFilterRepository;
}

@Override
ExpertFilterRepository getRepository() {
return expertFilterRepository;
}

@Override
AbstractFilter toDto(ExpertFilterEntity filterEntity) {
return ExpertFilter.builder()
.id(filterEntity.getId())
.modificationDate(filterEntity.getModificationDate())
.equipmentType(filterEntity.getEquipmentType())
.rules(entityToDto(filterEntity.getRules()))
.build();
}

public static AbstractExpertRule entityToDto(ExpertRuleEntity filterEntity) {
switch (filterEntity.getDataType()) {
case COMBINATOR -> {
return CombinatorExpertRule.builder()
.combinator(filterEntity.getCombinator())
.rules(entitiesToDto(filterEntity.getRules()))
.build();
}
case BOOLEAN -> {
return BooleanExpertRule.builder()
.field(filterEntity.getField())
.operator(filterEntity.getOperator())
.value(Boolean.parseBoolean(filterEntity.getValue()))
.build();
}
case NUMBER -> {
return NumberExpertRule.builder()
.field(filterEntity.getField())
.operator(filterEntity.getOperator())
.value(Double.valueOf(filterEntity.getValue()))
.build();
}
case STRING -> {
return StringExpertRule.builder()
.field(filterEntity.getField())
.operator(filterEntity.getOperator())
.value(filterEntity.getValue())
.build();
}
case ENUM -> {
return EnumExpertRule.builder()
.field(filterEntity.getField())
.operator(filterEntity.getOperator())
.value(filterEntity.getValue())
.build();
}
default -> throw new PowsyblException("Unknown rule data type: " + filterEntity.getDataType() + ", supported data types are: COMBINATOR, BOOLEAN, NUMBER, STRING, ENUM");
}
}

private static List<AbstractExpertRule> entitiesToDto(List<ExpertRuleEntity> entities) {
if (entities == null) {
return Collections.emptyList();
}

return entities.stream()
.map(ExpertFilterRepositoryProxy::entityToDto)
.collect(Collectors.toList());
}

@Override
ExpertFilterEntity fromDto(AbstractFilter dto) {
if (dto instanceof ExpertFilter filter) {
var expertFilterEntityBuilder = ExpertFilterEntity.builder()
.modificationDate(filter.getModificationDate())
.equipmentType(filter.getEquipmentType())
.rules(dtoToEntity(filter.getRules()));
buildAbstractFilter(expertFilterEntityBuilder, filter);
return expertFilterEntityBuilder.build();
}
throw new PowsyblException(WRONG_FILTER_TYPE);
}

public static ExpertRuleEntity dtoToEntity(AbstractExpertRule filter) {
var expertFilterEntityBuilder = ExpertRuleEntity.builder()
.id(UUID.randomUUID())
.combinator(filter.getCombinator())
.operator(filter.getOperator())
.dataType(filter.getDataType())
.field(filter.getField())
.value(filter.getStringValue());
expertFilterEntityBuilder.rules(dtoToEntities(filter.getRules(), expertFilterEntityBuilder.build()));
return expertFilterEntityBuilder.build();
}

private static List<ExpertRuleEntity> dtoToEntities(List<AbstractExpertRule> ruleFromDto, ExpertRuleEntity parentRuleEntity) {
if (ruleFromDto == null) {
return Collections.emptyList();
}

return ruleFromDto.stream()
.map(rule -> {
var expertRuleEntityBuilder = ExpertRuleEntity.builder()
.id(UUID.randomUUID())
.combinator(rule.getCombinator())
.operator(rule.getOperator())
.dataType(rule.getDataType())
.field(rule.getField())
.value(rule.getStringValue())
.parentRule(parentRuleEntity);

List<ExpertRuleEntity> rules = dtoToEntities(rule.getRules(), expertRuleEntityBuilder.build());
expertRuleEntityBuilder.rules(rules);

return expertRuleEntityBuilder.build();
})
.collect(Collectors.toList());
}

@Override
FilterType getFilterType() {
return FilterType.EXPERT;
}

@Override
public EquipmentType getEquipmentType() {
throw new UnsupportedOperationException("A filter id must be provided to get equipment type !!");
}

@Override
public EquipmentType getEquipmentType(UUID id) {
return expertFilterRepository.findById(id)
.map(ExpertFilterEntity::getEquipmentType)
.orElseThrow(() -> new PowsyblException("Identifier list filter " + id + " not found"));
}

@Override
public AbstractEquipmentFilterForm buildEquipmentFormFilter(AbstractFilterEntity entity) {
return null;
}
}
43 changes: 43 additions & 0 deletions src/main/java/org/gridsuite/filter/server/dto/ExpertFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2023, 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 org.gridsuite.filter.server.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.gridsuite.filter.server.dto.expertrule.AbstractExpertRule;
import org.gridsuite.filter.server.utils.EquipmentType;
import org.gridsuite.filter.server.utils.FilterType;

import java.util.Date;
import java.util.UUID;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
*/
@Getter
@Schema(description = "Expert Filters", allOf = AbstractFilter.class)
@SuperBuilder
@NoArgsConstructor
public class ExpertFilter extends AbstractFilter {

@Schema(description = "Rules")
private AbstractExpertRule rules;

public ExpertFilter(UUID id, Date modificationDate, EquipmentType equipmentType, AbstractExpertRule rules) {
super(id, modificationDate, equipmentType);
this.rules = rules;
}

@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@Override
public FilterType getType() {
return FilterType.EXPERT;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Copyright (c) 2023, 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 org.gridsuite.filter.server.dto.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.powsybl.iidm.network.Identifiable;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.gridsuite.filter.server.utils.CombinatorType;
import org.gridsuite.filter.server.utils.DataType;
import org.gridsuite.filter.server.utils.FieldType;
import org.gridsuite.filter.server.utils.OperatorType;

import java.util.List;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
*/
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
property = "dataType",
include = JsonTypeInfo.As.EXISTING_PROPERTY)
@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")
})
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
@AllArgsConstructor
@Getter
@SuperBuilder
public abstract class AbstractExpertRule {

@Schema(description = "Combinator")
private CombinatorType combinator;

@Schema(description = "Field")
private FieldType field;

@Schema(description = "Operator")
private OperatorType operator;

@Schema(description = "Rules")
private List<AbstractExpertRule> rules;

public abstract boolean evaluateRule(Identifiable<?> identifiable);

public abstract DataType getDataType();

@JsonIgnore
public abstract String getStringValue();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright (c) 2023, 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 org.gridsuite.filter.server.dto.expertrule;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.Identifiable;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.gridsuite.filter.server.utils.DataType;

import static org.gridsuite.filter.server.utils.ExpertFilterUtils.getFieldValue;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
*/
@AllArgsConstructor
@NoArgsConstructor
@Getter
@SuperBuilder
public class BooleanExpertRule extends AbstractExpertRule {

@Schema(description = "Value")
private boolean value;

private static boolean getBooleanValue(String value) {
return Boolean.parseBoolean(value);
}

@Override
public String getStringValue() {
return String.valueOf(isValue());
}

@Override
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public DataType getDataType() {
return DataType.BOOLEAN;
}

@Override
public boolean evaluateRule(Identifiable<?> identifiable) {
boolean identifiableValue = getBooleanValue(getFieldValue(this.getField(), identifiable));
boolean filterValue = this.isValue();
return switch (this.getOperator()) {
case EQUALS -> identifiableValue == filterValue;
case NOT_EQUALS -> identifiableValue != filterValue;
default -> throw new PowsyblException(this.getOperator() + " operator not supported with " + this.getDataType() + " rule data type");
};
}
}
Loading

0 comments on commit ba8e65e

Please sign in to comment.