1 package org.springframework.roo.shell;
2
3 import java.util.LinkedHashMap;
4 import java.util.Map;
5
6 import org.springframework.roo.support.util.Assert;
7
8 public class ParserUtils {
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public static Map<String,String> tokenize(String remainingBuffer) {
27 Assert.notNull(remainingBuffer, "Remaining buffer cannot be null, although it can be empty");
28 Map<String,String> result = new LinkedHashMap<String, String>();
29 StringBuilder currentOption = new StringBuilder();
30 StringBuilder currentValue = new StringBuilder();
31 boolean inQuotes = false;
32
33
34 int count = 0;
35 for (char c : remainingBuffer.toCharArray()) {
36 if ('"' == c) {
37 count++;
38 }
39 }
40 Assert.isTrue(count % 2 == 0, "Cannot have an unbalanced number of quotation marks");
41
42 if ("".equals(remainingBuffer.trim())) {
43
44 return result;
45 }
46
47 String[] split = remainingBuffer.split(" ");
48 for (int i = 0 ; i < split.length; i++) {
49 String currentToken = split[i];
50
51 if (inQuotes == true) {
52
53 if (currentToken.endsWith("\"")) {
54
55 String tokenLessDelimiters = currentToken.substring(0, currentToken.length()-1);
56 currentValue.append(" ").append(tokenLessDelimiters);
57 inQuotes = false;
58
59
60 store(result, currentOption, currentValue);
61 currentOption = new StringBuilder();
62 currentValue = new StringBuilder();
63
64 } else {
65
66 currentValue.append(" ").append(currentToken);
67 }
68 continue;
69 }
70
71 if (currentToken.startsWith("\"")) {
72
73 String tokenLessDelimiters = currentToken.substring(1);
74 currentValue.append(tokenLessDelimiters);
75 inQuotes = true;
76 continue;
77 }
78
79 if (currentToken.trim().equals("")) {
80
81 continue;
82 }
83
84 if (currentToken.startsWith("--")) {
85
86
87 int lastIndex = currentToken.lastIndexOf("-");
88 String tokenLessDelimiters = currentToken.substring(lastIndex+1);
89 currentOption.append(tokenLessDelimiters);
90
91
92 if (i+1 == split.length) {
93
94 store(result, currentOption, currentValue);
95 break;
96 }
97
98 if (split[i+1].startsWith("-")) {
99
100 store(result, currentOption, currentValue);
101 currentOption = new StringBuilder();
102 currentValue = new StringBuilder();
103 }
104
105 continue;
106 }
107
108
109
110
111 if (currentOption.length() == 0) {
112 if (currentValue.length() > 0) {
113
114 currentValue.append(" ");
115 }
116 currentValue.append(currentToken);
117
118
119 if (i+1 == split.length) {
120
121 store(result, currentOption, currentValue);
122 break;
123 }
124
125 if (split[i+1].startsWith("--")) {
126
127 store(result, currentOption, currentValue);
128 currentOption = new StringBuilder();
129 currentValue = new StringBuilder();
130 }
131
132 continue;
133 }
134
135
136 currentValue.append(currentToken);
137 store(result, currentOption, currentValue);
138 currentOption = new StringBuilder();
139 currentValue = new StringBuilder();
140 }
141
142
143 if (result.containsKey("") && result.get("").trim().equals("")) {
144 result.remove("");
145 }
146
147 return result;
148 }
149
150 private static void store(Map<String,String> results, StringBuilder currentOption, StringBuilder currentValue) {
151
152 if (currentOption.length() > 0) {
153
154 String option = currentOption.toString();
155 Assert.isTrue(!results.containsKey(option), "You cannot specify option '" + option + "' more than once in a single command");
156 results.put(option, currentValue.toString());
157 } else {
158
159 Assert.isTrue(!results.containsKey(""), "You cannot add more than one default option ('" + currentValue.toString() + "') in a single command");
160 results.put("", currentValue.toString());
161 }
162 }
163
164 }