31d95bfe34b542d26bbb8c7cc5e34318ca8c5305
[yangtools.git] / yang / yang-data-util / src / main / java / org / opendaylight / yangtools / yang / data / util / AbstractNamespaceCodec.java
1 /*
2  * Copyright (c) 2014 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.data.util;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.base.Splitter;
12 import java.net.URI;
13 import java.util.Iterator;
14 import javax.annotation.Nonnull;
15 import javax.annotation.Nullable;
16 import org.opendaylight.yangtools.yang.common.QName;
17
18 abstract class AbstractNamespaceCodec {
19     private static final Splitter COLON_SPLITTER = Splitter.on(':');
20
21     /**
22      * Return string prefix for a particular namespace, allocating a new one if necessary.
23      *
24      * @param namespace Namespace to map
25      * @return Allocated unique prefix, or null if the prefix cannot be mapped.
26      */
27     @Nullable protected abstract String prefixForNamespace(@Nonnull URI namespace);
28
29     /**
30      * Create a QName for a prefix and local name.
31      *
32      * @param prefix Prefix for namespace
33      * @param localName local name
34      * @return QName
35      * @throws IllegalArgumentException if the prefix cannot be resolved
36      */
37     @Nullable protected abstract QName createQName(@Nonnull String prefix, @Nonnull String localName);
38
39     private static String getIdAndPrefixAsStr(final String pathPart) {
40         int predicateStartIndex = pathPart.indexOf('[');
41         return predicateStartIndex == -1 ? pathPart : pathPart.substring(0, predicateStartIndex);
42     }
43
44     protected final StringBuilder appendQName(final StringBuilder sb, final QName qname) {
45         final String prefix = prefixForNamespace(qname.getNamespace());
46         Preconditions.checkArgument(prefix != null, "Failed to map QName {}", qname);
47         sb.append(prefix);
48         sb.append(':');
49         sb.append(qname.getLocalName());
50         return sb;
51     }
52
53     protected final QName parseQName(final String str) {
54         final String xPathPartTrimmed = getIdAndPrefixAsStr(str).trim();
55         final Iterator<String> it = COLON_SPLITTER.split(xPathPartTrimmed).iterator();
56
57         // Empty string
58         if (!it.hasNext()) {
59             return null;
60         }
61
62
63         final String first = it.next().trim();
64         if (first.isEmpty()) {
65             return null;
66         }
67
68         final String identifier;
69         final String prefix;
70         if (it.hasNext()) {
71             // It is "prefix:value"
72             prefix = first;
73             identifier = it.next().trim();
74         } else {
75             prefix = "";
76             identifier = first;
77         }
78         if (identifier.isEmpty()) {
79             return null;
80         }
81
82         return createQName(prefix, identifier);
83     }
84 }