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