1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rendering.wikimodel.impl

File WikiScannerUtil.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart9.png
38% 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 34
0.857740685.8%
 

Contributing tests

This file is covered by 431 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  205 toggle public static String extractSubstring(String str, String open, String close)
52    {
53  205 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  6530 toggle public static String extractSubstring(
94    String str,
95    String open,
96    String close,
97    char escape,
98    boolean cleanEscape)
99    {
100  6530 int i;
101  6530 StringBuffer buf = new StringBuffer();
102  6530 int len = str.length();
103  6652 for (i = 0; i < len; i++) {
104  6481 if (str.startsWith(open, i)) {
105  6359 i += open.length();
106  6359 break;
107    }
108    }
109   
110  6530 boolean escaped = false;
111  242529 for (; i < len; i++) {
112  242358 if (escaped) {
113  22 char ch = str.charAt(i);
114  22 buf.append(ch);
115  22 escaped = false;
116    } else {
117  242336 if (str.startsWith(close, i)) {
118  6359 break;
119    }
120  235977 char ch = str.charAt(i);
121  235977 escaped = ch == escape;
122  235977 if (!escaped || !cleanEscape) {
123  235971 buf.append(ch);
124    }
125    }
126    }
127   
128  6530 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  32638 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  32638 buf.delete(0, buf.length());
195  32638 boolean escaped = false;
196  32638 if (pos < array.length && (array[pos] == '\'' || array[pos] == '"')) {
197  15773 trim[0] = false;
198  15773 char endChar = array[pos];
199  15773 pos++;
200  245271 for (; pos < array.length && (escaped || array[pos] != endChar); pos++) {
201  229497 if (escaped) {
202  69 buf.append(array[pos]);
203  69 escaped = false;
204    } else {
205  229428 escaped = array[pos] == escapeChar;
206  229429 if (!escaped) {
207  229360 buf.append(array[pos]);
208    }
209    }
210    }
211  15773 if (pos < array.length) {
212  15771 pos++;
213    }
214    } else {
215  16865 trim[0] = true;
216  94298 for (; pos < array.length; pos++) {
217  93876 if (escaped) {
218  7 buf.append(array[pos]);
219  7 escaped = false;
220    } else {
221  93869 if ((array[pos] == '=' || skipSequence(
222    array,
223    pos,
224    delimiter) > pos))
225    {
226  16443 break;
227    }
228  77426 if (array[pos] == '\'' || array[pos] == '"') {
229  0 break;
230    }
231   
232  77426 escaped = array[pos] == escapeChar;
233  77426 if (!escaped) {
234  77419 buf.append(array[pos]);
235    }
236    }
237    }
238    }
239   
240  32638 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  29 toggle public static boolean matchesSequence(
254    char[] array,
255    int arrayPos,
256    char[] sequence)
257    {
258  29 int i;
259  29 int j;
260  86 for (i = arrayPos, j = 0; i < array.length && j < sequence.length; i++, j++) {
261  67 if (array[i] != sequence[j]) {
262  10 break;
263    }
264    }
265  29 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  39288 toggle private static int removeSpaces(char[] array, int pos, StringBuffer buf)
279    {
280  39288 buf.delete(0, buf.length());
281  73700 for (; pos < array.length
282    && (array[pos] == '=' || Character.isSpaceChar(array[pos])); pos++)
283    {
284  34412 if (array[pos] == '=') {
285  16311 buf.append(array[pos]);
286    }
287    }
288  39288 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  93922 toggle public static int skipSequence(char[] array, int arrayPos, char[] sequence)
302    {
303  93922 int i;
304  93922 int j;
305  94081 for (i = arrayPos, j = 0; i < array.length && j < sequence.length; i++, j++) {
306  93922 if (array[i] != sequence[j]) {
307  93763 break;
308    }
309    }
310  93922 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  280 toggle public static int splitToPairs(String str, List<WikiParameter> list)
321    {
322  280 return splitToPairs(str, list, null);
323    }
324   
 
325  17879 toggle public static int splitToPairs(
326    String str,
327    List<WikiParameter> list,
328    char escapeChar)
329    {
330  17879 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  296 toggle public static int splitToPairs(
342    String str,
343    List<WikiParameter> list,
344    String delimiter)
345    {
346  296 return splitToPairs(str, list, delimiter, null);
347    }
348   
 
349  316 toggle public static int splitToPairs(
350    String str,
351    List<WikiParameter> list,
352    String delimiter,
353    String end)
354    {
355  316 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  18193 toggle public static int splitToPairs(
370    String str,
371    List<WikiParameter> list,
372    String delimiter,
373    String end,
374    char escapeChar)
375    {
376  18194 if (str == null) {
377  18 return 0;
378    }
379  18177 char[] array = str.toCharArray();
380  18175 if (delimiter == null) {
381  18159 delimiter = " ";
382    }
383  18177 char[] delimiterArray = delimiter.toCharArray();
384  18176 char[] endArray = end != null ? end.toCharArray() : new char[0];
385  18177 StringBuffer buf = new StringBuffer();
386  18177 int i = 0;
387  18177 boolean[] trim = {false};
388  34504 for (; i < array.length; ) {
389  22952 String key = null;
390  22952 String value = null;
391  22952 i = removeSpaces(array, i, buf);
392  22952 if (i >= array.length) {
393  6606 break;
394    }
395  16346 int prev = i;
396  16346 i = skipSequence(array, i, delimiterArray);
397  16346 if (i >= array.length) {
398  0 break;
399    }
400  16346 if (i > prev) {
401  9 i = removeSpaces(array, i, buf);
402  9 if (i >= array.length) {
403  0 break;
404    }
405    }
406    // if provided ending sequence is found, we stop parsing
407  16346 if (end != null && matchesSequence(array, i, endArray)) {
408  19 break;
409    }
410   
411  16327 i = getNextToken(array, i, delimiterArray, buf, trim, escapeChar);
412  16327 key = buf.toString().trim();
413   
414  16327 i = removeSpaces(array, i, buf);
415  16327 if (buf.indexOf("=") >= 0) {
416  16311 i = getNextToken(
417    array,
418    i,
419    delimiterArray,
420    buf,
421    trim,
422    escapeChar);
423  16311 value = buf.toString();
424  16311 if (trim[0]) {
425  542 value = value.trim();
426    }
427    }
428   
429  16327 WikiParameter entry = new WikiParameter(key, value);
430  16327 list.add(entry);
431    }
432   
433  18176 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  357 toggle public static String unescape(String str)
444    {
445  357 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  357 toggle public static String unescape(String str, char escape)
456    {
457  357 if (str == null) {
458  0 return "";
459    }
460  357 StringBuffer buf = new StringBuffer();
461  357 char[] array = str.toCharArray();
462  357 boolean escaped = false;
463  1332 for (int i = 0; i < array.length; i++) {
464  975 char ch = array[i];
465  975 if (escaped) {
466  1 buf.append(ch);
467  1 escaped = false;
468    } else {
469  974 escaped = (ch == escape);
470  974 if (!escaped) {
471  973 buf.append(ch);
472    }
473    }
474    }
475  357 return buf.toString();
476    }
477    }