1 package com.github.mygreen.supercsv.cellprocessor.conversion;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Comparator;
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Set;
11
12 import com.github.mygreen.supercsv.util.ArgUtils;
13 import com.github.mygreen.supercsv.util.Utils;
14
15
16
17
18
19
20
21
22
23 public class CharReplacer {
24
25
26 private final Map<Character, String> singles = new HashMap<>();
27
28
29 private final List<MultiChar> multi = new ArrayList<>();
30
31
32
33
34
35 private static class MultiChar {
36
37 private final String word;
38
39 private final String replacement;
40
41 private MultiChar(final String word, final String replacement) {
42 this.word = word;
43 this.replacement = replacement;
44 }
45
46 }
47
48
49
50
51
52
53
54
55 public void register(final String word, final String replacement) {
56 ArgUtils.notEmpty(word, "word");
57 ArgUtils.notNull(replacement, "replacement");
58
59 if(word.length() == 1) {
60 singles.computeIfAbsent(word.charAt(0), key -> replacement);
61
62 } else {
63 multi.add(new MultiChar(word, replacement));
64 }
65
66 }
67
68
69
70
71 public void ready() {
72
73
74 final Set<String> duplicatedWords = new HashSet<>();
75 final List<MultiChar> newMulti = new ArrayList<>();
76 for(MultiChar word : multi) {
77 if(duplicatedWords.contains(word.word)) {
78 continue;
79 }
80 duplicatedWords.add(word.word);
81 newMulti.add(word);
82 }
83
84
85 Collections.sort(newMulti, new Comparator<MultiChar>() {
86
87 @Override
88 public int compare(final MultiChar o1, final MultiChar o2) {
89
90 final int length1 = o1.word.length();
91 final int length2 = o2.word.length();
92 if(length1 < length2) {
93 return 1;
94
95 } else if(length1 > length2) {
96 return -1;
97
98 } else {
99 return o1.word.compareTo(o2.word);
100 }
101 }
102 });
103
104 multi.clear();
105 multi.addAll(newMulti);
106
107 }
108
109
110
111
112
113
114 public String replace(final String text) {
115
116 if(Utils.isEmpty(text)) {
117 return text;
118 }
119
120 final int length = text.length();
121 StringBuilder replaced = new StringBuilder();
122 int index = 0;
123
124 while(index < length) {
125 int multiIndex = replaceMulti(text, index, replaced);
126 if(multiIndex > index) {
127 index = multiIndex;
128 continue;
129 }
130
131 int singleIndex = replaceSingle(text, index, replaced);
132 if(singleIndex > index) {
133 index = singleIndex;
134 continue;
135 }
136
137
138 replaced.append(text.charAt(index));
139 index++;
140
141 }
142
143 return replaced.toString();
144 }
145
146 private int replaceSingle(final String source, final int index, final StringBuilder replaced) {
147
148 final char c = source.charAt(index);
149 if(singles.containsKey(c)) {
150 replaced.append(singles.get(c));
151 return index + 1;
152 }
153
154 return index;
155
156 }
157
158 private int replaceMulti(final String source, final int index, final StringBuilder replaced) {
159
160 for(MultiChar word : multi) {
161 if(source.indexOf(word.word, index) == index) {
162 replaced.append(word.replacement);
163 return index + word.word.length();
164 }
165 }
166
167 return index;
168 }
169
170 }