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