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.StmtContext.Mutable;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
25 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
28 * Statement local namespace, which holds direct schema node descendants.
31 public final class ChildSchemaNodeNamespace<D extends DeclaredStatement<QName>, E extends EffectiveStatement<QName, D>>
32 extends NamespaceBehaviour<QName, StmtContext<?, D, E>, ChildSchemaNodeNamespace<D, E>>
33 implements StatementNamespace<QName, D, E> {
35 public ChildSchemaNodeNamespace() {
36 super((Class) ChildSchemaNodeNamespace.class);
40 public StmtContext<?, D, E> get(final QName key) {
41 // TODO Auto-generated method stub
46 public StmtContext<?, D, E> getFrom(final NamespaceStorageNode storage, final QName key) {
47 return globalOrStatementSpecific(storage).getFromLocalStorage(getIdentifier(), key);
51 public Map<QName, StmtContext<?, D, E>> getAllFrom(final NamespaceStorageNode storage) {
52 // TODO Auto-generated method stub
56 @SuppressWarnings("unchecked")
58 public void addTo(final NamespaceStorageNode storage, final QName key, final StmtContext<?, D, E> value) {
59 final StmtContext<?, D, E> prev = globalOrStatementSpecific(storage).putToLocalStorageIfAbsent(
60 ChildSchemaNodeNamespace.class, key, value);
63 throw new SourceException(value.getStatementSourceReference(),
64 "Error in module '%s': cannot add '%s'. Node name collision: '%s' already declared at %s",
65 value.getRoot().getStatementArgument(), key, prev.getStatementArgument(),
66 prev.getStatementSourceReference());
71 * Find statement context identified by interpreting specified {@link SchemaNodeIdentifier} starting at specified
72 * {@link StmtContext}.
74 * @param root Search root context
75 * @param identifier {@link SchemaNodeIdentifier} relative to search root
76 * @return Matching statement context, if present.
77 * @throws NullPointerException if any of the arguments is null
79 public static Optional<StmtContext<?, ?, ?>> findNode(final StmtContext<?, ?, ?> root,
80 final SchemaNodeIdentifier identifier) {
81 final Iterator<QName> iterator = identifier.getPathFromRoot().iterator();
82 if (!iterator.hasNext()) {
83 return Optional.of(root);
86 QName nextPath = iterator.next();
87 @SuppressWarnings("unchecked")
88 Mutable<?, ?, EffectiveStatement<?, ?>> current = (Mutable)root.getFromNamespace(ChildSchemaNodeNamespace.class,
90 if (current == null) {
91 return Optional.ofNullable(tryToFindUnknownStatement(nextPath.getLocalName(),
92 (Mutable<?, ?, EffectiveStatement<?, ?>>) root));
94 while (current != null && iterator.hasNext()) {
95 nextPath = iterator.next();
96 @SuppressWarnings("unchecked")
97 final Mutable<?, ?, EffectiveStatement<?, ?>> nextNodeCtx = (Mutable)current.getFromNamespace(
98 ChildSchemaNodeNamespace.class, nextPath);
99 if (nextNodeCtx == null) {
100 return Optional.ofNullable(tryToFindUnknownStatement(nextPath.getLocalName(), current));
102 current = nextNodeCtx;
104 return Optional.ofNullable(current);
107 @SuppressWarnings("unchecked")
108 static Mutable<?, ?, EffectiveStatement<?, ?>> tryToFindUnknownStatement(final String localName,
109 final Mutable<?, ?, EffectiveStatement<?, ?>> current) {
110 final Collection<? extends StmtContext<?, ?, ?>> unknownSubstatements = StmtContextUtils.findAllSubstatements(
111 current, UnknownStatement.class);
112 for (final StmtContext<?, ?, ?> unknownSubstatement : unknownSubstatements) {
113 if (localName.equals(unknownSubstatement.rawStatementArgument())) {
114 return (Mutable<?, ?, EffectiveStatement<?, ?>>) unknownSubstatement;
120 private static NamespaceStorageNode globalOrStatementSpecific(final NamespaceStorageNode storage) {
121 NamespaceStorageNode current = storage;
122 while (!isLocalOrGlobal(current.getStorageNodeType())) {
123 current = current.getParentNamespaceStorage();
128 private static boolean isLocalOrGlobal(final StorageNodeType type) {
129 return type == StorageNodeType.STATEMENT_LOCAL || type == StorageNodeType.GLOBAL;