Tag InstanceIdentifier methods with @Nullable/@NonNull
[mdsal.git] / binding / yang-binding / src / main / java / org / opendaylight / yangtools / yang / binding / InstanceIdentifierBuilderImpl.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.binding;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ImmutableList;
12 import com.google.common.collect.Iterables;
13 import java.util.Objects;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.yangtools.util.HashCodeBuilder;
16 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
17 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
18 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
19 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
20
21 final class InstanceIdentifierBuilderImpl<T extends DataObject> implements InstanceIdentifierBuilder<T> {
22     private final ImmutableList.Builder<PathArgument> pathBuilder = ImmutableList.builder();
23     private final HashCodeBuilder<PathArgument> hashBuilder;
24     private final Iterable<? extends PathArgument> basePath;
25     private boolean wildcard = false;
26     private PathArgument arg = null;
27
28     InstanceIdentifierBuilderImpl() {
29         this.hashBuilder = new HashCodeBuilder<>();
30         this.basePath = null;
31     }
32
33     InstanceIdentifierBuilderImpl(final PathArgument item, final Iterable<? extends PathArgument> pathArguments,
34             final int hash, final boolean wildcard) {
35         this.hashBuilder = new HashCodeBuilder<>(hash);
36         this.basePath = pathArguments;
37         this.wildcard = wildcard;
38         this.arg = item;
39     }
40
41     @Override
42     public int hashCode() {
43         return hashBuilder.build();
44     }
45
46     @Override
47     public boolean equals(final Object obj) {
48         if (this == obj) {
49             return true;
50         }
51         if (obj instanceof InstanceIdentifierBuilderImpl) {
52             @SuppressWarnings("unchecked")
53             final InstanceIdentifierBuilderImpl<T> otherBuilder = (InstanceIdentifierBuilderImpl<T>) obj;
54             return wildcard == otherBuilder.wildcard && Objects.equals(basePath, otherBuilder.basePath)
55                     && Objects.equals(arg, otherBuilder.arg)
56                     && Objects.equals(hashBuilder.build(), otherBuilder.hashBuilder.build());
57         }
58         return false;
59     }
60
61     @Override
62     public <N extends ChildOf<? super T>> InstanceIdentifierBuilderImpl<N> child(final Class<N> container) {
63         return addNode(container);
64     }
65
66     @Override
67     public <C extends ChoiceIn<? super T> & DataObject, N extends ChildOf<? super C>> InstanceIdentifierBuilder<N>
68             child(final Class<C> caze, final Class<N> container) {
69         return addWildNode(Item.of(caze, container));
70     }
71
72     @Override
73     public <N extends Identifiable<K> & ChildOf<? super T>, K extends Identifier<N>> InstanceIdentifierBuilderImpl<N>
74             child(final Class<N> listItem, final K listKey) {
75         return addNode(IdentifiableItem.of(listItem, listKey));
76     }
77
78     @Override
79     public <C extends ChoiceIn<? super T> & DataObject, K extends Identifier<N>,
80         N extends Identifiable<K> & ChildOf<? super C>> InstanceIdentifierBuilder<N> child(final Class<C> caze,
81                 final Class<N> listItem, final K listKey) {
82         return addNode(IdentifiableItem.of(caze, listItem, listKey));
83     }
84
85     /**
86      * Build an identifier which refers to a specific augmentation of the current InstanceIdentifier referenced by
87      * the builder.
88      *
89      * @param container Augmentation to be added
90      * @param <N> Augmentation type
91      * @return This builder
92      */
93     @Override
94     public <N extends DataObject & Augmentation<? super T>> InstanceIdentifierBuilderImpl<N> augmentation(
95             final Class<N> container) {
96         return addNode(container);
97     }
98
99     @Override
100     public InstanceIdentifier<T> build() {
101         Preconditions.checkState(arg != null, "No path arguments present");
102
103         final Iterable<PathArgument> pathArguments;
104         if (basePath == null) {
105             pathArguments = pathBuilder.build();
106         } else {
107             pathArguments = Iterables.concat(basePath, pathBuilder.build());
108         }
109
110         return InstanceIdentifier.trustedCreate(arg, pathArguments, hashBuilder.build(), wildcard);
111     }
112
113     <N extends DataObject> @NonNull InstanceIdentifierBuilderImpl<N> addWildNode(final PathArgument newArg) {
114         if (Identifiable.class.isAssignableFrom(newArg.getType())) {
115             wildcard = true;
116         }
117         return addNode(newArg);
118     }
119
120     @SuppressWarnings("unchecked")
121     <N extends DataObject> @NonNull InstanceIdentifierBuilderImpl<N> addNode(final PathArgument newArg) {
122         arg = newArg;
123         hashBuilder.addArgument(newArg);
124         pathBuilder.add(newArg);
125         return (InstanceIdentifierBuilderImpl<N>) this;
126     }
127
128     private <N extends DataObject> @NonNull InstanceIdentifierBuilderImpl<N> addNode(final Class<N> container) {
129         return addWildNode(Item.of(container));
130     }
131 }