17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 2002-2012, International Business Machines Corporation and * 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved. * 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.util; 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Collection; 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Iterator; 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Map; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.UnicodeSet; 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.UnicodeSetIterator; 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic abstract class Visitor { 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void doAt(Object item) { 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (item instanceof Collection) { 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAt((Collection) item); 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (item instanceof Map) { 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAt((Map) item); 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (item instanceof Object[]) { 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAt((Object[]) item); 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (item instanceof UnicodeSet) { 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAt((UnicodeSet) item); 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doSimpleAt(item); 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int count(Object item) { 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (item instanceof Collection) { 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ((Collection) item).size(); 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (item instanceof Map) { 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ((Map) item).size(); 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (item instanceof Object[]) { 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ((Object[]) item).length; 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (item instanceof UnicodeSet) { 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ((UnicodeSet) item).size(); 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return 1; 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // the default implementation boxing 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void doAt(int o) { 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doSimpleAt(new Integer(o)); 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void doAt(double o) { 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doSimpleAt(new Double(o)); 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void doAt(char o) { 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doSimpleAt(new Character(o)); 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // for subclassing 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void doAt (Collection c) { 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (c.size() == 0) doBefore(c, null); 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Iterator it = c.iterator(); 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean first = true; 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Object last = null; 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (it.hasNext()) { 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Object item = it.next(); 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (first) { 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doBefore(c, item); 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert first = false; 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doBetween(c, last, item); 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAt(last=item); 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAfter(c, last); 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void doAt (Map c) { 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAt(c.entrySet()); 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void doAt (UnicodeSet c) { 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (c.size() == 0) doBefore(c, null); 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UnicodeSetIterator it = new UnicodeSetIterator(c); 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean first = true; 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Object last = null; 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Object item; 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CodePointRange cpr0 = new CodePointRange(); 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CodePointRange cpr1 = new CodePointRange(); 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CodePointRange cpr; 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while(it.nextRange()) { 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (it.codepoint == UnicodeSetIterator.IS_STRING) { 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert item = it.string; 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cpr = last == cpr0 ? cpr1 : cpr0; // make sure we don't override last 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cpr.codepoint = it.codepoint; 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cpr.codepointEnd = it.codepointEnd; 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert item = cpr; 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!first) { 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doBefore(c, item); 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert first = true; 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doBetween(c, last, item); 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAt(last = item); 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAfter(c, last); 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void doAt (Object[] c) { 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doBefore(c, c.length == 0 ? null : c[0]); 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Object last = null; 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < c.length; ++i) { 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (i != 0) doBetween(c, last, c[i]); 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAt(last = c[i]); 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert doAfter(c, last); 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static class CodePointRange{ 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int codepoint, codepointEnd; 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // ===== MUST BE OVERRIDEN ===== 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract protected void doBefore(Object container, Object item); 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract protected void doBetween(Object container, Object lastItem, Object nextItem); 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract protected void doAfter(Object container, Object item); 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract protected void doSimpleAt(Object o); 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}