/* * Copyright (c) 2016 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.yangtools.yang.data.util; import java.net.URI; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; public final class ParserStreamUtils { private ParserStreamUtils() { throw new UnsupportedOperationException("Utility class should not be instantiated."); } /** * Returns stack of schema nodes via which it was necessary to pass to get schema node with specified * {@code childName} and {@code namespace} * * @param dataSchemaNode * @param childName * @param namespace * @return stack of schema nodes via which it was passed through. If found schema node is direct child then stack * contains only one node. If it is found under choice and case then stack should contains 2*n+1 element * (where n is number of choices through it was passed) */ public static Deque<DataSchemaNode> findSchemaNodeByNameAndNamespace(final DataSchemaNode dataSchemaNode, final String childName, final URI namespace) { final Deque<DataSchemaNode> result = new ArrayDeque<>(); final List<ChoiceSchemaNode> childChoices = new ArrayList<>(); DataSchemaNode potentialChildNode = null; if (dataSchemaNode instanceof DataNodeContainer) { for (final DataSchemaNode childNode : ((DataNodeContainer) dataSchemaNode).getChildNodes()) { if (childNode instanceof ChoiceSchemaNode) { childChoices.add((ChoiceSchemaNode) childNode); } else { final QName childQName = childNode.getQName(); if (childQName.getLocalName().equals(childName) && childQName.getNamespace().equals(namespace)) { if (potentialChildNode == null || childQName.getRevision().after(potentialChildNode.getQName().getRevision())) { potentialChildNode = childNode; } } } } } if (potentialChildNode != null) { result.push(potentialChildNode); return result; } // try to find data schema node in choice (looking for first match) for (final ChoiceSchemaNode choiceNode : childChoices) { for (final ChoiceCaseNode concreteCase : choiceNode.getCases()) { final Deque<DataSchemaNode> resultFromRecursion = findSchemaNodeByNameAndNamespace(concreteCase, childName, namespace); if (!resultFromRecursion.isEmpty()) { resultFromRecursion.push(concreteCase); resultFromRecursion.push(choiceNode); return resultFromRecursion; } } } return result; } }