Project

General

Profile

Download (17 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.common;
10

    
11
import java.io.BufferedReader;
12
import java.io.IOException;
13
import java.io.InputStream;
14
import java.io.InputStreamReader;
15
import java.lang.annotation.Annotation;
16
import java.lang.reflect.Field;
17
import java.lang.reflect.Modifier;
18
import java.net.HttpURLConnection;
19
import java.net.MalformedURLException;
20
import java.net.URL;
21
import java.util.ArrayList;
22
import java.util.HashMap;
23
import java.util.List;
24
import java.util.Map;
25
import java.util.regex.Matcher;
26
import java.util.regex.Pattern;
27

    
28
import org.apache.commons.lang3.StringUtils;
29
import org.apache.logging.log4j.LogManager;
30
import org.apache.logging.log4j.Logger;
31

    
32
/**
33
 * @author a.mueller
34
 * @author a.kohlbecker
35
 */
36
public class CdmUtils {
37

    
38
    private static final Logger logger = LogManager.getLogger();
39

    
40
    static private boolean urlIsJarOrBundle(URL url){
41
        return url.getProtocol().startsWith("jar") || url.getProtocol().startsWith("bundleresource");
42
    }
43

    
44
    /**
45
     * Returns the an InputStream for a read-only source
46
     * @param resourceFileName the resources path within the classpath(!)
47
     * @return
48
     * @throws IOException
49
     */
50
    public static InputStream getReadableResourceStream(String resourceFileName)
51
            throws IOException{
52
        InputStream urlStream = CdmUtils.class.getResourceAsStream("/"+ resourceFileName);
53
        return urlStream;
54
    }
55

    
56
    /**
57
     * Returns an InputStream for a read-only source
58
     * @param resourceFileName the resources path within the classpath(!)
59
     * @return
60
     * @throws IOException
61
     */
62
    public static InputStreamReader getUtf8ResourceReader(String resourceFileName)
63
            throws IOException{
64
        InputStream urlStream = CdmUtils.class.getResourceAsStream("/"+ resourceFileName);
65
        InputStreamReader inputStreamReader = new InputStreamReader(urlStream, "UTF8");
66
        return inputStreamReader;
67
    }
68

    
69
    /**
70
     * Returns the file name for the file in which 'clazz' is to be found (helps finding according libraries)
71
     * @param clazz
72
     * @return
73
     */
74
    static public String findLibrary(Class<?> clazz){
75
        String result = null;
76
        if (clazz != null){
77
            String fullPackageName = clazz.getCanonicalName();
78
            fullPackageName = fullPackageName.replace(".", "/");
79
            URL url = CdmUtils.class.getResource("/" + fullPackageName + ".class" );
80
            if (url != null){
81
                result = url.getFile();
82
            }else{
83
                result = "";
84
            }
85
            logger.debug("LibraryURL for " + clazz.getCanonicalName() + " : " + result);
86
        }
87
        return result;
88
    }
89

    
90
    static public String readInputLine(String inputQuestion){
91

    
92
        try {
93
            System.out.print(inputQuestion);
94
            BufferedReader in = new BufferedReader( new InputStreamReader( System.in ));
95
            String input;
96
            input = in.readLine();
97
            return input;
98
        } catch (IOException e) {
99
            logger.warn("IOExeption");
100
            return null;
101
        }
102
    }
103

    
104
    /**
105
     * Returns the trimmed value string if value is not <code>null</code>.
106
     * Returns the empty string if value is <code>null</code>.
107
     * @param value
108
     * @return
109
     */
110
    static public String NzTrim(String value){
111
        return (value == null ? "" : value);
112
    }
113

    
114
    /**
115
     * Returns value if value is not <code>null</code>. Returns empty string if value is <code>null</code>.
116
     * @param value
117
     * @return
118
     */
119
    static public String Nz(String value){
120
        return (value == null ? "" : value);
121
    }
122

    
123
    /**
124
     * Returns value if value is not <code>null</code>. Returns defaultValue if value is <code>null</code>.
125
     * @param value
126
     * @return
127
     */
128
    static public String Nz(String value, String defaultValue){
129
        return (value == null ? defaultValue : value);
130
    }
131

    
132
    /**
133
     * Returns value if value is not <code>null</code>. Returns 0 if value is <code>null</code>.
134
     * @param value
135
     * @return
136
     */
137
    static public Integer Nz(Integer value){
138
        return (value == null ? 0 : value);
139
    }
140

    
141
    /**
142
     * Returns value if value is not <code>null</code>. Returns 0 if value is <code>null</code>.
143
     * @param value
144
     * @return
145
     */
146
    static public Long Nz(Long value){
147
        return (value == null ? 0 : value);
148
    }
149

    
150
    /**
151
     * Returns str if str is not the empty String (''). Returns null if str is empty.
152
     * @param str
153
     * @return
154
     */
155
    static public String Ne(String str){
156
        return ("".equals(str)? null : str);
157
    }
158

    
159
    /**
160
     * Returns str if str.trim() is not empty. Returns null otherwise.
161
     * @param str
162
     * @return
163
     */
164
    static public String Nb(String str){
165
        return (str == null || str.trim().equals("")? null : str);
166
    }
167

    
168
    /**
169
     * Concatenates an array of strings using the defined separator.<BR>
170
     * <code>Null</code> values and empty strings are handled as if they
171
     * do not exist. So <BR><BR>
172
     *
173
     * concat(":", "a", "", null, "b") results in "a:b"<BR><BR>
174
     *
175
     * If all strings are <code>null</code> then <code>null</code> is returned.
176
     *
177
     * @see #concat(CharSequence, String, String)
178
     * @param strings the strings to concatenate
179
     * @param seperator the separator for concatenation
180
     * @return String the concatenation result
181
     */
182
    static public String concat(CharSequence separator, String... strings){
183
        StringBuilder result = new StringBuilder();
184
        boolean allNull = true;
185
        for (String string : strings){
186
            if (string != null){
187
                if (result.length() > 0 && string.length() > 0){
188
                    result.append(separator);
189
                }
190
                result.append(string);
191
                allNull = false;
192
            }
193
        }
194
        //if all strings are null result should be null, not ""
195
        if (allNull){
196
            return null;
197
        }else {
198
            return result.toString();
199
        }
200
    }
201

    
202

    
203
    /**
204
     * Concatenates two strings, using the defined separator.<BR>
205
     * <code>Null</code> values are interpreted as empty strings.<BR>
206
     * Empty strings are not included in concatenation so concat(":", "a", "")
207
     * results in "a", not "a:".<BR>
208
     *
209
     * If both strings are <code>null</code> then <code>null</code> is returned.
210
     *
211
     * @see #concat(CharSequence, String[])
212
     * @param sepearator the separator
213
     * @param string1 first string to concatenate
214
     * @param string2 second string to concatenate
215
     * @return String the concatenated string
216
     */
217
    static public String concat(CharSequence separator, String string1, String string2){
218
        String[] strings = {string1, string2};
219
        return concat(separator, strings);
220
    }
221

    
222
	/**
223
	 * Returns <code>preferred</code> if not blank, else returns <code>alternative</code>.
224
	 * If reverse is <code>true</code> computation is
225
	 * the other way round (<code>alternative</code> if not blank, otherwise <code>preferred</code>).
226
	 * @param preferred first string
227
	 * @param alternative second string
228
	 * @param reverse reverse flag
229
	 * @param nzTrim if <code>true</code> the result is trimmed and <code>null</code> values are replaced by empty string.
230
	 * @return the preferred string
231
	 */
232
	static public String getPreferredNonEmptyString(String preferred, String alternative, boolean reverse, boolean nzTrim){
233
		String result;
234
		if (! reverse){
235
			result = StringUtils.isBlank(preferred) ? alternative : preferred;
236
		}else{
237
			result = StringUtils.isBlank(alternative) ? preferred : alternative;
238
		}
239
		if (nzTrim){
240
			result = Nz(result).trim();
241
		}
242
		return result;
243
	}
244

    
245
    /** Returns a version of the input where all contiguous
246
     * whitespace characters are replaced with a single
247
     * space. Line terminators are treated like whitespace.
248
     *
249
     * @param inputStr
250
     * @return
251
     */
252
    public static CharSequence removeDuplicateWhitespace(CharSequence inputStr) {
253

    
254
        String patternStr = "\\s+";
255
        String replaceStr = " ";
256
        Pattern pattern = Pattern.compile(patternStr);
257
        Matcher matcher = pattern.matcher(inputStr);
258
        return matcher.replaceAll(replaceStr);
259
    }
260

    
261
    /**
262
     * Builds a list of strings by splitting an input string
263
     * with delimiters whitespace, comma, or semicolon
264
     * @param value
265
     * @return
266
     */
267
    public static List<String> buildList(String value) {
268

    
269
        List<String> resultList = new ArrayList<String>();
270
        for (String tag : value.split("[\\s,;]+")) {
271
            resultList.add(tag);
272
        }
273
        return resultList;
274
    }
275

    
276
    static public boolean urlExists(String strUrl, boolean withWarning){
277
        try {
278
             HttpURLConnection.setFollowRedirects(false);
279
              // note : you may also need
280
              //        HttpURLConnection.setInstanceFollowRedirects(false)
281
              HttpURLConnection con =
282
                 (HttpURLConnection) new URL(strUrl).openConnection();
283
              con.setRequestMethod("HEAD");
284
              return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
285
        } catch (MalformedURLException e) {
286
            if (withWarning) {
287
                logger.warn(e);
288
            }
289
        } catch (IOException e) {
290
            //
291
        }
292
        return false;
293
    }
294

    
295
    static public boolean isNumeric(String string){
296
        if (string == null){
297
            return false;
298
        }
299
        try {
300
            Double.valueOf(string);
301
            return true;
302
        } catch (NumberFormatException e) {
303
            return false;
304
        }
305
    }
306

    
307
    /**
308
     * Returns <code>true</code> if the passed string starts with an upper case letter.
309
     * <code>false</code> otherwise. The later includes <code>null</code> and empty strings.
310
     * @param string
311
     * @return
312
     */
313
    static public boolean isCapital(String string){
314
        if (isBlank(string)){
315
            return false;
316
        }else{
317
            Character firstChar = string.charAt(0);
318
            if (firstChar.equals(Character.toUpperCase(firstChar))){
319
                return true;
320
            }else{
321
                return false;
322
            }
323
        }
324
    }
325

    
326
    /**
327
     * Returns true if string is null, "" or string.trim() is ""
328
     * @see isNotEmpty(String string)
329
     * @param string
330
     * @return
331
     */
332
    static public boolean isBlank(String string){
333
        if (string == null){
334
            return true;
335
        }
336
        if ("".equals(string.trim())){
337
            return true;
338
        }
339
        return false;
340
    }
341

    
342
    /**
343
     * Returns <code>false</code> if string is null, "" or string.trim() is ""
344
     * @see isNotEmpty(String string)
345
     * @param string
346
     * @return
347
     */
348
    static public boolean isNotBlank(String string){
349
        return ! isBlank(string);
350
    }
351

    
352
    /**
353
     * @see #isBlank(String)
354
     * @deprecated use {@link #isBlank(String)} instead
355
     * @param string
356
     * @return
357
     */
358
    @Deprecated
359
    static public boolean isEmpty(String string){
360
        return isBlank(string);
361
    }
362

    
363
    static public boolean areBlank(String ... strings){
364
        for (String string : strings){
365
            if (! isBlank(string)){
366
                return false;
367
            }
368
        }
369
        return true;
370
    }
371

    
372
    /**
373
     * Tests if two objects are equal or both null. Otherwise returns <code>false</code>.
374
     */
375
    public static boolean nullSafeEqual(Object obj1, Object obj2) {
376
        if (obj1 == null){
377
            return obj2 == null;
378
        }
379
        return (obj1 == obj2) || (obj1.equals(obj2));
380
    }
381

    
382
    /**
383
     * Compares 2 instances of {@link Comparable} with defined values for <code>null</code>
384
     */
385
    public static <T extends Comparable<T>> int nullSafeCompareTo(T c1, T c2) {
386
        if (c1 == null){
387
            return c2 == null ? 0 : -1;
388
        }else if (c2 == null){
389
            return 1;
390
        }else{
391
            return (c1.compareTo(c2));
392
        }
393
    }
394

    
395
    /**
396
     * Computes all fields recursively
397
     * @param clazz
398
     * @return
399
     */
400
    public static Map<String, Field> getAllFields(Class clazz, Class highestClass, boolean includeStatic, boolean includeTransient, boolean makeAccessible, boolean includeHighestClass) {
401
        Map<String, Field> result = new HashMap<>();
402
        if ( highestClass.isAssignableFrom(clazz) && (clazz != highestClass || includeHighestClass)){
403
            //exclude static
404
            for (Field field: clazz.getDeclaredFields()){
405
                if (includeStatic || ! Modifier.isStatic(field.getModifiers())){
406
                    if (includeTransient || ! isTransient(field)){
407
                        field.setAccessible(makeAccessible);
408
                        result.put(field.getName(), field);
409
                    }
410
                }
411
            }
412

    
413
            //include superclass fields
414
            Class<?> superclass = clazz.getSuperclass();
415
            if (superclass != null){
416
                result.putAll(getAllFields(superclass, highestClass, includeStatic, includeTransient, makeAccessible, includeHighestClass));
417
            }
418
        }
419
        return result;
420
    }
421

    
422
    /**
423
     * Returns true, if field has an annotation of type javax.persistence.Annotation
424
     * @param field
425
     * @return
426
     */
427
    protected static boolean isTransient(Field field) {
428
        for (Annotation annotation : field.getAnnotations()){
429
            //if (Transient.class.isAssignableFrom(annotation.annotationType())){
430
            if (annotation.annotationType().getSimpleName().equals("Transient")){
431
                return true;
432
            }
433
        }
434
        return false;
435
    }
436

    
437
    /**
438
     * Trims the string and if the string ends with 1 or more dots removes it.
439
     */
440
    public static String removeTrailingDots(String string){
441
        while (string != null && string.trim().endsWith(".")){
442
            return string.substring(0, string.length() -1);
443
        }
444
        return string;
445
    }
446

    
447
    /**
448
     * Adds a trailing dot to the given String
449
     * if string is not blank and does not end with dot already.
450
     * Otherwise str is returned.
451
     */
452
    public static String addTrailingDotIfNotExists(String str){
453
        if (StringUtils.isNotBlank(str) && !str.endsWith(".")){
454
            str += ".";
455
         }
456
        return str;
457
    }
458

    
459
    /**
460
     * Returns surrounding brackets "(",")". Trim the string if necessary.
461
     * @param text
462
     * @return
463
     */
464
    public static String removeBrackets(String text) {
465
        if (text == null){
466
            return null;
467
        }
468
        text = text.trim();
469
        if (text.matches("^\\(.*\\)$")){
470
            text = text.substring(1, text.length() -1);
471
        }
472
        return text;
473
    }
474

    
475
    /**
476
     * Compares 2 strings. If they are not empty and equal returns <code>true</code>
477
     * otherwise false.
478
     *
479
     * @param str1
480
     * @param str2
481
     * @return compare result as boolean
482
     */
483
    public static boolean nonEmptyEquals(String str1, String str2) {
484
        return (isNotBlank(str1) && str1.equals(str2));
485
    }
486

    
487
    /**
488
     * Compares if str1 and str2 is equal when ignoring whitespaces.
489
     * Returns <code>true</code> if both or <code>null</code> or
490
     * whitespace ignore equal.
491
     * @param str1
492
     * @param str2
493
     * @return
494
     */
495
    public static boolean equalsIgnoreWS(String str1, String str2) {
496
        if (str1 == null){
497
            return str2 == null;
498
        }else if (str2 == null){
499
            return false;
500
        }else{
501
            return str1.replaceAll("\\s", "").equals(str2.replaceAll("\\s", ""));
502
        }
503
    }
504

    
505
    /**
506
     * Checks if all strings given provide are {@link #isBlank(String) blank}.
507
     * Returns <code>true</code> if strs is null or empty
508
     * @param strs
509
     * @return
510
     */
511
    public static boolean isBlank(String ... strs) {
512
        if (strs == null){
513
            return true;
514
        }
515
        for (String str : strs) {
516
            if (isNotBlank(str)){
517
                return false;
518
            }
519
        }
520
        return true;
521
    }
522

    
523
    /**
524
     * Transforms a search string which allows wildcard "*" into a
525
     * java regular expression such that all other characters are handled as normal text.
526
     * @param regEx
527
     * @return
528
     */
529
    public static String quoteRegExWithWildcard(String regEx){
530
        return Pattern.quote(regEx).replace("*", "\\E.*\\Q").replace("\\Q\\E", "");
531
    }
532

    
533
    public static int diffIndex(String str1, String str2) {
534
        if (str1 == null || str2 == null){
535
            return 0;
536
        }
537
        for (int i = 0; i<str1.length() && i<str2.length() ;i++) {
538
            if (str1.charAt(i)!= str2.charAt(i)){
539
                return i;
540
            }
541
        }
542
        if(str1.length()!=str2.length()){
543
            return Math.max(str1.length(), str2.length());
544
        }
545
        return -1;
546
    }
547

    
548
    public static String userFriendlyCamelCase(String camelCase){
549
        return String.join(" ", StringUtils.splitByCharacterTypeCamelCase(camelCase));
550
    }
551

    
552
    public static String userFriendlyClassName(Class<?> clazz){
553
        return userFriendlyCamelCase(clazz.getSimpleName());
554
    }
555

    
556
}
(4-4/26)