ConfigDescriptionParameter & Input: Add null annotations & improve JavaDoc (#4465)

* Add null annotations to org.openhab.core.automation.type.Input
* Add null annotations to org.openhab.core.config.core.ConfigDescriptionParameter

Signed-off-by: Florian Hotze <dev@florianhotze.com>
This commit is contained in:
Florian Hotze 2024-12-01 12:28:25 +01:00 committed by GitHub
parent fa29f52a99
commit 7005c7f15e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 118 additions and 108 deletions

View File

@ -14,6 +14,8 @@ package org.openhab.core.automation.type;
import java.util.Set; import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.Module; import org.openhab.core.automation.Module;
import org.openhab.core.automation.Rule; import org.openhab.core.automation.Rule;
@ -32,20 +34,26 @@ import org.openhab.core.automation.Rule;
* "temperature", for example. The value "*" means that all possible types are acceptable. The type is used to determine * "temperature", for example. The value "*" means that all possible types are acceptable. The type is used to determine
* which {@link Output} can be connected to this {@link Input}.</li> * which {@link Output} can be connected to this {@link Input}.</li>
* <li>label (optional) - short description (one word) of the {@link Input}</li> * <li>label (optional) - short description (one word) of the {@link Input}</li>
* <li>description (optional) - long user friendly description of the {@link Input}</li> * <li>description (optional) - long user-friendly description of the {@link Input}</li>
* <li>tags (optional) - add additional restrictions to connections between {@code Input}s and {@link Output}s. The
* input tags must be subset of the output tags to succeed the connection.</li>
* <li>required (optional) - defines if the {@link Input} is required or optional. The default value is false.</li>
* <li>reference (optional) - refers to the input of parent module type or null. If this input is part of the system
* module the reference should be null.</li>
* <li>default value (optional) - the string representation of the default value of the {@link Input}. It must be * <li>default value (optional) - the string representation of the default value of the {@link Input}. It must be
* compatible with the type of the {@link Input}</li> * compatible with the type of the {@link Input}</li>
* <li>required (optional) - defines if the {@link Input} is required or optional. The default value is false.</li>
* </ul> * </ul>
* *
* @author Yordan Mihaylov - Initial contribution * @author Yordan Mihaylov - Initial contribution
* @author Florian Hotze - Add null annotations
*/ */
@NonNullByDefault
public class Input { public class Input {
/** /**
* Specifies a unique name of the {@code Input} in scope of the {@link Module}. * Specifies a unique name of the {@code Input} in scope of the {@link Module}.
*/ */
private String name; private @NonNullByDefault({}) String name;
/** /**
* Specifies the acceptable data type for this {@link Input}. The value could be any string that makes sense for the * Specifies the acceptable data type for this {@link Input}. The value could be any string that makes sense for the
@ -53,25 +61,25 @@ public class Input {
* value "*" means that all possible types are acceptable. The type is used to determine which {@link Output} can be * value "*" means that all possible types are acceptable. The type is used to determine which {@link Output} can be
* connected to this {@link Input} instance. * connected to this {@link Input} instance.
*/ */
private String type; private @NonNullByDefault({}) String type;
/** /**
* Keeps a single word description of the {@code Input}. * Keeps a single word description of the {@code Input}.
*/ */
private String label; private @Nullable String label;
/** /**
* Keeps the user friendly description of the {@code Input}. * Keeps the user-friendly description of the {@code Input}.
*/ */
private String description; private @Nullable String description;
/** /**
* Determines if the {@code Input} is required or optional. * Determines if the {@code Input} is required or optional.
*/ */
private boolean required = false; private boolean required = false;
private Set<String> tags; private @Nullable Set<String> tags;
private String reference; private @Nullable String reference;
private String defaultValue; private @Nullable String defaultValue;
/** /**
* Default constructor for deserialization e.g. by Gson. * Default constructor for deserialization e.g. by Gson.
@ -98,12 +106,12 @@ public class Input {
* @param name unique name of the {@code Input} in scope of the module. * @param name unique name of the {@code Input} in scope of the module.
* @param type the acceptable data type for this {@link Input}. * @param type the acceptable data type for this {@link Input}.
* @param label a single word description of the {@code Input}. * @param label a single word description of the {@code Input}.
* @param description user friendly description of the {@code Input}. * @param description user-friendly description of the {@code Input}.
* @param tags are associated with the {@code Input}. The tags adds additional restrictions to connections * @param tags are associated with the {@code Input}. The tags add additional restrictions to connections
* between {@code Input}s and {@link Output}s. The input tags must be subset of the output tags * between {@code Input}s and {@link Output}s. The input tags must be subset of the output tags
* to succeed the connection. * to succeed the connection.
* For example: When we want to connect input to output and both have same java.lang.double data * For example: When we want to connect input to output and both have same java.lang.double data
* type. The the output has assign "temperature" and "celsius" tags then the input must have at * type. The output has assign "temperature" and "celsius" tags then the input must have at
* least one of these output's tags (i.e. "temperature") to connect this {@code Input} to the * least one of these output's tags (i.e. "temperature") to connect this {@code Input} to the
* selected output. * selected output.
* @param required determines if the {@code Input} is required or optional. * @param required determines if the {@code Input} is required or optional.
@ -113,8 +121,8 @@ public class Input {
* must be the type the Input. * must be the type the Input.
* @throws IllegalArgumentException If one of the name or type parameters is null. * @throws IllegalArgumentException If one of the name or type parameters is null.
*/ */
public Input(String name, String type, String label, String description, Set<String> tags, boolean required, public Input(String name, String type, @Nullable String label, @Nullable String description,
String reference, String defaultValue) { @Nullable Set<String> tags, boolean required, @Nullable String reference, @Nullable String defaultValue) {
if (name == null) { if (name == null) {
throw new IllegalArgumentException("The name of the input must not be NULL!"); throw new IllegalArgumentException("The name of the input must not be NULL!");
} }
@ -145,16 +153,16 @@ public class Input {
* *
* @return label of the Input. * @return label of the Input.
*/ */
public String getLabel() { public @Nullable String getLabel() {
return label; return label;
} }
/** /**
* Gets the long description of the Input. * Gets the long description of the Input.
* *
* @return user friendly description of the Input. * @return user-friendly description of the Input.
*/ */
public String getDescription() { public @Nullable String getDescription() {
return description; return description;
} }
@ -188,6 +196,7 @@ public class Input {
* @return tags associated with this Input. * @return tags associated with this Input.
*/ */
public Set<String> getTags() { public Set<String> getTags() {
Set<String> tags = this.tags;
return tags != null ? tags : Set.of(); return tags != null ? tags : Set.of();
} }
@ -197,7 +206,7 @@ public class Input {
* *
* @return reference to data source. * @return reference to data source.
*/ */
public String getReference() { public @Nullable String getReference() {
return reference; return reference;
} }
@ -207,7 +216,7 @@ public class Input {
* *
* @return the string representation of the default value of this {@link Input}. * @return the string representation of the default value of this {@link Input}.
*/ */
public String getDefaultValue() { public @Nullable String getDefaultValue() {
return defaultValue; return defaultValue;
} }

View File

@ -18,6 +18,9 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
/** /**
@ -38,7 +41,9 @@ import com.google.gson.annotations.SerializedName;
* getter to return primitive types * getter to return primitive types
* @author Thomas Höfer - Added unit * @author Thomas Höfer - Added unit
* @author Laurent Garnier - Removed constraint on unit value * @author Laurent Garnier - Removed constraint on unit value
* @author Florian Hotze - Add null annotations
*/ */
@NonNullByDefault
public class ConfigDescriptionParameter { public class ConfigDescriptionParameter {
/** /**
@ -73,27 +78,27 @@ public class ConfigDescriptionParameter {
} }
private String name; private @NonNullByDefault({}) String name;
private Type type; private @NonNullByDefault({}) Type type;
private String groupName; private @Nullable String groupName;
private BigDecimal min; private @Nullable BigDecimal min;
private BigDecimal max; private @Nullable BigDecimal max;
private BigDecimal step; private @Nullable BigDecimal step;
private String pattern; private @Nullable String pattern;
private boolean required = false; private boolean required = false;
private boolean readOnly = false; private boolean readOnly = false;
private boolean multiple = false; private boolean multiple = false;
private Integer multipleLimit; private @Nullable Integer multipleLimit;
private String unit; private @Nullable String unit;
private String unitLabel; private @Nullable String unitLabel;
private String context; private @Nullable String context;
@SerializedName("default") @SerializedName("default")
private String defaultValue; private @Nullable String defaultValue;
private String label; private @Nullable String label;
private String description; private @Nullable String description;
private List<ParameterOption> options = new ArrayList<>(); private List<ParameterOption> options = new ArrayList<>();
private List<FilterCriteria> filterCriteria = new ArrayList<>(); private List<FilterCriteria> filterCriteria = new ArrayList<>();
@ -116,29 +121,23 @@ public class ConfigDescriptionParameter {
/** /**
* Creates a new instance of this class with the specified parameters. * Creates a new instance of this class with the specified parameters.
* *
* @param name the name of the configuration parameter (must neither be null * @param name the name of the configuration parameter (must not be empty)
* nor empty) * @param type the data type of the configuration parameter
* @param type the data type of the configuration parameter (nullable)
* @param minimum the minimal value for numeric types, or the minimal length of * @param minimum the minimal value for numeric types, or the minimal length of
* strings, or the minimal number of selected options (nullable) * strings, or the minimal number of selected options
* @param maximum the maximal value for numeric types, or the maximal length of * @param maximum the maximal value for numeric types, or the maximal length of
* strings, or the maximal number of selected options (nullable) * strings, or the maximal number of selected options
* @param stepsize the value granularity for a numeric value (nullable) * @param stepsize the value granularity for a numeric value
* @param pattern the regular expression for a text type (nullable) * @param pattern the regular expression for a text type
* @param required specifies whether the value is required * @param required specifies whether the value is required
* @param readOnly specifies whether the value is read-only * @param readOnly specifies whether the value is read-only
* @param multiple specifies whether multiple selections of options are allowed * @param multiple specifies whether multiple selections of options are allowed
* @param context the context of the configuration parameter (can be null or * @param context the context of the configuration parameter (can be empty)
* empty) * @param defaultValue the default value of the configuration parameter
* @param defaultValue the default value of the configuration parameter (can be null) * @param label a human-readable label for the configuration parameter (can be empty)
* @param label a human readable label for the configuration parameter (can be * @param description a human-readable description for the configuration parameter (can be empty)
* null or empty) * @param filterCriteria a list of filter criteria for values of a dynamic selection list
* @param description a human readable description for the configuration parameter
* (can be null or empty)
* @param filterCriteria a list of filter criteria for values of a dynamic selection
* list (nullable)
* @param options a list of element definitions of a static selection list * @param options a list of element definitions of a static selection list
* (nullable)
* @param groupName a string used to group parameters together into logical blocks * @param groupName a string used to group parameters together into logical blocks
* so that the UI can display them together * so that the UI can display them together
* @param advanced specifies if this is an advanced parameter. An advanced * @param advanced specifies if this is an advanced parameter. An advanced
@ -151,10 +150,11 @@ public class ConfigDescriptionParameter {
* can enter values other than those in the list * can enter values other than those in the list
* @param multipleLimit specifies the maximum number of options that can be selected * @param multipleLimit specifies the maximum number of options that can be selected
* when multiple is true * when multiple is true
* @param unit specifies the unit of measurements for the configuration parameter (nullable) * @param unit specifies the unit of measurements for the configuration parameter
* @param unitLabel specifies the unit label for the configuration parameter. This attribute can also be used to * @param unitLabel specifies the unit label for the configuration parameter. This attribute can also be used to
* provide * provide
* natural language units as iterations, runs, etc. * natural language units as iterations, runs, etc.
* @param verify specifies whether the parameter should be considered dangerous
* @throws IllegalArgumentException * @throws IllegalArgumentException
* <ul> * <ul>
* <li>if the name is null or empty, or the type is null</li> * <li>if the name is null or empty, or the type is null</li>
@ -166,11 +166,14 @@ public class ConfigDescriptionParameter {
* @deprecated Use {@link ConfigDescriptionParameterBuilder} instead. * @deprecated Use {@link ConfigDescriptionParameterBuilder} instead.
*/ */
@Deprecated @Deprecated
ConfigDescriptionParameter(String name, Type type, BigDecimal minimum, BigDecimal maximum, BigDecimal stepsize, ConfigDescriptionParameter(String name, Type type, @Nullable BigDecimal minimum, @Nullable BigDecimal maximum,
String pattern, Boolean required, Boolean readOnly, Boolean multiple, String context, String defaultValue, @Nullable BigDecimal stepsize, @Nullable String pattern, @Nullable Boolean required,
String label, String description, List<ParameterOption> options, List<FilterCriteria> filterCriteria, @Nullable Boolean readOnly, @Nullable Boolean multiple, @Nullable String context,
String groupName, Boolean advanced, Boolean limitToOptions, Integer multipleLimit, String unit, @Nullable String defaultValue, @Nullable String label, @Nullable String description,
String unitLabel, Boolean verify) throws IllegalArgumentException { @Nullable List<ParameterOption> options, @Nullable List<FilterCriteria> filterCriteria,
@Nullable String groupName, @Nullable Boolean advanced, @Nullable Boolean limitToOptions,
@Nullable Integer multipleLimit, @Nullable String unit, @Nullable String unitLabel,
@Nullable Boolean verify) throws IllegalArgumentException {
if ((name == null) || (name.isEmpty())) { if ((name == null) || (name.isEmpty())) {
throw new IllegalArgumentException("The name must neither be null nor empty!"); throw new IllegalArgumentException("The name must neither be null nor empty!");
} }
@ -233,7 +236,7 @@ public class ConfigDescriptionParameter {
/** /**
* Returns the name of the configuration parameter. * Returns the name of the configuration parameter.
* *
* @return the name of the configuration parameter (neither null, nor empty) * @return the name of the configuration parameter (not empty)
*/ */
public String getName() { public String getName() {
return this.name; return this.name;
@ -242,7 +245,7 @@ public class ConfigDescriptionParameter {
/** /**
* Returns the data type of the configuration parameter. * Returns the data type of the configuration parameter.
* *
* @return the data type of the configuration parameter (not null) * @return the data type of the configuration parameter
*/ */
public Type getType() { public Type getType() {
return this.type; return this.type;
@ -250,17 +253,17 @@ public class ConfigDescriptionParameter {
/** /**
* @return the minimal value for numeric types, or the minimal length of * @return the minimal value for numeric types, or the minimal length of
* strings, or the minimal number of selected options (nullable) * strings, or the minimal number of selected options
*/ */
public BigDecimal getMinimum() { public @Nullable BigDecimal getMinimum() {
return min; return min;
} }
/** /**
* @return the maximal value for numeric types, or the maximal length of * @return the maximal value for numeric types, or the maximal length of
* strings, or the maximal number of selected options (nullable) * strings, or the maximal number of selected options
*/ */
public BigDecimal getMaximum() { public @Nullable BigDecimal getMaximum() {
return max; return max;
} }
@ -269,23 +272,23 @@ public class ConfigDescriptionParameter {
* <p> * <p>
* By setting the step size to <code>0</code>, any granularity is allowed, i.e. any number of decimals is accepted. * By setting the step size to <code>0</code>, any granularity is allowed, i.e. any number of decimals is accepted.
* *
* @return the value granularity for a numeric value (nullable) * @return the value granularity for a numeric value
*/ */
public BigDecimal getStepSize() { public @Nullable BigDecimal getStepSize() {
return step; return step;
} }
/** /**
* @return the regular expression for a text type (nullable) * @return the regular expression for a text type
*/ */
public String getPattern() { public @Nullable String getPattern() {
return pattern; return pattern;
} }
/** /**
* @return true if the value is required, otherwise false. * @return true if the value is required, otherwise false.
*/ */
public Boolean isReadOnly() { public boolean isReadOnly() {
return readOnly; return readOnly;
} }
@ -293,14 +296,14 @@ public class ConfigDescriptionParameter {
* @return true if multiple selections of options are allowed, otherwise * @return true if multiple selections of options are allowed, otherwise
* false. * false.
*/ */
public Boolean isMultiple() { public boolean isMultiple() {
return multiple; return multiple;
} }
/** /**
* @return the maximum number of options that can be selected from the options list * @return the maximum number of options that can be selected from the options list
*/ */
public Integer getMultipleLimit() { public @Nullable Integer getMultipleLimit() {
return multipleLimit; return multipleLimit;
} }
@ -347,10 +350,9 @@ public class ConfigDescriptionParameter {
* - location: A latitude,longitude[,altitude] GPS location. A user-interface would probably render a world map for * - location: A latitude,longitude[,altitude] GPS location. A user-interface would probably render a world map for
* selection. * selection.
* *
* @return the context of the configuration parameter (could be null or * @return the context of the configuration parameter (could be empty)
* empty)
*/ */
public String getContext() { public @Nullable String getContext() {
return this.context; return this.context;
} }
@ -362,35 +364,34 @@ public class ConfigDescriptionParameter {
* false * false
*/ */
public boolean isRequired() { public boolean isRequired() {
return this.required; return required;
} }
/** /**
* Returns the default value of the configuration parameter. * Returns the default value of the configuration parameter.
* *
* @return the default value of the configuration parameter (could be null) * @return the default value of the configuration parameter
*/ */
public String getDefault() { public @Nullable String getDefault() {
return this.defaultValue; return defaultValue;
} }
/** /**
* Returns a human readable label for the configuration parameter. * Returns a human-readable label for the configuration parameter.
* *
* @return a human readable label for the configuration parameter (could be * @return a human-readable label for the configuration parameter (could be empty)
* null or empty)
*/ */
public String getLabel() { public @Nullable String getLabel() {
return this.label; return label;
} }
/** /**
* Returns a the group for this configuration parameter. * Returns the group for this configuration parameter.
* *
* @return a group for the configuration parameter (could be null or empty) * @return a group for the configuration parameter (could be empty)
*/ */
public String getGroupName() { public @Nullable String getGroupName() {
return this.groupName; return groupName;
} }
/** /**
@ -400,7 +401,7 @@ public class ConfigDescriptionParameter {
* @return true if the value is limited to the options list * @return true if the value is limited to the options list
*/ */
public boolean getLimitToOptions() { public boolean getLimitToOptions() {
return this.limitToOptions; return limitToOptions;
} }
/** /**
@ -409,17 +410,16 @@ public class ConfigDescriptionParameter {
* @return true if the value is an advanced option * @return true if the value is an advanced option
*/ */
public boolean isAdvanced() { public boolean isAdvanced() {
return this.advanced; return advanced;
} }
/** /**
* Returns a human readable description for the configuration parameter. * Returns a human-readable description for the configuration parameter.
* *
* @return a human readable description for the configuration parameter * @return a human-readable description for the configuration parameter (could be empty)
* (could be null or empty)
*/ */
public String getDescription() { public @Nullable String getDescription() {
return this.description; return description;
} }
/** /**
@ -428,7 +428,7 @@ public class ConfigDescriptionParameter {
* @return static selection list for the value of this parameter * @return static selection list for the value of this parameter
*/ */
public List<ParameterOption> getOptions() { public List<ParameterOption> getOptions() {
return this.options; return options;
} }
/** /**
@ -440,24 +440,24 @@ public class ConfigDescriptionParameter {
* @return list of filter criteria for a dynamically created selection list * @return list of filter criteria for a dynamically created selection list
*/ */
public List<FilterCriteria> getFilterCriteria() { public List<FilterCriteria> getFilterCriteria() {
return this.filterCriteria; return filterCriteria;
} }
/** /**
* Returns the unit of measurements of this parameter. * Returns the unit of measurements of this parameter.
* *
* @return the unit of measurements of this parameter (could be null) * @return the unit of measurements of this parameter
*/ */
public String getUnit() { public @Nullable String getUnit() {
return unit; return unit;
} }
/** /**
* Returns the unit label of this parameter. * Returns the unit label of this parameter.
* *
* @return the unit label of this parameter (could be null) * @return the unit label of this parameter
*/ */
public String getUnitLabel() { public @Nullable String getUnitLabel() {
return unitLabel; return unitLabel;
} }
@ -467,7 +467,7 @@ public class ConfigDescriptionParameter {
* *
* @return true if the parameter requires verification in the UI * @return true if the parameter requires verification in the UI
*/ */
public Boolean isVerifyable() { public boolean isVerifyable() {
return verify; return verify;
} }

View File

@ -68,7 +68,10 @@ public class ConfigUtil {
} }
static @Nullable Object getDefaultValueAsCorrectType(String parameterName, Type parameterType, static @Nullable Object getDefaultValueAsCorrectType(String parameterName, Type parameterType,
String defaultValue) { @Nullable String defaultValue) {
if (defaultValue == null) {
return null;
}
try { try {
switch (parameterType) { switch (parameterType) {
case TEXT: case TEXT:

View File

@ -29,11 +29,12 @@ final class PatternValidator implements ConfigDescriptionParameterValidator {
@Override @Override
public @Nullable ConfigValidationMessage validate(ConfigDescriptionParameter parameter, @Nullable Object value) { public @Nullable ConfigValidationMessage validate(ConfigDescriptionParameter parameter, @Nullable Object value) {
if (value == null || parameter.getType() != Type.TEXT || parameter.getPattern() == null) { String pattern = parameter.getPattern();
if (value == null || parameter.getType() != Type.TEXT || pattern == null) {
return null; return null;
} }
if (!((String) value).matches(parameter.getPattern())) { if (!((String) value).matches(pattern)) {
MessageKey messageKey = MessageKey.PATTERN_VIOLATED; MessageKey messageKey = MessageKey.PATTERN_VIOLATED;
return new ConfigValidationMessage(parameter.getName(), messageKey.defaultMessage, messageKey.key, return new ConfigValidationMessage(parameter.getName(), messageKey.defaultMessage, messageKey.key,
String.valueOf(value), parameter.getPattern()); String.valueOf(value), parameter.getPattern());

View File

@ -18,8 +18,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.config.core.ConfigDescriptionParameter.Type; import org.openhab.core.config.core.ConfigDescriptionParameter.Type;
import org.openhab.core.config.core.dto.ConfigDescriptionParameterDTO; import org.openhab.core.config.core.dto.ConfigDescriptionParameterDTO;
import org.openhab.core.config.core.dto.FilterCriteriaDTO; import org.openhab.core.config.core.dto.FilterCriteriaDTO;
@ -31,16 +29,15 @@ import org.openhab.core.config.core.dto.ParameterOptionDTO;
* *
* @author Christoph Weitkamp - Initial contribution * @author Christoph Weitkamp - Initial contribution
*/ */
@NonNullByDefault
public class EnrichedConfigDescriptionParameterDTO extends ConfigDescriptionParameterDTO { public class EnrichedConfigDescriptionParameterDTO extends ConfigDescriptionParameterDTO {
private static final String DEFAULT_LIST_DELIMITER = ","; private static final String DEFAULT_LIST_DELIMITER = ",";
public @Nullable Collection<String> defaultValues; public Collection<String> defaultValues;
public EnrichedConfigDescriptionParameterDTO(String name, Type type, BigDecimal minimum, BigDecimal maximum, public EnrichedConfigDescriptionParameterDTO(String name, Type type, BigDecimal minimum, BigDecimal maximum,
BigDecimal stepsize, String pattern, Boolean required, Boolean readOnly, Boolean multiple, String context, BigDecimal stepsize, String pattern, Boolean required, Boolean readOnly, Boolean multiple, String context,
@Nullable String defaultValue, String label, String description, List<ParameterOptionDTO> options, String defaultValue, String label, String description, List<ParameterOptionDTO> options,
List<FilterCriteriaDTO> filterCriteria, String groupName, Boolean advanced, Boolean limitToOptions, List<FilterCriteriaDTO> filterCriteria, String groupName, Boolean advanced, Boolean limitToOptions,
Integer multipleLimit, String unit, String unitLabel, Boolean verify) { Integer multipleLimit, String unit, String unitLabel, Boolean verify) {
super(name, type, minimum, maximum, stepsize, pattern, required, readOnly, multiple, context, defaultValue, super(name, type, minimum, maximum, stepsize, pattern, required, readOnly, multiple, context, defaultValue,