1. Project Clover database Mon Dec 22 2025 14:59:38 CST
  2. Package org.europa.together.utils

File StringUtils.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

24
93
16
1
347
205
31
0.33
5.81
16
1.94

Classes

Class Line # Actions
StringUtils 21 93 0% 31 0
1.0100%
 

Contributing tests

This file is covered by 217 tests. .

Source view

1    package org.europa.together.utils;
2   
3    import java.nio.charset.Charset;
4    import java.nio.charset.StandardCharsets;
5    import java.text.DateFormat;
6    import java.text.ParseException;
7    import java.text.SimpleDateFormat;
8    import java.util.ArrayList;
9    import java.util.Base64;
10    import java.util.Date;
11    import java.util.List;
12    import java.util.UUID;
13    import org.europa.together.application.LogbackLogger;
14    import org.europa.together.business.Logger;
15    import org.europa.together.domain.ByteOrderMark;
16    import org.europa.together.domain.LogLevel;
17   
18    /**
19    * Some useful Methods for String manipulation, Hash and UUID generation.
20    */
 
21    public final class StringUtils {
22   
23    private static final Logger LOGGER = new LogbackLogger(StringUtils.class);
24    private static final Charset CHARSET = Charset.forName("UTF-8");
25    private static final int LIMES = 9;
26    private static final int LIMIT = 2100;
27   
28    /**
29    * Constructor.
30    */
 
31  1 toggle private StringUtils() {
32  1 throw new UnsupportedOperationException();
33    }
34   
35    /**
36    * Test a String if is empty or NULL. Return TRUE when the String is empty
37    * or NULL. The test don't figure out when a Sting contains only non
38    * printable or whitespace characters.
39    *
40    * @param string as String
41    * @return true on success
42    */
 
43  3268 toggle public static boolean isEmpty(final String string) {
44  3268 boolean test = false;
45  3268 if (string == null || string.equals("")) {
46  440 test = true;
47    }
48  3268 return test;
49    }
50   
51    /**
52    * Convert a Hash String to an Integer. Takes each character of the hash
53    * string, convert them to his ASCII number as int and add the result to a
54    * sum.
55    *
56    * @param hash as String
57    * @return hash as integer
58    */
 
59  4 toggle public static int hashToInt(final String hash) {
60  4 int hashNumber = 0;
61  268 for (int i = 0; i < hash.length(); i++) {
62  264 char character = hash.charAt(i);
63  264 int ascii = (int) character;
64  264 hashNumber += ascii;
65    }
66  4 LOGGER.log("hashToInt() " + hash + " -> " + hashNumber, LogLevel.DEBUG);
67  4 return hashNumber;
68    }
69   
70    /**
71    * Creates a List with Strings entries in a short way. Sample:
72    * List&lt;String&gt; list = new arrayList(); list.add("foo");
73    * list.add("more");
74    * <br> is reduced to stringListBuilder("foo", "more");
75    *
76    * @param strings as String
77    * @return a List of Strings
78    */
 
79  3 toggle public static List<String> stringListBuilder(final String... strings) {
80  3 List<String> list = new ArrayList<>();
81  3 for (String s : strings) {
82  5 if (s != null) {
83  4 list.add(s);
84    }
85    }
86  3 return list;
87    }
88   
89    /**
90    * Create a String from a given ByteArray. Each character get converted to
91    * his UTF-8 hexadecimal expression. e.g. '#' -> "23"
92    *
93    * @param bytes as byteArray
94    * @return bytes as String
95    */
 
96  618 toggle public static String byteToString(final byte[] bytes) {
97  618 StringBuilder sb = new StringBuilder(bytes.length * 2);
98  18791 for (int i = 0; i < bytes.length; ++i) {
99  18173 sb.append(Integer.toHexString(
100    (bytes[i] & Constraints.HEX_255) | Constraints.HEX_256).substring(1, 1 + 2));
101    }
102  618 return sb.toString();
103    }
104   
105    /**
106    * Concatenate a list of Strings using StringBuilder.
107    *
108    * @param strings as String
109    * @return string as String
110    */
 
111  1 toggle public static String concatString(final String... strings) {
112  1 StringBuilder result = new StringBuilder();
113  1 for (String s : strings) {
114  4 result.append(s);
115    }
116  1 return result.toString();
117    }
118   
119    /**
120    * Decode a given URL to a Base64 String.
121    *
122    * @param url as String
123    * @return decodedUrl as String
124    */
 
125  1 toggle public static String base64UrlEncoding(final String url) {
126  1 return Base64.getUrlEncoder().encodeToString(url.getBytes(StandardCharsets.UTF_8));
127    }
128   
129    /**
130    * Encode from a Base64 back to a readable URL.
131    *
132    * @param base64Url as byte[]
133    * @return encodedUrl as String
134    */
 
135  2 toggle public static String base64UrlDecoding(final String base64Url) {
136  2 String encoded = "";
137  2 try {
138  2 byte[] decodedBytes = Base64.getUrlDecoder().decode(base64Url);
139  1 encoded = new String(decodedBytes, StandardCharsets.UTF_8.toString());
140    } catch (Exception ex) {
141  1 LOGGER.catchException(ex);
142    }
143  2 return encoded;
144    }
145   
146    /**
147    * Produce a lorem ipsum text with 4 paragraphs and 2100 characters. The
148    * parameter chars reduce the output to the given count of characters. To
149    * get the whole text set chars to 0.
150    *
151    * @param chars as int
152    * @return out as String
153    */
 
154  7 toggle public static String generateLoremIpsum(final int chars) {
155  7 String out
156    = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy "
157    + "eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam "
158    + "voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet "
159    + "clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit "
160    + "amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
161    + "nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed "
162    + "diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. "
163    + "Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor "
164    + "sitView Generated Project Site amet. Lorem ipsum dolor sit amet, consetetur "
165    + "sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore "
166    + "magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo "
167    + "dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus "
168    + "est Lorem ipsum dolor sit amet.\n"
169    + "\n"
170    + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie "
171    + "consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan"
172    + " et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis"
173    + " dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer "
174    + "adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore "
175    + "magna aliquam erat volutpat.\n"
176    + "\n"
177    + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit "
178    + "lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure "
179    + "dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore"
180    + " eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim "
181    + "qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla "
182    + "facilisi.\n"
183    + "\n"
184    + "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet "
185    + "doming id quod mazim placera facer possim assum. Lorem ipsum dolor sit amet, "
186    + "consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut "
187    + "laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis "
188    + "nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea "
189    + "commodo consequat.";
190  7 if (chars > 0 && chars <= LIMIT) {
191  1 out = out.substring(0, chars);
192    }
193  7 return out;
194    }
195   
196    /**
197    * Creates a String of specified length with the content of numbers.
198    * generateStringOfLength(13) = [0123456789012]
199    *
200    * @param length as int
201    * @return string as String
202    */
 
203  2 toggle public static String generateStringOfLength(final int length) {
204  2 StringBuilder sb = new StringBuilder(length);
205  2 int counter = 0;
206  25 for (int i = 0; i < length; ++i) {
207  23 sb.append(counter);
208  23 counter++;
209  23 if (counter > LIMES) {
210  1 counter = 0;
211    }
212    }
213  2 return sb.toString();
214    }
215   
216    /**
217    * Generates an universally unique identifier (UUID). The UUID is a type 4
218    * (pseudo randomly generated) UUID. The UUID is generated using a
219    * cryptographically strong pseudo random number generator.
220    *
221    * @return UUID as String
222    */
 
223  2281 toggle public static String generateUUID() {
224  2281 UUID uuid = UUID.randomUUID();
225  2281 LOGGER.log("generateUUID() " + uuid, LogLevel.DEBUG);
226  2281 return uuid.toString();
227    }
228   
229    /**
230    * Detect and remove the (BOM) Byte Order Mark from a string.
231    *
232    * @param content as String
233    * @return utf-8 String
234    */
 
235  8 toggle public static String skipBom(final String content) {
236  7 if (content.isEmpty()) {
237  1 throw new NullPointerException("The String in StringUtils.skipBom() is null.");
238    }
239  6 List<ByteOrderMark> bomList = new ArrayList<>();
240  6 bomList.add(ByteOrderMark.UTF_8);
241  6 bomList.add(ByteOrderMark.UTF_16LE);
242  6 bomList.add(ByteOrderMark.UTF_16BE);
243  6 bomList.add(ByteOrderMark.UTF_32LE);
244  6 bomList.add(ByteOrderMark.UTF_32BE);
245  6 String clean = content;
246  6 byte[] array = content.getBytes(CHARSET);
247  6 for (ByteOrderMark entry : bomList) {
248  18 boolean hasBOM = true;
249  29 for (int i = 0; i < entry.getBytes().length; i++) {
250  26 byte[] s = {array[i]};
251  26 byte[] d = {entry.getBytes()[i]};
252  26 LOGGER.log(i + "> " + byteToString(s) + " : " + byteToString(d),
253    LogLevel.TRACE);
254   
255  26 if (array[i] != entry.getBytes()[i]) {
256  15 hasBOM = false;
257  15 break;
258    }
259    }
260   
261  18 if (hasBOM) {
262  3 clean = content.substring(1);
263  3 LOGGER.log("BOM: " + entry.toString() + " detected and removed.",
264    LogLevel.DEBUG);
265  3 break;
266    } else {
267  15 LOGGER.log("No BOM detected for: " + entry.toString(), LogLevel.DEBUG);
268    }
269    }
270  6 return clean;
271    }
272   
273    /**
274    * Create from a given String for UTC in the format of yyyy-mm-dd HH:mm:ss a
275    * java.util.Date class.
276    *
277    * @param timestamp as Sting
278    * @return timestamp as Date
279    * @throws java.text.ParseException
280    */
 
281  2 toggle public static Date createDateFromString(final String timestamp)
282    throws ParseException {
283  2 DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
284  2 return dateFormat.parse(timestamp);
285    }
286   
287    /**
288    * Split a string of numbers into an ordered list of integer digits. If the
289    * string contains something else than a digit like a letter etc. the result
290    * will be an empty list.
291    *
292    * @param digits as String
293    * @return List of Integers
294    */
 
295  14 toggle public static List<Integer> splitDigitStringToIntegerList(final String digits) {
296  14 List<Integer> integerList = new ArrayList<>();
297  14 if (Validator.validate(digits, Validator.DIGIT)) {
298  10 String[] charArray = digits.split("(?<=.)");
299  10 for (String character : charArray) {
300  47 integerList.add(Integer.decode(character));
301    }
302    } else {
303  4 LOGGER.log("Imput string contains non digit characters", LogLevel.ERROR);
304    }
305  14 return integerList;
306    }
307   
308    /**
309    * Shrink XML, JS and CSS Files to reduce the payload for network traffic.
310    * The shrinker removes comments and unnecessary whitespace and line breaks.
311    *
312    * @param content as String
313    * @return shrinked content as String
314    */
 
315  4 toggle public static String shrink(final String content) {
316    //Comments
317  4 String shrink = content
318    .replaceAll("(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)", "");
319  4 shrink = shrink.replaceAll("(?s)<!--.*?-->", "");
320    //whitespace
321  4 shrink = shrink.replaceAll("\\s+", " ");
322  4 shrink = shrink.replaceAll(" ", " ");
323  4 shrink = shrink.replaceAll(">.*?<", "><");
324  4 return shrink;
325    }
326   
327    /**
328    * Escape (decode) in a String all special Characters for XML to their
329    * equivalent representation. Characters: &lt;, @gt;, &amp;, ', ". Also
330    * whitespaces before and after the content got removed.<br>
331    * This replacement extend the security of a web Application against XSS and
332    * SQL Injections for user modified content.
333    *
334    * @param content as String
335    * @return escapedXml as String
336    */
 
337  18 toggle public static String escapeXmlCharacters(final String content) {
338    //do not change ordering!
339  18 String replace = content.replaceAll("&", "&#0038;");
340  18 replace = replace.replaceAll("'", "&#0039;");
341  18 replace = replace.replaceAll("<", "&#0060;");
342  18 replace = replace.replaceAll(">", "&#0062;");
343  18 replace = replace.replaceAll("\"", "&#0034;");
344  18 return replace.trim();
345    }
346   
347    }