5a17f887d98e974122d72206db036ea46049cb27
[sdc.git] /
1 /*
2  * Copyright © 2016-2017 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.core.utilities;
18
19 import org.apache.commons.codec.binary.Base64;
20 import org.apache.commons.collections4.MapUtils;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.io.ObjectInputStream;
26 import java.io.ObjectOutputStream;
27 import java.io.PrintWriter;
28 import java.io.Serializable;
29 import java.io.StringWriter;
30 import java.lang.reflect.Array;
31 import java.net.URL;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Objects;
40 import java.util.Set;
41 import java.util.UUID;
42
43 /**
44  * This class provides auxiliary static methods.
45  */
46 public class CommonMethods {
47
48   private static final char[] CHARS = new char[]{
49       '0', '1', '2', '3', '4', '5', '6', '7',
50       '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
51   };
52   private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
53
54   /**
55    * Private default constructor to prevent instantiation of the class objects.
56    */
57   private CommonMethods() {
58   }
59
60   /**
61    * Serializes an object instance into byte array.
62    *
63    * @param object An instance to be serialized.
64    * @return Java array of bytes.
65    * @see #deserializeObject(byte[]) #deserializeObject(byte[])
66    */
67   public static byte[] serializeObject(Serializable object) {
68     ByteArrayOutputStream byteArray = new ByteArrayOutputStream(2048);
69     try {
70       ObjectOutputStream ds = new ObjectOutputStream(byteArray);
71       ds.writeObject(object);
72       ds.close();
73     } catch (IOException exception) {
74       throw new RuntimeException(exception);
75     }
76
77     return byteArray.toByteArray();
78   } // serializeObject
79
80   /**
81    * Deserializes an object instance.
82    *
83    * @param bytes Java array of bytes.
84    * @return Deserialized instance of an object.
85    * @see #serializeObject(Serializable) #serializeObject(Serializable)
86    */
87   public static Serializable deserializeObject(byte[] bytes) {
88     Serializable obj = null;
89     try {
90       ObjectInputStream stream = new ObjectInputStream(new ByteArrayInputStream(bytes));
91       obj = (Serializable) stream.readObject();
92       stream.close();
93     } catch (IOException | ClassNotFoundException exception) {
94       throw new RuntimeException(exception);
95     }
96
97     return obj;
98   } // deserializeObject
99
100   /**
101    * Encodes binary byte stream to ASCII format.
102    *
103    * @param binary An Java array of bytes in binary format.
104    * @return An Java array of bytes encoded in ASCII format.
105    * @see #decode(byte[]) #decode(byte[])
106    */
107   public static byte[] encode(byte[] binary) {
108     return Base64.encodeBase64(binary);
109   }
110
111   /**
112    * Decodes ASCII byte stream into binary format.
113    *
114    * @param ascii An Java array of bytes in ASCII format.
115    * @return An Java array of bytes encoded in binary format.
116    * @see #encode(byte[]) #encode(byte[])
117    */
118   public static byte[] decode(byte[] ascii) {
119     return Base64.decodeBase64(ascii);
120   }
121
122   /**
123    * Checks whether the given <tt>Object</tt> is empty.
124    *
125    * @param obj Object to be checked.
126    * @return <tt>true</tt> - if the Object is null, <tt>false</tt> otherwise.
127    */
128   public static boolean isEmpty(Object obj) {
129     return obj == null;
130   }
131
132   /**
133    * Checks whether the given <tt>Object</tt> is empty.
134    *
135    * @param byteArray Object to be checked.
136    * @return <tt>true</tt> - if the Object is null, <tt>false</tt> otherwise.
137    */
138   public static boolean isEmpty(byte[] byteArray) {
139     return byteArray == null || byteArray.length == 0;
140   }
141
142   /**
143    * Checks whether the given <tt>String</tt> is empty.
144    *
145    * @param str String object to be checked.
146    * @return <tt>true</tt> - if the String is null or empty, <tt>false</tt> - otherwise.
147    */
148   public static boolean isEmpty(String str) {
149     return str == null || str.length() == 0;
150   }
151
152   /**
153    * Checks whether the given Java array is empty.
154    *
155    * @param array Java array to be checked.
156    * @return <tt>true</tt> - if the array is null or empty, <tt>false</tt> - otherwise.
157    */
158   public static boolean isEmpty(Object[] array) {
159     return array == null || array.length == 0;
160   }
161
162   /**
163    * Checks whether the given collection is empty.
164    *
165    * @param collection A collection to be checked.
166    * @return <tt>true</tt> - if the collection is null or empty, <tt>false</tt> - otherwise.
167    */
168   public static boolean isEmpty(Collection<?> collection) {
169     return collection == null || collection.isEmpty();
170   }
171
172   /**
173    * Checks whether the given map is empty.
174    *
175    * @param map A map to be checked.
176    * @return <tt>true</tt> - if the map is null or empty, <tt>false</tt> - otherwise.
177    */
178   public static boolean isEmpty(Map<?, ?> map) {
179     return map == null || map.isEmpty();
180   }
181
182   /**
183    * Converts the array with Long elements to the array with long (primitive type).
184    *
185    * @param array input array with Long elements
186    * @return array with the same elements converted to the long type (primitive)
187    */
188   public static long[] toPrimitive(Long[] array) {
189     if (array == null) {
190       return null;
191     }
192
193     long[] result = new long[array.length];
194     for (int i = 0; i < array.length; i++) {
195       result[i] = array[i] != null ? array[i] : 0L;
196     }
197     return result;
198   }
199
200   /**
201    * Converts a collection to Java array.
202    *
203    * @param <T>  Java type of the collection element.
204    * @param col  Collection to be converted to array
205    * @param type Java type of collection/array element
206    * @return An Java array of collection elements, or empty array if collection is null or empty.
207    */
208   @SuppressWarnings("unchecked")
209   public static <T> T[] toArray(Collection<? extends T> col, Class<T> type) {
210     int length = isEmpty(col) ? 0 : col.size();
211     T[] array = (T[]) Array.newInstance(type, length);
212     return col != null ? col.toArray(array) : array;
213   }
214
215   /**
216    * Gets an universally unique identifier (UUID).
217    *
218    * @return String representation of generated UUID.
219    */
220   public static String nextUuId() {
221     UUID uuid = UUID.randomUUID();
222
223     StringBuilder buff = new StringBuilder(32);
224     long2string(uuid.getMostSignificantBits(), buff);
225     long2string(uuid.getLeastSignificantBits(), buff);
226
227     return buff.toString();
228   }
229
230   private static void long2string(long lng, StringBuilder buff) {
231     long value = lng;
232     for (int i = 0; i < 16; i++) {
233       long nextByte = value & 0xF000000000000000L;
234       value <<= 4;
235       boolean isNegative = nextByte < 0;
236       nextByte = rightShift(nextByte, 60);
237
238       if (isNegative) {
239         nextByte |= 0x08;
240       }
241
242       buff.append(CHARS[(int) nextByte]);
243     }
244   }
245
246   private static long rightShift(long lng, int num) {
247     return lng >>> num;
248   }
249
250   /**
251    * Concatenates two Java arrays. The method allocates a new array and copies
252    * all elements to it or returns one of input arrays if another one is
253    * empty.
254    *
255    * @param <T>   the type parameter
256    * @param left  Elements of this array will be copied to positions from 0 to <tt>left.length -
257    *              1</tt> in the target array.
258    * @param right Elements of this array will be copied to positions from <tt>left.length</tt> to
259    *              <tt>left.length + right.length</tt>
260    * @return A newly allocate Java array that accommodates elements of source (left/right) arrays
261     orone of source arrays if another is empty, <tt>null</tt> - otherwise.
262    */
263   @SuppressWarnings("unchecked")
264   public static <T> T[] concat(T[] left, T[] right) {
265     T[] res;
266
267     if (isEmpty(left)) {
268       res = right;
269     } else if (isEmpty(right)) {
270       res = left;
271     } else {
272       res = (T[]) Array.newInstance(left[0].getClass(), left.length + right.length);
273       System.arraycopy(left, 0, res, 0, left.length);
274       System.arraycopy(right, 0, res, left.length, right.length);
275     }
276
277     return res;
278   } // concat
279
280   /**
281    * Casts an object to the class or interface represented by the specified
282    * <tt>Class</tt> object. The method logic is similar to Java method
283    * <tt>Class.cast(Object)</tt> with the only difference that unlike Java's
284    * version the type name of the current object instance is specified in the
285    * error message if casting fails to simplify error tracking.
286    *
287    * @param <B> the type parameter
288    * @param <D> the type parameter
289    * @param b1  An object instance to be casted to the specified Java type.
290    * @param cls Target Java type.
291    * @return Object instance safely casted to the requested Java type.
292    * @throws ClassCastException In case which is the given object is not instance of the specified
293    *                            Java type.
294    */
295   @SuppressWarnings("unchecked")
296   public static <B, D> D cast(B b1, Class<D> cls) {
297     D d1 = null;
298     if (b1 != null) {
299       if (!cls.isInstance(b1)) {
300         throw new ClassCastException(String
301             .format("Failed to cast from '%s' to '%s'", b1.getClass().getName(), cls.getName()));
302       } else {
303         d1 = (D) b1;
304       }
305     }
306
307     return d1;
308   } // cast
309
310   /**
311    * New instance object.
312    *
313    * @param classname the classname
314    * @return the object
315    */
316   public static Object newInstance(String classname) {
317     return newInstance(classname, Object.class);
318   }
319
320   /**
321    * New instance t.
322    *
323    * @param <T>       the type parameter
324    * @param classname the classname
325    * @param cls       the cls
326    * @return the t
327    */
328   @SuppressWarnings("unchecked")
329   public static <T> T newInstance(String classname, Class<T> cls) {
330
331     if (isEmpty(classname)) {
332       throw new IllegalArgumentException();
333     }
334
335     if (cls == null) {
336       throw new IllegalArgumentException();
337     }
338
339     try {
340       Class<?> temp = Class.forName(classname);
341
342       if (!cls.isAssignableFrom(temp)) {
343         throw new ClassCastException(
344             String.format("Failed to cast from '%s' to '%s'", classname, cls.getName()));
345       }
346
347       Class<? extends T> impl = (Class<? extends T>) temp;
348
349       return newInstance(impl);
350     } catch (ClassNotFoundException exception) {
351       throw new IllegalArgumentException(exception);
352     }
353   }
354
355   /**
356    * New instance t.
357    *
358    * @param <T> the type parameter
359    * @param cls the cls
360    * @return the t
361    */
362   public static <T> T newInstance(Class<T> cls) {
363     try {
364       return cls.newInstance();
365     } catch (InstantiationException | IllegalAccessException exception) {
366       throw new RuntimeException(exception);
367     }
368   }
369
370   /**
371    * Gets resources path.
372    *
373    * @param resourceName the resource name
374    * @return the resources path
375    */
376   public static String getResourcesPath(String resourceName) {
377     URL resourceUrl = CommonMethods.class.getClassLoader().getResource(resourceName);
378     return resourceUrl != null ? resourceUrl.getPath()
379         .substring(0, resourceUrl.getPath().lastIndexOf("/") + 1) : null;
380   }
381
382   /**
383    * Gets stack trace.
384    *
385    * @param throwable the throwable
386    * @return the stack trace
387    */
388   public static String getStackTrace(Throwable throwable) {
389     if (null == throwable) {
390       return "";
391     }
392     StringWriter sw = new StringWriter();
393     throwable.printStackTrace(new PrintWriter(sw));
394     return sw.toString();
395   }
396
397   /**
398    * Print stack trace string.
399    *
400    * @return the string
401    */
402   public static String printStackTrace() {
403     StringBuilder sb = new StringBuilder();
404     StackTraceElement[] trace = Thread.currentThread().getStackTrace();
405     for (StackTraceElement traceElement : trace) {
406       sb.append("\t  ").append(traceElement);
407       sb.append(System.lineSeparator());
408     }
409     return sb.toString();
410   }
411
412   /**
413    * Is equal object boolean.
414    *
415    * @param obj1 the obj 1
416    * @param obj2 the obj 2
417    * @return the boolean
418    */
419   public static boolean isEqualObject(Object obj1, Object obj2) {
420     boolean isEqualValue = false;
421     if (obj1 == null && obj2 == null) {
422       isEqualValue = true;
423     }
424
425     if (!isEqualValue && obj1 != null && obj2 != null && obj1.equals(obj2)) {
426       isEqualValue = true;
427     }
428     return isEqualValue;
429   }
430
431   /**
432    * Converts array of strings to comma-separated string.
433    *
434    * @param arr array of strings
435    * @return the string
436    */
437   public static String arrayToCommaSeparatedString(String[] arr) {
438     return arrayToSeparatedString(arr, ',');
439   }
440
441   /**
442    * Collection to comma separated string string.
443    *
444    * @param elementCollection the element collection
445    * @return the string
446    */
447   public static String collectionToCommaSeparatedString(Collection<String> elementCollection) {
448     List<String> list = new ArrayList<>();
449     list.addAll(elementCollection);
450     return listToSeparatedString(list, ',');
451   }
452
453   /**
454    * Converts array of strings to string separated with specified character.
455    *
456    * @param arr       array of strings
457    * @param separator the separator
458    * @return the string
459    */
460   public static String arrayToSeparatedString(String[] arr, char separator) {
461     return listToSeparatedString(Arrays.asList(arr), separator);
462   }
463
464   /**
465    * Converts array of strings to string separated with specified character.
466    *
467    * @param list      array of strings
468    * @param separator the separator
469    * @return the string
470    */
471   public static String listToSeparatedString(List<String> list, char separator) {
472     String res = null;
473     if (null != list) {
474       StringBuilder sb = new StringBuilder();
475       int sz = list.size();
476       for (int i = 0; i < sz; i++) {
477         if (i > 0) {
478           sb.append(separator);
479         }
480         sb.append(list.get(i));
481       }
482       res = sb.toString();
483     }
484     return res;
485   }
486
487   /**
488    * Duplicate string with delimiter string.
489    *
490    * @param arg                  the arg
491    * @param separator            the separator
492    * @param numberOfDuplications the number of duplications
493    * @return the string
494    */
495   public static String duplicateStringWithDelimiter(String arg, char separator,
496                                                     int numberOfDuplications) {
497     StringBuilder sb = new StringBuilder();
498
499     for (int i = 0; i < numberOfDuplications; i++) {
500       if (i > 0) {
501         sb.append(separator);
502       }
503       sb.append(arg);
504     }
505     return sb.toString();
506   }
507
508   /**
509    * Bytes to hex string.
510    *
511    * @param bytes the bytes
512    * @return the string
513    */
514   public static String bytesToHex(byte[] bytes) {
515     char[] hexChars = new char[bytes.length * 2];
516     for (int j = 0; j < bytes.length; j++) {
517       int var = bytes[j] & 0xFF;
518       int x1 = j << 1;
519       hexChars[x1] = hexArray[var >>> 4];
520       hexChars[x1 + 1] = hexArray[var & 0x0F];
521     }
522     return new String(hexChars);
523   }
524
525   /**
526    * To single element set set.
527    *
528    * @param <T>     the class of the objects in the set
529    * @param element the single element to be contained in the returned Set
530    * @return an immutable set containing only the specified object. The returned set is
531     serializable.
532    */
533   public static <T> Set<T> toSingleElementSet(T element) {
534     return Collections.singleton(element);
535
536   }
537
538   /**
539    * Merge lists of map list.
540    *
541    * @param <T>    the type parameter
542    * @param <S>    the type parameter
543    * @param target the target
544    * @param source the source
545    * @return the list
546    */
547   public static <T, S> List<Map<T, S>> mergeListsOfMap(List<Map<T, S>> target,
548                                                        List<Map<T, S>> source) {
549     List<Map<T, S>> retList = new ArrayList<>();
550     if (Objects.nonNull(target)) {
551       retList.addAll(target);
552     }
553
554     if (Objects.nonNull(source)) {
555       for (Map<T, S> sourceMap : source) {
556         for (Map.Entry<T, S> entry : sourceMap.entrySet()) {
557           mergeEntryInList(entry.getKey(), entry.getValue(), retList);
558         }
559       }
560     }
561     return retList;
562   }
563
564   /**
565    * Merge lists list.
566    *
567    * @param <T>    the type parameter
568    * @param target the target
569    * @param source the source
570    * @return the list
571    */
572   public static <T> List<T> mergeLists(List<T> target, List<T> source) {
573     List<T> retList = new ArrayList<>();
574
575     if (Objects.nonNull(source)) {
576       retList.addAll(source);
577     }
578     if (Objects.nonNull(target)) {
579       retList.addAll(target);
580     }
581
582     return retList;
583   }
584
585   /**
586    * Merge entry in list.
587    *
588    * @param <T>    the type parameter
589    * @param <S>    the type parameter
590    * @param key    the key
591    * @param value  the value
592    * @param target the target
593    */
594   public static <T, S> void mergeEntryInList(T key, S value, List<Map<T, S>> target) {
595     boolean found = false;
596     for (Map<T, S> map : target) {
597       if (map.containsKey(key)) {
598         map.put(key, value);
599         found = true;
600       }
601     }
602
603     if (!found) {
604       Map<T, S> newMap = new HashMap<>();
605       newMap.put(key, value);
606       target.add(newMap);
607     }
608   }
609
610
611   /**
612    * Merge maps map.
613    *
614    * @param <T>    the type parameter
615    * @param <S>    the type parameter
616    * @param target the target
617    * @param source the source
618    * @return the map
619    */
620   public static <T, S> Map<T, S> mergeMaps(Map<T, S> target, Map<T, S> source) {
621     Map<T, S> retMap = new HashMap<>();
622     if (MapUtils.isNotEmpty(source)) {
623       retMap.putAll(source);
624     }
625     if (MapUtils.isNotEmpty(target)) {
626       retMap.putAll(target);
627     }
628     return retMap;
629   }
630
631 }
632