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