/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.tajo.util;
import com.google.common.base.Objects;
import java.lang.reflect.Array;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* It provides miscellaneous and useful util methods.
*/
public class TUtil {
/**
* check two objects as equals.
* It will return true even if they are all null.
*
* @param s1 the first object to be compared.
* @param s2 the second object to be compared
*
* @return true if they are equal or all null
*/
public static boolean checkEquals(Object s1, Object s2) {
return Objects.equal(s1, s2);
}
/**
* check two collections as equals. It also check the equivalence of null.
* It will return true even if they are all null.
*
* @param s1 the first collection to be compared.
* @param s2 the second collection to be compared
* @return true if they are equal or all null
*/
public static boolean checkEquals(Collection<?> s1, Collection<?> s2) {
if (s1 == null && s2 == null) {
return true;
} else if (s1 == null || s2 == null) {
return false;
} else {
if (s1.size() == 0 && s2.size() == 0) {
return true;
} else if (s1.size() == s2.size()) {
Iterator<?> it1 = s1.iterator();
Iterator<?> it2 = s2.iterator();
Object o1;
Object o2;
for (o1 = it1.next(), o2 = it2.next(); it1.hasNext() && it2.hasNext(); o1 = it1.next(), o2 = it2.next()) {
if (!o1.equals(o2)) {
return false;
}
}
}
return true;
}
}
/**
* check two arrays as equals. It also check the equivalence of null.
* It will return true even if they are all null.
*
* @param s1 the first array to be compared.
* @param s2 the second array to be compared
* @return true if they are equal or all null
*/
public static boolean checkEquals(Object [] s1, Object [] s2) {
if (s1 == null ^ s2 == null) {
return false;
} else if (s1 == null && s2 == null) {
return true;
} else {
return Arrays.equals(s1, s2);
}
}
public static boolean checkEquals(int [] s1, int [] s2) {
if (s1 == null ^ s2 == null) {
return false;
} else if (s1 == null && s2 == null) {
return true;
} else {
return Arrays.equals(s1, s2);
}
}
public static <T> T[] concat(T[] first, T[] second) {
T[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
public static <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
totalLength += array.length;
}
T[] result = Arrays.copyOf(first, totalLength);
int offset = first.length;
for (T[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
public static <K,V> Map<K,V> newConcurrentHashMap() {
return new ConcurrentHashMap<>();
}
/**
* It check if T is null or not.
*
* @param reference the object reference to be checked
* @param <T> The object type
* @return The reference
*/
public static <T> T checkNotNull(T reference) {
if (reference == null) {
throw new NullPointerException();
}
return reference;
}
public static <KEY1, VALUE> void putToNestedList(Map<KEY1, List<VALUE>> map, KEY1 k1, VALUE value) {
if (map.containsKey(k1)) {
map.get(k1).add(value);
} else {
List inputList = new ArrayList<>();
inputList.add(value);
map.put(k1, inputList);
}
}
public static <KEY1, VALUE> void putCollectionToNestedList(Map<KEY1, List<VALUE>> map, KEY1 k1,
Collection<VALUE> list) {
if (map.containsKey(k1)) {
map.get(k1).addAll(list);
} else {
map.put(k1, new ArrayList<>(list));
}
}
public static <KEY1, KEY2, VALUE> void putToNestedMap(Map<KEY1, Map<KEY2, VALUE>> map, KEY1 k1, KEY2 k2,
VALUE value) {
if (map.containsKey(k1)) {
map.get(k1).put(k2, value);
} else {
HashMap<KEY2, VALUE> newMap = new LinkedHashMap<>();
newMap.put(k2, value);
map.put(k1, newMap);
}
}
/**
* It checks if an item is included in Map<KEY1, Map<KEY2, VALUE>>.
*
* @return True if the item is included in the nested map.
*/
public static <KEY1, KEY2, VALUE> boolean containsInNestedMap(Map<KEY1, Map<KEY2, VALUE>> map, KEY1 k1, KEY2 k2) {
return map.containsKey(k1) && map.get(k1).containsKey(k2);
}
/**
* Get an item in Map<KEY1, Map<KEY2, VALUE>>.
*
* @return a VALUE
*/
public static <KEY1, KEY2, VALUE> VALUE getFromNestedMap(Map<KEY1, Map<KEY2, VALUE>> map, KEY1 k1, KEY2 k2) {
if (map.containsKey(k1)) {
return map.get(k1).get(k2);
} else {
return null;
}
}
public static <T> T [] toArray(Collection<T> collection, Class<T> type) {
T array = (T) Array.newInstance(type, collection.size());
return collection.toArray((T[]) array);
}
public static int[] toArray(Collection<Integer> collection) {
int[] array = new int[collection.size()];
int index = 0;
for (Integer eachInt: collection) {
array[index++] = eachInt;
}
return array;
}
/**
* It returns the exact code point at which this running thread is executed.
*
* @param depth in the call stack (0 means current method, 1 means call method, ...)
* @return A string including class name, method, and line.
*/
public static String getCurrentCodePoint(final int depth) {
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
StackTraceElement element = ste[2 + depth];
return element.getClassName() + ":" + element.getMethodName() + "(" + element.getLineNumber() +")";
}
public static URI stringToURI(String str) {
try {
return new URI(str);
} catch (URISyntaxException e) {
throw new RuntimeException("Cannot convert " + str + " to the URI type", e);
}
}
public static <T> T checkTypeAndGet(Object instance, Class<T> type) {
if (!type.isInstance(instance)) {
throw new IllegalArgumentException(instance.getClass().getSimpleName()
+ " must be a " + type.getSimpleName() + " type");
}
return (T) instance;
}
}