1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.rendering.wikimodel.impl

File WikiScannerUtil.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart9.png
41% of files have more coverage

Code metrics

86
138
15
1
477
287
70
0.51
9.2
15
4.67

Classes

Class Line # Actions
WikiScannerUtil 32 138 0% 70 32
0.866108886.6%
 

Contributing tests

This file is covered by 466 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.rendering.wikimodel.impl;
21   
22    import java.util.List;
23   
24    import org.xwiki.rendering.wikimodel.WikiParameter;
25   
26    /**
27    * This class contains some utility methods used by scanners.
28    *
29    * @version $Id: 712fba3ebe77aad51abf943a66a44c38eec2025b $
30    * @since 4.0M1
31    */
 
32    public class WikiScannerUtil
33    {
34    /**
35    * The default character to use has escaping char.
36    */
37    private static final char DEFAULT_ESCAPECHAR = '\u005c\u005c';
38   
39    /**
40    * Extracts and returns a substring of the given string starting from the
41    * given open sequence and finishing by the specified close sequence. This
42    * method unescapes all symbols prefixed by the given escape symbol.
43    *
44    * @param str from this string the substring framed by the specified open
45    * and close sequence will be returned
46    * @param open the start substring sequence
47    * @param close the closing substring sequence
48    * @return a substring of the given string starting from the given open
49    * sequence and finishing by the specified close sequence
50    */
 
51  203 toggle public static String extractSubstring(String str, String open, String close)
52    {
53  203 return extractSubstring(str, open, close, DEFAULT_ESCAPECHAR, true);
54    }
55   
56    /**
57    * Extracts and returns a substring of the given string starting from the
58    * given open sequence and finishing by the specified close sequence. This
59    * method unescapes all symbols prefixed by the given escape symbol.
60    *
61    * @param str from this string the substring framed by the specified open
62    * and close sequence will be returned
63    * @param open the start substring sequence
64    * @param close the closing substring sequence
65    * @param escape the escape symbol
66    * @return a substring of the given string starting from the given open
67    * sequence and finishing by the specified close sequence
68    */
 
69  12 toggle public static String extractSubstring(
70    String str,
71    String open,
72    String close,
73    char escape)
74    {
75  12 return extractSubstring(str, open, close, escape, true);
76    }
77   
78    /**
79    * Extracts and returns a substring of the given string starting from the
80    * given open sequence and finishing by the specified close sequence. This
81    * method unescapes all symbols prefixed by the given escape symbol.
82    *
83    * @param str from this string the substring framed by the specified open
84    * and close sequence will be returned
85    * @param open the start substring sequence
86    * @param close the closing substring sequence
87    * @param escape the escape symbol
88    * @param cleanEscape indicate if the escaping char has to be removed.
89    * Useful when the substring use the same escaping that the string.
90    * @return a substring of the given string starting from the given open
91    * sequence and finishing by the specified close sequence
92    */
 
93  61330 toggle public static String extractSubstring(
94    String str,
95    String open,
96    String close,
97    char escape,
98    boolean cleanEscape)
99    {
100  61330 int i;
101  61330 StringBuffer buf = new StringBuffer();
102  61329 int len = str.length();
103  61451 for (i = 0; i < len; i++) {
104  61281 if (str.startsWith(open, i)) {
105  61160 i += open.length();
106  61160 break;
107    }
108    }
109   
110  61330 boolean escaped = false;
111  2389539 for (; i < len; i++) {
112  2389371 if (escaped) {
113  22 char ch = str.charAt(i);
114  22 buf.append(ch);
115  22 escaped = false;
116    } else {
117  2389362 if (str.startsWith(close, i)) {
118  61160 break;
119    }
120  2328205 char ch = str.charAt(i);
121  2328199 escaped = ch == escape;
122  2328194 if (!escaped || !cleanEscape) {
123  2328178 buf.append(ch);
124    }
125    }
126    }
127   
128  61330 return buf.toString();
129    }
130   
131    /**
132    * This method copies to the given buffer all characters from the specified
133    * position of the character array to the next delimiter position. This
134    * method returns the next position just after the delimiter (or the length
135    * of the array if no delimiters was found).
136    *
137    * @param array the array of character used as a source of chars
138    * @param pos the start position in the array
139    * @param delimiter the delimiter; this method copies all character from the
140    * current position to the first delimiter sequence
141    * @param buf the buffer where the content should be appended
142    * @return the next position just after the delimiter of the end of the
143    * sequence
144    */
 
145  0 toggle public static int getNextSequence(
146    char[] array,
147    int pos,
148    char[] delimiter,
149    StringBuffer buf)
150    {
151  0 buf.delete(0, buf.length());
152  0 char quot = 0;
153  0 for (; pos < array.length; pos++) {
154  0 char ch = array[pos];
155  0 if (quot != 0) {
156  0 if (ch == quot) {
157  0 quot = 0;
158    }
159    } else {
160  0 if (ch == '\"') {
161  0 quot = ch;
162    } else {
163    // Checks if a new delimiter sequence was found in the
164    // current position
165  0 int i = skipSequence(array, pos, delimiter);
166  0 if (i > pos) {
167  0 pos = i;
168  0 break;
169    }
170    }
171    }
172  0 buf.append(ch);
173    }
174  0 return pos;
175    }
176   
177    /**
178    * @param array from this array of bytes the next token will be returned
179    * @param pos the current position in the array of bytes
180    * @param buf to this buffer the extracted token value will be appended
181    * @param trim this array is used to return the boolean flag specifying if
182    * the value collected in the buffer should be trimmed or not
183    * @param escapeChar the escaping character
184    * @return the new position in the array after extracting of a new token
185    */
 
186  608641 toggle private static int getNextToken(
187    char[] array,
188    int pos,
189    char[] delimiter,
190    StringBuffer buf,
191    boolean[] trim,
192    char escapeChar)
193    {
194  608647 buf.delete(0, buf.length());
195  608651 boolean escaped = false;
196  608651 if (pos < array.length && (array[pos] == '\'' || array[pos] == '"')) {
197  302674 trim[0] = false;
198  302677 char endChar = array[pos];
199  302677 pos++;
200  4593797 for (; pos < array.length && (escaped || array[pos] != endChar); pos++) {
201  4291148 if (escaped) {
202  1418 buf.append(array[pos]);
203  1418 escaped = false;
204    } else {
205  4289730 escaped = array[pos] == escapeChar;
206  4289753 if (!escaped) {
207  4288352 buf.append(array[pos]);
208    }
209    }
210    }
211  302676 if (pos < array.length) {
212  302627 pos++;
213    }
214    } else {
215  305971 trim[0] = true;
216  2040269 for (; pos < array.length; pos++) {
217  2039056 if (escaped) {
218  7 buf.append(array[pos]);
219  7 escaped = false;
220    } else {
221  2039046 if ((array[pos] == '=' || skipSequence(
222    array,
223    pos,
224    delimiter) > pos))
225    {
226  304694 break;
227    }
228  1734351 if (array[pos] == '\'' || array[pos] == '"') {
229  62 break;
230    }
231   
232  1734287 escaped = array[pos] == escapeChar;
233  1734287 if (!escaped) {
234  1734282 buf.append(array[pos]);
235    }
236    }
237    }
238    }
239   
240  608652 return pos;
241    }
242   
243    /**
244    * Indicate if the specified sequence starts from the given position in the
245    * character array.
246    *
247    * @param array the array of characters
248    * @param arrayPos the position of the first character in the array;
249    * starting from this position the sequence should be skipped
250    * @param sequence the sequence of characters to match
251    * @return true if the sequence is found, false otherwise
252    */
 
253  48 toggle public static boolean matchesSequence(
254    char[] array,
255    int arrayPos,
256    char[] sequence)
257    {
258  48 int i;
259  48 int j;
260  162 for (i = arrayPos, j = 0; i < array.length && j < sequence.length; i++, j++) {
261  124 if (array[i] != sequence[j]) {
262  10 break;
263    }
264    }
265  48 return j == sequence.length;
266    }
267   
268    /**
269    * Moves forward the current position in the array until the first not empty
270    * character is found.
271    *
272    * @param array the array of characters where the spaces are searched
273    * @param pos the current position in the array; starting from this position
274    * the spaces will be searched
275    * @param buf to this buffer all not empty characters will be added
276    * @return the new position int the array of characters
277    */
 
278  680881 toggle private static int removeSpaces(char[] array, int pos, StringBuffer buf)
279    {
280  680883 buf.delete(0, buf.length());
281  1162540 for (; pos < array.length
282    && (array[pos] == '=' || Character.isSpaceChar(array[pos])); pos++)
283    {
284  481656 if (array[pos] == '=') {
285  304240 buf.append(array[pos]);
286    }
287    }
288  680883 return pos;
289    }
290   
291    /**
292    * Skips the specified sequence if it starts from the given position in the
293    * character array.
294    *
295    * @param array the array of characters
296    * @param arrayPos the position of the first character in the array;
297    * starting from this position the sequence should be skipped
298    * @param sequence the sequence of characters to skip
299    * @return a new value of the character counter
300    */
 
301  2040058 toggle public static int skipSequence(char[] array, int arrayPos, char[] sequence)
302    {
303  2040076 int i;
304  2040080 int j;
305  2041358 for (i = arrayPos, j = 0; i < array.length && j < sequence.length; i++, j++) {
306  2040083 if (array[i] != sequence[j]) {
307  2038801 break;
308    }
309    }
310  2040083 return j == sequence.length ? i : arrayPos;
311    }
312   
313    /**
314    * Splits the given string into a set of key-value pairs; all extracted
315    * values will be added to the given list
316    *
317    * @param str the string to split
318    * @param list to this list all extracted values will be added
319    */
 
320  277 toggle public static int splitToPairs(String str, List<WikiParameter> list)
321    {
322  277 return splitToPairs(str, list, null);
323    }
324   
 
325  322840 toggle public static int splitToPairs(
326    String str,
327    List<WikiParameter> list,
328    char escapeChar)
329    {
330  322845 return splitToPairs(str, list, null, null, escapeChar);
331    }
332   
333    /**
334    * Splits the given string into a set of key-value pairs; all extracted
335    * values will be added to the given list
336    *
337    * @param str the string to split
338    * @param list to this list all extracted values will be added
339    * @param delimiter a delimiter for individual key/value pairs
340    */
 
341  288 toggle public static int splitToPairs(
342    String str,
343    List<WikiParameter> list,
344    String delimiter)
345    {
346  288 return splitToPairs(str, list, delimiter, null);
347    }
348   
 
349  327 toggle public static int splitToPairs(
350    String str,
351    List<WikiParameter> list,
352    String delimiter,
353    String end)
354    {
355  327 return splitToPairs(str, list, delimiter, end, DEFAULT_ESCAPECHAR);
356    }
357   
358    /**
359    * Splits the given string into a set of key-value pairs; all extracted
360    * values will be added to the given list
361    *
362    * @param str the string to split
363    * @param list to this list all extracted values will be added
364    * @param delimiter a delimiter for individual key/value pairs
365    * @param end the ending sequence, if null it's not taken into account
366    * @param escapeChar the escaping character
367    * @return the index where parser stopped
368    */
 
369  323161 toggle public static int splitToPairs(
370    String str,
371    List<WikiParameter> list,
372    String delimiter,
373    String end,
374    char escapeChar)
375    {
376  323170 if (str == null) {
377  18 return 0;
378    }
379  323156 char[] array = str.toCharArray();
380  323154 if (delimiter == null) {
381  323143 delimiter = " ";
382    }
383  323154 char[] delimiterArray = delimiter.toCharArray();
384  323156 char[] endArray = end != null ? end.toCharArray() : new char[0];
385  323155 StringBuffer buf = new StringBuffer();
386  323150 int i = 0;
387  323153 boolean[] trim = {false};
388  627563 for (; i < array.length; ) {
389  376469 String key = null;
390  376468 String value = null;
391  376467 i = removeSpaces(array, i, buf);
392  376463 if (i >= array.length) {
393  72019 break;
394    }
395  304449 int prev = i;
396  304449 i = skipSequence(array, i, delimiterArray);
397  304448 if (i >= array.length) {
398  0 break;
399    }
400  304451 if (i > prev) {
401  4 i = removeSpaces(array, i, buf);
402  4 if (i >= array.length) {
403  0 break;
404    }
405    }
406    // if provided ending sequence is found, we stop parsing
407  304450 if (end != null && matchesSequence(array, i, endArray)) {
408  38 break;
409    }
410   
411  304411 i = getNextToken(array, i, delimiterArray, buf, trim, escapeChar);
412  304412 key = buf.toString().trim();
413   
414  304413 i = removeSpaces(array, i, buf);
415  304409 if (buf.indexOf("=") >= 0) {
416  304235 i = getNextToken(
417    array,
418    i,
419    delimiterArray,
420    buf,
421    trim,
422    escapeChar);
423  304240 value = buf.toString();
424  304239 if (trim[0]) {
425  1629 value = value.trim();
426    }
427    }
428   
429  304412 WikiParameter entry = new WikiParameter(key, value);
430  304411 list.add(entry);
431    }
432   
433  323150 return i;
434    }
435   
436    /**
437    * Unescapes the given string and returns the result. This method uses the
438    * default escape symbol (see {@link #DEFAULT_ESCAPECHAR}).
439    *
440    * @param str the string to unescape
441    * @return an unescaped string
442    */
 
443  343 toggle public static String unescape(String str)
444    {
445  343 return unescape(str, DEFAULT_ESCAPECHAR);
446    }
447   
448    /**
449    * Unescapes the given string and returns the result.
450    *
451    * @param str the string to unescape
452    * @param escape the symbol used to escape characters
453    * @return an unescaped string
454    */
 
455  343 toggle public static String unescape(String str, char escape)
456    {
457  343 if (str == null) {
458  0 return "";
459    }
460  343 StringBuffer buf = new StringBuffer();
461  343 char[] array = str.toCharArray();
462  343 boolean escaped = false;
463  1304 for (int i = 0; i < array.length; i++) {
464  961 char ch = array[i];
465  961 if (escaped) {
466  1 buf.append(ch);
467  1 escaped = false;
468    } else {
469  960 escaped = (ch == escape);
470  960 if (!escaped) {
471  959 buf.append(ch);
472    }
473    }
474    }
475  343 return buf.toString();
476    }
477    }