2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.netconf.cli.reader.impl;
10 import com.google.common.base.Function;
11 import com.google.common.base.Optional;
12 import com.google.common.collect.Collections2;
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.List;
20 import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
21 import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
22 import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
23 import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
24 import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
25 import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
26 import org.opendaylight.controller.netconf.cli.reader.ReadingException;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
30 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
32 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
33 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
34 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
35 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 class ListEntryReader extends AbstractReader<ListSchemaNode> implements GenericListEntryReader<ListSchemaNode> {
43 private static final Logger LOG = LoggerFactory.getLogger(ListEntryReader.class);
45 private final CommandArgHandlerRegistry argumentHandlerRegistry;
47 public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
48 final SchemaContext schemaContext) {
49 super(console, schemaContext);
50 this.argumentHandlerRegistry = argumentHandlerRegistry;
53 public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
54 final SchemaContext schemaContext, final boolean readConfigNode) {
55 super(console, schemaContext, readConfigNode);
56 this.argumentHandlerRegistry = argumentHandlerRegistry;
60 public List<NormalizedNode<?, ?>> readWithContext(final ListSchemaNode listNode) throws IOException, ReadingException {
61 console.formatLn("Submit child nodes for list entry: %s, %s", listNode.getQName().getLocalName(),
62 Collections2.transform(listNode.getChildNodes(), new Function<DataSchemaNode, String>() {
64 public String apply(final DataSchemaNode input) {
65 return input.getQName().getLocalName();
69 final String listName = listNode.getQName().getLocalName();
71 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder =
72 ImmutableMapEntryNodeBuilder.create();
73 // final CompositeNodeBuilder<ImmutableCompositeNode> compositeNodeBuilder = ImmutableCompositeNode.builder();
74 // compositeNodeBuilder.setQName(listNode.getQName());
76 final SeparatedNodes separatedChildNodes = SeparatedNodes.separateNodes(listNode, getReadConfigNode());
78 final List<NormalizedNode<?, ?>> nodes = readKeys(separatedChildNodes.getKeyNodes());
79 final Map<QName, Object> qnameToValues = new HashMap<>();
80 for (NormalizedNode node : nodes) {
81 qnameToValues.put(node.getNodeType(), node.getValue());
83 builder.withNodeIdentifier(new NodeIdentifierWithPredicates(listNode.getQName(), qnameToValues));
85 nodes.addAll(readMandatoryNotKeys(separatedChildNodes.getMandatoryNotKey()));
86 if (!separatedChildNodes.getOthers().isEmpty()) {
87 final Optional<Boolean> readNodesWhichAreNotKey = new DecisionReader().read(console,
88 "Add non-key, non-mandatory nodes to list %s? [Y|N]", listName);
89 if (readNodesWhichAreNotKey.isPresent() && readNodesWhichAreNotKey.get()) {
90 nodes.addAll(readNotKeys(separatedChildNodes.getOthers()));
94 if (!nodes.isEmpty()) {
95 // compositeNodeBuilder.addAll(nodes);
96 builder.withValue((List) nodes);
97 return Collections.<NormalizedNode<?, ?>>singletonList(
98 ImmutableMapNodeBuilder.create()
99 .withNodeIdentifier(new NodeIdentifier(listNode.getQName()))
100 .withChild(builder.build()).build());
101 // return Collections.<DataContainerChild<?, ?>> singletonList(compositeNodeBuilder.toInstance());
103 return Collections.emptyList();
107 private List<NormalizedNode<?, ?>> readKeys(final Set<DataSchemaNode> keys) throws ReadingException, IOException {
108 final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
109 console.writeLn("Reading keys:");
110 for (final DataSchemaNode key : keys) {
111 final List<NormalizedNode<?, ?>> readKey = new LeafReader(console, getSchemaContext(), getReadConfigNode())
112 .read((LeafSchemaNode) key);
113 if (readKey.size() != 1) {
114 final String message = String.format(
115 "Value for key element %s has to be set. Creation of this entry is canceled.", key.getQName()
118 throw new ReadingException(message);
120 newNodes.addAll(readKey);
126 private List<NormalizedNode<?, ?>> readMandatoryNotKeys(final Set<DataSchemaNode> mandatoryNotKeys) throws ReadingException,
128 final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
129 console.writeLn("Reading mandatory not keys nodes:");
131 for (final DataSchemaNode mandatoryNode : mandatoryNotKeys) {
132 final List<NormalizedNode<?, ?>> redValue = argumentHandlerRegistry.getGenericReader(getSchemaContext(),
133 getReadConfigNode()).read(mandatoryNode);
134 if (redValue.isEmpty()) {
135 final String message = String.format(
136 "Value for mandatory element %s has to be set. Creation of this entry is canceled.",
137 mandatoryNode.getQName().getLocalName());
139 throw new ReadingException(message);
141 newNodes.addAll(redValue);
146 private List<NormalizedNode<?, ?>> readNotKeys(final Set<DataSchemaNode> notKeys) throws ReadingException {
147 final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
148 for (final DataSchemaNode notKey : notKeys) {
149 newNodes.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(), getReadConfigNode()).read(
156 protected ConsoleContext getContext(final ListSchemaNode schemaNode) {
157 return new BaseConsoleContext<ListSchemaNode>(schemaNode) {
159 public Optional<String> getPrompt() {
160 return Optional.of("[entry]");