/*
* Copyright 2008-2016 the original author or authors.
*
* Licensed 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 com.nominanuda.zen.seq;
import com.nominanuda.zen.stereotype.ScopedSingletonFactory;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.concurrent.ThreadSafe;
import static com.nominanuda.zen.common.Check.unsupportedoperation;
@ThreadSafe
public class Seq {
public static final Seq SEQ = ScopedSingletonFactory.getInstance().buildJvmSingleton(Seq.class);
public boolean nullOrEmpty(Iterable<?> coll) {
if(coll == null) {
return true;
} else if(coll instanceof Collection) {
return ((Collection<?>)coll).size() == 0;
} else {
return ! coll.iterator().hasNext();
}
}
@SuppressWarnings("unchecked")
public <K,V> Map<K,V> buildMap(@SuppressWarnings("rawtypes") Class<? extends Map> mclass, Object... members) throws IllegalArgumentException {
int len = members.length;
if(len % 2 != 0) {
throw new IllegalArgumentException("odd number of arguments");
}
try {
Map<K,V> m = mclass.newInstance();
for(int i = 0; i < len; i += 2) {
m.put((K)members[i], (V)members[i+1]);
}
return m;
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public <T> HashSet<T> hashSet(@SuppressWarnings("unchecked") T... ts) {
return (HashSet<T>)buildSet(HashSet.class, ts);
}
public <T> LinkedHashSet<T> linkedHashSet(@SuppressWarnings("unchecked") T... ts) {
return (LinkedHashSet<T>)buildSet(LinkedHashSet.class, ts);
}
@SuppressWarnings("unchecked")
public <K,V> LinkedHashMap<K,V> linkedHashMap(Object... ts) {
return (LinkedHashMap<K,V>)buildMap(LinkedHashMap.class, ts);
}
public <T> LinkedList<T> linkedList(Iterable<T> c) {
LinkedList<T> l = new LinkedList<>();
for(T t : c) {
l.add(t);
}
return l;
}
public <T> LinkedList<T> linkedList(@SuppressWarnings("unchecked") T... ts) {
return (LinkedList<T>)buildList(LinkedList.class, ts);
}
@SuppressWarnings("unchecked")
public <T> Set<T> buildSet(@SuppressWarnings("rawtypes") Class<? extends Set> sclass, T...ts) {
try {
Set<T> s = sclass.newInstance();
for(T t : ts) {
s.add(t);
}
return (Set<T>)s;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public <T> List<T> buildList(@SuppressWarnings("rawtypes") Class<? extends List> sclass, T...ts) {
try {
List<T> s = sclass.newInstance();
for(T t : ts) {
s.add(t);
}
return s;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public <T> boolean find(T needle, Iterable<? extends T> haystack) {
for(T x : haystack) {
if(needle.equals(x)) {
return true;
}
}
return false;
}
public <T> boolean find(T needle, T[] haystack) {
for(T x : haystack) {
if(needle.equals(x)) {
return true;
}
}
return false;
}
public <K,V> MapEntry<K, V> mapEntry(K k, V v) {
return new MapEntry<K, V>(k, v);
}
public class MapEntry<K,V> implements Entry<K, V> {
private final K k;
private final V v;
public MapEntry<K, V> of(K k, V v) {
return new MapEntry<K, V>(k, v);
}
public MapEntry(K k, V v) {
this.k = k;
this.v = v;
}
public V setValue(V arg0) {
unsupportedoperation.fail();
return null;
}
public V getValue() {
return v;
}
public K getKey() {
return k;
}
}
@SuppressWarnings("unchecked")
public <T,K extends Collection<? extends T>> K copyAndReverse(K coll) throws RuntimeException /* wrapping InstantiationException, IllegalAccessException*/ {
try {
K res = (K) coll.getClass().newInstance();
if(res instanceof List) {
((Collection<? super T>)res).addAll(coll);
Collections.reverse((List<?>)res);
} else {
List<T> l = copyToList(((Collection<T>)coll));
Collections.reverse((List<?>)l);
((Collection<? super T>)res).addAll(l);
}
return res;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public <T,K extends Collection<? extends T>> K copy(K coll) throws RuntimeException /* wrapping InstantiationException, IllegalAccessException*/ {
try {
K res = (K) coll.getClass().newInstance();
((Collection<? super T>)res).addAll(coll);
return res;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public <T> LinkedList<T> copyToList(Iterable<T> iter) {
LinkedList<T> l = new LinkedList<>();
for(T t : iter) {
l.add(t);
}
return l;
}
public <T> Iterable<T> asIterable(final Iterator<T> iterator) {
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return iterator;
}
};
}
public int writeToArray(Iterable<? extends Object> iter, Object[] arr) {
int idx = 0;
int max = arr.length;
for(Object o : iter) {
arr[idx++] = o;
if(max == idx) {
break;
}
}
return idx;
}
public <X> X[] toTypedArray(Collection<? extends Object> coll, Class<X> elementType) {
@SuppressWarnings("unchecked")
X[] arr = (X[]) Array.newInstance(elementType, coll.size());
writeToArray(coll, arr);
return arr;
}
@SuppressWarnings("unchecked")
public <T> Collection<T> emptyImmutbleSet() {
return (Collection<T>)Collections.EMPTY_SET;
}
public <T> List<T> emptyList() {
return Collections.emptyList();
}
public Map<String, Object> emptyMap() {
return Collections.emptyMap();
}
public <T> List<T> fixedList(T... ts) {
return Arrays.asList(ts);
}
public <T> List<T> reversedClone(List<T> list) {
try {
@SuppressWarnings("unchecked")
List<T> l2 = list.getClass().newInstance();
l2.addAll(list);
Collections.reverse(l2);
return l2;
} catch (Exception e) {
return null;
}
}
}