Bug 1698: Updated handling of choice node inside choice node 40/10940/1
authorTony Tkacik <ttkacik@cisco.com>
Tue, 9 Sep 2014 12:18:16 +0000 (14:18 +0200)
committerTony Tkacik <ttkacik@cisco.com>
Tue, 9 Sep 2014 12:20:54 +0000 (14:20 +0200)
As it turned out, Composite Node to Binding codec
had problem with handling situations, where case
was augmented to choice and that case contained
another choice directly on first level.

Updated code to detect this situation and do proper lookup
to find choice in case in choice.

Change-Id: I2c39542520b842857884468dc0dcd28502ff41b3
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/LazyGeneratedCodecRegistry.java
restconf/restconf-util/src/main/java/org/opendaylight/yangtools/restconf/utils/RestconfUtils.java

index f72856e1c11b540c2c6d855ef26b0ab7455a209e..65e80d05843cb5566be494788b2551d6980dd607 100644 (file)
@@ -984,8 +984,21 @@ class LazyGeneratedCodecRegistry implements CodecRegistry, SchemaContextListener
 
         @Override
         protected void adaptForPathImpl(final InstanceIdentifier<?> augTarget, final DataNodeContainer ctxNode) {
-            Optional<ChoiceNode> newChoice = BindingSchemaContextUtils.findInstantiatedChoice(ctxNode, choiceType);
             tryToLoadImplementations();
+            Optional<ChoiceNode> newChoice = BindingSchemaContextUtils.findInstantiatedChoice(ctxNode, choiceType);
+            if(!newChoice.isPresent()) {
+                // Choice is nested inside other choice, so we need to look two levels deep.
+                in_choices: for(DataSchemaNode child : ctxNode.getChildNodes()) {
+                    if(child instanceof ChoiceNode) {
+                        Optional<ChoiceNode> potential = findChoiceInChoiceCases((ChoiceNode) child, choiceType);
+                        if(potential.isPresent()) {
+                            newChoice = potential;
+                            break in_choices;
+                        }
+                    }
+                }
+            }
+
             Preconditions.checkState(newChoice.isPresent(), "BUG: Unable to find instantiated choice node in schema.");
             for (@SuppressWarnings("rawtypes")
             Entry<Class, ChoiceCaseCodecImpl<?>> codec : getImplementations().entrySet()) {
@@ -998,6 +1011,16 @@ class LazyGeneratedCodecRegistry implements CodecRegistry, SchemaContextListener
             }
         }
 
+        private Optional<ChoiceNode> findChoiceInChoiceCases(ChoiceNode choice, Class<?> choiceType) {
+            for(ChoiceCaseNode caze : choice.getCases()) {
+                Optional<ChoiceNode> potential = BindingSchemaContextUtils.findInstantiatedChoice(caze, choiceType);
+                if(potential.isPresent()) {
+                    return potential;
+                }
+            }
+            return Optional.absent();
+        }
+
         @Override
         public String toString() {
             return "DispatchChoiceCodecImpl [choiceType=" + choiceType + "]";
index 8c3d8e94880a88bac967df66ae02c183b6c47d48..6a772f4ae4f30326e1c2b3f7f35891621fcf7728 100644 (file)
@@ -31,10 +31,10 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
@@ -293,7 +293,7 @@ public class RestconfUtils {
             Document doc = builder.parse(inputStream);
             Element rootElement = doc.getDocumentElement();
             Node<?> domNode = XmlDocumentUtils.toDomNode(rootElement, Optional.of(dataSchema),
-                    Optional.<XmlCodecProvider> absent());
+                    Optional.<XmlCodecProvider> absent(), Optional.of(schemaContext));
             DataObject dataObject = mappingService.dataObjectFromDataDom(path, (CompositeNode) domNode); // getDataFromResponse
             return dataObject;
         } catch (DeserializationException e) {