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.impl.codec.xml;
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.BiMap;
13 import com.google.common.collect.HashBiMap;
18 import javax.xml.XMLConstants;
19 import javax.xml.namespace.NamespaceContext;
22 // 32 characters, carefully chosen
23 private static final String LOOKUP = "abcdefghiknoprstABCDEFGHIKNOPRST";
24 private static final int MASK = 0x1f;
25 private static final int SHIFT = 5;
27 private int counter = 0;
29 // BiMap to make values lookup faster
30 private final BiMap<URI, String> prefixes = HashBiMap.create();
31 private final NamespaceContext context;
37 RandomPrefix(final NamespaceContext context) {
38 this.context = Preconditions.checkNotNull(context);
41 Iterable<Map.Entry<URI, String>> getPrefixes() {
42 return prefixes.entrySet();
45 String encodePrefix(final URI namespace) {
46 String prefix = prefixes.get(namespace);
52 prefix = encode(counter);
54 } while (alreadyUsedPrefix(prefix));
56 prefixes.put(namespace, prefix);
60 private boolean alreadyUsedPrefix(final String prefix) {
61 if (context == null) {
65 final String str = context.getNamespaceURI(prefix);
66 return !XMLConstants.NULL_NS_URI.equals(str);
70 static int decode(final String str) {
72 for (char c : str.toCharArray()) {
73 int idx = LOOKUP.indexOf(c);
74 Preconditions.checkArgument(idx != -1, "Invalid string %s", str);
75 ret = (ret << SHIFT) + idx;
82 static String encode(int num) {
83 final StringBuilder sb = new StringBuilder();
86 sb.append(LOOKUP.charAt(num & MASK));
90 return sb.reverse().toString();