From 5fe39d510d77c624781f646a0b5986900d86ba85 Mon Sep 17 00:00:00 2001 From: Ravi Nadahar Date: Sun, 18 May 2025 05:42:56 +0200 Subject: [PATCH] Create YamlConfigDescriptionParameterDTO YamlConfigDescriptionParameterDTO is separated from the other rule-related classes because it can also be used by other element types. Signed-off-by: Ravi Nadahar --- .../YamlConfigDescriptionParameterDTO.java | 262 ++++++++++++++++++ .../yaml/internal/rules/YamlRuleDTO.java | 14 +- .../yaml/internal/rules/YamlRuleProvider.java | 9 +- 3 files changed, 278 insertions(+), 7 deletions(-) create mode 100644 bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/config/YamlConfigDescriptionParameterDTO.java diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/config/YamlConfigDescriptionParameterDTO.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/config/YamlConfigDescriptionParameterDTO.java new file mode 100644 index 0000000000..5d2ac0c374 --- /dev/null +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/config/YamlConfigDescriptionParameterDTO.java @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2010-2025 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.core.model.yaml.internal.config; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +import org.eclipse.jdt.annotation.NonNull; +import org.openhab.core.config.core.ConfigDescriptionParameter; +import org.openhab.core.config.core.ConfigDescriptionParameter.Type; +import org.openhab.core.config.core.ConfigDescriptionParameterBuilder; +import org.openhab.core.config.core.FilterCriteria; +import org.openhab.core.config.core.ParameterOption; +import org.openhab.core.config.core.dto.FilterCriteriaDTO; +import org.openhab.core.config.core.dto.ParameterOptionDTO; + +import com.fasterxml.jackson.annotation.JsonAlias; + +/** + * This is a data transfer object used to serialize a parameter of a configuration description in a YAML configuration. + * + * @author Ravi Nadahar - Initial contribution + */ +public class YamlConfigDescriptionParameterDTO { + + public String context; + @JsonAlias({ "default", "defaultValue" }) + public String defaultValue; + public String description; + public String label; + public String name; + public boolean required; + public Type type; + public BigDecimal min; + public BigDecimal max; + public BigDecimal stepsize; + public String pattern; + public Boolean readOnly; + public Boolean multiple; + public Integer multipleLimit; + public String groupName; + public Boolean advanced; + public Boolean verify; + public Boolean limitToOptions; + public String unit; + public String unitLabel; + + public List options; + public List filterCriteria; + + /** + * Creates a new instance. + */ + public YamlConfigDescriptionParameterDTO() { + } + + /** + * Creates a new instance based on the specified {@link ConfigDescriptionParameter}. + * + * @param parameter the {@link ConfigDescriptionParameter}. + */ + public YamlConfigDescriptionParameterDTO(@NonNull ConfigDescriptionParameter parameter) { + this.name = parameter.getName(); + this.type = parameter.getType(); + this.min = parameter.getMinimum(); + this.max = parameter.getMaximum(); + this.stepsize = parameter.getStepSize(); + this.pattern = parameter.getPattern(); + this.readOnly = parameter.isReadOnly(); + this.multiple = parameter.isMultiple(); + this.context = parameter.getContext(); + this.required = parameter.isRequired(); + this.defaultValue = parameter.getDefault(); + this.label = parameter.getLabel(); + this.description = parameter.getDescription(); + List<@NonNull ParameterOption> options = parameter.getOptions(); + if (!options.isEmpty()) { + List optionDtos = new ArrayList<>(options.size()); + for (ParameterOption option : options) { + optionDtos.add(new ParameterOptionDTO(option.getValue(), option.getLabel())); + } + this.options = optionDtos; + } + List<@NonNull FilterCriteria> filterCriterias = parameter.getFilterCriteria(); + if (!filterCriteria.isEmpty()) { + List filterCriteriaDtos = new ArrayList<>(filterCriteria.size()); + for (FilterCriteria filterCriteria : filterCriterias) { + filterCriteriaDtos.add(new FilterCriteriaDTO(filterCriteria.getName(), filterCriteria.getValue())); + } + this.filterCriteria = filterCriteriaDtos; + } + this.groupName = parameter.getGroupName(); + this.advanced = parameter.isAdvanced(); + this.limitToOptions = parameter.getLimitToOptions(); + this.multipleLimit = parameter.getMultipleLimit(); + this.unit = parameter.getUnit(); + this.unitLabel = parameter.getUnitLabel(); + this.verify = parameter.isVerifyable(); + } + + @Override + public int hashCode() { + return Objects.hash(advanced, context, defaultValue, description, filterCriteria, groupName, label, + limitToOptions, max, min, multiple, multipleLimit, name, options, pattern, readOnly, required, stepsize, + type, unit, unitLabel, verify); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof YamlConfigDescriptionParameterDTO)) { + return false; + } + YamlConfigDescriptionParameterDTO other = (YamlConfigDescriptionParameterDTO) obj; + return Objects.equals(advanced, other.advanced) && Objects.equals(context, other.context) + && Objects.equals(defaultValue, other.defaultValue) && Objects.equals(description, other.description) + && Objects.equals(filterCriteria, other.filterCriteria) && Objects.equals(groupName, other.groupName) + && Objects.equals(label, other.label) && Objects.equals(limitToOptions, other.limitToOptions) + && Objects.equals(max, other.max) && Objects.equals(min, other.min) + && Objects.equals(multiple, other.multiple) && Objects.equals(multipleLimit, other.multipleLimit) + && Objects.equals(name, other.name) && Objects.equals(options, other.options) + && Objects.equals(pattern, other.pattern) && Objects.equals(readOnly, other.readOnly) + && required == other.required && Objects.equals(stepsize, other.stepsize) && type == other.type + && Objects.equals(unit, other.unit) && Objects.equals(unitLabel, other.unitLabel) + && Objects.equals(verify, other.verify); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(getClass().getSimpleName()); + builder.append(" ["); + if (context != null) { + builder.append("context=").append(context).append(", "); + } + if (defaultValue != null) { + builder.append("defaultValue=").append(defaultValue).append(", "); + } + if (description != null) { + builder.append("description=").append(description).append(", "); + } + if (label != null) { + builder.append("label=").append(label).append(", "); + } + if (name != null) { + builder.append("name=").append(name).append(", "); + } + builder.append("required=").append(required).append(", "); + if (type != null) { + builder.append("type=").append(type).append(", "); + } + if (min != null) { + builder.append("min=").append(min).append(", "); + } + if (max != null) { + builder.append("max=").append(max).append(", "); + } + if (stepsize != null) { + builder.append("stepsize=").append(stepsize).append(", "); + } + if (pattern != null) { + builder.append("pattern=").append(pattern).append(", "); + } + if (readOnly != null) { + builder.append("readOnly=").append(readOnly).append(", "); + } + if (multiple != null) { + builder.append("multiple=").append(multiple).append(", "); + } + if (multipleLimit != null) { + builder.append("multipleLimit=").append(multipleLimit).append(", "); + } + if (groupName != null) { + builder.append("groupName=").append(groupName).append(", "); + } + if (advanced != null) { + builder.append("advanced=").append(advanced).append(", "); + } + if (verify != null) { + builder.append("verify=").append(verify).append(", "); + } + if (limitToOptions != null) { + builder.append("limitToOptions=").append(limitToOptions).append(", "); + } + if (unit != null) { + builder.append("unit=").append(unit).append(", "); + } + if (unitLabel != null) { + builder.append("unitLabel=").append(unitLabel).append(", "); + } + if (options != null) { + builder.append("options=").append(options).append(", "); + } + if (filterCriteria != null) { + builder.append("filterCriteria=").append(filterCriteria); + } + builder.append("]"); + return builder.toString(); + } + + /** + * Creates a {@link List} of {@link ConfigDescriptionParameter}s from a {@link Collection} of + * {@link YamlConfigDescriptionParameterDTO}s, + * to be used during deserialization. + * + * @param configDescriptionDtos the {@link Collection} of {@link YamlConfigDescriptionParameterDTO}s. + * @return The corresponding {@link List} of {@link ConfigDescriptionParameter}s. + */ + public static @NonNull List<@NonNull ConfigDescriptionParameter> mapConfigDescriptions( + @NonNull Collection<@NonNull YamlConfigDescriptionParameterDTO> configDescriptionDtos) { + List result = new ArrayList<>(configDescriptionDtos.size()); + List filterCriteriaDtos; + List filterCriterias; + List parameterOptionDtos; + List parameterOptions; + ConfigDescriptionParameterBuilder builder; + for (YamlConfigDescriptionParameterDTO parameterDto : configDescriptionDtos) { + builder = ConfigDescriptionParameterBuilder.create(parameterDto.name, parameterDto.type) + .withAdvanced(parameterDto.advanced).withContext(parameterDto.context) + .withDefault(parameterDto.defaultValue).withDescription(parameterDto.description) + .withGroupName(parameterDto.groupName).withLabel(parameterDto.label) + .withLimitToOptions(parameterDto.limitToOptions).withMaximum(parameterDto.max) + .withMinimum(parameterDto.min).withMultiple(parameterDto.multiple) + .withMultipleLimit(parameterDto.multipleLimit).withPattern(parameterDto.pattern) + .withReadOnly(parameterDto.readOnly).withRequired(parameterDto.required) + .withStepSize(parameterDto.stepsize).withUnit(parameterDto.unit) + .withUnitLabel(parameterDto.unitLabel).withVerify(parameterDto.verify); + filterCriteriaDtos = parameterDto.filterCriteria; + if (filterCriteriaDtos != null) { + filterCriterias = new ArrayList<>(filterCriteriaDtos.size()); + for (FilterCriteriaDTO filterCriteriaDto : filterCriteriaDtos) { + filterCriterias.add(new FilterCriteria(filterCriteriaDto.name, filterCriteriaDto.value)); + } + builder.withFilterCriteria(filterCriterias); + } + parameterOptionDtos = parameterDto.options; + if (parameterOptionDtos != null) { + parameterOptions = new ArrayList<>(parameterOptionDtos.size()); + for (ParameterOptionDTO optionDto : parameterOptionDtos) { + parameterOptions.add(new ParameterOption(optionDto.value, optionDto.label)); + } + builder.withOptions(parameterOptions); + } + result.add(builder.build()); + } + return result; + } +} diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/rules/YamlRuleDTO.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/rules/YamlRuleDTO.java index 128ac9417d..b189323f86 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/rules/YamlRuleDTO.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/rules/YamlRuleDTO.java @@ -35,6 +35,7 @@ import org.openhab.core.io.dto.ModularDTO; import org.openhab.core.io.dto.SerializationException; import org.openhab.core.model.yaml.YamlElement; import org.openhab.core.model.yaml.YamlElementName; +import org.openhab.core.model.yaml.internal.config.YamlConfigDescriptionParameterDTO; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.core.JsonProcessingException; @@ -59,7 +60,7 @@ public class YamlRuleDTO implements ModularDTO config; - public List<@NonNull ConfigDescriptionParameter> configDescriptions; + public List<@NonNull YamlConfigDescriptionParameterDTO> configDescriptions; public List<@NonNull YamlConditionDTO> conditions; public List<@NonNull YamlActionDTO> actions; public List<@NonNull YamlModuleDTO> triggers; @@ -84,7 +85,14 @@ public class YamlRuleDTO implements ModularDTO configDescriptions = rule.getConfigurationDescriptions(); + if (!configDescriptions.isEmpty()) { + List configDescriptionDtos = new ArrayList<>(configDescriptions.size()); + for (ConfigDescriptionParameter parameter : configDescriptions) { + configDescriptionDtos.add(new YamlConfigDescriptionParameterDTO(parameter)); + } + this.configDescriptions = configDescriptionDtos; + } List<@NonNull Action> actions = rule.getActions(); if (!actions.isEmpty()) { List actionDtos = new ArrayList<>(actions.size()); @@ -380,7 +388,7 @@ public class YamlRuleDTO implements ModularDTO config; - public List<@NonNull ConfigDescriptionParameter> configDescriptions; + public List<@NonNull YamlConfigDescriptionParameterDTO> configDescriptions; public JsonNode conditions; public JsonNode actions; public JsonNode triggers; diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/rules/YamlRuleProvider.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/rules/YamlRuleProvider.java index d557c4a4b7..48460e1161 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/rules/YamlRuleProvider.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/rules/YamlRuleProvider.java @@ -28,9 +28,9 @@ import org.openhab.core.automation.Rule; import org.openhab.core.automation.RuleProvider; import org.openhab.core.automation.Trigger; import org.openhab.core.automation.util.RuleBuilder; -import org.openhab.core.config.core.ConfigDescriptionParameter; import org.openhab.core.config.core.Configuration; import org.openhab.core.model.yaml.YamlModelListener; +import org.openhab.core.model.yaml.internal.config.YamlConfigDescriptionParameterDTO; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; @@ -157,9 +157,10 @@ public class YamlRuleProvider extends AbstractYamlRuleProvider if (configuration != null) { ruleBuilder.withConfiguration(new Configuration(configuration)); } - List configurationDescriptions = ruleDto.configDescriptions; - if (configurationDescriptions != null) { - ruleBuilder.withConfigurationDescriptions(configurationDescriptions); + List configDescriptionDtos = ruleDto.configDescriptions; + if (configDescriptionDtos != null) { + ruleBuilder.withConfigurationDescriptions( + YamlConfigDescriptionParameterDTO.mapConfigDescriptions(configDescriptionDtos)); } List triggerDTOs = ruleDto.triggers; List conditionDTOs = ruleDto.conditions;