1// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) 2 3package org.xbill.DNS; 4 5import java.util.HashMap; 6 7/** 8 * A utility class for converting between numeric codes and mnemonics 9 * for those codes. Mnemonics are case insensitive. 10 * 11 * @author Brian Wellington 12 */ 13 14class Mnemonic { 15 16private static Integer cachedInts[] = new Integer[64]; 17 18static { 19 for (int i = 0; i < cachedInts.length; i++) { 20 cachedInts[i] = new Integer(i); 21 } 22} 23 24/* Strings are case-sensitive. */ 25static final int CASE_SENSITIVE = 1; 26 27/* Strings will be stored/searched for in uppercase. */ 28static final int CASE_UPPER = 2; 29 30/* Strings will be stored/searched for in lowercase. */ 31static final int CASE_LOWER = 3; 32 33private HashMap strings; 34private HashMap values; 35private String description; 36private int wordcase; 37private String prefix; 38private int max; 39private boolean numericok; 40 41/** 42 * Creates a new Mnemonic table. 43 * @param description A short description of the mnemonic to use when 44 * @param wordcase Whether to convert strings into uppercase, lowercase, 45 * or leave them unchanged. 46 * throwing exceptions. 47 */ 48public 49Mnemonic(String description, int wordcase) { 50 this.description = description; 51 this.wordcase = wordcase; 52 strings = new HashMap(); 53 values = new HashMap(); 54 max = Integer.MAX_VALUE; 55} 56 57/** Sets the maximum numeric value */ 58public void 59setMaximum(int max) { 60 this.max = max; 61} 62 63/** 64 * Sets the prefix to use when converting to and from values that don't 65 * have mnemonics. 66 */ 67public void 68setPrefix(String prefix) { 69 this.prefix = sanitize(prefix); 70} 71 72/** 73 * Sets whether numeric values stored in strings are acceptable. 74 */ 75public void 76setNumericAllowed(boolean numeric) { 77 this.numericok = numeric; 78} 79 80/** 81 * Converts an int into a possibly cached Integer. 82 */ 83public static Integer 84toInteger(int val) { 85 if (val >= 0 && val < cachedInts.length) 86 return (cachedInts[val]); 87 return new Integer(val); 88} 89 90/** 91 * Checks that a numeric value is within the range [0..max] 92 */ 93public void 94check(int val) { 95 if (val < 0 || val > max) { 96 throw new IllegalArgumentException(description + " " + val + 97 "is out of range"); 98 } 99} 100 101/* Converts a String to the correct case. */ 102private String 103sanitize(String str) { 104 if (wordcase == CASE_UPPER) 105 return str.toUpperCase(); 106 else if (wordcase == CASE_LOWER) 107 return str.toLowerCase(); 108 return str; 109} 110 111private int 112parseNumeric(String s) { 113 try { 114 int val = Integer.parseInt(s); 115 if (val >= 0 && val <= max) 116 return val; 117 } 118 catch (NumberFormatException e) { 119 } 120 return -1; 121} 122 123/** 124 * Defines the text representation of a numeric value. 125 * @param val The numeric value 126 * @param string The text string 127 */ 128public void 129add(int val, String str) { 130 check(val); 131 Integer value = toInteger(val); 132 str = sanitize(str); 133 strings.put(str, value); 134 values.put(value, str); 135} 136 137/** 138 * Defines an additional text representation of a numeric value. This will 139 * be used by getValue(), but not getText(). 140 * @param val The numeric value 141 * @param string The text string 142 */ 143public void 144addAlias(int val, String str) { 145 check(val); 146 Integer value = toInteger(val); 147 str = sanitize(str); 148 strings.put(str, value); 149} 150 151/** 152 * Copies all mnemonics from one table into another. 153 * @param val The numeric value 154 * @param string The text string 155 * @throws IllegalArgumentException The wordcases of the Mnemonics do not 156 * match. 157 */ 158public void 159addAll(Mnemonic source) { 160 if (wordcase != source.wordcase) 161 throw new IllegalArgumentException(source.description + 162 ": wordcases do not match"); 163 strings.putAll(source.strings); 164 values.putAll(source.values); 165} 166 167/** 168 * Gets the text mnemonic corresponding to a numeric value. 169 * @param val The numeric value 170 * @return The corresponding text mnemonic. 171 */ 172public String 173getText(int val) { 174 check(val); 175 String str = (String) values.get(toInteger(val)); 176 if (str != null) 177 return str; 178 str = Integer.toString(val); 179 if (prefix != null) 180 return prefix + str; 181 return str; 182} 183 184/** 185 * Gets the numeric value corresponding to a text mnemonic. 186 * @param str The text mnemonic 187 * @return The corresponding numeric value, or -1 if there is none 188 */ 189public int 190getValue(String str) { 191 str = sanitize(str); 192 Integer value = (Integer) strings.get(str); 193 if (value != null) { 194 return value.intValue(); 195 } 196 if (prefix != null) { 197 if (str.startsWith(prefix)) { 198 int val = parseNumeric(str.substring(prefix.length())); 199 if (val >= 0) { 200 return val; 201 } 202 } 203 } 204 if (numericok) { 205 return parseNumeric(str); 206 } 207 return -1; 208} 209 210} 211