X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-codec-gson%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fcodec%2Fgson%2FCompositeNodeDataWithSchema.java;h=4d40db27f78c2b48cf7611659e46610619156b9d;hb=b52c1ffb0df2b84665b4d222166a3e4cdb8427bb;hp=83d715cefe20f973d7a466d2d2d741529bb110e4;hpb=d0d16d8daa03bb9d1651af08c3751c49d856ac17;p=yangtools.git diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/CompositeNodeDataWithSchema.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/CompositeNodeDataWithSchema.java index 83d715cefe..4d40db27f7 100644 --- a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/CompositeNodeDataWithSchema.java +++ b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/CompositeNodeDataWithSchema.java @@ -7,168 +7,159 @@ */ package org.opendaylight.yangtools.yang.data.codec.gson; +import com.google.common.base.Preconditions; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Map.Entry; -import java.util.Set; - -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.api.schema.stream.SchemaAwareNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils; import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; -import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; -import org.opendaylight.yangtools.yang.model.api.ChoiceNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.YangModeledAnyXmlSchemaNode; +/** + * A node which is composed of multiple simpler nodes. + */ class CompositeNodeDataWithSchema extends AbstractNodeDataWithSchema { /** * nodes which were added to schema via augmentation and are present in data input */ - protected Map> augmentationsToChild = new HashMap<>(); + private final Multimap augmentationsToChild = ArrayListMultimap.create(); /** - * remaining data nodes (which aren't added via augment). Every of them should have the same QName + * remaining data nodes (which aren't added via augment). Every of one them should have the same QName. */ - protected List childs = new ArrayList<>(); + private final List children = new ArrayList<>(); public CompositeNodeDataWithSchema(final DataSchemaNode schema) { super(schema); } - public AbstractNodeDataWithSchema addSimpleChild(final DataSchemaNode schema) { - SimpleNodeDataWithSchema newChild = null; - if (schema instanceof LeafSchemaNode) { - newChild = new LeafNodeDataWithSchema(schema); - } else if (schema instanceof AnyXmlSchemaNode) { - newChild = new AnyXmlNodeDataWithSchema(schema); + public AbstractNodeDataWithSchema addChild(final Deque schemas) { + Preconditions.checkArgument(!schemas.isEmpty(), "Expecting at least one schema"); + + // Pop the first node... + final DataSchemaNode schema = schemas.pop(); + if (schemas.isEmpty()) { + // Simple, direct node + return addChild(schema); } - if (newChild != null) { + // The choice/case mess, reuse what we already popped + final DataSchemaNode choiceCandidate = schema; + Preconditions.checkArgument(choiceCandidate instanceof ChoiceSchemaNode, + "Expected node of type ChoiceNode but was %s", choiceCandidate.getClass().getSimpleName()); + final ChoiceSchemaNode choiceNode = (ChoiceSchemaNode) choiceCandidate; - AugmentationSchema augSchema = null; - if (schema.isAugmenting()) { - augSchema = findCorrespondingAugment(getSchema(), schema); - } - if (augSchema != null) { - addChildToAugmentation(augSchema, newChild); - } else { - addChild(newChild); - } - return newChild; - } - return null; - } + final DataSchemaNode caseCandidate = schemas.pop(); + Preconditions.checkArgument(caseCandidate instanceof ChoiceCaseNode, + "Expected node of type ChoiceCaseNode but was %s", caseCandidate.getClass().getSimpleName()); + final ChoiceCaseNode caseNode = (ChoiceCaseNode) caseCandidate; - private void addChildToAugmentation(final AugmentationSchema augSchema, final AbstractNodeDataWithSchema newChild) { - List childsInAugment = augmentationsToChild.get(augSchema); - if (childsInAugment == null) { - childsInAugment = new ArrayList<>(); - augmentationsToChild.put(augSchema, childsInAugment); + AugmentationSchema augSchema = null; + if (choiceCandidate.isAugmenting()) { + augSchema = SchemaUtils.findCorrespondingAugment(getSchema(), choiceCandidate); } - childsInAugment.add(newChild); - } - public AbstractNodeDataWithSchema addChild(final Deque schemas) { - if (schemas.size() == 1) { - final DataSchemaNode childDataSchemaNode = schemas.pop(); - return addChild(childDataSchemaNode); + // looking for existing choice + final Collection childNodes; + if (augSchema != null) { + childNodes = augmentationsToChild.get(augSchema); } else { - DataSchemaNode choiceCandidate = schemas.pop(); - DataSchemaNode caseCandidate = schemas.pop(); - ChoiceNode choiceNode = null; - ChoiceCaseNode caseNode = null; - if (choiceCandidate instanceof ChoiceNode) { - choiceNode = (ChoiceNode) choiceCandidate; - } else { - throw new IllegalArgumentException("Awaited node of type ChoiceNode but was " - + choiceCandidate.getClass().getSimpleName()); - } - - if (caseCandidate instanceof ChoiceCaseNode) { - caseNode = (ChoiceCaseNode) caseCandidate; - } else { - throw new IllegalArgumentException("Awaited node of type ChoiceCaseNode but was " - + caseCandidate.getClass().getSimpleName()); - } + childNodes = children; + } - AugmentationSchema augSchema = null; - if (choiceCandidate.isAugmenting()) { - augSchema = findCorrespondingAugment(getSchema(), choiceCandidate); - } + CompositeNodeDataWithSchema caseNodeDataWithSchema = findChoice(childNodes, choiceCandidate, caseCandidate); + if (caseNodeDataWithSchema == null) { + ChoiceNodeDataWithSchema choiceNodeDataWithSchema = new ChoiceNodeDataWithSchema(choiceNode); + childNodes.add(choiceNodeDataWithSchema); + caseNodeDataWithSchema = choiceNodeDataWithSchema.addCompositeChild(caseNode); + } - // looking for existing choice - List childNodes = Collections.emptyList(); - if (augSchema != null) { - childNodes = augmentationsToChild.get(augSchema); - } else { - childNodes = childs; - } + return caseNodeDataWithSchema.addChild(schemas); + } - CompositeNodeDataWithSchema caseNodeDataWithSchema = findChoice(childNodes, choiceCandidate, caseCandidate); - if (caseNodeDataWithSchema == null) { - ChoiceNodeDataWithSchema choiceNodeDataWithSchema = new ChoiceNodeDataWithSchema(choiceNode); - addChild(choiceNodeDataWithSchema); - caseNodeDataWithSchema = choiceNodeDataWithSchema.addCompositeChild(caseNode); + private AbstractNodeDataWithSchema addSimpleChild(final DataSchemaNode schema) { + SimpleNodeDataWithSchema newChild = null; + if (schema instanceof LeafSchemaNode) { + newChild = new LeafNodeDataWithSchema(schema); + } else if (schema instanceof AnyXmlSchemaNode) { + // YangModeledAnyXmlSchemaNode is handled by addCompositeChild method. + if (schema instanceof YangModeledAnyXmlSchemaNode) { + return null; } - - return caseNodeDataWithSchema.addChild(schemas); + newChild = new AnyXmlNodeDataWithSchema(schema); + } else { + return null; } + AugmentationSchema augSchema = null; + if (schema.isAugmenting()) { + augSchema = SchemaUtils.findCorrespondingAugment(getSchema(), schema); + } + if (augSchema != null) { + augmentationsToChild.put(augSchema, newChild); + } else { + addChild(newChild); + } + return newChild; } - private CaseNodeDataWithSchema findChoice(final List childNodes, final DataSchemaNode choiceCandidate, - final DataSchemaNode caseCandidate) { - if (childNodes == null) { - return null; - } - for (AbstractNodeDataWithSchema nodeDataWithSchema : childNodes) { - if (nodeDataWithSchema instanceof ChoiceNodeDataWithSchema - && nodeDataWithSchema.getSchema().getQName().equals(choiceCandidate.getQName())) { - CaseNodeDataWithSchema casePrevious = ((ChoiceNodeDataWithSchema) nodeDataWithSchema).getCase(); - if (casePrevious.getSchema().getQName() != caseCandidate.getQName()) { - throw new IllegalArgumentException("Data from case " + caseCandidate.getQName() - + " are specified but other data from case " + casePrevious.getSchema().getQName() - + " were specified erlier. Data aren't from the same case."); + private static CaseNodeDataWithSchema findChoice(final Collection childNodes, + final DataSchemaNode choiceCandidate, final DataSchemaNode caseCandidate) { + if (childNodes != null) { + for (AbstractNodeDataWithSchema nodeDataWithSchema : childNodes) { + if (nodeDataWithSchema instanceof ChoiceNodeDataWithSchema + && nodeDataWithSchema.getSchema().getQName().equals(choiceCandidate.getQName())) { + CaseNodeDataWithSchema casePrevious = ((ChoiceNodeDataWithSchema) nodeDataWithSchema).getCase(); + + Preconditions.checkArgument(casePrevious.getSchema().getQName().equals(caseCandidate.getQName()), + "Data from case %s are specified but other data from case %s were specified erlier. Data aren't from the same case.", + caseCandidate.getQName(), casePrevious.getSchema().getQName()); + + return casePrevious; } - return casePrevious; } } return null; } - public AbstractNodeDataWithSchema addCompositeChild(final DataSchemaNode schema) { - CompositeNodeDataWithSchema newChild; + AbstractNodeDataWithSchema addCompositeChild(final DataSchemaNode schema) { + final CompositeNodeDataWithSchema newChild; + if (schema instanceof ListSchemaNode) { newChild = new ListNodeDataWithSchema(schema); } else if (schema instanceof LeafListSchemaNode) { newChild = new LeafListNodeDataWithSchema(schema); } else if (schema instanceof ContainerSchemaNode) { newChild = new ContainerNodeDataWithSchema(schema); + } else if (schema instanceof YangModeledAnyXmlSchemaNode) { + newChild = new YangModeledAnyXmlNodeDataWithSchema((YangModeledAnyXmlSchemaNode)schema); } else { newChild = new CompositeNodeDataWithSchema(schema); } + addCompositeChild(newChild); return newChild; } - public void addCompositeChild(final CompositeNodeDataWithSchema newChild) { - AugmentationSchema augSchema = findCorrespondingAugment(getSchema(), newChild.getSchema()); + void addCompositeChild(final CompositeNodeDataWithSchema newChild) { + AugmentationSchema augSchema = SchemaUtils.findCorrespondingAugment(getSchema(), newChild.getSchema()); if (augSchema != null) { - addChildToAugmentation(augSchema, newChild); + augmentationsToChild.put(augSchema, newChild); } else { addChild(newChild); } @@ -180,55 +171,34 @@ class CompositeNodeDataWithSchema extends AbstractNodeDataWithSchema { } public void addChild(final AbstractNodeDataWithSchema newChild) { - childs.add(newChild); + children.add(newChild); } /** - * Tries to find in {@code parent} which is dealed as augmentation target node with QName as {@code child}. If such - * node is found then it is returned, else null. + * Return a hint about how may children we are going to generate. + * @return Size of currently-present node list. */ - protected AugmentationSchema findCorrespondingAugment(final DataSchemaNode parent, final DataSchemaNode child) { - if (parent instanceof AugmentationTarget) { - for (AugmentationSchema augmentation : ((AugmentationTarget) parent).getAvailableAugmentations()) { - DataSchemaNode childInAugmentation = augmentation.getDataChildByName(child.getQName()); - if (childInAugmentation != null) { - return augmentation; - } - } - } - return null; + protected final int childSizeHint() { + return children.size(); } @Override - protected void writeToStream(final NormalizedNodeStreamWriter nnStreamWriter) throws IOException { - for (AbstractNodeDataWithSchema child : childs) { - child.writeToStream(nnStreamWriter); + public void write(final SchemaAwareNormalizedNodeStreamWriter writer) throws IOException { + for (AbstractNodeDataWithSchema child : children) { + child.write(writer); } - for (Entry> augmentationToChild : augmentationsToChild.entrySet()) { - - final List childsFromAgumentation = augmentationToChild.getValue(); - + for (Entry> augmentationToChild : augmentationsToChild.asMap().entrySet()) { + final Collection childsFromAgumentation = augmentationToChild.getValue(); if (!childsFromAgumentation.isEmpty()) { - nnStreamWriter.startAugmentationNode(toAugmentationIdentifier(augmentationToChild)); + // FIXME: can we get the augmentation schema? + writer.startAugmentationNode(SchemaUtils.getNodeIdentifierForAugmentation(augmentationToChild.getKey())); for (AbstractNodeDataWithSchema nodeDataWithSchema : childsFromAgumentation) { - nodeDataWithSchema.writeToStream(nnStreamWriter); + nodeDataWithSchema.write(writer); } - nnStreamWriter.endNode(); + writer.endNode(); } } } - - private static AugmentationIdentifier toAugmentationIdentifier( - final Entry> augmentationToChild) { - Collection nodes = augmentationToChild.getKey().getChildNodes(); - Set nodesQNames = new HashSet<>(); - for (DataSchemaNode node : nodes) { - nodesQNames.add(node.getQName()); - } - - return new AugmentationIdentifier(nodesQNames); - } - }