2 * Copyright (c) 2015 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.yangtools.yang.parser.rfc7950.namespace;
10 import com.google.common.annotations.Beta;
11 import java.util.Collection;
12 import java.util.Iterator;
14 import java.util.Optional;
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
17 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
18 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
19 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
21 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
24 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
27 * Statement local namespace, which holds direct schema node descendants.
30 public final class ChildSchemaNodeNamespace<D extends DeclaredStatement<QName>, E extends EffectiveStatement<QName, D>>
31 extends NamespaceBehaviour<QName, StmtContext<?, D, E>, ChildSchemaNodeNamespace<D, E>>
32 implements StatementNamespace<QName, D, E> {
34 public ChildSchemaNodeNamespace() {
35 super((Class) ChildSchemaNodeNamespace.class);
39 public StmtContext<?, D, E> get(final QName key) {
40 // TODO Auto-generated method stub
45 public StmtContext<?, D, E> getFrom(final NamespaceStorageNode storage, final QName key) {
46 return globalOrStatementSpecific(storage).getFromLocalStorage(getIdentifier(), key);
50 public Map<QName, StmtContext<?, D, E>> getAllFrom(final NamespaceStorageNode storage) {
51 // TODO Auto-generated method stub
55 @SuppressWarnings("unchecked")
57 public void addTo(final NamespaceStorageNode storage, final QName key, final StmtContext<?, D, E> value) {
58 final StmtContext<?, D, E> prev = globalOrStatementSpecific(storage).putToLocalStorageIfAbsent(
59 ChildSchemaNodeNamespace.class, key, value);
62 throw new SourceException(value.getStatementSourceReference(),
63 "Error in module '%s': cannot add '%s'. Node name collision: '%s' already declared at %s",
64 value.getRoot().getStatementArgument(), key, prev.getStatementArgument(),
65 prev.getStatementSourceReference());
70 * Find statement context identified by interpreting specified {@link SchemaNodeIdentifier} starting at specified
71 * {@link StmtContext}.
73 * @param root Search root context
74 * @param identifier {@link SchemaNodeIdentifier} relative to search root
75 * @return Matching statement context, if present.
76 * @throws NullPointerException if any of the arguments is null
78 public static Optional<StmtContext<?, ?, ?>> findNode(final StmtContext<?, ?, ?> root,
79 final SchemaNodeIdentifier identifier) {
80 final Iterator<QName> iterator = identifier.getNodeIdentifiers().iterator();
81 if (!iterator.hasNext()) {
82 return Optional.of(root);
85 QName nextPath = iterator.next();
86 @SuppressWarnings("unchecked")
87 StmtContext<?, ?, ?> current = (StmtContext<?, ?, ?>) root.getFromNamespace(ChildSchemaNodeNamespace.class,
89 if (current == null) {
90 return Optional.ofNullable(tryToFindUnknownStatement(nextPath.getLocalName(), root));
92 while (current != null && iterator.hasNext()) {
93 nextPath = iterator.next();
94 @SuppressWarnings("unchecked")
95 final StmtContext<?, ?, ?> nextNodeCtx = (StmtContext<?, ?, ?>) current.getFromNamespace(
96 ChildSchemaNodeNamespace.class, nextPath);
97 if (nextNodeCtx == null) {
98 return Optional.ofNullable(tryToFindUnknownStatement(nextPath.getLocalName(), current));
100 current = nextNodeCtx;
102 return Optional.ofNullable(current);
105 @SuppressWarnings("unchecked")
106 private static StmtContext<?, ?, ?> tryToFindUnknownStatement(final String localName,
107 final StmtContext<?, ?, ?> current) {
108 final Collection<? extends StmtContext<?, ?, ?>> unknownSubstatements = StmtContextUtils.findAllSubstatements(
109 current, UnknownStatement.class);
110 for (final StmtContext<?, ?, ?> unknownSubstatement : unknownSubstatements) {
111 if (localName.equals(unknownSubstatement.rawStatementArgument())) {
112 return unknownSubstatement;
118 private static NamespaceStorageNode globalOrStatementSpecific(final NamespaceStorageNode storage) {
119 NamespaceStorageNode current = storage;
120 while (!isLocalOrGlobal(current.getStorageNodeType())) {
121 current = current.getParentNamespaceStorage();
126 private static boolean isLocalOrGlobal(final StorageNodeType type) {
127 return type == StorageNodeType.STATEMENT_LOCAL || type == StorageNodeType.GLOBAL;