BUG-7052: Move qnameFromArgument to StmtContextUtils
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / StmtNamespaceContext.java
1 /*
2  * Copyright (c) 2015 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.parser.stmt.rfc6020;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.base.Verify;
12 import com.google.common.collect.BiMap;
13 import com.google.common.collect.ImmutableBiMap;
14 import com.google.common.collect.Iterators;
15 import java.util.Iterator;
16 import javax.xml.namespace.NamespaceContext;
17 import org.opendaylight.yangtools.yang.common.QNameModule;
18 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
19 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
20
21 /**
22  * A {@link NamespaceContext} implementation based on the set of imports and local module namespace.
23  *
24  * TODO: this is a useful utility, so should probably move to yang.parser.spi.meta.
25  */
26 final class StmtNamespaceContext implements NamespaceContext {
27     private final StmtContext<?, ?, ?> ctx;
28     private final BiMap<String, String> URIToPrefixMap;
29     private String localNamespaceURI;
30
31     private StmtNamespaceContext(final StmtContext<?, ?, ?> ctx) {
32         this(ctx, ImmutableBiMap.of());
33     }
34
35     private StmtNamespaceContext(final StmtContext<?, ?, ?> ctx, final BiMap<String, String> URIToPrefixMap) {
36         this.ctx = Preconditions.checkNotNull(ctx);
37         this.URIToPrefixMap = ImmutableBiMap.copyOf(Preconditions.checkNotNull(URIToPrefixMap));
38     }
39
40     public static NamespaceContext create(final StmtContext<?, ?, ?> ctx) {
41         return new StmtNamespaceContext(ctx);
42     }
43
44     public static NamespaceContext create(final StmtContext<?, ?, ?> ctx, final BiMap<String, String> URIToPrefixMap) {
45         return new StmtNamespaceContext(ctx, URIToPrefixMap);
46     }
47
48     private String localNamespaceURI() {
49         if (localNamespaceURI == null) {
50             localNamespaceURI = Verify.verifyNotNull(
51                 ctx.getPublicDefinition().getStatementName().getNamespace().toString(),
52                 "Local namespace URI not found in %s", ctx);
53         }
54         return localNamespaceURI;
55     }
56
57     @Override
58     public String getNamespaceURI(final String prefix) {
59         // API-mandated by NamespaceContext
60         Preconditions.checkArgument(prefix != null);
61
62         final String uri = URIToPrefixMap.inverse().get(prefix);
63         if (uri != null) {
64             return uri;
65         }
66
67         if (prefix.isEmpty()) {
68             return localNamespaceURI();
69         }
70
71         final QNameModule module = StmtContextUtils.getModuleQNameByPrefix(ctx, prefix);
72         return module == null ? null : module.getNamespace().toString();
73     }
74
75     @Override
76     public String getPrefix(final String namespaceURI) {
77         // API-mandated by NamespaceContext
78         Preconditions.checkArgument(namespaceURI != null);
79
80         final String prefix = URIToPrefixMap.get(namespaceURI);
81         if (prefix != null) {
82             return prefix;
83         }
84
85         if (localNamespaceURI().equals(namespaceURI)) {
86             return "";
87         }
88         return ctx.getFromNamespace(URIStringToImpPrefix.class, namespaceURI);
89     }
90
91     @Override
92     public Iterator<String> getPrefixes(final String namespaceURI) {
93         // Ensures underlying map remains constant
94         return Iterators.unmodifiableIterator(Iterators.concat(
95                 ctx.getAllFromNamespace(URIStringToImpPrefix.class).values().iterator(),
96                 URIToPrefixMap.values().iterator()));
97     }
98 }