Merge "Distributed Datastore integration with config subsystem Updated with the usage...
[controller.git] / opendaylight / netconf / netconf-cli / src / main / java / org / opendaylight / controller / netconf / cli / reader / impl / ListEntryReader.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.netconf.cli.reader.impl;
9
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.List;
17 import java.util.Set;
18 import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
19 import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
20 import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
21 import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
22 import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
23 import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
24 import org.opendaylight.controller.netconf.cli.reader.ReadingException;
25 import org.opendaylight.yangtools.yang.data.api.Node;
26 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
27 import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
28 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
31 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 class ListEntryReader extends AbstractReader<ListSchemaNode> implements GenericListEntryReader<ListSchemaNode> {
36     private static final Logger LOG = LoggerFactory.getLogger(ListEntryReader.class);
37
38     private final CommandArgHandlerRegistry argumentHandlerRegistry;
39
40     public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
41             final SchemaContext schemaContext) {
42         super(console, schemaContext);
43         this.argumentHandlerRegistry = argumentHandlerRegistry;
44     }
45
46     public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
47             final SchemaContext schemaContext, final boolean readConfigNode) {
48         super(console, schemaContext, readConfigNode);
49         this.argumentHandlerRegistry = argumentHandlerRegistry;
50     }
51
52     @Override
53     public List<Node<?>> readWithContext(final ListSchemaNode listNode) throws IOException, ReadingException {
54         console.formatLn("Submit child nodes for list entry: %s, %s", listNode.getQName().getLocalName(),
55                 Collections2.transform(listNode.getChildNodes(), new Function<DataSchemaNode, String>() {
56                     @Override
57                     public String apply(final DataSchemaNode input) {
58                         return input.getQName().getLocalName();
59                     }
60                 }));
61
62         final String listName = listNode.getQName().getLocalName();
63         final CompositeNodeBuilder<ImmutableCompositeNode> compositeNodeBuilder = ImmutableCompositeNode.builder();
64         compositeNodeBuilder.setQName(listNode.getQName());
65
66         final SeparatedNodes separatedChildNodes = SeparatedNodes.separateNodes(listNode, getReadConfigNode());
67
68         final List<Node<?>> nodes = readKeys(separatedChildNodes.getKeyNodes());
69         nodes.addAll(readMandatoryNotKeys(separatedChildNodes.getMandatoryNotKey()));
70         if (!separatedChildNodes.getOthers().isEmpty()) {
71             final Optional<Boolean> readNodesWhichAreNotKey = new DecisionReader().read(console,
72                     "Add non-key, non-mandatory nodes to list %s? [Y|N]", listName);
73             if (readNodesWhichAreNotKey.isPresent() && readNodesWhichAreNotKey.get()) {
74                 nodes.addAll(readNotKeys(separatedChildNodes.getOthers()));
75             }
76         }
77
78         if (!nodes.isEmpty()) {
79             compositeNodeBuilder.addAll(nodes);
80             return Collections.<Node<?>> singletonList(compositeNodeBuilder.toInstance());
81         } else {
82             return Collections.emptyList();
83         }
84     }
85
86     private List<Node<?>> readKeys(final Set<DataSchemaNode> keys) throws ReadingException, IOException {
87         final List<Node<?>> newNodes = new ArrayList<>();
88         console.writeLn("Reading keys:");
89         for (final DataSchemaNode key : keys) {
90             final List<Node<?>> readKey = new LeafReader(console, getSchemaContext(), getReadConfigNode())
91                     .read((LeafSchemaNode) key);
92             if (readKey.size() != 1) {
93                 final String message = String.format(
94                         "Value for key element %s has to be set. Creation of this entry is canceled.", key.getQName()
95                                 .getLocalName());
96                 LOG.error(message);
97                 throw new ReadingException(message);
98             }
99             newNodes.addAll(readKey);
100         }
101         return newNodes;
102     }
103
104     private List<Node<?>> readMandatoryNotKeys(final Set<DataSchemaNode> mandatoryNotKeys) throws ReadingException,
105             IOException {
106         final List<Node<?>> newNodes = new ArrayList<>();
107         console.writeLn("Reading mandatory not keys nodes:");
108
109         for (final DataSchemaNode mandatoryNode : mandatoryNotKeys) {
110             final List<Node<?>> redValue = argumentHandlerRegistry.getGenericReader(getSchemaContext(),
111                     getReadConfigNode()).read(mandatoryNode);
112             if (redValue.isEmpty()) {
113                 final String message = String.format(
114                         "Value for mandatory element %s has to be set. Creation of this entry is canceled.",
115                         mandatoryNode.getQName().getLocalName());
116                 LOG.error(message);
117                 throw new ReadingException(message);
118             }
119             newNodes.addAll(redValue);
120         }
121         return newNodes;
122     }
123
124     private List<Node<?>> readNotKeys(final Set<DataSchemaNode> notKeys) throws ReadingException {
125         final List<Node<?>> newNodes = new ArrayList<>();
126         for (final DataSchemaNode notKey : notKeys) {
127             newNodes.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(), getReadConfigNode()).read(
128                     notKey));
129         }
130         return newNodes;
131     }
132
133     @Override
134     protected ConsoleContext getContext(final ListSchemaNode schemaNode) {
135         return new BaseConsoleContext<ListSchemaNode>(schemaNode) {
136             @Override
137             public Optional<String> getPrompt() {
138                 return Optional.of("[entry]");
139             }
140         };
141     }
142
143 }