1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.accumulo.core.util.shell.commands;
18
19 import java.util.ArrayList;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.StringTokenizer;
23
24 /**
25 *
26 * EscapeTokenizer - Supports tokenizing with delimiters while being able to escape the delims. String "1,2,3,4" with delims "," = ["1", "2", "3", "4"] String
27 * "1\,2,3,4" with delims "," = ["1,2", "3", "4"]
28 *
29 * - The escape char '\' only has a special meaning when it is before a delim String "1,\2,3,4" with delims "," = ["1" , "\2", "3", "4"]
30 *
31 * - Multiple delims in a row are considered one delim String "1,,,,,,,,,,,,,,2,3,4","," with delims "," = ["1", "2", "3", "4"]
32 *
33 */
34
35 public class EscapeTokenizer implements Iterable<String> {
36
37 private List<String> tokens;
38
39 public EscapeTokenizer(final String line, final String delimeters) {
40 this.tokens = new ArrayList<String>();
41 preprocess(line, delimeters);
42 }
43
44 private void preprocess(final String line, final String delimeters) {
45 final StringTokenizer st = new StringTokenizer(line, delimeters, true);
46 boolean inEscape = false;
47 String current = "", prev = "";
48 final List<String> toks = new ArrayList<String>();
49
50 while (st.hasMoreTokens()) {
51 current = st.nextToken();
52 if (inEscape) {
53 prev += current;
54 inEscape = false;
55 } else {
56 inEscape = current.endsWith("\\");
57 if (inEscape) {
58 prev = current.substring(0, current.length() - 1);
59 } else {
60 if (current.length() == 1 && delimeters.contains(current)) {
61 if (!prev.isEmpty()) {
62 toks.add(prev);
63 }
64 } else {
65 toks.add(prev + current);
66 }
67 prev = "";
68 }
69 }
70 }
71 if (!prev.isEmpty()) {
72 toks.add(prev);
73 }
74 this.tokens = toks;
75 }
76
77 @Override
78 public Iterator<String> iterator() {
79 return this.tokens.iterator();
80 }
81
82 public int count() {
83 return tokens.size();
84 }
85 }