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.log4j.Logger;
30

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

    
37
    private static final Logger logger = Logger.getLogger(CdmUtils.class);
38

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

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

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

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

    
89
    static public String readInputLine(String inputQuestion){
90

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

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

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

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

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

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

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

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

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

    
201

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
554
    public static String userFriendlyClassName(Class<?> clazz){
555
        return userFriendlyCamelCase(clazz.getSimpleName());
556
    }
557
}
(4-4/25)