/** * 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.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 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 <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 <T> Set<T> newHashSet() { return new HashSet<T>(); } public static <T> Set<T> newHashSet(T ...items) { return new HashSet<T>(Arrays.asList(items)); } public static <K,V> Map<K,V> newHashMap() { return new HashMap<K, V>(); } public static <K,V> Map<K,V> newHashMap(Map<K,V> map) { return new HashMap<K, V>(map); } public static <K, V> Map<K,V> newHashMap(K k, V v) { HashMap<K, V> newMap = new HashMap<K, V>(); newMap.put(k, v); return newMap; } public static <K,V> Map<K,V> newLinkedHashMap() { return new LinkedHashMap<K, V>(); } public static <K, V> Map<K,V> newLinkedHashMap(K k, V v) { HashMap<K, V> newMap = new LinkedHashMap<K, V>(); newMap.put(k, v); return newMap; } public static <K,V> Map<K,V> newConcurrentHashMap() { return new ConcurrentHashMap<K, V>(); } public static <T> List<T> newList() { return new ArrayList<T>(); } public static <T> List<T> newList(T...items) { List<T> list = new ArrayList<T>(); for (T t : items) { list.add(t); } return list; } public static <T> List<T> newList(Collection<T> items) { List<T> list = new ArrayList<T>(); for (T t : items) { list.add(t); } return list; } /** * 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 { map.put(k1, TUtil.newList(value)); } } 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, TUtil.newList(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 { map.put(k1, TUtil.newLinkedHashMap(k2, value)); } } public static String collectionToString(Collection objects) { boolean first = true; StringBuilder sb = new StringBuilder(); for(Object object : objects) { if (first) { first = false; } else { sb.append(", "); } sb.append(object.toString()); } return sb.toString(); } public static String arrayToString(Object [] objects) { boolean first = true; StringBuilder sb = new StringBuilder(); for(Object object : objects) { if (first) { first = false; } else { sb.append(", "); } sb.append(object.toString()); } return sb.toString(); } public static <T> T [] toArray(Collection<T> collection, Class<T> type) { T array = (T) Array.newInstance(type, collection.size()); return collection.toArray((T[]) 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() +")"; } }