1 /* 2 ******************************************************************************* 3 * Copyright (C) 2002-2012, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 package org.unicode.cldr.util; 8 9 import java.util.Collection; 10 import java.util.Iterator; 11 import java.util.Map; 12 13 import com.ibm.icu.text.UnicodeSet; 14 import com.ibm.icu.text.UnicodeSetIterator; 15 16 public abstract class Visitor { 17 doAt(Object item)18 public void doAt(Object item) { 19 if (item instanceof Collection) { 20 doAt((Collection) item); 21 } else if (item instanceof Map) { 22 doAt((Map) item); 23 } else if (item instanceof Object[]) { 24 doAt((Object[]) item); 25 } else if (item instanceof UnicodeSet) { 26 doAt((UnicodeSet) item); 27 } else { 28 doSimpleAt(item); 29 } 30 } 31 count(Object item)32 public int count(Object item) { 33 if (item instanceof Collection) { 34 return ((Collection) item).size(); 35 } else if (item instanceof Map) { 36 return ((Map) item).size(); 37 } else if (item instanceof Object[]) { 38 return ((Object[]) item).length; 39 } else if (item instanceof UnicodeSet) { 40 return ((UnicodeSet) item).size(); 41 } else { 42 return 1; 43 } 44 } 45 46 // the default implementation boxing 47 doAt(int o)48 public void doAt(int o) { 49 doSimpleAt(new Integer(o)); 50 } 51 doAt(double o)52 public void doAt(double o) { 53 doSimpleAt(new Double(o)); 54 } 55 doAt(char o)56 public void doAt(char o) { 57 doSimpleAt(new Character(o)); 58 } 59 60 // for subclassing 61 doAt(Collection c)62 protected void doAt(Collection c) { 63 if (c.size() == 0) doBefore(c, null); 64 Iterator it = c.iterator(); 65 boolean first = true; 66 Object last = null; 67 while (it.hasNext()) { 68 Object item = it.next(); 69 if (first) { 70 doBefore(c, item); 71 first = false; 72 } else { 73 doBetween(c, last, item); 74 } 75 doAt(last = item); 76 } 77 doAfter(c, last); 78 } 79 doAt(Map c)80 protected void doAt(Map c) { 81 doAt(c.entrySet()); 82 } 83 doAt(UnicodeSet c)84 protected void doAt(UnicodeSet c) { 85 if (c.size() == 0) doBefore(c, null); 86 UnicodeSetIterator it = new UnicodeSetIterator(c); 87 boolean first = true; 88 Object last = null; 89 Object item; 90 CodePointRange cpr0 = new CodePointRange(); 91 CodePointRange cpr1 = new CodePointRange(); 92 CodePointRange cpr; 93 94 while (it.nextRange()) { 95 if (it.codepoint == UnicodeSetIterator.IS_STRING) { 96 item = it.string; 97 } else { 98 cpr = last == cpr0 ? cpr1 : cpr0; // make sure we don't override last 99 cpr.codepoint = it.codepoint; 100 cpr.codepointEnd = it.codepointEnd; 101 item = cpr; 102 } 103 if (!first) { 104 doBefore(c, item); 105 first = true; 106 } else { 107 doBetween(c, last, item); 108 } 109 doAt(last = item); 110 } 111 doAfter(c, last); 112 } 113 doAt(Object[] c)114 protected void doAt(Object[] c) { 115 doBefore(c, c.length == 0 ? null : c[0]); 116 Object last = null; 117 for (int i = 0; i < c.length; ++i) { 118 if (i != 0) doBetween(c, last, c[i]); 119 doAt(last = c[i]); 120 } 121 doAfter(c, last); 122 } 123 124 public static class CodePointRange { 125 public int codepoint, codepointEnd; 126 127 @Override toString()128 public String toString() { 129 return "[" + codepoint + ", " + codepointEnd + "]"; 130 } 131 } 132 133 // ===== MUST BE OVERRIDEN ===== 134 doBefore(Object container, Object item)135 abstract protected void doBefore(Object container, Object item); 136 doBetween(Object container, Object lastItem, Object nextItem)137 abstract protected void doBetween(Object container, Object lastItem, Object nextItem); 138 doAfter(Object container, Object item)139 abstract protected void doAfter(Object container, Object item); 140 doSimpleAt(Object o)141 abstract protected void doSimpleAt(Object o); 142 143 }