2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.data.util;
10 import com.google.common.base.Preconditions;
11 import com.google.common.base.Splitter;
13 import java.util.Iterator;
14 import javax.annotation.Nonnull;
15 import javax.annotation.Nullable;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.common.QNameModule;
19 abstract class AbstractNamespaceCodec {
20 private static final Splitter COLON_SPLITTER = Splitter.on(':');
23 * Return string prefix for a particular namespace, allocating a new one if necessary.
25 * @param namespace Namespace to map
26 * @return Allocated unique prefix, or null if the prefix cannot be mapped.
28 @Nullable protected abstract String prefixForNamespace(@Nonnull URI namespace);
31 * Create a QName for a prefix and local name.
33 * @param prefix Prefix for namespace
34 * @param localName local name
36 * @throws IllegalArgumentException if the prefix cannot be resolved
38 @Nullable protected abstract QName createQName(@Nonnull String prefix, @Nonnull String localName);
40 private static String getIdAndPrefixAsStr(final String pathPart) {
41 int predicateStartIndex = pathPart.indexOf('[');
42 return predicateStartIndex == -1 ? pathPart : pathPart.substring(0, predicateStartIndex);
45 protected final StringBuilder appendQName(final StringBuilder sb, final QName qname) {
46 final String prefix = prefixForNamespace(qname.getNamespace());
47 Preconditions.checkArgument(prefix != null, "Failed to map QName %s to prefix", qname);
48 sb.append(prefix).append(':').append(qname.getLocalName());
53 * Append a QName, potentially taking into account last QNameModule encountered in the serialized path.
55 * @param sb target StringBuilder
56 * @param qname QName to append
57 * @param lastModule last QNameModule encountered, may be null
58 * @return target StringBuilder
60 protected StringBuilder appendQName(final StringBuilder sb, final QName qname,
61 final @Nullable QNameModule lastModule) {
62 // Covers XML and uncompressed JSON codec
63 return appendQName(sb, qname);
66 protected final QName parseQName(final String str) {
67 final String xPathPartTrimmed = getIdAndPrefixAsStr(str).trim();
68 final Iterator<String> it = COLON_SPLITTER.split(xPathPartTrimmed).iterator();
76 final String first = it.next().trim();
77 if (first.isEmpty()) {
81 final String identifier;
84 // It is "prefix:value"
86 identifier = it.next().trim();
91 if (identifier.isEmpty()) {
95 return createQName(prefix, identifier);