2 *******************************************************************************
3 * Copyright (C) 2002-2011, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 package com.ibm.icu.dev.test.util;
9 import java.io.BufferedReader;
10 import java.io.BufferedWriter;
12 import java.io.FileInputStream;
13 import java.io.FileOutputStream;
14 import java.io.IOException;
15 import java.io.InputStreamReader;
16 import java.io.OutputStreamWriter;
17 import java.io.PrintWriter;
18 import java.io.StringWriter;
19 import java.text.MessageFormat;
20 import java.util.Collection;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.Locale;
26 import com.ibm.icu.impl.Utility;
27 import com.ibm.icu.text.NumberFormat;
28 import com.ibm.icu.text.Transliterator;
29 import com.ibm.icu.text.UTF16;
30 import com.ibm.icu.text.UnicodeSet;
32 public class BagFormatter {
33 static final boolean DEBUG = false;
34 public static final boolean SHOW_FILES;
36 boolean showFiles = false;
38 showFiles = System.getProperty("SHOW_FILES") != null;
40 catch (SecurityException e) {
42 SHOW_FILES = showFiles;
45 public static final PrintWriter CONSOLE = new PrintWriter(System.out,true);
47 private static PrintWriter log = CONSOLE;
49 private boolean abbreviated = false;
50 private String separator = ",";
51 private String prefix = "[";
52 private String suffix = "]";
53 private UnicodeProperty.Factory source;
54 private UnicodeLabel nameSource;
55 private UnicodeLabel labelSource;
56 private UnicodeLabel rangeBreakSource;
57 private UnicodeLabel valueSource;
58 private String propName = "";
59 private boolean showCount = true;
60 //private boolean suppressReserved = true;
61 private boolean hexValue = false;
62 private static final String NULL_VALUE = "_NULL_VALUE_";
63 private int fullTotal = -1;
64 private boolean showTotal = true;
65 private String lineSeparator = "\r\n";
66 private Tabber tabber = new Tabber.MonoTabber();
69 * Compare two UnicodeSets, and show the differences
70 * @param name1 name of first set to be compared
71 * @param set1 first set
72 * @param name2 name of second set to be compared
73 * @param set2 second set
74 * @return formatted string
76 public String showSetDifferences(
82 StringWriter result = new StringWriter();
83 showSetDifferences(new PrintWriter(result),name1,set1,name2,set2);
85 return result.getBuffer().toString();
88 public String showSetDifferences(
94 StringWriter result = new StringWriter();
95 showSetDifferences(new PrintWriter(result), name1, set1, name2, set2);
97 return result.getBuffer().toString();
100 public void showSetDifferences(
106 showSetDifferences(pw, name1, set1, name2, set2, -1);
109 * Compare two UnicodeSets, and show the differences
110 * @param name1 name of first set to be compared
111 * @param set1 first set
112 * @param name2 name of second set to be compared
113 * @param set2 second set
115 public void showSetDifferences(
123 if (pw == null) pw = CONSOLE;
124 String[] names = { name1, name2 };
128 if ((flags&1) != 0) {
129 temp = new UnicodeSet(set1).removeAll(set2);
130 pw.print(lineSeparator);
131 pw.print(inOut.format(names));
132 pw.print(lineSeparator);
133 showSetNames(pw, temp);
136 if ((flags&2) != 0) {
137 temp = new UnicodeSet(set2).removeAll(set1);
138 pw.print(lineSeparator);
139 pw.print(outIn.format(names));
140 pw.print(lineSeparator);
141 showSetNames(pw, temp);
144 if ((flags&4) != 0) {
145 temp = new UnicodeSet(set2).retainAll(set1);
146 pw.print(lineSeparator);
147 pw.print(inIn.format(names));
148 pw.print(lineSeparator);
149 showSetNames(pw, temp);
154 public void showSetDifferences(
161 if (pw == null) pw = CONSOLE;
162 String[] names = { name1, name2 };
163 // damn'd collection doesn't have a clone, so
164 // we go with Set, even though that
165 // may not preserve order and duplicates
166 Collection temp = new HashSet(set1);
167 temp.removeAll(set2);
169 pw.println(inOut.format(names));
170 showSetNames(pw, temp);
174 temp.removeAll(set1);
176 pw.println(outIn.format(names));
177 showSetNames(pw, temp);
181 temp.retainAll(set2);
183 pw.println(inIn.format(names));
184 showSetNames(pw, temp);
188 * Returns a list of items in the collection, with each separated by the separator.
189 * Each item must not be null; its toString() is called for a printable representation
190 * @param c source collection
191 * @return a String representation of the list
193 public String showSetNames(Object c) {
194 StringWriter buffer = new StringWriter();
195 PrintWriter output = new PrintWriter(buffer);
196 showSetNames(output,c);
197 return buffer.toString();
201 * Returns a list of items in the collection, with each separated by the separator.
202 * Each item must not be null; its toString() is called for a printable representation
203 * @param output destination to which to write names
204 * @param c source collection
206 public void showSetNames(PrintWriter output, Object c) {
207 mainVisitor.doAt(c, output);
212 * Returns a list of items in the collection, with each separated by the separator.
213 * Each item must not be null; its toString() is called for a printable representation
214 * @param filename destination to which to write names
215 * @param c source collection
217 public void showSetNames(String filename, Object c) throws IOException {
218 PrintWriter pw = new PrintWriter(
219 new OutputStreamWriter(
220 new FileOutputStream(filename),"utf-8"));
225 public String getAbbreviatedName(
230 int matchEnd = NameIterator.findMatchingEnd(src, pattern);
231 int sdiv = src.length() - matchEnd;
232 int pdiv = pattern.length() - matchEnd;
233 StringBuffer result = new StringBuffer();
235 src.substring(0, sdiv),
236 pattern.substring(0, pdiv),
241 pattern.substring(pdiv),
244 return result.toString();
247 abstract public static class Relation {
248 abstract public String getRelation(String a, String b);
251 static class NullRelation extends Relation {
252 public String getRelation(String a, String b) { return ""; }
255 private Relation r = new NullRelation();
257 public BagFormatter setRelation(Relation r) {
259 return this; // for chaining
262 public Relation getRelation() {
267 r.getRelati on(last, s) + quote(s) + "\t#" + UnicodeSetFormatter.getResolvedName(s)
270 static final UnicodeSet NO_NAME =
271 new UnicodeSet("[\\u0080\\u0081\\u0084\\u0099\\p{Cn}\\p{Co}]");
272 static final UnicodeSet HAS_NAME = new UnicodeSet(NO_NAME).complement();
273 static final UnicodeSet NAME_CHARACTERS =
274 new UnicodeSet("[A-Za-z0-9\\<\\>\\-\\ ]");
276 public UnicodeSet getSetForName(String namePattern) {
277 UnicodeSet result = new UnicodeSet();
278 Matcher m = Pattern.compile(namePattern).matcher("");
279 // check for no-name items, and add in bulk
280 m.reset("<no name>");
282 result.addAll(NO_NAME);
285 UnicodeSetIterator usi = new UnicodeSetIterator(HAS_NAME);
287 String name = getName(usi.codepoint);
292 result.add(usi.codepoint);
295 // Note: if Regex had some API so that if we could tell that
296 // an initial substring couldn't match, e.g. "CJK IDEOGRAPH-"
297 // then we could optimize by skipping whole swathes of characters
302 public BagFormatter setMergeRanges(boolean in) {
306 public BagFormatter setShowSetAlso(boolean b) {
311 public String getName(int codePoint) {
312 return getName("", codePoint, codePoint);
315 public String getName(String sep, int start, int end) {
316 if (getNameSource() == null || getNameSource() == UnicodeLabel.NULL) return "";
317 String result = getName(start, false);
318 if (start == end) return sep + result;
319 String endString = getName(end, false);
320 if (result.length() == 0 && endString.length() == 0) return sep;
321 if (abbreviated) endString = getAbbreviatedName(endString,result,"~");
322 return sep + result + ".." + endString;
325 public String getName(String s) {
326 return getName(s, false);
329 public static class NameLabel extends UnicodeLabel {
330 UnicodeProperty nameProp;
332 UnicodeSet private_use;
333 UnicodeSet noncharacter;
334 UnicodeSet surrogate;
336 public NameLabel(UnicodeProperty.Factory source) {
337 nameProp = source.getProperty("Name");
338 control = source.getSet("gc=Cc");
339 private_use = source.getSet("gc=Co");
340 surrogate = source.getSet("gc=Cs");
341 noncharacter = source.getSet("noncharactercodepoint=yes");
344 public String getValue(int codePoint, boolean isShort) {
345 String hcp = !isShort
346 ? "U+" + Utility.hex(codePoint, 4) + " "
348 String result = nameProp.getValue(codePoint);
351 if (control.contains(codePoint)) {
352 return "<control-" + Utility.hex(codePoint, 4) + ">";
354 if (private_use.contains(codePoint)) {
355 return "<private-use-" + Utility.hex(codePoint, 4) + ">";
357 if (surrogate.contains(codePoint)) {
358 return "<surrogate-" + Utility.hex(codePoint, 4) + ">";
360 if (noncharacter.contains(codePoint)) {
361 return "<noncharacter-" + Utility.hex(codePoint, 4) + ">";
363 //if (suppressReserved) return "";
364 return hcp + "<reserved-" + Utility.hex(codePoint, 4) + ">";
370 public String getName(int codePoint, boolean withCodePoint) {
371 String result = getNameSource().getValue(codePoint, !withCodePoint);
372 return fixName == null ? result : fixName.transliterate(result);
375 public String getName(String s, boolean withCodePoint) {
376 String result = getNameSource().getValue(s, separator, !withCodePoint);
377 return fixName == null ? result : fixName.transliterate(result);
380 public String hex(String s) {
381 return hex(s,separator);
384 public String hex(String s, String sep) {
385 return UnicodeLabel.HEX.getValue(s, sep, true);
388 public String hex(int start, int end) {
389 String s = Utility.hex(start,4);
390 if (start == end) return s;
391 return s + ".." + Utility.hex(end,4);
394 public BagFormatter setUnicodePropertyFactory(UnicodeProperty.Factory source) {
395 this.source = source;
399 public UnicodeProperty.Factory getUnicodePropertyFactory() {
400 if (source == null) source = ICUPropertyFactory.make();
404 public BagFormatter () {
407 public BagFormatter (UnicodeProperty.Factory source) {
408 setUnicodePropertyFactory(source);
411 public String join(Object o) {
412 return labelVisitor.join(o);
415 // ===== PRIVATES =====
417 private Join labelVisitor = new Join();
419 private boolean mergeRanges = true;
420 private Transliterator showLiteral = null;
421 private Transliterator fixName = null;
422 private boolean showSetAlso = false;
424 private RangeFinder rf = new RangeFinder();
426 private MessageFormat inOut = new MessageFormat("In {0}, but not in {1}:");
427 private MessageFormat outIn = new MessageFormat("Not in {0}, but in {1}:");
428 private MessageFormat inIn = new MessageFormat("In both {0}, and in {1}:");
430 private MyVisitor mainVisitor = new MyVisitor();
433 private String getLabels(int start, int end) {
434 Set names = new TreeSet();
435 for (int cp = start; cp <= end; ++cp) {
436 names.add(getLabel(cp));
438 return labelVisitor.join(names);
442 private void addMatching(
446 StringBuffer result) {
447 NameIterator n1 = new NameIterator(src);
448 NameIterator n2 = new NameIterator(pattern);
449 boolean first = true;
451 String s1 = n1.next();
454 String s2 = n2.next();
459 result.append(substitute);
465 private static NumberFormat nf =
466 NumberFormat.getIntegerInstance(Locale.ENGLISH);
468 nf.setGroupingUsed(false);
471 private int maxWidthOverride = -1;
472 private int maxLabelWidthOverride = -1;
474 public BagFormatter setValueWidthOverride(int maxWidthOverride) {
475 this.maxWidthOverride = maxWidthOverride;
479 public int getValueWidthOverride() {
480 return maxWidthOverride;
483 public BagFormatter setLabelWidthOverride(int maxWidthOverride) {
484 this.maxLabelWidthOverride = maxWidthOverride;
488 public int getLabelWidthOverride() {
489 return maxLabelWidthOverride;
493 private class MyVisitor extends Visitor {
494 private PrintWriter output;
495 String commentSeparator;
500 boolean inTable = false;
502 public void toOutput(String s) {
505 output.print("</table>");
512 output.println("</p>");
514 output.print(lineSeparator);
517 public void toTable(String s) {
518 if (isHtml && !inTable) {
519 output.print("<table>");
522 output.print(tabber.process(s) + lineSeparator);
525 public void doAt(Object c, PrintWriter out) {
527 isHtml = tabber instanceof Tabber.HTMLTabber;
532 // 0009..000D ; White_Space # Cc [5] <control-0009>..<control-000D>
534 // 0009..000D ; White_Space #Cc [5] <control>..<control>
535 tabber.add(mergeRanges ? 14 : 6,Tabber.LEFT);
537 if (propName.length() > 0) {
538 tabber.add(propName.length() + 2,Tabber.LEFT);
541 valueSize = maxWidthOverride > 0 ? maxWidthOverride : getValueSource().getMaxWidth(shortValue);
543 if (DEBUG) System.out.println("ValueSize: " + valueSize);
545 tabber.add(valueSize + 2,Tabber.LEFT); // value
548 tabber.add(3,Tabber.LEFT); // comment character
550 labelSize = maxLabelWidthOverride > 0 ? maxLabelWidthOverride : getLabelSource(true).getMaxWidth(shortLabel);
552 tabber.add(labelSize + 1,Tabber.LEFT); // value
555 if (mergeRanges && showCount) {
556 tabber.add(5,Tabber.RIGHT);
559 if (showLiteral != null) {
560 tabber.add(4,Tabber.LEFT);
562 //myTabber.add(7,Tabber.LEFT);
564 commentSeparator = (showCount || showLiteral != null
565 || getLabelSource(true) != UnicodeLabel.NULL
566 || getNameSource() != UnicodeLabel.NULL)
569 if (DEBUG) System.out.println("Tabber: " + tabber.toString());
570 if (DEBUG) System.out.println("Tabber: " + tabber.process(
571 "200C..200D\t; White_Space\t #\tCf\t [2]\t ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER"));
575 @SuppressWarnings("unused")
576 public String format(Object o) {
577 StringWriter sw = new StringWriter();
578 PrintWriter pw = new PrintWriter(sw);
581 String result = sw.getBuffer().toString();
586 protected void doBefore(Object container, Object o) {
587 if (showSetAlso && container instanceof UnicodeSet) {
588 toOutput("#" + container);
592 protected void doBetween(Object container, Object lastItem, Object nextItem) {
595 protected void doAfter(Object container, Object o) {
596 if (fullTotal != -1 && fullTotal != counter) {
599 toOutput("# The above property value applies to " + nf.format(fullTotal-counter) + " code points not listed here.");
600 toOutput("# Total code points: " + nf.format(fullTotal));
603 } else if (showTotal) {
605 toOutput("# Total code points: " + nf.format(counter));
609 protected void doSimpleAt(Object o) {
610 if (o instanceof Map.Entry) {
611 Map.Entry oo = (Map.Entry)o;
612 Object key = oo.getKey();
613 Object value = oo.getValue();
616 output.println("\u2192");
620 } else if (o instanceof Visitor.CodePointRange) {
621 doAt((Visitor.CodePointRange) o);
623 String thing = o.toString();
624 String value = getValueSource() == UnicodeLabel.NULL ? "" : getValueSource().getValue(thing, ",", true);
625 if (getValueSource() != UnicodeLabel.NULL) value = "\t; " + value;
626 String label = getLabelSource(true) == UnicodeLabel.NULL ? "" : getLabelSource(true).getValue(thing, ",", true);
627 if (label.length() != 0) label = " " + label;
633 + insertLiteral(thing)
640 protected void doAt(Visitor.CodePointRange usi) {
642 for (int cp = usi.codepoint; cp <= usi.codepointEnd; ++cp) {
646 rf.reset(usi.codepoint, usi.codepointEnd + 1);
648 showLine(rf.start, rf.limit - 1);
653 private void showLine(int start, int end) {
654 String label = getLabelSource(true).getValue(start, shortLabel);
655 String value = getValue(start, shortValue);
656 if (value == NULL_VALUE) return;
658 counter += end - start + 1;
659 String pn = propName;
660 if (pn.length() != 0) {
664 value = "\t; " + value;
665 } else if (value.length() > 0) {
666 throw new IllegalArgumentException("maxwidth bogus " + value + "," + getValueSource().getMaxWidth(shortValue));
669 label = "\t" + label;
670 } else if (label.length() > 0) {
671 throw new IllegalArgumentException("maxwidth bogus " + label + ", " + getLabelSource(true).getMaxWidth(shortLabel));
675 if (mergeRanges && showCount) {
676 if (end == start) count = "\t";
677 else count = "\t ["+ nf.format(end - start + 1)+ "]";
687 + insertLiteral(start, end)
688 + getName("\t ", start, end));
691 private String insertLiteral(String thing) {
692 return (showLiteral == null ? ""
693 : " \t(" + showLiteral.transliterate(thing) + ") ");
696 private String insertLiteral(int start, int end) {
697 return (showLiteral == null ? "" :
698 " \t(" + showLiteral.transliterate(UTF16.valueOf(start))
700 ? (".." + showLiteral.transliterate(UTF16.valueOf(end)))
705 private String insertLiteral(int cp) {
706 return (showLiteral == null ? ""
707 : " \t(" + showLiteral.transliterate(UTF16.valueOf(cp)) + ") ");
713 * Iterate through a string, breaking at words.
716 private static class NameIterator {
721 NameIterator(String source) {
722 this.source = source;
723 this.limit = source.length();
726 * Find next word, including trailing spaces
727 * @return the next word
730 if (position >= limit)
732 int pos = source.indexOf(' ', position);
733 if (pos < 0 || pos >= limit)
735 String result = source.substring(position, pos);
740 static int findMatchingEnd(String s1, String s2) {
745 --i; // decrement both before calling function!
747 if (s1.charAt(i) != s2.charAt(j))
750 } catch (Exception e) {} // run off start
752 ++i; // counteract increment
753 i = s1.indexOf(' ', i); // move forward to space
756 return s1.length() - i;
760 private class RangeFinder {
762 private int veryLimit;
763 //String label, value;
764 void reset(int rangeStart, int rangeLimit) {
766 veryLimit = rangeLimit;
769 if (limit >= veryLimit)
771 start = limit; // set to end of last
772 String label = getLabelSource(false).getValue(limit, true);
773 String value = getValue(limit, true);
774 String breaker = getRangeBreakSource().getValue(limit,true);
775 if (DEBUG && limit < 0x7F) System.out.println("Label: " + label + ", Value: " + value + ", Break: " + breaker);
777 for (; limit < veryLimit; limit++) {
778 String s = getLabelSource(false).getValue(limit, true);
779 String v = getValue(limit, true);
780 String b = getRangeBreakSource().getValue(limit, true);
781 if (DEBUG && limit < 0x7F) System.out.println("*Label: " + label + ", Value: " + value + ", Break: " + breaker);
782 if (!equalTo(s, label) || !equalTo(v, value) || !equalTo(b, breaker)) break;
784 // at this point, limit is the first item that has a different label than source
785 // OR, we got to the end, and limit == veryLimit
790 boolean equalTo(Object a, Object b) {
791 if (a == b) return true;
792 if (a == null) return false;
796 boolean shortLabel = true;
797 boolean shortValue = true;
799 public String getPrefix() {
803 public String getSuffix() {
807 public BagFormatter setPrefix(String string) {
812 public BagFormatter setSuffix(String string) {
817 public boolean isAbbreviated() {
821 public BagFormatter setAbbreviated(boolean b) {
826 public UnicodeLabel getLabelSource(boolean visible) {
827 if (labelSource == null) {
828 Map labelMap = new HashMap();
829 //labelMap.put("Lo","L&");
830 labelMap.put("Lu","L&");
831 labelMap.put("Lt","L&");
832 labelMap.put("Ll","L&");
833 labelSource = new UnicodeProperty.FilteredProperty(
834 getUnicodePropertyFactory().getProperty("General_Category"),
835 new UnicodeProperty.MapFilter(labelMap)
836 ).setAllowValueAliasCollisions(true);
844 public static void addAll(UnicodeSet source, Collection target) {
845 source.addAllTo(target);
850 public static final Transliterator hex = Transliterator.getInstance(
851 "[^\\u0009\\u0020-\\u007E\\u00A0-\\u00FF] hex");
853 public static BufferedReader openUTF8Reader(String dir, String filename) throws IOException {
854 return openReader(dir,filename,"UTF-8");
857 public static BufferedReader openReader(String dir, String filename, String encoding) throws IOException {
858 File file = dir.length() == 0 ? new File(filename) : new File(dir, filename);
859 if (SHOW_FILES && log != null) {
860 log.println("Opening File: "
861 + file.getCanonicalPath());
863 return new BufferedReader(
864 new InputStreamReader(
865 new FileInputStream(file),
870 public static PrintWriter openUTF8Writer(String dir, String filename) throws IOException {
871 return openWriter(dir,filename,"UTF-8");
874 public static PrintWriter openWriter(String dir, String filename, String encoding) throws IOException {
875 File file = new File(dir, filename);
876 if (SHOW_FILES && log != null) {
877 log.println("Creating File: "
878 + file.getCanonicalPath());
880 String parentName = file.getParent();
881 if (parentName != null) {
882 File parent = new File(parentName);
885 return new PrintWriter(
887 new OutputStreamWriter(
888 new FileOutputStream(file),
892 public static PrintWriter getLog() {
895 public BagFormatter setLog(PrintWriter writer) {
899 public String getSeparator() {
902 public BagFormatter setSeparator(String string) {
906 public Transliterator getShowLiteral() {
909 public BagFormatter setShowLiteral(Transliterator transliterator) {
910 showLiteral = transliterator;
914 // ===== CONVENIENCES =====
915 private class Join extends Visitor {
916 StringBuffer output = new StringBuffer();
917 @SuppressWarnings("unused")
919 String join (Object o) {
922 return output.toString();
924 protected void doBefore(Object container, Object item) {
926 output.append(prefix);
928 protected void doAfter(Object container, Object item) {
929 output.append(suffix);
932 protected void doBetween(Object container, Object lastItem, Object nextItem) {
933 output.append(separator);
935 protected void doSimpleAt(Object o) {
936 if (o != null) output.append(o.toString());
943 public BagFormatter setLabelSource(UnicodeLabel label) {
944 if (label == null) label = UnicodeLabel.NULL;
950 * @return the NameLable representing the source
952 public UnicodeLabel getNameSource() {
953 if (nameSource == null) {
954 nameSource = new NameLabel(getUnicodePropertyFactory());
962 public BagFormatter setNameSource(UnicodeLabel label) {
963 if (label == null) label = UnicodeLabel.NULL;
969 * @return the UnicodeLabel representing the value
971 public UnicodeLabel getValueSource() {
972 if (valueSource == null) valueSource = UnicodeLabel.NULL;
976 private String getValue(int cp, boolean shortVal) {
977 String result = getValueSource().getValue(cp, shortVal);
978 if (result == null) return NULL_VALUE;
979 if (hexValue) result = hex(result, " ");
986 public BagFormatter setValueSource(UnicodeLabel label) {
987 if (label == null) label = UnicodeLabel.NULL;
992 public BagFormatter setValueSource(String label) {
993 return setValueSource(new UnicodeLabel.Constant(label));
997 * @return true if showCount is true
999 public boolean isShowCount() {
1004 * @param b true to show the count
1005 * @return this (for chaining)
1007 public BagFormatter setShowCount(boolean b) {
1013 * @return the property name
1015 public String getPropName() {
1021 * @return this (for chaining)
1023 public BagFormatter setPropName(String string) {
1024 if (string == null) string = "";
1030 * @return true if this is a hexValue
1032 public boolean isHexValue() {
1038 * @return this (for chaining)
1040 public BagFormatter setHexValue(boolean b) {
1046 * @return the full total
1048 public int getFullTotal() {
1053 * @param i set the full total
1054 * @return this (for chaining)
1056 public BagFormatter setFullTotal(int i) {
1062 * @return the line separator
1064 public String getLineSeparator() {
1065 return lineSeparator;
1070 * @return this (for chaining)
1072 public BagFormatter setLineSeparator(String string) {
1073 lineSeparator = string;
1078 * @return the UnicodeLabel representing the range break source
1080 public UnicodeLabel getRangeBreakSource() {
1081 if (rangeBreakSource == null) {
1082 Map labelMap = new HashMap();
1083 // reflects the code point types on p 25
1084 labelMap.put("Lo", "G&");
1085 labelMap.put("Lm", "G&");
1086 labelMap.put("Lu", "G&");
1087 labelMap.put("Lt", "G&");
1088 labelMap.put("Ll", "G&");
1089 labelMap.put("Mn", "G&");
1090 labelMap.put("Me", "G&");
1091 labelMap.put("Mc", "G&");
1092 labelMap.put("Nd", "G&");
1093 labelMap.put("Nl", "G&");
1094 labelMap.put("No", "G&");
1095 labelMap.put("Zs", "G&");
1096 labelMap.put("Pd", "G&");
1097 labelMap.put("Ps", "G&");
1098 labelMap.put("Pe", "G&");
1099 labelMap.put("Pc", "G&");
1100 labelMap.put("Po", "G&");
1101 labelMap.put("Pi", "G&");
1102 labelMap.put("Pf", "G&");
1103 labelMap.put("Sm", "G&");
1104 labelMap.put("Sc", "G&");
1105 labelMap.put("Sk", "G&");
1106 labelMap.put("So", "G&");
1108 labelMap.put("Zl", "Cf");
1109 labelMap.put("Zp", "Cf");
1114 getUnicodePropertyFactory().getProperty(
1115 "General_Category"),
1116 new UnicodeProperty.MapFilter(labelMap))
1117 .setAllowValueAliasCollisions(true);
1120 "Cn", // = Other, Not Assigned 0
1121 "Cc", // = Other, Control 15
1122 "Cf", // = Other, Format 16
1123 UnicodeProperty.UNUSED, // missing
1124 "Co", // = Other, Private Use 18
1125 "Cs", // = Other, Surrogate 19
1128 return rangeBreakSource;
1134 public BagFormatter setRangeBreakSource(UnicodeLabel label) {
1135 if (label == null) label = UnicodeLabel.NULL;
1136 rangeBreakSource = label;
1141 * @return Returns the fixName.
1143 public Transliterator getFixName() {
1147 * @param fixName The fixName to set.
1149 public BagFormatter setFixName(Transliterator fixName) {
1150 this.fixName = fixName;
1154 public Tabber getTabber() {
1158 public void setTabber(Tabber tabber) {
1159 this.tabber = tabber;
1162 public boolean isShowTotal() {
1166 public void setShowTotal(boolean showTotal) {
1167 this.showTotal = showTotal;