| 1 32 package net.sf.retrotranslator.runtime.format; 33 34 import java.text.DecimalFormatSymbols ; 35 import java.util.*; 36 import java.util.regex.*; 37 38 41 public abstract class FormatContext { 42 43 private static final DecimalFormatSymbols US_SYMBOLS = new DecimalFormatSymbols (Locale.US); 44 private static final Pattern PATTERN = Pattern.compile("%(?:(\\d+)\\$)?([-#+ 0,(\\<]*)?(\\d+)?(?:\\.(\\d+))?" + 45 "([bBhHsScCdoxXeEfgGaA%n]|(?:[tT][HIklMSLNpzZsQBbhAaCYyjmdeRTrDFc]))"); 46 47 private Locale locale; 48 private DecimalFormatSymbols symbols; 49 private Object [] arguments; 50 private int effectiveIndex; 51 private int ordinaryIndex; 52 private boolean effectiveIndexComputed; 53 private String specifier; 54 private int explicitIndex; 55 private String flags; 56 private int width; 57 private int precision; 58 private String conversion; 59 60 protected FormatContext(Locale locale) { 61 this.locale = locale; 62 } 63 64 public abstract void append(char c); 65 66 public abstract void append(String s); 67 68 public abstract void append(String s, int start, int end); 69 70 public abstract boolean writeFormattable(); 71 72 public void printf(String format, Object ... args) { 73 arguments = args; 74 effectiveIndex = 0; 75 ordinaryIndex = 0; 76 int position = 0; 77 for (Matcher matcher = PATTERN.matcher(format); matcher.find(position); position = matcher.end()) { 78 writeText(format, position, matcher.start()); 79 effectiveIndexComputed = false; 80 specifier = matcher.group(); 81 explicitIndex = parse(matcher.group(1)); 82 String f = matcher.group(2); 83 flags = f != null ? f : ""; 84 width = parse(matcher.group(3)); 85 precision = parse(matcher.group(4)); 86 conversion = matcher.group(5); 87 Conversion.getInstance(conversion).format(this); 88 } 89 writeText(format, position, format.length()); 90 } 91 92 private static int parse(String s) { 93 return s == null ? -1 : Integer.valueOf(s); 94 } 95 96 private char getConversionType() { 97 return conversion.charAt(0); 98 } 99 100 public int getWidth() { 101 return width; 102 } 103 104 public int getPrecision() { 105 return precision; 106 } 107 108 public int getNumberPrecision() { 109 return precision >= 0 ? precision : 6; 110 } 111 112 public Locale getLocale() { 113 return locale; 114 } 115 116 public DecimalFormatSymbols getSymbols(boolean localized) { 117 if (localized && locale != null) { 118 if (symbols == null) { 119 symbols = new DecimalFormatSymbols (locale); 120 } 121 return symbols; 122 } else { 123 return US_SYMBOLS; 124 } 125 } 126 127 public IllegalFormatConversionException getConversionException() { 128 return new IllegalFormatConversionException(getConversionType(), getArgument().getClass()); 129 } 130 131 public boolean isUpperCase() { 132 return Character.isUpperCase(getConversionType()); 133 } 134 135 public boolean isFlag(char c) { 136 return flags.indexOf(c) >= 0; 137 } 138 139 public Object getArgument() { 140 if (!effectiveIndexComputed) { 141 computeEffectiveIndex(); 142 effectiveIndexComputed = true; 143 } 144 return arguments[effectiveIndex - 1]; 145 } 146 147 private void computeEffectiveIndex() { 148 if (flags.indexOf('<') < 0) { 149 effectiveIndex = explicitIndex != -1 ? explicitIndex : ++ordinaryIndex; 150 } 151 if (arguments == null || effectiveIndex == 0 || effectiveIndex > arguments.length) { 152 throw new MissingFormatArgumentException(specifier); 153 } 154 } 155 156 private void writeText(String s, int start, int end) { 157 if (start == end) return; 158 int i = s.indexOf('%', start); 159 if (i >= 0 && i < end) { 160 String unknownFormat = s.substring(i + 1, end); 161 throw new UnknownFormatConversionException(unknownFormat.length() > 0 ? unknownFormat : "%"); 162 } 163 append(s, start, end); 164 } 165 166 public void writeRestricted(String s) { 167 writePadded(precision != -1 && precision < s.length() ? s.substring(0, precision) : s); 168 } 169 170 public void writePadded(String s) { 171 if (isFlag('-')) { 172 writeCaseSensitive(s); 173 writePadding(s); 174 } else { 175 writePadding(s); 176 writeCaseSensitive(s); 177 } 178 } 179 180 private void writePadding(String s) { 181 for (int i = width - s.length(); i > 0; i--) { 182 append(' '); 183 } 184 } 185 186 private void writeCaseSensitive(String s) { 187 if (isUpperCase()) { 188 append(s.toUpperCase()); 189 } else { 190 append(s); 191 } 192 } 193 194 public void assertNoFlag(char flag) { 195 if (isFlag(flag)) throw new FormatFlagsConversionMismatchException(flags, getConversionType()); 196 } 197 198 public void assertNoPrecision() { 199 if (precision != -1) throw new IllegalFormatPrecisionException(precision); 200 } 201 202 public void assertNoWidth() { 203 if (width != -1) throw new IllegalFormatWidthException(width); 204 } 205 206 public void checkWidth() { 207 if ((isFlag('-') || isFlag('0')) && width == -1) { 208 throw new MissingFormatWidthException(specifier); 209 } 210 } 211 212 public void checkFlags() { 213 if (isFlag('+') && isFlag(' ') || isFlag('-') && isFlag('0')) { 214 throw new IllegalFormatFlagsException(flags); 215 } 216 } 217 218 } 219 | Popular Tags |