1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki.util

File Util.java

 

Coverage histogram

../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

46
470
37
1
908
693
78
0.17
12.7
37
2.11

Classes

Class Line # Actions
Util 74 470 0% 78 115
0.792043479.2%
 

Contributing tests

This file is covered by 186 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 com.xpn.xwiki.util;
21   
22    import java.io.BufferedReader;
23    import java.io.File;
24    import java.io.FileInputStream;
25    import java.io.IOException;
26    import java.io.InputStream;
27    import java.io.StreamTokenizer;
28    import java.io.StringReader;
29    import java.net.URLDecoder;
30    import java.net.URLEncoder;
31    import java.security.MessageDigest;
32    import java.security.NoSuchAlgorithmException;
33    import java.util.ArrayList;
34    import java.util.Date;
35    import java.util.HashMap;
36    import java.util.HashSet;
37    import java.util.Hashtable;
38    import java.util.List;
39    import java.util.Locale;
40    import java.util.Map;
41    import java.util.MissingResourceException;
42    import java.util.Set;
43    import java.util.Vector;
44   
45    import javax.servlet.http.Cookie;
46    import javax.servlet.http.HttpServletRequest;
47    import javax.xml.parsers.DocumentBuilderFactory;
48    import javax.xml.parsers.ParserConfigurationException;
49   
50    import org.apache.commons.lang3.ArrayUtils;
51    import org.apache.commons.lang3.StringUtils;
52    import org.apache.oro.text.PatternCache;
53    import org.apache.oro.text.PatternCacheLRU;
54    import org.apache.oro.text.perl.Perl5Util;
55    import org.apache.oro.text.regex.MalformedPatternException;
56    import org.apache.oro.text.regex.MatchResult;
57    import org.apache.oro.text.regex.Pattern;
58    import org.apache.oro.text.regex.PatternMatcherInput;
59    import org.apache.oro.text.regex.Perl5Matcher;
60    import org.slf4j.Logger;
61    import org.slf4j.LoggerFactory;
62    import org.xml.sax.InputSource;
63    import org.xml.sax.SAXException;
64    import org.xwiki.container.Container;
65    import org.xwiki.xml.XMLUtils;
66   
67    import com.xpn.xwiki.XWikiContext;
68    import com.xpn.xwiki.XWikiException;
69    import com.xpn.xwiki.monitor.api.MonitorPlugin;
70    import com.xpn.xwiki.render.WikiSubstitution;
71    import com.xpn.xwiki.web.Utils;
72    import com.xpn.xwiki.web.XWikiRequest;
73   
 
74    public class Util
75    {
76    /**
77    * Encoding used for URL encoding/decoding. UTF-8 is the default encoding in RFC 3986, and is recommended by the W3
78    * consortium.
79    */
80    private static final String URL_ENCODING = "UTF-8";
81   
82    private static final Logger LOGGER = LoggerFactory.getLogger(Util.class);
83   
84    private static PatternCache patterns = new PatternCacheLRU(200);
85   
86    private Perl5Matcher matcher = new Perl5Matcher();
87   
88    private Perl5Util p5util = new Perl5Util(getPatterns());
89   
 
90  70 toggle public String substitute(String pattern, String text)
91    {
92  70 return getP5util().substitute(pattern, text);
93    }
94   
 
95  29 toggle public boolean match(String pattern, String text)
96    {
97  29 return getP5util().match(pattern, text);
98    }
99   
 
100  0 toggle public boolean matched()
101    {
102  0 return (getP5util().getMatch() != null);
103    }
104   
 
105  0 toggle public String substitute(String pattern, String substitution, String text)
106    {
107  0 WikiSubstitution subst = new WikiSubstitution(this, pattern);
108  0 subst.setSubstitution(substitution);
109  0 return subst.substitute(text);
110    }
111   
 
112  0 toggle public Perl5Matcher getMatcher()
113    {
114  0 return this.matcher;
115    }
116   
 
117  99 toggle public Perl5Util getP5util()
118    {
119  99 return this.p5util;
120    }
121   
 
122  984 toggle public List<String> getAllMatches(String content, String spattern, int group) throws MalformedPatternException
123    {
124  984 List<String> list = new ArrayList<String>();
125  984 PatternMatcherInput input = new PatternMatcherInput(content);
126  984 Pattern pattern = patterns.addPattern(spattern);
127  994 while (this.matcher.contains(input, pattern)) {
128  10 MatchResult result = this.matcher.getMatch();
129  10 String smatch = result.group(group);
130  10 list.add(smatch);
131    }
132   
133  984 return list;
134    }
135   
 
136  984 toggle public List<String> getUniqueMatches(String content, String spattern, int group) throws MalformedPatternException
137    {
138    // Remove duplicate entries
139  984 Set<String> uniqueMatches = new HashSet<String>();
140  984 uniqueMatches.addAll(getAllMatches(content, spattern, group));
141   
142  984 List<String> matches = new ArrayList<String>();
143  984 matches.addAll(uniqueMatches);
144   
145  984 return matches;
146    }
147   
 
148  0 toggle public static String cleanValue(String value)
149    {
150  0 value = StringUtils.replace(value, "\r\r\n", "%_N_%");
151  0 value = StringUtils.replace(value, "\r\n", "%_N_%");
152  0 value = StringUtils.replace(value, "\n\r", "%_N_%");
153  0 value = StringUtils.replace(value, "\r", "\n");
154  0 value = StringUtils.replace(value, "\n", "%_N_%");
155  0 value = StringUtils.replace(value, "\"", "%_Q_%");
156   
157  0 return value;
158    }
159   
 
160  0 toggle public static String restoreValue(String value)
161    {
162  0 value = StringUtils.replace(value, "%_N_%", "\n");
163  0 value = StringUtils.replace(value, "%_Q_%", "\"");
164   
165  0 return value;
166    }
167   
168    /**
169    * Create a Map from a string holding a space separated list of key=value pairs. If keys or values must contain
170    * spaces, they can be placed inside quotes, like <code>"this key"="a larger value"</code>. To use a quote as part
171    * of a key/value, use <code>%_Q_%</code>.
172    *
173    * @param mapString The string that must be parsed.
174    * @return A Map containing the keys and values. If a key is defined more than once, the last value is used.
175    */
 
176  0 toggle public static Hashtable<String, String> keyValueToHashtable(String mapString) throws IOException
177    {
178  0 Hashtable<String, String> result = new Hashtable<String, String>();
179  0 StreamTokenizer st = new StreamTokenizer(new BufferedReader(new StringReader(mapString)));
180  0 st.resetSyntax();
181  0 st.quoteChar('"');
182  0 st.wordChars('a', 'z');
183  0 st.wordChars('A', 'Z');
184  0 st.whitespaceChars(' ', ' ');
185  0 st.whitespaceChars('=', '=');
186  0 while (st.nextToken() != StreamTokenizer.TT_EOF) {
187  0 String key = st.sval;
188  0 st.nextToken();
189  0 String value = (st.sval != null) ? st.sval : "";
190  0 result.put(key, restoreValue(value));
191    }
192  0 return result;
193    }
194   
 
195  144 toggle public static PatternCache getPatterns()
196    {
197  144 return patterns;
198    }
199   
 
200  45 toggle public static Map<String, String[]> getObject(XWikiRequest request, String prefix)
201    {
202  45 @SuppressWarnings("unchecked")
203    Map<String, String[]> parameters = request.getParameterMap();
204  45 return getSubMap(parameters, prefix);
205    }
206   
 
207  45 toggle public static <T> Map<String, T> getSubMap(Map<String, T> map, String prefix)
208    {
209  45 Map<String, T> result = new HashMap<String, T>();
210  45 for (String name : map.keySet()) {
211  278 if (name.startsWith(prefix + "_")) {
212  96 String newname = name.substring(prefix.length() + 1);
213  96 result.put(newname, map.get(name));
214  182 } else if (name.equals(prefix)) {
215  29 result.put("", map.get(name));
216    }
217    }
218   
219  45 return result;
220    }
221   
 
222  0 toggle public static String getWeb(String fullname)
223    {
224  0 int i = fullname.lastIndexOf(".");
225   
226  0 return fullname.substring(0, i);
227    }
228   
 
229  0 toggle public Vector<String> split(String pattern, String text)
230    {
231  0 Vector<String> results = new Vector<String>();
232  0 getP5util().split(results, pattern, text);
233   
234  0 return results;
235    }
236   
 
237  41 toggle public static boolean contains(String name, String list, String sep)
238    {
239  41 String[] sarray = StringUtils.split(list, sep);
240   
241  40 return ArrayUtils.contains(sarray, name);
242    }
243   
 
244  39 toggle public static String noaccents(String text)
245    {
246  39 String temp = text;
247  39 temp = temp.replaceAll("\u00c0", "A");
248  39 temp = temp.replaceAll("\u00c1", "A");
249  39 temp = temp.replaceAll("\u00c2", "A");
250  39 temp = temp.replaceAll("\u00c3", "A");
251  39 temp = temp.replaceAll("\u00c4", "A");
252  39 temp = temp.replaceAll("\u00c5", "A");
253  39 temp = temp.replaceAll("\u0100", "A");
254  39 temp = temp.replaceAll("\u0102", "A");
255  39 temp = temp.replaceAll("\u0104", "A");
256  39 temp = temp.replaceAll("\u01cd", "A");
257  39 temp = temp.replaceAll("\u01de", "A");
258  39 temp = temp.replaceAll("\u01e0", "A");
259  39 temp = temp.replaceAll("\u01fa", "A");
260  39 temp = temp.replaceAll("\u0200", "A");
261  39 temp = temp.replaceAll("\u0202", "A");
262  39 temp = temp.replaceAll("\u0226", "A");
263  39 temp = temp.replaceAll("\u00e0", "a");
264  39 temp = temp.replaceAll("\u00e1", "a");
265  39 temp = temp.replaceAll("\u00e2", "a");
266  39 temp = temp.replaceAll("\u00e3", "a");
267  39 temp = temp.replaceAll("\u00e4", "a");
268  39 temp = temp.replaceAll("\u00e5", "a");
269  39 temp = temp.replaceAll("\u0101", "a");
270  39 temp = temp.replaceAll("\u0103", "a");
271  39 temp = temp.replaceAll("\u0105", "a");
272  39 temp = temp.replaceAll("\u01ce", "a");
273  39 temp = temp.replaceAll("\u01df", "a");
274  39 temp = temp.replaceAll("\u01e1", "a");
275  39 temp = temp.replaceAll("\u01fb", "a");
276  39 temp = temp.replaceAll("\u0201", "a");
277  39 temp = temp.replaceAll("\u0203", "a");
278  39 temp = temp.replaceAll("\u0227", "a");
279  39 temp = temp.replaceAll("\u00c6", "AE");
280  39 temp = temp.replaceAll("\u01e2", "AE");
281  39 temp = temp.replaceAll("\u01fc", "AE");
282  39 temp = temp.replaceAll("\u00e6", "ae");
283  39 temp = temp.replaceAll("\u01e3", "ae");
284  39 temp = temp.replaceAll("\u01fd", "ae");
285  39 temp = temp.replaceAll("\u008c", "OE");
286  39 temp = temp.replaceAll("\u0152", "OE");
287  39 temp = temp.replaceAll("\u009c", "oe");
288  39 temp = temp.replaceAll("\u0153", "oe");
289  39 temp = temp.replaceAll("\u00c7", "C");
290  39 temp = temp.replaceAll("\u0106", "C");
291  39 temp = temp.replaceAll("\u0108", "C");
292  39 temp = temp.replaceAll("\u010a", "C");
293  39 temp = temp.replaceAll("\u010c", "C");
294  39 temp = temp.replaceAll("\u00e7", "c");
295  39 temp = temp.replaceAll("\u0107", "c");
296  39 temp = temp.replaceAll("\u0109", "c");
297  39 temp = temp.replaceAll("\u010b", "c");
298  39 temp = temp.replaceAll("\u010d", "c");
299  39 temp = temp.replaceAll("\u00d0", "D");
300  39 temp = temp.replaceAll("\u010e", "D");
301  39 temp = temp.replaceAll("\u0110", "D");
302  39 temp = temp.replaceAll("\u00f0", "d");
303  39 temp = temp.replaceAll("\u010f", "d");
304  39 temp = temp.replaceAll("\u0111", "d");
305  39 temp = temp.replaceAll("\u00c8", "E");
306  39 temp = temp.replaceAll("\u00c9", "E");
307  39 temp = temp.replaceAll("\u00ca", "E");
308  39 temp = temp.replaceAll("\u00cb", "E");
309  39 temp = temp.replaceAll("\u0112", "E");
310  39 temp = temp.replaceAll("\u0114", "E");
311  39 temp = temp.replaceAll("\u0116", "E");
312  39 temp = temp.replaceAll("\u0118", "E");
313  39 temp = temp.replaceAll("\u011a", "E");
314  39 temp = temp.replaceAll("\u0204", "E");
315  39 temp = temp.replaceAll("\u0206", "E");
316  39 temp = temp.replaceAll("\u0228", "E");
317  39 temp = temp.replaceAll("\u00e8", "e");
318  39 temp = temp.replaceAll("\u00e9", "e");
319  39 temp = temp.replaceAll("\u00ea", "e");
320  39 temp = temp.replaceAll("\u00eb", "e");
321  39 temp = temp.replaceAll("\u0113", "e");
322  39 temp = temp.replaceAll("\u0115", "e");
323  39 temp = temp.replaceAll("\u0117", "e");
324  39 temp = temp.replaceAll("\u0119", "e");
325  39 temp = temp.replaceAll("\u011b", "e");
326  39 temp = temp.replaceAll("\u01dd", "e");
327  39 temp = temp.replaceAll("\u0205", "e");
328  39 temp = temp.replaceAll("\u0207", "e");
329  39 temp = temp.replaceAll("\u0229", "e");
330  39 temp = temp.replaceAll("\u011c", "G");
331  39 temp = temp.replaceAll("\u011e", "G");
332  39 temp = temp.replaceAll("\u0120", "G");
333  39 temp = temp.replaceAll("\u0122", "G");
334  39 temp = temp.replaceAll("\u01e4", "G");
335  39 temp = temp.replaceAll("\u01e6", "G");
336  39 temp = temp.replaceAll("\u01f4", "G");
337  39 temp = temp.replaceAll("\u011d", "g");
338  39 temp = temp.replaceAll("\u011f", "g");
339  39 temp = temp.replaceAll("\u0121", "g");
340  39 temp = temp.replaceAll("\u0123", "g");
341  39 temp = temp.replaceAll("\u01e5", "g");
342  39 temp = temp.replaceAll("\u01e7", "g");
343  39 temp = temp.replaceAll("\u01f5", "g");
344  39 temp = temp.replaceAll("\u0124", "H");
345  39 temp = temp.replaceAll("\u0126", "H");
346  39 temp = temp.replaceAll("\u021e", "H");
347  39 temp = temp.replaceAll("\u0125", "h");
348  39 temp = temp.replaceAll("\u0127", "h");
349  39 temp = temp.replaceAll("\u021f", "h");
350  39 temp = temp.replaceAll("\u00cc", "I");
351  39 temp = temp.replaceAll("\u00cd", "I");
352  39 temp = temp.replaceAll("\u00ce", "I");
353  39 temp = temp.replaceAll("\u00cf", "I");
354  39 temp = temp.replaceAll("\u0128", "I");
355  39 temp = temp.replaceAll("\u012a", "I");
356  39 temp = temp.replaceAll("\u012c", "I");
357  39 temp = temp.replaceAll("\u012e", "I");
358  39 temp = temp.replaceAll("\u0130", "I");
359  39 temp = temp.replaceAll("\u01cf", "I");
360  39 temp = temp.replaceAll("\u0208", "I");
361  39 temp = temp.replaceAll("\u020a", "I");
362  39 temp = temp.replaceAll("\u00ec", "i");
363  39 temp = temp.replaceAll("\u00ed", "i");
364  39 temp = temp.replaceAll("\u00ee", "i");
365  39 temp = temp.replaceAll("\u00ef", "i");
366  39 temp = temp.replaceAll("\u0129", "i");
367  39 temp = temp.replaceAll("\u012b", "i");
368  39 temp = temp.replaceAll("\u012d", "i");
369  39 temp = temp.replaceAll("\u012f", "i");
370  39 temp = temp.replaceAll("\u0131", "i");
371  39 temp = temp.replaceAll("\u01d0", "i");
372  39 temp = temp.replaceAll("\u0209", "i");
373  39 temp = temp.replaceAll("\u020b", "i");
374  39 temp = temp.replaceAll("\u0132", "IJ");
375  39 temp = temp.replaceAll("\u0133", "ij");
376  39 temp = temp.replaceAll("\u0134", "J");
377  39 temp = temp.replaceAll("\u0135", "j");
378  39 temp = temp.replaceAll("\u0136", "K");
379  39 temp = temp.replaceAll("\u01e8", "K");
380  39 temp = temp.replaceAll("\u0137", "k");
381  39 temp = temp.replaceAll("\u0138", "k");
382  39 temp = temp.replaceAll("\u01e9", "k");
383  39 temp = temp.replaceAll("\u0139", "L");
384  39 temp = temp.replaceAll("\u013b", "L");
385  39 temp = temp.replaceAll("\u013d", "L");
386  39 temp = temp.replaceAll("\u013f", "L");
387  39 temp = temp.replaceAll("\u0141", "L");
388  39 temp = temp.replaceAll("\u013a", "l");
389  39 temp = temp.replaceAll("\u013c", "l");
390  39 temp = temp.replaceAll("\u013e", "l");
391  39 temp = temp.replaceAll("\u0140", "l");
392  39 temp = temp.replaceAll("\u0142", "l");
393  39 temp = temp.replaceAll("\u0234", "l");
394  39 temp = temp.replaceAll("\u00d1", "N");
395  39 temp = temp.replaceAll("\u0143", "N");
396  39 temp = temp.replaceAll("\u0145", "N");
397  39 temp = temp.replaceAll("\u0147", "N");
398  39 temp = temp.replaceAll("\u014a", "N");
399  39 temp = temp.replaceAll("\u01f8", "N");
400  39 temp = temp.replaceAll("\u00f1", "n");
401  39 temp = temp.replaceAll("\u0144", "n");
402  39 temp = temp.replaceAll("\u0146", "n");
403  39 temp = temp.replaceAll("\u0148", "n");
404  39 temp = temp.replaceAll("\u0149", "n");
405  39 temp = temp.replaceAll("\u014b", "n");
406  39 temp = temp.replaceAll("\u01f9", "n");
407  39 temp = temp.replaceAll("\u0235", "n");
408  39 temp = temp.replaceAll("\u00d2", "O");
409  39 temp = temp.replaceAll("\u00d3", "O");
410  39 temp = temp.replaceAll("\u00d4", "O");
411  39 temp = temp.replaceAll("\u00d5", "O");
412  39 temp = temp.replaceAll("\u00d6", "O");
413  39 temp = temp.replaceAll("\u00d8", "O");
414  39 temp = temp.replaceAll("\u014c", "O");
415  39 temp = temp.replaceAll("\u014e", "O");
416  39 temp = temp.replaceAll("\u0150", "O");
417  39 temp = temp.replaceAll("\u01d1", "O");
418  39 temp = temp.replaceAll("\u01ea", "O");
419  39 temp = temp.replaceAll("\u01ec", "O");
420  39 temp = temp.replaceAll("\u01fe", "O");
421  39 temp = temp.replaceAll("\u020c", "O");
422  39 temp = temp.replaceAll("\u020e", "O");
423  39 temp = temp.replaceAll("\u022a", "O");
424  39 temp = temp.replaceAll("\u022c", "O");
425  39 temp = temp.replaceAll("\u022e", "O");
426  39 temp = temp.replaceAll("\u0230", "O");
427  39 temp = temp.replaceAll("\u00f2", "o");
428  39 temp = temp.replaceAll("\u00f3", "o");
429  39 temp = temp.replaceAll("\u00f4", "o");
430  39 temp = temp.replaceAll("\u00f5", "o");
431  39 temp = temp.replaceAll("\u00f6", "o");
432  39 temp = temp.replaceAll("\u00f8", "o");
433  39 temp = temp.replaceAll("\u014d", "o");
434  39 temp = temp.replaceAll("\u014f", "o");
435  39 temp = temp.replaceAll("\u0151", "o");
436  39 temp = temp.replaceAll("\u01d2", "o");
437  39 temp = temp.replaceAll("\u01eb", "o");
438  39 temp = temp.replaceAll("\u01ed", "o");
439  39 temp = temp.replaceAll("\u01ff", "o");
440  39 temp = temp.replaceAll("\u020d", "o");
441  39 temp = temp.replaceAll("\u020f", "o");
442  39 temp = temp.replaceAll("\u022b", "o");
443  39 temp = temp.replaceAll("\u022d", "o");
444  39 temp = temp.replaceAll("\u022f", "o");
445  39 temp = temp.replaceAll("\u0231", "o");
446  39 temp = temp.replaceAll("\u0156", "R");
447  39 temp = temp.replaceAll("\u0158", "R");
448  39 temp = temp.replaceAll("\u0210", "R");
449  39 temp = temp.replaceAll("\u0212", "R");
450  39 temp = temp.replaceAll("\u0157", "r");
451  39 temp = temp.replaceAll("\u0159", "r");
452  39 temp = temp.replaceAll("\u0211", "r");
453  39 temp = temp.replaceAll("\u0213", "r");
454  39 temp = temp.replaceAll("\u015a", "S");
455  39 temp = temp.replaceAll("\u015c", "S");
456  39 temp = temp.replaceAll("\u015e", "S");
457  39 temp = temp.replaceAll("\u0160", "S");
458  39 temp = temp.replaceAll("\u0218", "S");
459  39 temp = temp.replaceAll("\u015b", "s");
460  39 temp = temp.replaceAll("\u015d", "s");
461  39 temp = temp.replaceAll("\u015f", "s");
462  39 temp = temp.replaceAll("\u0161", "s");
463  39 temp = temp.replaceAll("\u0219", "s");
464  39 temp = temp.replaceAll("\u00de", "T");
465  39 temp = temp.replaceAll("\u0162", "T");
466  39 temp = temp.replaceAll("\u0164", "T");
467  39 temp = temp.replaceAll("\u0166", "T");
468  39 temp = temp.replaceAll("\u021a", "T");
469  39 temp = temp.replaceAll("\u00fe", "t");
470  39 temp = temp.replaceAll("\u0163", "t");
471  39 temp = temp.replaceAll("\u0165", "t");
472  39 temp = temp.replaceAll("\u0167", "t");
473  39 temp = temp.replaceAll("\u021b", "t");
474  39 temp = temp.replaceAll("\u0236", "t");
475  39 temp = temp.replaceAll("\u00d9", "U");
476  39 temp = temp.replaceAll("\u00da", "U");
477  39 temp = temp.replaceAll("\u00db", "U");
478  39 temp = temp.replaceAll("\u00dc", "U");
479  39 temp = temp.replaceAll("\u0168", "U");
480  39 temp = temp.replaceAll("\u016a", "U");
481  39 temp = temp.replaceAll("\u016c", "U");
482  39 temp = temp.replaceAll("\u016e", "U");
483  39 temp = temp.replaceAll("\u0170", "U");
484  39 temp = temp.replaceAll("\u0172", "U");
485  39 temp = temp.replaceAll("\u01d3", "U");
486  39 temp = temp.replaceAll("\u01d5", "U");
487  39 temp = temp.replaceAll("\u01d7", "U");
488  39 temp = temp.replaceAll("\u01d9", "U");
489  39 temp = temp.replaceAll("\u01db", "U");
490  39 temp = temp.replaceAll("\u0214", "U");
491  39 temp = temp.replaceAll("\u0216", "U");
492  39 temp = temp.replaceAll("\u00f9", "u");
493  39 temp = temp.replaceAll("\u00fa", "u");
494  39 temp = temp.replaceAll("\u00fb", "u");
495  39 temp = temp.replaceAll("\u00fc", "u");
496  39 temp = temp.replaceAll("\u0169", "u");
497  39 temp = temp.replaceAll("\u016b", "u");
498  39 temp = temp.replaceAll("\u016d", "u");
499  39 temp = temp.replaceAll("\u016f", "u");
500  39 temp = temp.replaceAll("\u0171", "u");
501  39 temp = temp.replaceAll("\u0173", "u");
502  39 temp = temp.replaceAll("\u01d4", "u");
503  39 temp = temp.replaceAll("\u01d6", "u");
504  39 temp = temp.replaceAll("\u01d8", "u");
505  39 temp = temp.replaceAll("\u01da", "u");
506  39 temp = temp.replaceAll("\u01dc", "u");
507  39 temp = temp.replaceAll("\u0215", "u");
508  39 temp = temp.replaceAll("\u0217", "u");
509  39 temp = temp.replaceAll("\u0174", "W");
510  39 temp = temp.replaceAll("\u0175", "w");
511  39 temp = temp.replaceAll("\u00dd", "Y");
512  39 temp = temp.replaceAll("\u0176", "Y");
513  39 temp = temp.replaceAll("\u0178", "Y");
514  39 temp = temp.replaceAll("\u0232", "Y");
515  39 temp = temp.replaceAll("\u00fd", "y");
516  39 temp = temp.replaceAll("\u00ff", "y");
517  39 temp = temp.replaceAll("\u0177", "y");
518  39 temp = temp.replaceAll("\u0233", "y");
519  39 temp = temp.replaceAll("\u0179", "Z");
520  39 temp = temp.replaceAll("\u017b", "Z");
521  39 temp = temp.replaceAll("\u017d", "Z");
522  39 temp = temp.replaceAll("\u017a", "z");
523  39 temp = temp.replaceAll("\u017c", "z");
524  39 temp = temp.replaceAll("\u017e", "z");
525  39 temp = temp.replaceAll("\u00df", "ss");
526   
527  39 return temp;
528    }
529   
 
530  0 toggle public static boolean isAlphaNumeric(String text)
531    {
532  0 return StringUtils.isAlphanumeric(text.replace('-', 'a').replace('.', 'a'));
533    }
534   
 
535  0 toggle public static String getName(String name)
536    {
537  0 int i0 = name.indexOf(":");
538  0 if (i0 != -1) {
539  0 name = name.substring(i0 + 1);
540  0 return name;
541    }
542   
543  0 if (name.indexOf(".") != -1) {
544  0 return name;
545    } else {
546  0 return "XWiki." + name;
547    }
548    }
549   
 
550  68 toggle public static String getName(String name, XWikiContext context)
551    {
552  68 String database = null;
553  68 int i0 = name.indexOf(":");
554  68 if (i0 != -1) {
555  57 database = name.substring(0, i0);
556  57 name = name.substring(i0 + 1);
557  57 context.setWikiId(database);
558  57 return name;
559    }
560   
561    // This does not make sense
562    // context.setWikiId(context.getWiki().getDatabase());
563  11 if (name.indexOf(".") != -1) {
564  11 return name;
565    } else {
566  0 return "XWiki." + name;
567    }
568    }
569   
 
570  924 toggle public static Cookie getCookie(String cookieName, XWikiContext context)
571    {
572  924 return getCookie(cookieName, context.getRequest());
573    }
574   
 
575  2003 toggle public static Cookie getCookie(String cookieName, HttpServletRequest request)
576    {
577  2004 Cookie[] cookies = request.getCookies();
578  2005 if (cookies != null) {
579  1963 for (Cookie cookie : cookies) {
580  9363 if (cookieName.equals(cookie.getName())) {
581  0 return (cookie);
582    }
583    }
584    }
585   
586  2009 return null;
587    }
588   
 
589  0 toggle public static String getHTMLExceptionMessage(XWikiException xe, XWikiContext context)
590    {
591  0 String title = XMLUtils.escape(xe.getMessage());
592  0 String text = XMLUtils.escape(xe.getFullMessage());
593   
594  0 return "<div class=\"xwikirenderingerror\" title=\"Read technical information related to this error\" "
595    + "style=\"cursor: pointer;\">" + title + "</div>"
596    + "<div class=\"xwikirenderingerrordescription hidden\"><pre>" + text + "</pre></div>";
597    }
598   
 
599  52041 toggle public static MonitorPlugin getMonitorPlugin(XWikiContext context)
600    {
601  52035 try {
602  52030 if ((context == null) || (context.getWiki() == null)) {
603  0 return null;
604    }
605   
606  52026 return (MonitorPlugin) context.getWiki().getPlugin("monitor", context);
607    } catch (Exception e) {
608  6924 return null;
609    }
610    }
611   
612    /**
613    * API to obtain a DOM document for the specified string
614    *
615    * @param str The parsed text
616    * @return A DOM document element corresponding to the string, or null on error
617    */
 
618  0 toggle public org.w3c.dom.Document getDOMForString(String str)
619    {
620  0 try {
621  0 return DocumentBuilderFactory.newInstance().newDocumentBuilder()
622    .parse(new InputSource(new StringReader(str)));
623    } catch (SAXException ex) {
624  0 LOGGER.warn("Cannot parse string:" + str, ex);
625    } catch (IOException ex) {
626  0 LOGGER.warn("Cannot parse string:" + str, ex);
627    } catch (ParserConfigurationException ex) {
628  0 LOGGER.warn("Cannot parse string:" + str, ex);
629    }
630   
631  0 return null;
632    }
633   
634    /**
635    * API to get a new DOM document
636    *
637    * @return a new DOM document element, or null on error
638    */
 
639  0 toggle public org.w3c.dom.Document getDOMDocument()
640    {
641  0 try {
642  0 return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
643    } catch (ParserConfigurationException ex) {
644  0 LOGGER.warn("Cannot create DOM tree", ex);
645    }
646   
647  0 return null;
648    }
649   
650    /**
651    * API to protect Text from Radeox transformation
652    *
653    * @param text
654    * @return escaped text
655    * @deprecated dedicated to Radeox which is deprecated since a long time
656    */
 
657  0 toggle @Deprecated
658    public static String escapeText(String text)
659    {
660  0 text = text.replaceAll("http://", "&#104;ttp://");
661  0 text = text.replaceAll("ftp://", "&#102;tp://");
662  0 text = text.replaceAll("\\-", "&#45;");
663  0 text = text.replaceAll("\\*", "&#42;");
664  0 text = text.replaceAll("\\~", "&#126;");
665  0 text = text.replaceAll("\\[", "&#91;");
666  0 text = text.replaceAll("\\]", "&#93;");
667  0 text = text.replaceAll("\\{", "&#123;");
668  0 text = text.replaceAll("\\}", "&#125;");
669  0 text = text.replaceAll("\\1", "&#49;");
670   
671  0 return text;
672    }
673   
674    /**
675    * API to protect URLs from Radeox transformation
676    *
677    * @param url
678    * @return encoded URL
679    * @deprecated dedicated to Radeox which is deprecated since a long time
680    */
 
681  0 toggle @Deprecated
682    public static String escapeURL(String url)
683    {
684  0 url = url.replaceAll("\\~", "%7E");
685  0 url = url.replaceAll("\\[", "%5B");
686  0 url = url.replaceAll("\\]", "%5D");
687  0 url = url.replaceAll("\\{", "%7B");
688  0 url = url.replaceAll("\\}", "%7D");
689    // We should not encode the following char for non local urls
690    // since this might not be handle correctly by FF
691  0 if (url.indexOf("//") == -1) {
692  0 url = url.replaceAll("-", "%2D");
693  0 url = url.replaceAll("\\*", "%2A");
694    }
695   
696  0 return url;
697    }
698   
699    /**
700    * Translates a string into <code>application/x-www-form-urlencoded</code> format, so that it can be safely used in
701    * URIs, as a parameter value in a query string or as a segment in the URI path. This uses the UTF-8 encoding, the
702    * default encoding for URIs, as stated in <a href="http://tools.ietf.org/html/rfc3986#section-2.5">RFC 3986</a>.
703    *
704    * @param text the non encoded text
705    * @param context the current context
706    * @return encoded text
707    * @see #decodeURI(String, XWikiContext)
708    */
 
709  241 toggle public static String encodeURI(String text, XWikiContext context)
710    {
711  241 try {
712  241 return URLEncoder.encode(text, URL_ENCODING);
713    } catch (Exception e) {
714    // Should not happen (UTF-8 is always available), but if so, fail securely
715  0 return null;
716    }
717    }
718   
719    /**
720    * Decodes a <code>application/x-www-form-urlencoded</code> string, the reverse of
721    * {@link #encodeURI(String, XWikiContext)}. This uses the UTF-8 encoding, the default encoding for URIs, as stated
722    * in <a href="http://tools.ietf.org/html/rfc3986#section-2.5">RFC 3986</a>.
723    *
724    * @param text the encoded text
725    * @param context the current context
726    * @return decoded text
727    * @see #encodeURI(String, XWikiContext)
728    */
 
729  3311 toggle public static String decodeURI(String text, XWikiContext context)
730    {
731  3311 try {
732  3311 return URLDecoder.decode(text, URL_ENCODING);
733    } catch (Exception e) {
734    // Should not happen (UTF-8 is always available)
735  0 return text;
736    }
737    }
738   
739    /**
740    * Removes all non alpha numerical characters from the passed text. First tries to convert accented chars to their
741    * alpha numeric representation.
742    *
743    * @param text the text to convert
744    * @return the alpha numeric equivalent
745    */
 
746  35 toggle public static String convertToAlphaNumeric(String text)
747    {
748    // Start by removing accents
749  35 String textNoAccents = Util.noaccents(text);
750   
751    // Now remove all non alphanumeric chars
752  35 StringBuffer result = new StringBuffer(textNoAccents.length());
753  35 char[] testChars = textNoAccents.toCharArray();
754  35 for (char testChar : testChars) {
755  521 if (Character.isLetterOrDigit(testChar) && testChar < 128) {
756  505 result.append(testChar);
757    }
758    }
759   
760  35 return result.toString();
761    }
762   
 
763  318 toggle public static Date getFileLastModificationDate(String path)
764    {
765  318 try {
766  318 File f = new File(path);
767   
768  318 return (new Date(f.lastModified()));
769    } catch (Exception ex) {
770  0 return new Date();
771    }
772    }
773   
774    /**
775    * Validate a XML element name. XML elements must follow these naming rules :
776    * <ul>
777    * <li>Names can contain letters, numbers, and the following characters [., -, _].</li>
778    * <li>Names must not start with a number or punctuation character.</li>
779    * <li>Names must not start (case-insensitive) with the letters xml.</li>
780    * <li>Names cannot contain spaces.</li>
781    * </ul>
782    *
783    * @param elementName the XML element name to validate
784    * @return true if the element name is valid, false if it is not
785    */
 
786  21 toggle public static boolean isValidXMLElementName(String elementName)
787    {
788  21 if (elementName == null || elementName.equals("") || elementName.matches("(?i)^(xml).*")
789    || !elementName.matches("(^[a-zA-Z\\_]+[\\w\\.\\-]*$)")) {
790  8 return false;
791    }
792   
793  13 return true;
794    }
795   
796    /**
797    * Load resources from: 1. FileSystem 2. ServletContext 3. ClassPath in this order.
798    *
799    * @param resource resource path to load
800    * @return InputStream of resource or null if not found
801    */
 
802  298 toggle public static InputStream getResourceAsStream(String resource)
803    {
804  298 File file = new File(resource);
805  298 try {
806  298 if (file.exists()) {
807  28 return new FileInputStream(file);
808    }
809    } catch (Exception e) {
810    // Probably running under -security, which prevents calling File.exists()
811  0 LOGGER.debug("Failed load resource [" + resource + "] using a file path");
812    }
813  270 try {
814  270 Container container = Utils.getComponent(Container.class);
815  177 InputStream res = container.getApplicationContext().getResourceAsStream(resource);
816  32 if (res != null) {
817  32 return res;
818    }
819    } catch (Exception e) {
820  238 LOGGER.debug("Failed to load resource [" + resource + "] using the application context");
821    }
822   
823  238 return Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
824    }
825   
826    /**
827    * Normalize the given language code. Converts the given language code to lower case and checks its validity (i.e.
828    * whether it is an ISO 639 language code or the string "default").
829    *
830    * <pre>
831    * Util.normalizeLanguage(null) = null
832    * Util.normalizeLanguage("") = ""
833    * Util.normalizeLanguage(" ") = ""
834    * Util.normalizeLanguage("default") = "default"
835    * Util.normalizeLanguage("DeFault") = "default"
836    * Util.normalizeLanguage("invalid") = "default"
837    * Util.normalizeLanguage("en") = "en"
838    * Util.normalizeLanguage("DE_at") = "de_AT"
839    * </pre>
840    *
841    * @param languageCode the language code to normalize
842    * @return normalized language code or the string "default" if the code is invalid
843    */
 
844  21734 toggle public static String normalizeLanguage(String languageCode)
845    {
846  21722 if (languageCode == null) {
847  4058 return null;
848    }
849  17665 if (StringUtils.isBlank(languageCode)) {
850  3990 return "";
851    }
852    // handle language_COUNTRY case
853  13671 final String separator = "_";
854   
855  13671 String[] parts = StringUtils.split(languageCode.toLowerCase(), "_-.");
856  13661 String result = parts[0];
857  13665 if (parts.length > 1) {
858  7 parts[1] = parts[1].toUpperCase();
859    // NOTE cannot use Locale#toString(), because it would change some language codes
860  7 result = parts[0] + separator + parts[1];
861    }
862    // handle the "default" case
863  13656 final String defaultLanguage = "default";
864  13659 if (defaultLanguage.equals(result)) {
865  2 return defaultLanguage;
866    }
867  13649 try {
868  13659 Locale l = new Locale(parts[0], parts.length > 1 ? parts[1] : "");
869    // Will throw an exception if the language code is not valid
870  13672 l.getISO3Language();
871  13673 return result;
872    } catch (MissingResourceException ex) {
873  1 LOGGER.warn("Invalid language: " + languageCode);
874    }
875  1 return defaultLanguage;
876    }
877   
878    /**
879    * Get a likely unique 64bit hash representing the provided uid string. Use the MD5 hashing algorithm.
880    *
881    * @param uid an uid string usually provided by
882    * {@link org.xwiki.model.internal.reference.LocalUidStringEntityReferenceSerializer} or
883    * {@link org.xwiki.model.internal.reference.UidStringEntityReferenceSerializer}
884    * @return 64bit hash
885    * @since 4.0M1
886    */
 
887  335435 toggle public static long getHash(String uid)
888    {
889  335427 MessageDigest md5 = null;
890  335428 long hash = 0;
891   
892  335427 try {
893  335427 md5 = MessageDigest.getInstance("MD5");
894  335419 byte[] digest = md5.digest(uid.getBytes("UTF-8"));
895  3353931 for (int l = digest.length, i = Math.max(0, digest.length - 9); i < l; i++) {
896  3018524 hash = hash << 8 | ((long) digest[i] & 0xFF);
897    }
898    } catch (NoSuchAlgorithmException ex) {
899  0 LOGGER.error("Cannot retrieve MD5 provider for hashing", ex);
900  0 throw new RuntimeException("MD5 hash is required for id hash");
901    } catch (Exception ex) {
902  0 LOGGER.error("Id computation failed during MD5 processing", ex);
903  0 throw new RuntimeException("MD5 hash is required for id hash");
904    }
905   
906  335402 return hash;
907    }
908    }