2 * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.model.api.stmt;
10 import static java.util.Objects.requireNonNull;
11 import static org.opendaylight.yangtools.yang.model.api.stmt.DefaultMethodHelpers.filterOptional;
13 import com.google.common.annotations.Beta;
14 import java.util.Arrays;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.NoSuchElementException;
18 import java.util.Optional;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
23 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant;
27 * Interface implemented by all {@link EffectiveStatement}s which can contain a {@code schema tree} child. This tree
28 * can be walked using {@link SchemaNodeIdentifier}, looking up each component of
29 * {@link SchemaNodeIdentifier#getNodeIdentifiers()} using {@link #findSchemaTreeNode(QName)}.
31 * @param <A> Argument type
32 * @param <D> Class representing declared version of this statement.
35 public interface SchemaTreeAwareEffectiveStatement<A, D extends DeclaredStatement<A>> extends EffectiveStatement<A, D> {
37 * Namespace of {@code schema node}s defined within this node.
40 abstract class SchemaTreeNamespace extends EffectiveStatementNamespace<SchemaTreeEffectiveStatement<?>> {
41 private SchemaTreeNamespace() {
42 // Should never be instantiated
47 * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
49 * @param qname Child identifier
50 * @return Schema tree child, or empty
51 * @throws NullPointerException if {@code qname} is null
53 default @NonNull Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final @NonNull QName qname) {
54 return get(SchemaTreeNamespace.class, requireNonNull(qname));
58 * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
60 * @param <E> Effective substatement type
61 * @param type Effective substatement class
62 * @param qname Child identifier
63 * @return Schema tree child, or empty
64 * @throws NullPointerException if any argument is null
66 default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type, final @NonNull QName qname) {
67 return filterOptional(type, findSchemaTreeNode(qname));
71 * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
73 * @param qnames Child identifiers
74 * @return Schema tree child, or empty
75 * @throws NullPointerException if {@code qnames} is null or contains a null element
76 * @throws NoSuchElementException if {@code qnames} is empty
78 default @NonNull Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final @NonNull QName... qnames) {
79 return findSchemaTreeNode(Arrays.asList(qnames));
83 * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
85 * @param <E> Effective substatement type
86 * @param type Effective substatement class
87 * @param qnames Child identifiers
88 * @return Schema tree child, or empty
89 * @throws NullPointerException if any argument is null or if {@code qnames} contains a null element
90 * @throws NoSuchElementException if {@code qnames} is empty
92 default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type, final @NonNull QName... qnames) {
93 return filterOptional(type, findSchemaTreeNode(Arrays.asList(qnames)));
97 * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
99 * @param qnames Child identifiers
100 * @return Schema tree child, or empty
101 * @throws NullPointerException if {@code qnames} is null or contains a null element
102 * @throws NoSuchElementException if {@code qnames} is empty
104 default @NonNull Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final @NonNull List<QName> qnames) {
105 final Iterator<QName> it = qnames.iterator();
106 SchemaTreeAwareEffectiveStatement<?, ?> parent = this;
108 final Optional<SchemaTreeEffectiveStatement<?>> found = parent.findSchemaTreeNode(it.next());
109 if (!it.hasNext() || found.isEmpty()) {
112 final SchemaTreeEffectiveStatement<?> node = found.orElseThrow();
113 if (node instanceof SchemaTreeAwareEffectiveStatement) {
114 parent = (SchemaTreeAwareEffectiveStatement<?, ?>) node;
116 return Optional.empty();
122 * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
124 * @param <E> Effective substatement type
125 * @param type Effective substatement class
126 * @param qnames Child identifiers
127 * @return Schema tree child, or empty
128 * @throws NullPointerException if {@code qnames} is null or contains a null element
129 * @throws NoSuchElementException if {@code qnames} is empty
131 default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type,
132 final @NonNull List<QName> qnames) {
133 return filterOptional(type, findSchemaTreeNode(qnames));
137 * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its
138 * {@link Descendant descendant schema node identifier}.
141 * Default implementation defers to {@link #findSchemaTreeNode(List)}.
143 * @param descendant Descendant schema node identifier
144 * @return Schema tree child, or empty
145 * @throws NullPointerException if {@code descendant} is null
147 default @NonNull Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(
148 final @NonNull Descendant descendant) {
149 return findSchemaTreeNode(descendant.getNodeIdentifiers());
153 * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its
154 * {@link Descendant descendant schema node identifier}.
157 * Default implementation defers to {@link #findSchemaTreeNode(Class, List)}.
159 * @param <E> Effective substatement type
160 * @param type Effective substatement class
161 * @param descendant Descendant schema node identifier
162 * @return Schema tree child, or empty
163 * @throws NullPointerException if {@code descendant} is null
165 default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type,
166 final @NonNull Descendant descendant) {
167 return findSchemaTreeNode(type, descendant.getNodeIdentifiers());