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 static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
12 import com.google.common.base.Function;
13 import com.google.common.collect.Maps;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.List;
20 import jline.console.completer.Completer;
21 import jline.console.completer.StringsCompleter;
22 import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
23 import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
24 import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
25 import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
26 import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
27 import org.opendaylight.controller.netconf.cli.reader.ReadingException;
28 import org.opendaylight.yangtools.yang.data.api.Node;
29 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
30 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
31 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
32 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
33 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 public class ChoiceReader extends AbstractReader<ChoiceNode> {
41 private static final Logger LOG = LoggerFactory.getLogger(ChoiceReader.class);
43 private final CommandArgHandlerRegistry argumentHandlerRegistry;
45 public ChoiceReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
46 final SchemaContext schemaContext) {
47 super(console, schemaContext);
48 this.argumentHandlerRegistry = argumentHandlerRegistry;
51 public ChoiceReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
52 final SchemaContext schemaContext, final boolean readConfigNode) {
53 super(console, schemaContext, readConfigNode);
54 this.argumentHandlerRegistry = argumentHandlerRegistry;
58 public List<Node<?>> readWithContext(final ChoiceNode choiceNode) throws IOException, ReadingException {
59 final Map<String, ChoiceCaseNode> availableCases = collectAllCases(choiceNode);
60 console.formatLn("Select case for choice %s from: %s", choiceNode.getQName().getLocalName(),
61 formatSet(availableCases.keySet()));
63 ChoiceCaseNode selectedCase = null;
64 final String rawValue = console.read();
65 if (isSkipInput(rawValue)) {
66 return Collections.emptyList();
69 selectedCase = availableCases.get(rawValue);
70 if (selectedCase == null) {
71 final String message = String.format("Incorrect value (%s) for choice %s was selected.", rawValue,
72 choiceNode.getQName().getLocalName());
74 throw new ReadingException(message);
77 return readSelectedCase(selectedCase);
80 protected List<Node<?>> readSelectedCase(final ChoiceCaseNode selectedCase) throws ReadingException {
81 // IF there is a case that contains only one Empty type leaf, create the
82 // leaf without question, since the case was selected
83 if (containsOnlyOneEmptyLeaf(selectedCase)) {
84 final Node<?> newNode = NodeFactory.createImmutableSimpleNode(selectedCase.getChildNodes().iterator()
85 .next().getQName(), null, null);
86 return Collections.<Node<?>> singletonList(newNode);
89 final List<Node<?>> newNodes = new ArrayList<>();
90 for (final DataSchemaNode schemaNode : selectedCase.getChildNodes()) {
91 newNodes.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(), getReadConfigNode()).read(
97 private Object formatSet(final Set<String> values) {
98 final StringBuilder formatedValues = new StringBuilder();
99 for (final String value : values) {
100 formatedValues.append("\n ");
101 formatedValues.append(value);
103 return formatedValues.toString();
106 private boolean containsOnlyOneEmptyLeaf(final ChoiceCaseNode selectedCase) {
107 if (selectedCase.getChildNodes().size() != 1) {
110 final DataSchemaNode next = selectedCase.getChildNodes().iterator().next();
111 if (next instanceof LeafSchemaNode) {
112 final TypeDefinition<?> type = ((LeafSchemaNode) next).getType();
113 if (isEmptyType(type)) {
120 private Map<String, ChoiceCaseNode> collectAllCases(final ChoiceNode schemaNode) {
121 return Maps.uniqueIndex(schemaNode.getCases(), new Function<ChoiceCaseNode, String>() {
123 public String apply(final ChoiceCaseNode input) {
124 return input.getQName().getLocalName();
130 protected ConsoleContext getContext(final ChoiceNode schemaNode) {
131 return new BaseConsoleContext<ChoiceNode>(schemaNode) {
133 public List<Completer> getAdditionalCompleters() {
135 .<Completer> singletonList(new StringsCompleter(collectAllCases(schemaNode).keySet()));