davsclaus commented on code in PR #27079: URL: https://github.com/apache/camel/pull/27079#discussion_r4136335080
########## core/camel-core-model/src/main/java/org/apache/camel/model/SwitchValueDefinition.java: ########## @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.model; + +import java.math.BigDecimal; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlRootElement; + +import org.apache.camel.spi.Metadata; + +/** A named, typed literal in a switch case. */ +@Metadata(label = "configuration", description = "A named literal in a composite switch case") +@XmlRootElement(name = "switchValue") +@XmlAccessorType(XmlAccessType.FIELD) +public class SwitchValueDefinition { Review Comment: Scalar only for the first release (see CAMEL-24988): please remove the composite form. This class (and its typed literals) is no longer needed. ########## core/camel-core-model/src/main/java/org/apache/camel/model/SwitchCaseDefinition.java: ########## @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.model; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlTransient; + +import org.apache.camel.spi.Metadata; + +/** One literal combination and one fixed destination. */ +@Metadata(label = "configuration", description = "A literal switch case with one fixed endpoint destination") +@XmlRootElement(name = "case") +@XmlAccessorType(XmlAccessType.FIELD) +public class SwitchCaseDefinition extends OptionalIdentifiedDefinition<SwitchCaseDefinition> + implements EndpointRequiredDefinition { + @XmlAttribute + @Metadata(description = "The case-insensitive literal value for a scalar selector. Mutually exclusive with values.") + private String value; + @XmlElement(name = "values") + @Metadata(description = "Named, typed literal values for a composite selector. Every selected key must occur exactly once.") + private List<SwitchValueDefinition> values = new ArrayList<>(); Review Comment: Scalar only for the first release (see CAMEL-24988): please remove the composite form. A case has a single `value` attribute. ########## core/camel-core-model/src/main/java/org/apache/camel/model/SwitchDefinition.java: ########## @@ -0,0 +1,260 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlTransient; +import jakarta.xml.bind.annotation.XmlType; + +import org.apache.camel.Expression; +import org.apache.camel.NamedNode; +import org.apache.camel.builder.ExpressionClause; +import org.apache.camel.model.language.ExpressionDefinition; +import org.apache.camel.spi.Metadata; + +/** Routes a message to one fixed endpoint using a literal lookup table. */ +@Metadata(firstVersion = "4.23.0", label = "eip,routing", + description = "Evaluates a selector once and dispatches to a fixed endpoint by literal scalar or composite values") +@XmlRootElement(name = "switch") +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(propOrder = { "selector", "keys", "cases", "otherwise" }) +public class SwitchDefinition extends NoOutputDefinition<SwitchDefinition> { + @XmlElement(required = true) + @Metadata(required = true, + description = "Expression evaluated once per entry. Returns a scalar, or a map when keys are configured.") + private ExpressionSubElementDefinition selector; + @XmlElement(name = "keys") + @Metadata(description = "Exact map field names forming a composite key. Additional result fields are ignored.") + private List<String> keys = new ArrayList<>(); Review Comment: Scalar only for the first release (see CAMEL-24988): please remove the composite form. `keys` goes away with it. ########## core/camel-core-processor/src/main/java/org/apache/camel/processor/SwitchProcessor.java: ########## @@ -0,0 +1,232 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.processor; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLongArray; + +import org.apache.camel.AsyncCallback; +import org.apache.camel.AsyncProcessor; +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.Expression; +import org.apache.camel.Navigate; +import org.apache.camel.Processor; +import org.apache.camel.Traceable; +import org.apache.camel.spi.IdAware; +import org.apache.camel.spi.RouteIdAware; +import org.apache.camel.spi.StepIdAware; +import org.apache.camel.support.AsyncProcessorConverterHelper; +import org.apache.camel.support.MessageHelper; +import org.apache.camel.support.service.ServiceHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.camel.processor.PipelineHelper.continueProcessing; + +/** Evaluates one selector and dispatches through a table of literal keys. */ +public class SwitchProcessor extends BaseProcessorSupport + implements Navigate<Processor>, Traceable, IdAware, RouteIdAware, StepIdAware { + private static final Logger LOG = LoggerFactory.getLogger(SwitchProcessor.class); + private final CamelContext context; + private final Expression selector; + private final List<String> keys; + private final Map<Object, Integer> table = new LinkedHashMap<>(); + private final List<AsyncProcessor> processors = new ArrayList<>(); + private final AsyncProcessor otherwise; + private final AtomicLongArray counts; + private String id; + private String routeId; + private String stepId; + + public SwitchProcessor(CamelContext context, Expression selector, List<String> keys, + Map<Object, Processor> cases, Processor otherwise) { + this.context = context; + this.selector = selector; + this.keys = List.copyOf(keys); + cases.forEach((key, processor) -> { + table.put(key, processors.size()); + processors.add(AsyncProcessorConverterHelper.convert(processor)); + }); + this.otherwise = otherwise == null ? null : AsyncProcessorConverterHelper.convert(otherwise); + counts = new AtomicLongArray(processors.size() + 1); + } + + /** Normalize a typed literal, preserving the distinction between strings, booleans and numbers. */ + public static Object normalizeLiteral(Object value) { Review Comment: `normalizeLiteral` / `compositeKey` are only needed for composite typed literals; scalar matching is just a `toLowerCase(Locale.ENGLISH)` string lookup. ########## core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedSwitch.java: ########## @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.management.mbean; + +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; + +import org.apache.camel.CamelContext; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.api.management.ManagedResource; +import org.apache.camel.api.management.mbean.CamelOpenMBeanTypes; +import org.apache.camel.api.management.mbean.ManagedSwitchMBean; +import org.apache.camel.model.ProcessorDefinition; +import org.apache.camel.model.SwitchCaseDefinition; +import org.apache.camel.model.SwitchDefinition; +import org.apache.camel.processor.SwitchProcessor; + +@ManagedResource(description = "Managed Switch") +public class ManagedSwitch extends ManagedProcessor implements ManagedSwitchMBean { + public ManagedSwitch(CamelContext context, SwitchProcessor processor, ProcessorDefinition<?> definition) { + super(context, processor, definition); + } + + @Override + public SwitchProcessor getProcessor() { + return (SwitchProcessor) super.getProcessor(); + } + + @Override + public SwitchDefinition getDefinition() { + return (SwitchDefinition) super.getDefinition(); + } + + @Override + public Boolean getSupportExtendedInformation() { + return true; + } + + @Override + public long getUnmatchedCount() { + return getProcessor().getUnmatchedCount(); + } + + @Override + public void reset() { + getProcessor().reset(); + super.reset(); + } + + @Override + public TabularData extendedInformation() { + try { + TabularDataSupport table = new TabularDataSupport(CamelOpenMBeanTypes.switchTabularType()); + for (int i = 0; i < getDefinition().getCases().size(); i++) { + SwitchCaseDefinition c = getDefinition().getCases().get(i); + addRow(table, c.getId(), c.getValue() != null ? c.getValue() : c.getValues().toString(), + c.getUri(), getProcessor().getMatchedCount(i)); Review Comment: Mask the URI with `URISupport.sanitizeUri` when the management mask is on, as `ManagedSendProcessor` does, so secrets in URIs (e.g. `?password=...`) don't leak through JMX. Same at line 75 for the otherwise URI. ########## core/camel-core-engine/src/main/docs/modules/eips/pages/switch-eip.adoc: ########## @@ -0,0 +1,442 @@ += Switch EIP +:doctitle: Switch +:shortname: switch +:description: Evaluates a selector once and dispatches to a fixed endpoint by literal scalar or composite values +:since: 4.23 +:supportlevel: Stable +:tabs-sync-option: + +*Since Camel {since}* + +Switch selects one destination from a table declared by the route author. +The selector can use any Camel expression language. Its result selects a case; +it cannot supply a new endpoint URI. + +Use Switch for literal value dispatch. Use xref:choice-eip.adoc[Choice] for +predicates, ranges, overlapping conditions, or nested processing steps. A case can +send to a `direct:` route when more processing is needed. Use xref:toD-eip.adoc[To D] +when the endpoint URI itself must be calculated dynamically. + +== Options + +// eip options: START +include::partial$eip-options.adoc[] +// eip options: END + +== Scalar selectors + +The selector is evaluated once on each entry. Scalar results are converted to strings +and matched case-insensitively using the English locale. An empty string is a valid +literal. An asterisk is literal, not a wildcard. Duplicate normalized values are +rejected at startup. + +=== Route from a header + +This route reads the `department` header. The body is passed unchanged to the +selected destination. The examples on this page are independent; load one at a +time and connect the `direct:` destinations to your application's handling routes. + +[tabs] +==== +Java:: ++ +[source,java] +---- +from("direct:tickets") + .doSwitch(header("department")) + .doCase("billing", "direct:billing") + .doCase("technical", "direct:technical") + .otherwise("direct:review") + .end(); +---- +XML:: ++ +[source,xml] +---- +<route xmlns="http://camel.apache.org/schema/spring"> + <from uri="direct:tickets"/> + <switch> + <selector><header>department</header></selector> + <case value="billing" uri="direct:billing"/> + <case value="technical" uri="direct:technical"/> + <otherwise uri="direct:review"/> + </switch> +</route> +---- +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:tickets + steps: + - switch: + selector: + header: + expression: department + case: + - value: billing + uri: direct:billing + - value: technical + uri: direct:technical + otherwise: + uri: direct:review +---- +==== + +Send a message to any of these equivalent routes with a `ProducerTemplate`: + +[source,java] +---- +template.sendBodyAndHeader("direct:tickets", "Please check this invoice", + "department", "BILLING"); +---- + +[cols="1,2",options="header"] +|=== +|Header value |Destination +|`billing` or `BILLING` |`direct:billing` +|`technical` |`direct:technical` +|`sales` or an absent header |`direct:review` +|=== + +A null or unmatched result uses `otherwise`. Without `otherwise`, the exchange +continues after Switch. Selector failures follow normal Camel error handling and +never select the fallback. Streams are reset after selector evaluation when stream +caching is enabled. Loops and retries that enter Switch again evaluate the selector +again; results are not cached across entries. + +== Composite selectors Review Comment: Please remove the composite section (and regenerate the catalog copy). ########## components/camel-ai/camel-semantic/src/test/java/org/apache/camel/semantic/SemanticEipTest.java: ########## @@ -74,6 +74,10 @@ public SemanticResult evaluate(SemanticQuestion question, Object state) { "unfinished", question("unfinished", SemanticQuestion.Type.BOOLEAN), "urgency", question("urgency", SemanticQuestion.Type.SCORE))); + from("direct:switch").doSwitch().language("semantic", "refs:department,actionable") Review Comment: Please drop this with the composite form (and the new row in `semantic-language.adoc`); the scalar switch doesn't need anything in camel-semantic. ########## core/camel-core-model/src/main/java/org/apache/camel/model/SwitchDefinition.java: ########## @@ -0,0 +1,260 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlTransient; +import jakarta.xml.bind.annotation.XmlType; + +import org.apache.camel.Expression; +import org.apache.camel.NamedNode; +import org.apache.camel.builder.ExpressionClause; +import org.apache.camel.model.language.ExpressionDefinition; +import org.apache.camel.spi.Metadata; + +/** Routes a message to one fixed endpoint using a literal lookup table. */ +@Metadata(firstVersion = "4.23.0", label = "eip,routing", + description = "Evaluates a selector once and dispatches to a fixed endpoint by literal scalar or composite values") +@XmlRootElement(name = "switch") +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(propOrder = { "selector", "keys", "cases", "otherwise" }) +public class SwitchDefinition extends NoOutputDefinition<SwitchDefinition> { + @XmlElement(required = true) + @Metadata(required = true, + description = "Expression evaluated once per entry. Returns a scalar, or a map when keys are configured.") + private ExpressionSubElementDefinition selector; + @XmlElement(name = "keys") + @Metadata(description = "Exact map field names forming a composite key. Additional result fields are ignored.") + private List<String> keys = new ArrayList<>(); + @XmlElement(name = "case") + @Metadata(description = "Literal cases. Duplicate combinations are rejected at startup.") + private List<SwitchCaseDefinition> cases = new ArrayList<>(); + @XmlElement + @Metadata(description = "Fixed fallback URI for null or unmatched selector results. Without a fallback processing continues.") + private SwitchOtherwiseDefinition otherwise; + @XmlTransient + private ToDefinition otherwiseDefinition; + + public SwitchDefinition() { + } + + public SwitchDefinition(Expression selector) { + this.selector = new ExpressionSubElementDefinition(ExpressionNodeHelper.toExpressionDefinition(selector)); + } + + protected SwitchDefinition(SwitchDefinition source) { + super(source); + this.selector = source.selector != null ? source.selector.copyDefinition() : null; + this.keys = new ArrayList<>(source.keys); + this.otherwise = source.otherwise != null ? source.otherwise.copyDefinition() : null; + for (SwitchCaseDefinition c : source.cases) { + SwitchCaseDefinition copy = c.copyDefinition(); + copy.setParent(this); + cases.add(copy); + } + } + + @Override + public SwitchDefinition copyDefinition() { + return new SwitchDefinition(this); + } + + public ExpressionSubElementDefinition getSelector() { + preCreateProcessor(); Review Comment: Please avoid changing the model inside a getter; call `preCreateProcessor()` from the reifier instead. ########## core/camel-core-model/src/main/java/org/apache/camel/model/SwitchDefinition.java: ########## @@ -0,0 +1,260 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlTransient; +import jakarta.xml.bind.annotation.XmlType; + +import org.apache.camel.Expression; +import org.apache.camel.NamedNode; +import org.apache.camel.builder.ExpressionClause; +import org.apache.camel.model.language.ExpressionDefinition; +import org.apache.camel.spi.Metadata; + +/** Routes a message to one fixed endpoint using a literal lookup table. */ +@Metadata(firstVersion = "4.23.0", label = "eip,routing", + description = "Evaluates a selector once and dispatches to a fixed endpoint by literal scalar or composite values") +@XmlRootElement(name = "switch") +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(propOrder = { "selector", "keys", "cases", "otherwise" }) +public class SwitchDefinition extends NoOutputDefinition<SwitchDefinition> { + @XmlElement(required = true) + @Metadata(required = true, + description = "Expression evaluated once per entry. Returns a scalar, or a map when keys are configured.") + private ExpressionSubElementDefinition selector; + @XmlElement(name = "keys") + @Metadata(description = "Exact map field names forming a composite key. Additional result fields are ignored.") + private List<String> keys = new ArrayList<>(); + @XmlElement(name = "case") + @Metadata(description = "Literal cases. Duplicate combinations are rejected at startup.") + private List<SwitchCaseDefinition> cases = new ArrayList<>(); + @XmlElement + @Metadata(description = "Fixed fallback URI for null or unmatched selector results. Without a fallback processing continues.") + private SwitchOtherwiseDefinition otherwise; Review Comment: Design question: the plan had `otherwise` as a uri attribute on `<switch>`. An attribute wouldn't clash with a case literal named "otherwise" either. The element does allow YAML `uri`+`parameters` on the fallback, which may be a good reason to keep it — let's decide explicitly. ########## dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlSchemaMojo.java: ########## @@ -172,6 +172,16 @@ protected void generate() throws MojoFailureException { postProcessInheritance(inheritedDefinitions, inlineDefinitions); } + // Switch's YAML shorthand is one named, typed scalar per list entry. Review Comment: This special-case (and the matching hacks in `model-yaml-writer.vm`) only exists for the composite form; please drop it. ########## dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/SwitchValueDefinitionDeserializer.java: ########## @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.dsl.yaml.deserializers; + +import java.math.BigDecimal; + +import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver; +import org.apache.camel.dsl.yaml.common.YamlDeserializerSupport; +import org.apache.camel.dsl.yaml.common.exception.YamlDeserializationException; +import org.apache.camel.model.SwitchValueDefinition; +import org.apache.camel.spi.annotations.YamlType; +import org.snakeyaml.engine.v2.api.ConstructNode; +import org.snakeyaml.engine.v2.nodes.MappingNode; +import org.snakeyaml.engine.v2.nodes.Node; +import org.snakeyaml.engine.v2.nodes.NodeTuple; +import org.snakeyaml.engine.v2.nodes.ScalarNode; +import org.snakeyaml.engine.v2.nodes.Tag; + +@YamlType(types = SwitchValueDefinition.class, order = YamlDeserializerResolver.ORDER_DEFAULT) +public class SwitchValueDefinitionDeserializer extends YamlDeserializerSupport implements ConstructNode { Review Comment: With the composite form removed this hand-written deserializer (and its banned-definition entry) can go, so YAML stays generated and isomorphic with XML. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
