/** * Copyright (c) 2015 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.impl.leafref; import java.util.Deque; import java.util.Iterator; import java.util.LinkedList; 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; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaPath; public final class LeafRefUtils { private LeafRefUtils() { throw new UnsupportedOperationException(); } /** * @param leafRefPath leafRefPath * @param contextNodeSchemaPath contextNodeSchemaPath * @param module module * @return LeafRefPath object */ public static LeafRefPath createAbsoluteLeafRefPath( final LeafRefPath leafRefPath, final SchemaPath contextNodeSchemaPath, final Module module) { if (leafRefPath.isAbsolute()) { return leafRefPath; } final Deque<QNameWithPredicate> absoluteLeafRefTargetPathList = schemaPathToXPathQNames( contextNodeSchemaPath, module); final Iterable<QNameWithPredicate> leafRefTargetPathFromRoot = leafRefPath .getPathFromRoot(); final Iterator<QNameWithPredicate> leafRefTgtPathFromRootIterator = leafRefTargetPathFromRoot .iterator(); while (leafRefTgtPathFromRootIterator.hasNext()) { final QNameWithPredicate qname = leafRefTgtPathFromRootIterator.next(); if (qname.equals(QNameWithPredicate.UP_PARENT)) { absoluteLeafRefTargetPathList.removeLast(); } else { absoluteLeafRefTargetPathList.add(qname); } } return LeafRefPath.create(absoluteLeafRefTargetPathList, true); } /** * @param currentNodePath * @param module * @param absoluteLeafRefTargetPathList */ private static Deque<QNameWithPredicate> schemaPathToXPathQNames( final SchemaPath nodePath, final Module module) { final Deque<QNameWithPredicate> xpath = new LinkedList<>(); final Iterator<QName> nodePathIterator = nodePath.getPathFromRoot() .iterator(); DataNodeContainer currenDataNodeContainer = module; while (nodePathIterator.hasNext()) { final QName qname = nodePathIterator.next(); final DataSchemaNode child = currenDataNodeContainer .getDataChildByName(qname); if (child instanceof DataNodeContainer) { if (!(child instanceof ChoiceCaseNode)) { final QNameWithPredicate newQName = new QNameWithPredicateBuilder( qname.getModule(), qname.getLocalName()).build(); xpath.add(newQName); } currenDataNodeContainer = (DataNodeContainer) child; } else if (child instanceof ChoiceSchemaNode) { if (nodePathIterator.hasNext()) { currenDataNodeContainer = ((ChoiceSchemaNode) child) .getCaseNodeByName(nodePathIterator.next()); } else { break; } } else if (child instanceof LeafSchemaNode || child instanceof LeafListSchemaNode) { final QNameWithPredicate newQName = new QNameWithPredicateBuilder( qname.getModule(), qname.getLocalName()).build(); xpath.add(newQName); break; } else if (child == null) { throw new IllegalArgumentException("No child " + qname + " found in node container " + currenDataNodeContainer + " in module " + module.getName()); } else { throw new IllegalStateException( "Illegal schema node type in the path: " + child.getClass()); } } return xpath; } public static LeafRefPath schemaPathToLeafRefPath(final SchemaPath nodePath, final Module module) { final Deque<QNameWithPredicate> xpathQNames = schemaPathToXPathQNames( nodePath, module); return LeafRefPath.create(xpathQNames, true); } }