/* * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.controller.netconf.cli.reader.impl; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.Collections2; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry; import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext; import org.opendaylight.controller.netconf.cli.io.ConsoleContext; import org.opendaylight.controller.netconf.cli.io.ConsoleIO; import org.opendaylight.controller.netconf.cli.reader.AbstractReader; import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader; import org.opendaylight.controller.netconf.cli.reader.ReadingException; import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class ListEntryReader extends AbstractReader implements GenericListEntryReader { private static final Logger LOG = LoggerFactory.getLogger(ListEntryReader.class); private final CommandArgHandlerRegistry argumentHandlerRegistry; public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry, final SchemaContext schemaContext) { super(console, schemaContext); this.argumentHandlerRegistry = argumentHandlerRegistry; } public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry, final SchemaContext schemaContext, final boolean readConfigNode) { super(console, schemaContext, readConfigNode); this.argumentHandlerRegistry = argumentHandlerRegistry; } @Override public List> readWithContext(final ListSchemaNode listNode) throws IOException, ReadingException { console.formatLn("Submit child nodes for list entry: %s, %s", listNode.getQName().getLocalName(), Collections2.transform(listNode.getChildNodes(), new Function() { @Override public String apply(final DataSchemaNode input) { return input.getQName().getLocalName(); } })); final String listName = listNode.getQName().getLocalName(); final CompositeNodeBuilder compositeNodeBuilder = ImmutableCompositeNode.builder(); compositeNodeBuilder.setQName(listNode.getQName()); final SeparatedNodes separatedChildNodes = SeparatedNodes.separateNodes(listNode, getReadConfigNode()); final List> nodes = readKeys(separatedChildNodes.getKeyNodes()); nodes.addAll(readMandatoryNotKeys(separatedChildNodes.getMandatoryNotKey())); if (!separatedChildNodes.getOthers().isEmpty()) { final Optional readNodesWhichAreNotKey = new DecisionReader().read(console, "Add non-key, non-mandatory nodes to list %s? [Y|N]", listName); if (readNodesWhichAreNotKey.isPresent() && readNodesWhichAreNotKey.get()) { nodes.addAll(readNotKeys(separatedChildNodes.getOthers())); } } if (!nodes.isEmpty()) { compositeNodeBuilder.addAll(nodes); return Collections.> singletonList(compositeNodeBuilder.toInstance()); } else { return Collections.emptyList(); } } private List> readKeys(final Set keys) throws ReadingException, IOException { final List> newNodes = new ArrayList<>(); console.writeLn("Reading keys:"); for (final DataSchemaNode key : keys) { final List> readKey = new LeafReader(console, getSchemaContext(), getReadConfigNode()) .read((LeafSchemaNode) key); if (readKey.size() != 1) { final String message = String.format( "Value for key element %s has to be set. Creation of this entry is canceled.", key.getQName() .getLocalName()); LOG.error(message); throw new ReadingException(message); } newNodes.addAll(readKey); } return newNodes; } private List> readMandatoryNotKeys(final Set mandatoryNotKeys) throws ReadingException, IOException { final List> newNodes = new ArrayList<>(); console.writeLn("Reading mandatory not keys nodes:"); for (final DataSchemaNode mandatoryNode : mandatoryNotKeys) { final List> redValue = argumentHandlerRegistry.getGenericReader(getSchemaContext(), getReadConfigNode()).read(mandatoryNode); if (redValue.isEmpty()) { final String message = String.format( "Value for mandatory element %s has to be set. Creation of this entry is canceled.", mandatoryNode.getQName().getLocalName()); LOG.error(message); throw new ReadingException(message); } newNodes.addAll(redValue); } return newNodes; } private List> readNotKeys(final Set notKeys) throws ReadingException { final List> newNodes = new ArrayList<>(); for (final DataSchemaNode notKey : notKeys) { newNodes.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(), getReadConfigNode()).read( notKey)); } return newNodes; } @Override protected ConsoleContext getContext(final ListSchemaNode schemaNode) { return new BaseConsoleContext(schemaNode) { @Override public Optional getPrompt() { return Optional.of("[entry]"); } }; } }