Add ModuleNameNamespaceContext
[yangtools.git] / yang / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / BiMapYangNamespaceContext.java
1 /*
2  * Copyright (c) 2019 Pantheon Technologies, s.r.o.  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.common;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.annotations.Beta;
14 import com.google.common.base.MoreObjects;
15 import com.google.common.collect.BiMap;
16 import com.google.common.collect.ImmutableBiMap;
17 import com.google.common.collect.ImmutableBiMap.Builder;
18 import java.io.DataInput;
19 import java.io.DataOutput;
20 import java.io.IOException;
21 import java.util.Map.Entry;
22 import java.util.Objects;
23 import java.util.Optional;
24 import org.opendaylight.yangtools.concepts.WritableObject;
25
26 /**
27  * A BiMap-based implementation of {@link YangNamespaceContext}.
28  *
29  * @author Robert Varga
30  */
31 @Beta
32 public final class BiMapYangNamespaceContext implements YangNamespaceContext, WritableObject {
33     private static final long serialVersionUID = 1L;
34
35     private final ImmutableBiMap<String, QNameModule> mapping;
36     private final QNameModule defaultNamespace;
37
38     public BiMapYangNamespaceContext(final BiMap<String, QNameModule> mapping) {
39         this(mapping, null);
40     }
41
42     public BiMapYangNamespaceContext(final BiMap<String, QNameModule> mapping,
43             final QNameModule defaultNamespace) {
44         this.defaultNamespace = defaultNamespace;
45         this.mapping = ImmutableBiMap.copyOf(mapping);
46         if (defaultNamespace != null) {
47             checkArgument(this.mapping.containsValue(defaultNamespace),
48                 "Mapping %s does not contain default namespace %s", this.mapping, defaultNamespace);
49         }
50     }
51
52     @Override
53     public Optional<QNameModule> getDefaultNamespace() {
54         return Optional.ofNullable(defaultNamespace);
55     }
56
57     @Override
58     public Optional<QNameModule> findNamespaceForPrefix(final String prefix) {
59         return Optional.ofNullable(mapping.get(requireNonNull(prefix)));
60     }
61
62     @Override
63     public Optional<String> findPrefixForNamespace(final QNameModule namespace) {
64         return Optional.ofNullable(mapping.inverse().get(requireNonNull(namespace)));
65     }
66
67     @Override
68     public void writeTo(final DataOutput out) throws IOException {
69         if (defaultNamespace != null) {
70             out.writeBoolean(true);
71             defaultNamespace.writeTo(out);
72         } else {
73             out.writeBoolean(false);
74         }
75
76         out.writeInt(mapping.size());
77         for (Entry<String, QNameModule> entry : mapping.entrySet()) {
78             out.writeUTF(entry.getKey());
79             entry.getValue().writeTo(out);
80         }
81     }
82
83     public static BiMapYangNamespaceContext readFrom(final DataInput in) throws IOException {
84         final boolean haveDefault = in.readBoolean();
85         final QNameModule defaultNamespace = haveDefault ? QNameModule.readFrom(in) : null;
86         final int size = in.readInt();
87         final Builder<String, QNameModule> builder = ImmutableBiMap.builder();
88         for (int i = 0; i < size; ++i) {
89             final String prefix = in.readUTF();
90             final QNameModule namespace = QNameModule.readFrom(in);
91             builder.put(prefix, namespace);
92         }
93
94         return new BiMapYangNamespaceContext(builder.build(), defaultNamespace);
95     }
96
97     @Override
98     public int hashCode() {
99         return Objects.hash(defaultNamespace, mapping);
100     }
101
102     @Override
103     public boolean equals(final Object obj) {
104         if (this == obj) {
105             return true;
106         }
107         if (!(obj instanceof BiMapYangNamespaceContext)) {
108             return false;
109         }
110         final BiMapYangNamespaceContext other = (BiMapYangNamespaceContext) obj;
111         return defaultNamespace.equals(other.defaultNamespace) && mapping.equals(other.mapping);
112     }
113
114     @Override
115     public String toString() {
116         return MoreObjects.toStringHelper(this).add("defaultNamespace", defaultNamespace).add("mapping", mapping)
117                 .toString();
118     }
119 }