| /* |
| ******************************************************************************* |
| * Copyright (C) 2002-2012, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ******************************************************************************* |
| */ |
| package com.ibm.icu.dev.util; |
| |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import com.ibm.icu.text.UnicodeSet; |
| import com.ibm.icu.text.UnicodeSetIterator; |
| |
| public abstract class Visitor { |
| |
| public void doAt(Object item) { |
| if (item instanceof Collection) { |
| doAt((Collection) item); |
| } else if (item instanceof Map) { |
| doAt((Map) item); |
| } else if (item instanceof Object[]) { |
| doAt((Object[]) item); |
| } else if (item instanceof UnicodeSet) { |
| doAt((UnicodeSet) item); |
| } else { |
| doSimpleAt(item); |
| } |
| } |
| |
| public int count(Object item) { |
| if (item instanceof Collection) { |
| return ((Collection) item).size(); |
| } else if (item instanceof Map) { |
| return ((Map) item).size(); |
| } else if (item instanceof Object[]) { |
| return ((Object[]) item).length; |
| } else if (item instanceof UnicodeSet) { |
| return ((UnicodeSet) item).size(); |
| } else { |
| return 1; |
| } |
| } |
| |
| // the default implementation boxing |
| |
| public void doAt(int o) { |
| doSimpleAt(new Integer(o)); |
| } |
| public void doAt(double o) { |
| doSimpleAt(new Double(o)); |
| } |
| public void doAt(char o) { |
| doSimpleAt(new Character(o)); |
| } |
| |
| // for subclassing |
| |
| protected void doAt (Collection c) { |
| if (c.size() == 0) doBefore(c, null); |
| Iterator it = c.iterator(); |
| boolean first = true; |
| Object last = null; |
| while (it.hasNext()) { |
| Object item = it.next(); |
| if (first) { |
| doBefore(c, item); |
| first = false; |
| } else { |
| doBetween(c, last, item); |
| } |
| doAt(last=item); |
| } |
| doAfter(c, last); |
| } |
| |
| protected void doAt (Map c) { |
| doAt(c.entrySet()); |
| } |
| |
| protected void doAt (UnicodeSet c) { |
| if (c.size() == 0) doBefore(c, null); |
| UnicodeSetIterator it = new UnicodeSetIterator(c); |
| boolean first = true; |
| Object last = null; |
| Object item; |
| CodePointRange cpr0 = new CodePointRange(); |
| CodePointRange cpr1 = new CodePointRange(); |
| CodePointRange cpr; |
| |
| while(it.nextRange()) { |
| if (it.codepoint == UnicodeSetIterator.IS_STRING) { |
| item = it.string; |
| } else { |
| cpr = last == cpr0 ? cpr1 : cpr0; // make sure we don't override last |
| cpr.codepoint = it.codepoint; |
| cpr.codepointEnd = it.codepointEnd; |
| item = cpr; |
| } |
| if (!first) { |
| doBefore(c, item); |
| first = true; |
| } else { |
| doBetween(c, last, item); |
| } |
| doAt(last = item); |
| } |
| doAfter(c, last); |
| } |
| |
| protected void doAt (Object[] c) { |
| doBefore(c, c.length == 0 ? null : c[0]); |
| Object last = null; |
| for (int i = 0; i < c.length; ++i) { |
| if (i != 0) doBetween(c, last, c[i]); |
| doAt(last = c[i]); |
| } |
| doAfter(c, last); |
| } |
| |
| public static class CodePointRange{ |
| public int codepoint, codepointEnd; |
| } |
| |
| // ===== MUST BE OVERRIDEN ===== |
| |
| abstract protected void doBefore(Object container, Object item); |
| abstract protected void doBetween(Object container, Object lastItem, Object nextItem); |
| abstract protected void doAfter(Object container, Object item); |
| abstract protected void doSimpleAt(Object o); |
| |
| } |