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 }