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