1/* 2 ******************************************************************************* 3 * Copyright (C) 2002-2012, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7package com.ibm.icu.dev.util; 8 9import java.util.Collection; 10import java.util.Iterator; 11import java.util.Map; 12 13import com.ibm.icu.text.UnicodeSet; 14import com.ibm.icu.text.UnicodeSetIterator; 15 16public abstract class Visitor { 17 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 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 48 public void doAt(int o) { 49 doSimpleAt(new Integer(o)); 50 } 51 public void doAt(double o) { 52 doSimpleAt(new Double(o)); 53 } 54 public void doAt(char o) { 55 doSimpleAt(new Character(o)); 56 } 57 58 // for subclassing 59 60 protected void doAt (Collection c) { 61 if (c.size() == 0) doBefore(c, null); 62 Iterator it = c.iterator(); 63 boolean first = true; 64 Object last = null; 65 while (it.hasNext()) { 66 Object item = it.next(); 67 if (first) { 68 doBefore(c, item); 69 first = false; 70 } else { 71 doBetween(c, last, item); 72 } 73 doAt(last=item); 74 } 75 doAfter(c, last); 76 } 77 78 protected void doAt (Map c) { 79 doAt(c.entrySet()); 80 } 81 82 protected void doAt (UnicodeSet c) { 83 if (c.size() == 0) doBefore(c, null); 84 UnicodeSetIterator it = new UnicodeSetIterator(c); 85 boolean first = true; 86 Object last = null; 87 Object item; 88 CodePointRange cpr0 = new CodePointRange(); 89 CodePointRange cpr1 = new CodePointRange(); 90 CodePointRange cpr; 91 92 while(it.nextRange()) { 93 if (it.codepoint == UnicodeSetIterator.IS_STRING) { 94 item = it.string; 95 } else { 96 cpr = last == cpr0 ? cpr1 : cpr0; // make sure we don't override last 97 cpr.codepoint = it.codepoint; 98 cpr.codepointEnd = it.codepointEnd; 99 item = cpr; 100 } 101 if (!first) { 102 doBefore(c, item); 103 first = true; 104 } else { 105 doBetween(c, last, item); 106 } 107 doAt(last = item); 108 } 109 doAfter(c, last); 110 } 111 112 protected void doAt (Object[] c) { 113 doBefore(c, c.length == 0 ? null : c[0]); 114 Object last = null; 115 for (int i = 0; i < c.length; ++i) { 116 if (i != 0) doBetween(c, last, c[i]); 117 doAt(last = c[i]); 118 } 119 doAfter(c, last); 120 } 121 122 public static class CodePointRange{ 123 public int codepoint, codepointEnd; 124 } 125 126 // ===== MUST BE OVERRIDEN ===== 127 128 abstract protected void doBefore(Object container, Object item); 129 abstract protected void doBetween(Object container, Object lastItem, Object nextItem); 130 abstract protected void doAfter(Object container, Object item); 131 abstract protected void doSimpleAt(Object o); 132 133}