File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\server\web\PageParser.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.server.web;
8
9 import java.text.ParseException;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13 import org.h2.util.New;
14
15 /**
16 * A page parser can parse an HTML page and replace the tags there.
17 * This class is used by the H2 Console.
18 */
19 public class PageParser {
20 private final String page;
21 private int pos;
22 private final Map<String, Object> settings;
23 private final int len;
24 private StringBuilder result;
25
26 private PageParser(String page, Map<String, Object> settings, int pos) {
27 this.page = page;
28 this.pos = pos;
29 this.len = page.length();
30 this.settings = settings;
31 result = new StringBuilder(len);
32 }
33
34 /**
35 * Replace the tags in the HTML page with the given settings.
36 *
37 * @param page the HTML page
38 * @param settings the settings
39 * @return the converted page
40 */
41 public static String parse(String page, Map<String, Object> settings) {
42 PageParser block = new PageParser(page, settings, 0);
43 return block.replaceTags();
44 }
45
46 private void setError(int i) {
47 String s = page.substring(0, i) + "####BUG####" + page.substring(i);
48 s = PageParser.escapeHtml(s);
49 result = new StringBuilder();
50 result.append(s);
51 }
52
53 private String parseBlockUntil(String end) throws ParseException {
54 PageParser block = new PageParser(page, settings, pos);
55 block.parseAll();
56 if (!block.readIf(end)) {
57 throw new ParseException(page, block.pos);
58 }
59 pos = block.pos;
60 return block.result.toString();
61 }
62
63 private String replaceTags() {
64 try {
65 parseAll();
66 if (pos != len) {
67 setError(pos);
68 }
69 } catch (ParseException e) {
70 setError(pos);
71 }
72 return result.toString();
73 }
74
75 @SuppressWarnings("unchecked")
76 private void parseAll() throws ParseException {
77 StringBuilder buff = result;
78 String p = page;
79 int i = pos;
80 for (; i < len; i++) {
81 char c = p.charAt(i);
82 switch (c) {
83 case '<': {
84 if (p.charAt(i + 3) == ':' && p.charAt(i + 1) == '/') {
85 // end tag
86 pos = i;
87 return;
88 } else if (p.charAt(i + 2) == ':') {
89 pos = i;
90 if (readIf("<c:forEach")) {
91 String var = readParam("var");
92 String items = readParam("items");
93 read(">");
94 int start = pos;
95 List<Object> list = (List<Object>) get(items);
96 if (list == null) {
97 result.append("?items?");
98 list = New.arrayList();
99 }
100 if (list.size() == 0) {
101 parseBlockUntil("</c:forEach>");
102 }
103 for (Object o : list) {
104 settings.put(var, o);
105 pos = start;
106 String block = parseBlockUntil("</c:forEach>");
107 result.append(block);
108 }
109 } else if (readIf("<c:if")) {
110 String test = readParam("test");
111 int eq = test.indexOf("=='");
112 if (eq < 0) {
113 setError(i);
114 return;
115 }
116 String val = test.substring(eq + 3, test.length() - 1);
117 test = test.substring(0, eq);
118 String value = (String) get(test);
119 read(">");
120 String block = parseBlockUntil("</c:if>");
121 pos--;
122 if (value.equals(val)) {
123 result.append(block);
124 }
125 } else {
126 setError(i);
127 return;
128 }
129 i = pos;
130 } else {
131 buff.append(c);
132 }
133 break;
134 }
135 case '$':
136 if (p.length() > i + 1 && p.charAt(i + 1) == '{') {
137 i += 2;
138 int j = p.indexOf('}', i);
139 if (j < 0) {
140 setError(i);
141 return;
142 }
143 String item = p.substring(i, j).trim();
144 i = j;
145 String s = (String) get(item);
146 replaceTags(s);
147 } else {
148 buff.append(c);
149 }
150 break;
151 default:
152 buff.append(c);
153 break;
154 }
155 }
156 pos = i;
157 }
158
159 @SuppressWarnings("unchecked")
160 private Object get(String item) {
161 int dot = item.indexOf('.');
162 if (dot >= 0) {
163 String sub = item.substring(dot + 1);
164 item = item.substring(0, dot);
165 HashMap<String, Object> map = (HashMap<String, Object>) settings.get(item);
166 if (map == null) {
167 return "?" + item + "?";
168 }
169 return map.get(sub);
170 }
171 return settings.get(item);
172 }
173
174 private void replaceTags(String s) {
175 if (s != null) {
176 result.append(PageParser.parse(s, settings));
177 }
178 }
179
180 private String readParam(String name) throws ParseException {
181 read(name);
182 read("=");
183 read("\"");
184 int start = pos;
185 while (page.charAt(pos) != '"') {
186 pos++;
187 }
188 int end = pos;
189 read("\"");
190 String s = page.substring(start, end);
191 return PageParser.parse(s, settings);
192 }
193
194 private void skipSpaces() {
195 while (page.charAt(pos) == ' ') {
196 pos++;
197 }
198 }
199
200 private void read(String s) throws ParseException {
201 if (!readIf(s)) {
202 throw new ParseException(s, pos);
203 }
204 }
205
206 private boolean readIf(String s) {
207 skipSpaces();
208 if (page.regionMatches(pos, s, 0, s.length())) {
209 pos += s.length();
210 skipSpaces();
211 return true;
212 }
213 return false;
214 }
215
216 /**
217 * Convert data to HTML, but don't convert newlines and multiple spaces.
218 *
219 * @param s the data
220 * @return the escaped html text
221 */
222 static String escapeHtmlData(String s) {
223 return escapeHtml(s, false);
224 }
225
226 /**
227 * Convert data to HTML, including newlines and multiple spaces.
228 *
229 * @param s the data
230 * @return the escaped html text
231 */
232 public static String escapeHtml(String s) {
233 return escapeHtml(s, true);
234 }
235
236 private static String escapeHtml(String s, boolean convertBreakAndSpace) {
237 if (s == null) {
238 return null;
239 }
240 if (convertBreakAndSpace) {
241 if (s.length() == 0) {
242 return "&nbsp;";
243 }
244 }
245 StringBuilder buff = new StringBuilder(s.length());
246 boolean convertSpace = true;
247 for (int i = 0; i < s.length(); i++) {
248 char c = s.charAt(i);
249 if (c == ' ') {
250 if (convertSpace && convertBreakAndSpace) {
251 buff.append("&nbsp;");
252 } else {
253 buff.append(' ');
254 convertSpace = true;
255 }
256 continue;
257 }
258 convertSpace = false;
259 switch (c) {
260 case '$':
261 // so that ${ } in the text is interpreted correctly
262 buff.append("&#36;");
263 break;
264 case '<':
265 buff.append("&lt;");
266 break;
267 case '>':
268 buff.append("&gt;");
269 break;
270 case '&':
271 buff.append("&amp;");
272 break;
273 case '"':
274 buff.append("&quot;");
275 break;
276 case '\'':
277 buff.append("&#39;");
278 break;
279 case '\n':
280 if (convertBreakAndSpace) {
281 buff.append("<br />");
282 convertSpace = true;
283 } else {
284 buff.append(c);
285 }
286 break;
287 default:
288 if (c >= 128) {
289 buff.append("&#").append((int) c).append(';');
290 } else {
291 buff.append(c);
292 }
293 break;
294 }
295 }
296 return buff.toString();
297 }
298
299 /**
300 * Escape text as a the javascript string.
301 *
302 * @param s the text
303 * @return the javascript string
304 */
305 static String escapeJavaScript(String s) {
306 if (s == null) {
307 return null;
308 }
309 if (s.length() == 0) {
310 return "";
311 }
312 StringBuilder buff = new StringBuilder(s.length());
313 for (int i = 0; i < s.length(); i++) {
314 char c = s.charAt(i);
315 switch (c) {
316 case '"':
317 buff.append("\\\"");
318 break;
319 case '\'':
320 buff.append("\\'");
321 break;
322 case '\\':
323 buff.append("\\\\");
324 break;
325 case '\n':
326 buff.append("\\n");
327 break;
328 case '\r':
329 buff.append("\\r");
330 break;
331 case '\t':
332 buff.append("\\t");
333 break;
334 default:
335 buff.append(c);
336 break;
337 }
338 }
339 return buff.toString();
340 }
341 }
342