1 7 8 package com.ibm.icu.impl; 9 10 import java.util.Comparator ; 11 import java.util.Iterator ; 12 import java.util.Set ; 13 import java.util.TreeSet ; 14 15 import com.ibm.icu.impl.CollectionUtilities.MultiComparator; 16 import com.ibm.icu.lang.UCharacter; 17 import com.ibm.icu.text.Collator; 18 import com.ibm.icu.text.RuleBasedCollator; 19 import com.ibm.icu.text.Transliterator; 20 import com.ibm.icu.text.UTF16; 21 import com.ibm.icu.text.UnicodeSet; 22 import com.ibm.icu.text.UnicodeSetIterator; 23 import com.ibm.icu.util.ULocale; 24 25 27 public class PrettyPrinter { 28 private static final UnicodeSet patternWhitespace = (UnicodeSet) new UnicodeSet("[[:Cn:][:Default_Ignorable_Code_Point:][:patternwhitespace:]]").freeze(); 29 private static final UnicodeSet sortAtEnd = (UnicodeSet) new UnicodeSet("[[:Cn:][:Cs:][:Co:][:Ideographic:]]").freeze(); 30 31 private boolean first = true; 32 private StringBuffer target = new StringBuffer (); 33 private int firstCodePoint = -2; 34 private int lastCodePoint = -2; 35 private boolean compressRanges = true; 36 private String lastString = ""; 37 private UnicodeSet toQuote = new UnicodeSet(patternWhitespace); 38 private Transliterator quoter = null; 39 40 private Comparator ordering; 41 private Comparator spaceComp = Collator.getInstance(ULocale.ROOT); 42 { 43 setOrdering(Collator.getInstance(ULocale.ROOT)); 44 ((RuleBasedCollator)spaceComp).setStrength(RuleBasedCollator.PRIMARY); 45 } 46 47 public Transliterator getQuoter() { 48 return quoter; 49 } 50 51 public PrettyPrinter setQuoter(Transliterator quoter) { 52 this.quoter = quoter; 53 return this; } 55 56 public boolean isCompressRanges() { 57 return compressRanges; 58 } 59 60 64 public PrettyPrinter setCompressRanges(boolean compressRanges) { 65 this.compressRanges = compressRanges; 66 return this; 67 } 68 69 public Comparator getOrdering() { 70 return ordering; 71 } 72 73 77 public PrettyPrinter setOrdering(Comparator ordering) { 78 this.ordering = new MultiComparator(new Comparator [] {ordering, new UTF16.StringComparator(true,false,0)}); 79 return this; 80 } 81 82 public Comparator getSpaceComparator() { 83 return spaceComp; 84 } 85 86 90 public PrettyPrinter setSpaceComparator(Comparator spaceComp) { 91 this.spaceComp = spaceComp; 92 return this; 93 } 94 95 public UnicodeSet getToQuote() { 96 return toQuote; 97 } 98 99 103 public PrettyPrinter setToQuote(UnicodeSet toQuote) { 104 toQuote = (UnicodeSet)toQuote.clone(); 105 toQuote.addAll(patternWhitespace); 106 this.toQuote = toQuote; 107 return this; 108 } 109 110 115 public String toPattern(UnicodeSet uset) { 116 first = true; 117 UnicodeSet putAtEnd = new UnicodeSet(uset).retainAll(sortAtEnd); Set orderedStrings = new TreeSet (ordering); 120 for (UnicodeSetIterator it = new UnicodeSetIterator(uset); it.nextRange();) { 121 if (it.codepoint == it.IS_STRING) { 122 orderedStrings.add(it.string); 123 } else { 124 for (int i = it.codepoint; i <= it.codepointEnd; ++i) { 125 if (!putAtEnd.contains(i)) { 126 orderedStrings.add(UTF16.valueOf(i)); 127 } 128 } 129 } 130 } 131 target.setLength(0); 132 target.append("["); 133 for (Iterator it = orderedStrings.iterator(); it.hasNext();) { 134 appendUnicodeSetItem((String ) it.next()); 135 } 136 for (UnicodeSetIterator it = new UnicodeSetIterator(putAtEnd); it.next();) { appendUnicodeSetItem(it.codepoint); 138 } 139 flushLast(); 140 target.append("]"); 141 String sresult = target.toString(); 142 143 return sresult; 153 } 154 155 private PrettyPrinter appendUnicodeSetItem(String s) { 156 int cp; 157 if (UTF16.hasMoreCodePointsThan(s, 1)) { 158 flushLast(); 159 addSpace(s); 160 target.append("{"); 161 for (int i = 0; i < s.length(); i += UTF16.getCharCount(cp)) { 162 appendQuoted(cp = UTF16.charAt(s, i)); 163 } 164 target.append("}"); 165 lastString = s; 166 } else { 167 appendUnicodeSetItem(UTF16.charAt(s, 0)); 168 } 169 return this; 170 } 171 172 private void appendUnicodeSetItem(int cp) { 173 if (!compressRanges) 174 flushLast(); 175 if (cp == lastCodePoint + 1) { 176 lastCodePoint = cp; } else { flushLast(); 179 firstCodePoint = lastCodePoint = cp; 180 } 181 } 182 185 private void addSpace(String s) { 186 if (first) { 187 first = false; 188 } else if (spaceComp.compare(s, lastString) != 0) { 189 target.append(' '); 190 } else { 191 int cp = UTF16.charAt(s,0); 192 int type = UCharacter.getType(cp); 193 if (type == UCharacter.NON_SPACING_MARK || type == UCharacter.ENCLOSING_MARK) { 194 target.append(' '); 195 } else if (type == UCharacter.SURROGATE && cp >= UTF16.TRAIL_SURROGATE_MIN_VALUE) { 196 target.append(' '); } 198 } 199 } 200 201 private void flushLast() { 202 if (lastCodePoint >= 0) { 203 addSpace(UTF16.valueOf(firstCodePoint)); 204 if (firstCodePoint != lastCodePoint) { 205 appendQuoted(firstCodePoint); 206 target.append(firstCodePoint + 1 == lastCodePoint ? ' ' : '-'); 207 } 208 appendQuoted(lastCodePoint); 209 lastString = UTF16.valueOf(lastCodePoint); 210 firstCodePoint = lastCodePoint = -2; 211 } 212 } 213 PrettyPrinter appendQuoted(int codePoint) { 214 if (toQuote.contains(codePoint)) { 215 if (quoter != null) { 216 target.append(quoter.transliterate(UTF16.valueOf(codePoint))); 217 return this; 218 } 219 if (codePoint > 0xFFFF) { 220 target.append("\\U"); 221 target.append(Utility.hex(codePoint,8)); 222 } else { 223 target.append("\\u"); 224 target.append(Utility.hex(codePoint,4)); 225 } 226 return this; 227 } 228 switch (codePoint) { 229 case '[': case ']': case '-': case '^': case '&': case '\\': case '{': 236 case '}': 237 case '$': 238 case ':': 239 target.append('\\'); 240 break; 241 default: 242 if (patternWhitespace.contains(codePoint)) { 244 target.append('\\'); 245 } 246 break; 247 } 248 UTF16.append(target, codePoint); 249 return this; 250 } 251 } 259 | Popular Tags |