*/
package org.opendaylight.yangtools.yang.data.util;
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Verify.verify;
+
import java.io.IOException;
-import java.util.Collection;
import java.util.HashMap;
-import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.rfc7952.data.api.StreamWriterMetadataExtension;
+import org.opendaylight.yangtools.util.ImmutableMapTemplate;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
* <p>
* Represents a YANG list entry node.
*/
-public class ListEntryNodeDataWithSchema extends CompositeNodeDataWithSchema {
+public abstract class ListEntryNodeDataWithSchema extends AbstractMountPointDataWithSchema<ListSchemaNode> {
+ private static final class Keyed extends ListEntryNodeDataWithSchema {
+ private final Map<QName, SimpleNodeDataWithSchema<?>> keyValues = new HashMap<>();
+ // This template results in Maps in schema definition order
+ private final ImmutableMapTemplate<QName> predicateTemplate;
- private final Map<QName, SimpleNodeDataWithSchema> qnameToKeys = new HashMap<>();
+ Keyed(final ListSchemaNode schema, final List<QName> keyDef) {
+ super(schema);
+ predicateTemplate = ImmutableMapTemplate.ordered(keyDef);
+ }
- public ListEntryNodeDataWithSchema(final DataSchemaNode schema) {
- super(schema);
- }
+ @Override
+ public void addChild(final AbstractNodeDataWithSchema<?> newChild) {
+ final DataSchemaNode childSchema = newChild.getSchema();
+ if (childSchema instanceof LeafSchemaNode) {
+ final QName childName = childSchema.getQName();
+ if (predicateTemplate.keySet().contains(childName)) {
+ verify(newChild instanceof SimpleNodeDataWithSchema);
+ keyValues.put(childName, (SimpleNodeDataWithSchema<?>)newChild);
+ }
+ }
+ super.addChild(newChild);
+ }
+
+ @Override
+ public void write(final NormalizedNodeStreamWriter writer, final StreamWriterMetadataExtension metaWriter)
+ throws IOException {
+ writer.nextDataSchemaNode(getSchema());
+ final NodeIdentifierWithPredicates identifier = NodeIdentifierWithPredicates.of(getSchema().getQName(),
+ predicateTemplate.instantiateTransformed(keyValues, (key, node) -> node.getValue()));
- @Override
- public void addChild(final AbstractNodeDataWithSchema newChild) {
- final DataSchemaNode childSchema = newChild.getSchema();
- if (childSchema instanceof LeafSchemaNode && isPartOfKey((LeafSchemaNode) childSchema)) {
- qnameToKeys.put(childSchema.getQName(), (SimpleNodeDataWithSchema)newChild);
+ writer.startMapEntryNode(identifier, childSizeHint());
+ writeMetadata(metaWriter);
+ super.write(writer, metaWriter);
+ writer.endNode();
}
- super.addChild(newChild);
}
- private boolean isPartOfKey(final LeafSchemaNode potentialKey) {
- for (QName qname : ((ListSchemaNode) getSchema()).getKeyDefinition()) {
- if (qname.equals(potentialKey.getQName())) {
- return true;
- }
+ private static final class Unkeyed extends ListEntryNodeDataWithSchema {
+ Unkeyed(final ListSchemaNode schema) {
+ super(schema);
}
- return false;
- }
- @Override
- public void write(final NormalizedNodeStreamWriter writer) throws IOException {
- final Collection<QName> keyDef = ((ListSchemaNode) getSchema()).getKeyDefinition();
- if (keyDef.isEmpty()) {
+ @Override
+ public void write(final NormalizedNodeStreamWriter writer, final StreamWriterMetadataExtension metaWriter)
+ throws IOException {
writer.nextDataSchemaNode(getSchema());
writer.startUnkeyedListItem(provideNodeIdentifier(), childSizeHint());
- super.write(writer);
+ super.write(writer, metaWriter);
writer.endNode();
- return;
}
+ }
- Preconditions.checkState(keyDef.size() == qnameToKeys.size(), "Input is missing some of the keys of %s",
- getSchema().getQName());
-
- // Need to restore schema order...
- final Map<QName, Object> predicates = new LinkedHashMap<>();
- for (QName qname : keyDef) {
- predicates.put(qname, qnameToKeys.get(qname).getValue());
- }
+ ListEntryNodeDataWithSchema(final ListSchemaNode schema) {
+ super(schema);
+ }
- writer.nextDataSchemaNode(getSchema());
- writer.startMapEntryNode(
- new NodeIdentifierWithPredicates(getSchema().getQName(), predicates),
- childSizeHint());
- super.write(writer);
- writer.endNode();
+ public static @NonNull ListEntryNodeDataWithSchema forSchema(final ListSchemaNode schema) {
+ final List<QName> keyDef = schema.getKeyDefinition();
+ return keyDef.isEmpty() ? new Unkeyed(schema) : new Keyed(schema, keyDef);
}
}