Initial Commit

This commit is contained in:
Mark Milligan
2021-01-14 16:28:24 -06:00
parent 21c28201c5
commit 1334c110ff
318 changed files with 24160 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lanternsoftware.util</groupId>
<artifactId>lantern-util-common</artifactId>
<name>lantern-util-common</name>
<version>1.0.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.29</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<executions>
<execution>
<goals>
<goal>testCompile</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
<configuration>
<optimize>true</optimize>
<showDeprecation>true</showDeprecation>
<encoding>UTF-8</encoding>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,935 @@
package com.lanternsoftware.util;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.RandomAccess;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
public class CollectionUtils {
public static <T> T getFirst(Collection<T> _collObjects) {
if ((_collObjects != null) && !_collObjects.isEmpty())
return _collObjects.iterator().next();
return null;
}
public static <T> T removeFirst(Collection<T> _objects) {
if (_objects == null)
return null;
Iterator<T> iter = _objects.iterator();
if (iter.hasNext()) {
T t = iter.next();
iter.remove();
return t;
}
return null;
}
public static <T> T removeOne(Collection<T> _coll, IQualifier<T> _qualifier) {
if ((_coll == null) || (_qualifier == null))
return null;
Iterator<T> iter = _coll.iterator();
while (iter.hasNext()) {
T t = iter.next();
if (_qualifier.qualifies(t)) {
iter.remove();
return t;
}
}
return null;
}
public static <T> List<T> removeAll(Collection<T> _coll, IQualifier<T> _qualifier) {
if ((_coll == null) || (_qualifier == null))
return null;
List<T> ret = new ArrayList<>();
Iterator<T> iter = _coll.iterator();
while (iter.hasNext()) {
T t = iter.next();
if (_qualifier.qualifies(t)) {
iter.remove();
ret.add(t);
}
}
return ret;
}
public static <T> T getLast(Collection<T> _collObjects) {
if ((_collObjects == null) || _collObjects.isEmpty())
return null;
if (_collObjects instanceof RandomAccess) {
List<T> listObjects = (List<T>) _collObjects;
return listObjects.get(listObjects.size() - 1);
}
if (_collObjects instanceof Deque) {
Deque<T> listObjects = (Deque<T>) _collObjects;
return listObjects.getLast();
}
T t = null;
Iterator<T> iter = _collObjects.iterator();
while (iter.hasNext()) {
t = iter.next();
}
return t;
}
public static <T> T getFirst(T[] _arrObjects) {
if (size(_arrObjects) > 0)
return _arrObjects[0];
return null;
}
public static <T> boolean isEmpty(Collection<T> _collObjects) {
return (_collObjects == null) || _collObjects.isEmpty();
}
public static <T> boolean isNotEmpty(Collection<T> _collObjects) {
return (_collObjects != null) && !_collObjects.isEmpty();
}
public static <T,V> boolean isEmpty(Map<T,V> _map) {
return (_map == null) || _map.isEmpty();
}
public static <T,V> boolean isNotEmpty(Map<T,V> _map) {
return (_map != null) && !_map.isEmpty();
}
public static <T> Collection<T> makeNotNull(Collection<T> _collObjects) {
if (_collObjects != null)
return _collObjects;
return new ArrayList<T>();
}
public static <T> List<T> makeNotNull(List<T> _listObjects) {
if (_listObjects != null)
return _listObjects;
return new ArrayList<T>();
}
public static <T, V> Map<T, V> makeNotNull(Map<T, V> _mapObjects) {
if (_mapObjects != null)
return _mapObjects;
return new HashMap<T, V>();
}
public static int size(Collection<?> _collObjects) {
if (_collObjects == null)
return 0;
return _collObjects.size();
}
public static <T,V> int size(Map<T, V> _collObjects) {
if (_collObjects == null)
return 0;
return _collObjects.size();
}
public static <T> int size(T[] _arr) {
if (_arr == null)
return 0;
return _arr.length;
}
public static <T> T get(List<T> _list, int _idx) {
if (_list == null)
return null;
if ((_idx < 0) || (_idx >= _list.size()))
return null;
return _list.get(_idx);
}
public static <T> T get(T[] _t, int _idx) {
if (_t == null)
return null;
if ((_idx < 0) || (_idx >= _t.length))
return null;
return _t[_idx];
}
public static <T, V> List<V> get(Map<T, V> _map, Collection<T> _keys) {
if (_keys == null)
return null;
List<V> ret = new ArrayList<>();
for (T t : _keys) {
ret.add(_map.get(t));
}
return ret;
}
public static <T> T last(T[] _arr) {
if (_arr == null || _arr.length == 0)
return null;
return _arr[_arr.length - 1];
}
public static <T> boolean contains(Collection<T> _coll, T _t) {
if (_coll == null)
return false;
return _coll.contains(_t);
}
public static <T> boolean containsAny(Collection<T> _coll, T... _t) {
return containsAny(_coll, asArrayList(_t));
}
public static <T> boolean containsAny(Collection<T> _coll, Collection<T> _values) {
if (size(_values) == 0)
return false;
for (T t : _values) {
if (contains(_coll, t))
return true;
}
return false;
}
public static <T> boolean containsAll(Collection<T> _coll, T... _t) {
return containsAll(_coll, asArrayList(_t));
}
public static <T> boolean containsAll(Collection<T> _coll, Collection<T> _values) {
if (size(_values) == 0)
return true;
for (T t : _values) {
if (!contains(_coll, t))
return false;
}
return true;
}
public static <T> boolean containsNone(Collection<T> _coll, T... _t) {
return containsNone(_coll, asArrayList(_t));
}
public static <T> boolean containsNone(Collection<T> _coll, Collection<T> _values) {
if (size(_values) == 0)
return true;
for (T t : _values) {
if (contains(_coll, t))
return false;
}
return true;
}
public static <T> List<T> merge(Collection<List<T>> _colls) {
List<T> list = new ArrayList<>();
for (List<? extends T> coll : makeNotNull(_colls)) {
list.addAll(coll);
}
return list;
}
public static <T> List<T> merge(Collection<? extends T> _coll1, Collection<? extends T> _coll2) {
List<T> list = new ArrayList<>(makeNotNull(_coll1));
list.addAll(makeNotNull(_coll2));
return list;
}
public static <T, V> List<V> aggregate(Collection<T> _coll, IAggregator<T, V> _aggregator) {
List<V> list = new ArrayList<>();
for (T t : makeNotNull(_coll)) {
List<V> vs = _aggregator.aggregate(t);
if (vs != null)
list.addAll(vs);
}
return list;
}
public static <T, V, U> Map<U, V> aggregateToMap(Collection<T> _coll, IAggregator<T, V> _aggregator, ITransformer<V, U> _keyTransformer) {
return transformToMap(aggregate(_coll, _aggregator), _keyTransformer);
}
public static byte[] merge(byte[]... _arrs) {
int iSize = 0;
for (byte[] curArr : _arrs) {
if (curArr != null)
iSize += curArr.length;
}
byte[] arr = new byte[iSize];
int offset = 0;
for (byte[] curArr : _arrs) {
if (curArr == null)
continue;
System.arraycopy(curArr, 0, arr, offset, curArr.length);
offset += curArr.length;
}
return arr;
}
public static <T, V> List<V> getMultiMapList(T _key, Map<T, List<V>> _map) {
List<V> list = _map.get(_key);
if (list == null) {
list = new ArrayList<>();
_map.put(_key, list);
}
return list;
}
public static <T, V> Set<V> getMultiMapSet(T _key, Map<T, Set<V>> _map) {
Set<V> set = _map.get(_key);
if (set == null) {
set = new HashSet<>();
_map.put(_key, set);
}
return set;
}
public static <T, V> List<V> addToMultiMap(T _key, V _value, Map<T, List<V>> _map) {
List<V> list = getMultiMapList(_key, _map);
list.add(_value);
return list;
}
public static <T, V> Set<V> addToMultiMapSet(T _key, V _value, Map<T, Set<V>> _map) {
Set<V> set = getMultiMapSet(_key, _map);
set.add(_value);
return set;
}
public static int sumIntegers(Collection<Integer> _coll) {
int sum = 0;
for (Integer val : makeNotNull(_coll)) {
if (val != null)
sum += val;
}
return sum;
}
public static Double sum(Collection<Double> _coll) {
double sum = 0.0;
for (Double val : makeNotNull(_coll)) {
if (val != null)
sum += val;
}
return sum;
}
public static Double mean(Collection<Double> _coll) {
int cnt = 0;
double total = 0.0;
for (Double val : makeNotNull(_coll)) {
if (val != null) {
cnt++;
total += val;
}
}
if (cnt == 0)
return 0.0;
return total / cnt;
}
public static Double variance(Collection<Double> _coll) {
double mean = mean(_coll);
int cnt = 0;
double total = 0.0;
for (Double val : makeNotNull(_coll)) {
if (val != null) {
cnt++;
total += (val - mean) * (val - mean);
}
}
if (cnt == 0)
return 0.0;
return total / cnt;
}
public static Double standardDeviation(Collection<Double> _coll) {
return Math.sqrt(variance(_coll));
}
public static <T> List<List<T>> split(List<T> _list, int _size) {
if (_list == null)
return Collections.emptyList();
int iPieces = (_list.size() / _size) + 1;
List<List<T>> list = new ArrayList<>(iPieces);
for (int i = 0; i < iPieces; i++) {
list.add(_list.subList(i * _size, Math.min(_list.size(), (i + 1) * _size)));
}
return list;
}
public static <T> List<List<T>> splitEvenly(List<T> _list, int _maxSize) {
if (isEmpty(_list))
return Collections.emptyList();
return splitIntoPieces(_list, ((_list.size()-1) / _maxSize) + 1);
}
public static <T> List<List<T>> splitIntoPieces(List<T> _list, int _pieces) {
return splitIntoPieces(_list, _pieces, false);
}
public static <T> List<List<T>> splitIntoPieces(List<T> _list, int _pieces, boolean _createNewLists) {
if (isEmpty(_list))
return Collections.emptyList();
if (_list.size() < _pieces)
return Collections.singletonList(_list);
int size = (int)Math.ceil(((double)_list.size())/_pieces);
List<List<T>> list = new ArrayList<>(_pieces);
int offset = 0;
while (offset < _list.size()) {
List<T> subList = _list.subList(offset, Math.min(_list.size(), offset+size));
list.add(_createNewLists?new ArrayList<>(subList):subList);
offset += size;
}
return list;
}
public static <T> ArrayList<T> asArrayList(T... _values) {
if (_values == null)
return new ArrayList<>(0);
ArrayList<T> list = new ArrayList<>(_values.length);
for (T t : _values)
list.add(t);
return list;
}
public static <T> HashSet<T> asHashSet(T... _values) {
HashSet<T> setValues = new HashSet<>();
if (_values == null)
return setValues;
for (T t : _values)
setValues.add(t);
return setValues;
}
public static <K, V> HashMap<K, V> asHashMap(K _key, V _value) {
HashMap<K, V> map = new HashMap<>();
map.put(_key, _value);
return map;
}
public static <T> ArrayList<T> asArrayList(Iterable<T> _iterable) {
if (_iterable == null)
return new ArrayList<T>(0);
ArrayList<T> list = new ArrayList<>();
for (T t : _iterable)
list.add(t);
return list;
}
public static <T> ArrayList<T> asArrayList(Iterator<T> _iter) {
if (_iter == null)
return new ArrayList<T>(0);
ArrayList<T> list = new ArrayList<>();
while (_iter.hasNext())
list.add(_iter.next());
return list;
}
public static <T> HashSet<T> asHashSet(Iterable<T> _iterable) {
HashSet<T> setValues = new HashSet<>();
if (_iterable == null)
return setValues;
for (T t : _iterable)
setValues.add(t);
return setValues;
}
public static <T> HashSet<T> asHashSet(Iterator<T> _iter) {
HashSet<T> setValues = new HashSet<>();
if (_iter == null)
return setValues;
while (_iter.hasNext())
setValues.add(_iter.next());
return setValues;
}
public static <T> boolean allQualify(Collection<T> _coll, IQualifier<T> _qualifier) {
if ((_coll == null) || (_qualifier == null))
return false;
for (T t : _coll) {
if ((t == null) || !_qualifier.qualifies(t))
return false;
}
return true;
}
public static <T> boolean anyQualify(Collection<T> _coll, IQualifier<T> _qualifier) {
if ((_coll == null) || (_qualifier == null))
return false;
for (T t : _coll) {
if ((t != null) && _qualifier.qualifies(t))
return true;
}
return false;
}
public static <T> boolean noneQualify(Collection<T> _coll, IQualifier<T> _qualifier) {
if ((_coll == null) || (_qualifier == null))
return true;
for (T t : _coll) {
if ((t != null) && _qualifier.qualifies(t))
return false;
}
return true;
}
public static <T> List<T> filter(Collection<? extends T> _coll, IFilter<T> _filter) {
if ((_coll == null) || (_filter == null))
return new ArrayList<>();
List<T> listValues = new ArrayList<>();
for (T t : _coll) {
if (_filter.isFiltered(t))
listValues.add(t);
}
return listValues;
}
public static <T> T filterOne(Collection<? extends T> _coll, IFilter<T> _filter) {
if ((_coll == null) || (_filter == null))
return null;
for (T t : _coll) {
if (_filter.isFiltered(t))
return t;
}
return null;
}
public static <T> int indexOf(List<? extends T> _list, IQualifier<T> _qual) {
if ((_list == null) || (_qual == null))
return -1;
int i = 0;
for (T t : _list) {
if (_qual.qualifies(t))
return i;
i++;
}
return -1;
}
public static <T> void filterMod(Iterable<? extends T> _iterable, IFilter<T> _filter) {
if ((_iterable == null) || (_filter == null))
return;
Iterator<? extends T> iter = _iterable.iterator();
while (iter.hasNext()) {
if (!_filter.isFiltered(iter.next()))
iter.remove();
}
}
public static <T, V> List<V> filterToType(Iterable<? extends T> _iterable, Class<V> _class) {
List<V> list = new ArrayList<>();
if (_iterable == null)
return list;
for (T t : _iterable) {
if (_class.isInstance(t))
list.add(_class.cast(t));
}
return list;
}
public static <T> void edit(Iterable<T> _coll, IEditor<T> _editor) {
if ((_coll == null) || (_editor == null))
return;
for (T t : _coll) {
_editor.edit(t);
}
}
public static <T, V> List<V> transform(Collection<T> _coll, ITransformer<? super T, V> _transformer) {
return transform(_coll, _transformer, false);
}
public static <T, V> List<V> transform(Iterable<T> _iter, ITransformer<? super T, V> _transformer) {
return transform(_iter, _transformer, false);
}
public static <T, V> List<V> transform(Iterable<T> _iter, ITransformer<? super T, V> _transformer, boolean _excludeNulls) {
if ((_iter == null) || (_transformer == null))
return new ArrayList<>();
List<V> listValues = new ArrayList<>();
for (T t : _iter) {
if (_excludeNulls && (t == null))
continue;
V v = _transformer.transform(t);
if (!_excludeNulls || (v != null))
listValues.add(v);
}
return listValues;
}
public static <T, V> List<V> transform(Collection<T> _coll, ITransformer<? super T, V> _transformer, boolean _excludeNulls) {
if ((_coll == null) || (_transformer == null))
return new ArrayList<>();
List<V> listValues = new ArrayList<>(_coll.size());
for (T t : _coll) {
V v = _transformer.transform(t);
if (!_excludeNulls || (v != null))
listValues.add(v);
}
return listValues;
}
@SuppressWarnings("unchecked")
public static <T, V> V[] transform(T[] _coll, ITransformer<? super T, V> _transformer, Class<V> _destType) {
V[] ret = (V[])Array.newInstance(_destType, size(_coll));
for (int i=0; i < size(_coll); i++) {
ret[i] = _transformer.transform(_coll[i]);
}
return ret;
}
public static <T, V> Map<V, T> transformToMap(Collection<T> _coll, ITransformer<? super T, V> _transformer) {
Map<V, T> mapValues = new HashMap<>();
if ((_coll == null) || (_transformer == null))
return mapValues;
for (T t : _coll) {
V v = _transformer.transform(t);
if (v != null)
mapValues.put(v, t);
}
return mapValues;
}
public static <T, V, U> Map<V, U> transformToMap(Collection<T> _coll, ITransformer<? super T, V> _keyTrans, ITransformer<? super T, U> _valTrans) {
Map<V, U> mapValues = new HashMap<>();
if ((_coll == null) || (_keyTrans == null) || (_valTrans == null))
return mapValues;
for (T t : _coll) {
V v = _keyTrans.transform(t);
U u = _valTrans.transform(t);
if ((v != null) && (u != null))
mapValues.put(v, u);
}
return mapValues;
}
public static <T, V> Map<V, List<T>> transformToMultiMap(Collection<T> _coll, ITransformer<? super T, V> _transformer) {
Map<V, List<T>> mapValues = new HashMap<>();
if ((_coll == null) || (_transformer == null))
return mapValues;
for (T t : _coll) {
V v = _transformer.transform(t);
if (v != null)
addToMultiMap(v, t, mapValues);
}
return mapValues;
}
public static <T, V, U> Map<V, List<U>> transformToMultiMap(Collection<T> _coll, ITransformer<? super T, V> _keyTrans, ITransformer<? super T, U> _valTrans) {
Map<V, List<U>> mapValues = new HashMap<>();
if ((_coll == null) || (_keyTrans == null) || (_valTrans == null))
return mapValues;
for (T t : _coll) {
V v = _keyTrans.transform(t);
U u = _valTrans.transform(t);
if ((v != null) && (u != null))
addToMultiMap(v, u, mapValues);
}
return mapValues;
}
public static <T,V> void addAllToMap(Collection<T> _coll, ITransformer<? super T, V> _keyTrans, Map<V, T> _map) {
for (T t : makeNotNull(_coll)) {
V v = _keyTrans.transform(t);
if (v != null)
_map.put(v, t);
}
}
public static <T,V> void addAllToMultiMap(Collection<T> _coll, ITransformer<? super T, V> _keyTrans, Map<V, List<T>> _map) {
for (T t : makeNotNull(_coll)) {
V v = _keyTrans.transform(t);
if (v != null)
addToMultiMap(v, t, _map);
}
}
public static <T> String transformToCommaSeparated(Collection<T> _coll, ITransformer<? super T, String> _transformer) {
return transformToCommaSeparated(_coll, _transformer, false);
}
public static <T> String transformToCommaSeparated(Collection<T> _coll, ITransformer<? super T, String> _transformer, boolean _spaceAfterComma) {
if (_transformer == null)
return null;
return commaSeparated(transform(_coll, _transformer), _spaceAfterComma);
}
public static <T> String transformAndDelimit(Collection<T> _coll, ITransformer<? super T, String> _transformer, String _delimiter) {
return transformAndDelimit(_coll, _transformer, _delimiter, false);
}
public static <T> String transformAndDelimit(Collection<T> _coll, ITransformer<? super T, String> _transformer, String _delimiter, boolean _discardEmptyValues) {
if (_transformer == null)
return null;
return delimit(transform(_coll, _transformer), _delimiter, _discardEmptyValues);
}
public static String commaSeparated(Collection<String> _values) {
return commaSeparated(_values, false);
}
public static String commaSeparated(Collection<String> _values, boolean _spaceAfterComma) {
return delimit(_values, _spaceAfterComma ? ", " : ",");
}
public static String delimit(Collection<String> _values, String _delimiter) {
return delimit(_values, _delimiter, false);
}
public static String delimit(Collection<String> _values, String _delimiter, boolean _discardEmptyValues) {
StringBuilder builder = null;
for (String value : makeNotNull(_values)) {
if (_discardEmptyValues && NullUtils.isEmpty(value))
continue;
if (builder == null)
builder = new StringBuilder();
else
builder.append(_delimiter);
builder.append(value);
}
if (builder != null)
return builder.toString();
return null;
}
public static List<String> undelimit(String _value, String _delimiter) {
return undelimit(_value, _delimiter, true);
}
public static List<String> undelimit(String _value, String _delimiter, boolean _discardEmptyValues) {
if (_value == null)
return new ArrayList<>();
return asArrayList(_discardEmptyValues?NullUtils.cleanSplit(_value, _delimiter): _value.split(_delimiter));
}
public static <T, V> Set<V> transformToSet(Collection<T> _coll, ITransformer<T, V> _transformer) {
Set<V> setValues = new HashSet<V>();
if ((_coll == null) || (_transformer == null))
return setValues;
for (T t : _coll) {
if (t != null) {
V v = _transformer.transform(t);
if (v != null)
setValues.add(v);
}
}
return setValues;
}
public static <T extends Comparable<T>> T getSmallest(Collection<T> _collObjects)
{
return getSmallest(_collObjects, new Comparator<T>()
{
@Override
public int compare(T o1, T o2)
{
return NullUtils.compare(o1, o2);
}
});
}
public static <T> T getSmallest(Collection<T> _objects, Comparator<T> _comparator)
{
if (_objects == null)
return null;
T ret = null;
for (T t : _objects)
{
if (t == null)
continue;
if ((ret == null) || (_comparator.compare(t, ret) < 0))
ret = t;
}
return ret;
}
public static <T extends Comparable<T>> List<T> getAllSmallest(Collection<T> _collObjects)
{
return getAllSmallest(_collObjects, new Comparator<T>()
{
@Override
public int compare(T o1, T o2)
{
return NullUtils.compare(o1, o2);
}
});
}
public static <T> List<T> getAllSmallest(Collection<T> _objects, Comparator<T> _comparator)
{
final List<T> ret = new ArrayList<>();
if (_objects == null)
return ret;
for (T t : _objects) {
if (t == null)
continue;
if (ret.isEmpty())
ret.add(t);
else {
int comp = _comparator.compare(t, CollectionUtils.getFirst(ret));
if (comp == 0)
ret.add(t);
else if (comp < 0) {
ret.clear();
ret.add(t);
}
}
}
return ret;
}
public static <T extends Comparable<T>> T getLargest(Collection<T> _collObjects)
{
return getLargest(_collObjects, new Comparator<T>()
{
@Override
public int compare(T o1, T o2)
{
return NullUtils.compare(o1, o2);
}
});
}
public static <T> T getLargest(Collection<T> _objects, Comparator<T> _comparator)
{
if (_objects == null)
return null;
T ret = null;
for (T t : _objects)
{
if (t == null)
continue;
if ((ret == null) || (_comparator.compare(t, ret) > 0))
ret = t;
}
return ret;
}
public static <T> List<T> getSmallest(Collection<T> _objects, Comparator<T> _comparator, int _count)
{
return getSmallest(_objects, _comparator, _count, null);
}
public static <T> List<T> getSmallest(Collection<T> _objects, Comparator<T> _comparator, int _count, IFilter<T> _filter)
{
if (_objects == null)
return null;
if (_count * 4 > _objects.size())
{
List<T> items = new ArrayList<T>();
for (T t : _objects)
{
if ((_filter == null) || !_filter.isFiltered(t))
items.add(t);
}
Collections.sort(items, _comparator);
return subList(items, 0, _count);
}
TreeMap<T, List<T>> mapReturn = new TreeMap<>(_comparator);
for (T t : _objects)
{
if ((t == null) || ((_filter != null) && _filter.isFiltered(t)))
continue;
if (mapReturn.size() < _count)
addToMultiMap(t, t, mapReturn);
else
{
Iterator<T> iter = mapReturn.descendingKeySet().iterator();
if (_comparator.compare(t, iter.next()) < 0)
{
iter.remove();
addToMultiMap(t, t, mapReturn);
}
}
}
List<T> items = new ArrayList<T>(_count);
for (List<T> list : mapReturn.values())
{
items.addAll(list);
}
return subList(items, 0, _count);
}
public static <T> List<T> subList(List<T> _list, int _fromIndex, int _toIndex) {
if ((_list == null) || (_fromIndex > _list.size() - 1))
return new ArrayList<T>();
return _list.subList(_fromIndex, Math.min(_toIndex, _list.size()));
}
public static <T extends Comparable<T>> T mostCommon(Collection<T> _collObjects) {
return mostCommon(_collObjects, new Comparator<T>() {
@Override
public int compare(T _o1, T _o2) {
return NullUtils.compare(_o1, _o2);
}
});
}
public static <T> T mostCommon(Collection<T> _collObjects, Comparator<? super T> _comparator) {
int iMax = 0;
Map<T, AtomicInteger> mapCounts = new TreeMap<T, AtomicInteger>(_comparator);
for (T t : makeNotNull(_collObjects)) {
AtomicInteger i = mapCounts.get(t);
if (i == null) {
mapCounts.put(t, new AtomicInteger(1));
if (iMax == 0)
iMax = 1;
} else {
if (i.incrementAndGet() > iMax)
iMax = i.intValue();
}
}
for (Entry<T, AtomicInteger> e : mapCounts.entrySet()) {
if (e.getValue().intValue() == iMax)
return e.getKey();
}
return null;
}
public static <T,V> List<V> getAll(Map<T, V> _map, Collection<T> _keys) {
List<V> ret = new ArrayList<>();
if (_map == null)
return ret;
for (T t : makeNotNull(_keys)) {
V v = _map.get(t);
if (v != null)
ret.add(v);
}
return ret;
}
public static byte[] toByteArray(Collection<Integer> _integers) {
if (isEmpty(_integers))
return null;
ByteBuffer bb = ByteBuffer.allocate(_integers.size() * 4);
for (Integer i : _integers) {
bb.putInt(i);
}
return bb.array();
}
public static List<Integer> fromByteArrayOfIntegers(byte[] _btIntegers) {
if (length(_btIntegers) > 0) {
List<Integer> auxIds = new ArrayList<>(_btIntegers.length / 4);
ByteBuffer bb = ByteBuffer.wrap(_btIntegers);
while (bb.hasRemaining()) {
auxIds.add(bb.getInt());
}
return auxIds;
}
return new ArrayList<>();
}
public static int length(byte[] _arr)
{
if (_arr == null)
return 0;
return _arr.length;
}
}

View File

@@ -0,0 +1,658 @@
package com.lanternsoftware.util;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public abstract class DateUtils {
public static long toLong(Date _dt) {
if (_dt == null)
return Long.MIN_VALUE;
return _dt.getTime();
}
public static Date toDate(long _epochOffset) {
if (_epochOffset == Long.MIN_VALUE)
return null;
return new Date(_epochOffset);
}
public static Date millisecondsFromNow(long _milliseconds) {
return new Date(new Date().getTime() + _milliseconds);
}
public static Date secondsFromNow(long _seconds) {
return addSeconds(new Date(), _seconds);
}
public static Date minutesFromNow(int _minutes) {
return addMinutes(new Date(), _minutes);
}
public static Date hoursFromNow(int _hours) {
return addHours(new Date(), _hours);
}
public static Date daysFromNow(int _days) {
return addDays(new Date(), _days);
}
public static Date addSeconds(Date _dt, long _seconds) {
if (_dt == null)
return null;
return new Date(_dt.getTime() + _seconds * 1000L);
}
public static Date addMinutes(Date _dt, int _minutes) {
if (_dt == null)
return null;
return new Date(_dt.getTime() + _minutes * 60000L);
}
public static Date addHours(Date _dt, int _hours) {
if (_dt == null)
return null;
return new Date(_dt.getTime() + _hours * 3600000L);
}
public static Date addDays(Date _dt, int _days) {
if (_dt == null)
return null;
return new Date(_dt.getTime() + _days * 86400000L);
}
public static Date addDays(Date _dt, int _days, TimeZone _tz) {
if (_dt == null)
return null;
Calendar cal = toCalendar(_dt, _tz);
cal.add(Calendar.DAY_OF_YEAR, _days);
return cal.getTime();
}
public static Date addMonths(Date _dt, int _months) {
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(_dt);
cal.add(Calendar.MONTH, _months);
return cal.getTime();
}
public static Date addMonths(Date _dt, int _months, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
if (cal == null)
return null;
cal.add(Calendar.MONTH, _months);
return cal.getTime();
}
public static Date addMonthKeepDayOfWeek(Date _dt, int _months, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
if (cal == null)
return null;
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
int dayOfWeekInMonth = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
cal.add(Calendar.MONTH, _months);
cal.set(Calendar.DAY_OF_WEEK, dayOfWeek);
cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, dayOfWeekInMonth);
return cal.getTime();
}
public static Date addYears(Date _dt, int _years) {
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(_dt);
cal.add(Calendar.YEAR, _years);
return cal.getTime();
}
public static Date addYears(Date _dt, int _years, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
if (cal == null)
return null;
cal.add(Calendar.YEAR, _years);
return cal.getTime();
}
public static long diffInMilliseconds(Date _dt1, Date _dt2) {
return diffInMilliseconds(_dt1, _dt2, Long.MAX_VALUE);
}
public static long diffInMilliseconds(Date _dt1, Date _dt2, long _defaultIfNull) {
if ((_dt1 == null) || (_dt2 == null))
return _defaultIfNull;
return Math.abs(_dt1.getTime() - _dt2.getTime());
}
public static long diffInSeconds(Date _dt1, Date _dt2) {
return diffInSeconds(_dt1, _dt2, Long.MAX_VALUE);
}
public static long diffInSeconds(Date _dt1, Date _dt2, long _defaultIfNull) {
if ((_dt1 == null) || (_dt2 == null))
return _defaultIfNull;
return Math.abs(_dt1.getTime() - _dt2.getTime()) / 1000;
}
public static long diffInMinutes(Date _dt1, Date _dt2) {
return diffInMinutes(_dt1, _dt2, Long.MAX_VALUE);
}
public static long diffInMinutes(Date _dt1, Date _dt2, long _defaultIfNull) {
if ((_dt1 == null) || (_dt2 == null))
return _defaultIfNull;
return Math.abs(_dt1.getTime() - _dt2.getTime()) / 60000;
}
public static long diffInHours(Date _dt1, Date _dt2) {
return diffInHours(_dt1, _dt2, Long.MAX_VALUE);
}
public static long diffInHours(Date _dt1, Date _dt2, long _defaultIfNull) {
if ((_dt1 == null) || (_dt2 == null))
return _defaultIfNull;
return Math.abs(_dt1.getTime() - _dt2.getTime()) / 3600000;
}
public static boolean isAfter(Date _dt1, Date _dt2) {
return isAfter(_dt1, _dt2, false);
}
public static boolean isAfter(Date _dt1, Date _dt2, boolean _defaultIfNull) {
if ((_dt1 == null) || (_dt2 == null))
return _defaultIfNull;
return _dt1.after(_dt2);
}
public static boolean isAfterOrEqualTo(Date _dt1, Date _dt2) {
return isAfterOrEqualTo(_dt1, _dt2, false);
}
public static boolean isAfterOrEqualTo(Date _dt1, Date _dt2, boolean _defaultIfNull) {
if ((_dt1 == null) || (_dt2 == null))
return _defaultIfNull;
return _dt1.getTime() >= _dt2.getTime();
}
public static boolean isBefore(Date _dt1, Date _dt2) {
return isBefore(_dt1, _dt2, false);
}
public static boolean isBefore(Date _dt1, Date _dt2, boolean _defaultIfNull) {
if ((_dt1 == null) || (_dt2 == null))
return _defaultIfNull;
return _dt1.before(_dt2);
}
public static boolean isBeforeOrEqualTo(Date _dt1, Date _dt2) {
return isBeforeOrEqualTo(_dt1, _dt2, false);
}
public static boolean isBeforeOrEqualTo(Date _dt1, Date _dt2, boolean _defaultIfNull) {
if ((_dt1 == null) || (_dt2 == null))
return _defaultIfNull;
return _dt1.getTime() <= _dt2.getTime();
}
public static String getAge(Date _dtDOB) {
if (_dtDOB == null)
return "";
return getAge(_dtDOB, getMidnightBeforeNow());
}
public static String getAge(Date _dtDOB, Date _dtReference) {
if (_dtDOB == null)
return "";
return getAge(_dtDOB.getTime(), _dtReference.getTime());
}
public static String getAge(long _dob, long _reference) {
long lAge = _reference - _dob;
if (lAge < 24 * 3600000) // less than a day old
return String.format("%.2d:%.2d hours", lAge / 3600000, (lAge % 3600000) / 60000);
if (lAge < 7 * 24 * 3600000) // less than a week old
return String.format("%d days", lAge / (24 * 3600000));
Date dtStart = new Date(_dob);
Date dtEnd = new Date(_reference);
int iMonths = getMonthsBetween(dtStart, dtEnd);
if (iMonths == 0)
return String.format("%d days", (dtEnd.getTime() - dtStart.getTime()) / (7 * 24 * 3600000));
int iYears = getYearsBetween(dtStart, dtEnd);
if (iYears < 2)
return String.format("%d months", iMonths);
return String.format("%d years", iYears);
}
public static int getMonthsBetween(Date _dtStart, Date _dtEnd) {
Calendar calStart = getGMTCalendar(_dtStart.getTime());
Calendar calEnd = getGMTCalendar(_dtEnd.getTime());
int diff = calEnd.get(Calendar.YEAR) * 24 + calEnd.get(Calendar.MONTH) - calStart.get(Calendar.YEAR) * 24 + calStart.get(Calendar.MONTH);
if (calStart.get(Calendar.DAY_OF_MONTH) > calEnd.get(Calendar.DAY_OF_MONTH))
diff--;
return diff;
}
public static int getYearsBetween(Date _dtStart, Date _dtEnd) {
Calendar calStart = getGMTCalendar(_dtStart.getTime());
Calendar calEnd = getGMTCalendar(_dtEnd.getTime());
int diff = calEnd.get(Calendar.YEAR) - calStart.get(Calendar.YEAR);
if (isLaterInYear(calStart, calEnd))
diff--;
return diff;
}
public static int getAgeInYears(Date _dtDOB) {
if (_dtDOB == null)
return 0;
return getAgeInYears(_dtDOB.getTime());
}
public static int getAgeInYears(Date _dtDOB, Date _dtReference) {
if (_dtDOB == null)
return 0;
return getAgeInYears(_dtDOB.getTime(), _dtReference);
}
public static int getAgeInYears(long _lDOB) {
return getAgeInYears(_lDOB, getMidnightBeforeNow());
}
public static int getAgeInYears(long _lDOB, Date _dtReference) {
if (_lDOB == 0 || _dtReference == null)
return 0;
Calendar calDOB = getGMTCalendar(_lDOB);
Calendar calToday = getGMTCalendar(_dtReference.getTime());
int age = calToday.get(Calendar.YEAR) - calDOB.get(Calendar.YEAR);
if (!isLaterInYear(calToday, calDOB))
age--;
return age;
}
public static Calendar getGMTCalendar(long _lTime) {
return toCalendar(_lTime, TimeZone.getTimeZone("GMT"));
}
private static boolean isLaterInYear(Calendar _cal1, Calendar _cal2) {
if (_cal1.get(Calendar.MONTH) > _cal2.get(Calendar.MONTH))
return true;
return (_cal1.get(Calendar.MONTH) == _cal2.get(Calendar.MONTH)) && (_cal1.get(Calendar.DAY_OF_MONTH) >= _cal2.get(Calendar.DAY_OF_MONTH));
}
public static boolean isSameDay(Date _d1, Date _d2, TimeZone _tz) {
return getMidnightBefore(_d1, _tz).equals(getMidnightBefore(_d2, _tz));
}
public static boolean isSameDayOfWeek(Date _d1, Date _d2, TimeZone _tz) {
return getDayOfWeek(_d1, _tz) == getDayOfWeek(_d2, _tz);
}
public static boolean isSameTimeOfDay(Date _d1, Date _d2, TimeZone _tz) {
Calendar cal1 = toCalendar(_d1, _tz);
Calendar cal2 = toCalendar(_d2, _tz);
if ((cal1 == null) || (cal2 == null))
return false;
if (cal1.get(Calendar.HOUR_OF_DAY) != cal2.get(Calendar.HOUR_OF_DAY))
return false;
if (cal1.get(Calendar.MINUTE) != cal2.get(Calendar.MINUTE))
return false;
if (cal1.get(Calendar.SECOND) != cal2.get(Calendar.SECOND))
return false;
return (cal1.get(Calendar.MILLISECOND) == cal2.get(Calendar.MILLISECOND));
}
public static Date getMidnightBeforeNow() {
return getMidnightBeforeNow(TimeZone.getTimeZone("GMT"));
}
public static Date getMidnightBeforeNow(TimeZone _tz) {
return hoursAfterMidnight(new Date(), 0, _tz);
}
public static Calendar getMidnightBeforeNowCal(TimeZone _tz) {
return hoursAfterMidnightCal(new Date(), 0, _tz);
}
public static Date getMidnightBefore(Date _dt, TimeZone _tz) {
return hoursAfterMidnight(_dt, 0, _tz);
}
public static Calendar getMidnightBeforeCal(Date _dt, TimeZone _tz) {
return hoursAfterMidnightCal(_dt, 0, _tz);
}
public static Date getMidnightAfterNow() {
return getMidnightAfterNow(TimeZone.getTimeZone("GMT"));
}
public static Date getMidnightAfterNow(TimeZone _tz) {
return hoursAfterMidnight(new Date(), 24, _tz);
}
public static Calendar getMidnightAfterNowCal(TimeZone _tz) {
return hoursAfterMidnightCal(new Date(), 24, _tz);
}
public static Date getMidnightAfter(Date _dt, TimeZone _tz) {
return hoursAfterMidnight(_dt, 24, _tz);
}
public static Calendar getMidnightAfterCal(Date _dt, TimeZone _tz) {
return hoursAfterMidnightCal(_dt, 24, _tz);
}
public static Date hoursAfterMidnight(Date _dt, int _hours, TimeZone _tz) {
return hoursAfterMidnightCal(_dt, _hours, _tz).getTime();
}
public static Calendar hoursAfterMidnightCal(Date _dt, int _hours, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
if (cal == null)
return null;
cal.set(Calendar.HOUR_OF_DAY, _hours);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal;
}
public static boolean isBetween(Date _dt, Date _dtFrom, Date _dtTo) {
if (_dt == null)
return false;
if ((_dtFrom != null) && _dtFrom.after(_dt))
return false;
return (_dtTo == null) || _dtTo.after(_dt);
}
public static Date setTimeOfDay(Date _date, Date _time, TimeZone _tz) {
Calendar date = toCalendar(_date, _tz);
Calendar time = toCalendar(_time, _tz);
if ((date == null) || (time == null))
return null;
date.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY));
date.set(Calendar.MINUTE, time.get(Calendar.MINUTE));
date.set(Calendar.SECOND, time.get(Calendar.SECOND));
date.set(Calendar.MILLISECOND, time.get(Calendar.MILLISECOND));
return date.getTime();
}
public static Calendar toCalendar(long _ts, TimeZone _tz) {
return toCalendar(new Date(_ts), _tz);
}
public static Calendar toCalendar(Date _date, TimeZone _tz) {
if (_date == null)
return null;
Calendar cal = new GregorianCalendar(_tz);
cal.setTime(_date);
return cal;
}
public static DateFormat dateFormat(String _format, TimeZone _tz) {
SimpleDateFormat format = new SimpleDateFormat(_format);
format.setTimeZone(_tz);
return format;
}
public static String format(String _format, Date _dt) {
return format(_format, TimeZone.getTimeZone("UTC"), _dt);
}
public static String format(String _format, TimeZone _tz, Date _dt) {
if (_dt == null)
return null;
return dateFormat(_format, _tz).format(_dt);
}
public static Date parse(String _format, String _date) {
return parse(_format, TimeZone.getTimeZone("UTC"), _date);
}
public static Date parse(String _format, TimeZone _tz, String _date) {
if (NullUtils.isEmpty(_date))
return null;
try {
return dateFormat(_format, _tz).parse(_date);
}
catch (Exception _e) {
return null;
}
}
public static Date date(int _month, int _day, int _year, TimeZone _tz) {
return date(_month, _day, _year, 0, 0, 0, 0, _tz);
}
public static Date date(int _month, int _day, int _year, int _hour, int _minutes, int _seconds, int _ms, TimeZone _tz) {
Calendar cal = GregorianCalendar.getInstance(_tz);
cal.set(Calendar.YEAR, _year);
cal.set(Calendar.MONTH, _month - 1);
cal.set(Calendar.DAY_OF_MONTH, _day);
cal.set(Calendar.HOUR_OF_DAY, _hour);
cal.set(Calendar.MINUTE, _minutes);
cal.set(Calendar.SECOND, _seconds);
cal.set(Calendar.MILLISECOND, _ms);
return cal.getTime();
}
public static int getDayOfWeek(Date _dt, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
return cal == null ? 0 : cal.get(Calendar.DAY_OF_WEEK);
}
public static Date setDayOfWeek(Date _dt, TimeZone _tz, int _dayOfWeek) {
Calendar cal = toCalendar(_dt, _tz);
if (cal == null)
return null;
if ((_dayOfWeek >= Calendar.SUNDAY) && (_dayOfWeek <= Calendar.SATURDAY))
cal.set(Calendar.DAY_OF_WEEK, _dayOfWeek);
return cal.getTime();
}
public static Date getMidnightBeforeDayOfWeek(Date _dt, TimeZone _tz, int _dayOfWeek) {
return getMidnightBefore(setDayOfWeek(_dt, _tz, _dayOfWeek), _tz);
}
public static Date getMidnightAfterDayOfWeek(Date _dt, TimeZone _tz, int _dayOfWeek) {
return getMidnightAfter(setDayOfWeek(_dt, _tz, _dayOfWeek), _tz);
}
public static boolean isDstTransitionDay(Date _dt, TimeZone _tz) {
Date midnight = getMidnightBefore(_dt, _tz);
Calendar cal = toCalendar(midnight, _tz);
if (cal == null)
return false;
cal.set(Calendar.HOUR_OF_DAY, 8);
return (cal.getTimeInMillis() - midnight.getTime() != 28800000);
}
public static Date setDayOfWeek(Date _dt, TimeZone _tz, String _dayOfWeek) {
Calendar cal = toCalendar(_dt, _tz);
if (cal == null)
return null;
int dayOfWeekInt = 0;
switch (_dayOfWeek) {
case "Sunday":
dayOfWeekInt = Calendar.SUNDAY;
break;
case "Monday":
dayOfWeekInt = Calendar.MONDAY;
break;
case "Tuesday":
dayOfWeekInt = Calendar.TUESDAY;
break;
case "Wednesday":
dayOfWeekInt = Calendar.WEDNESDAY;
break;
case "Thursday":
dayOfWeekInt = Calendar.THURSDAY;
break;
case "Friday":
dayOfWeekInt = Calendar.FRIDAY;
break;
case "Saturday":
dayOfWeekInt = Calendar.SATURDAY;
break;
}
if (dayOfWeekInt > 0)
cal.set(Calendar.DAY_OF_WEEK, dayOfWeekInt);
return cal.getTime();
}
public static Date getStartOfMinute(TimeZone _tz) {
return getStartOfMinute(new Date(), _tz);
}
public static Date getStartOfMinute(Date _dt, TimeZone _tz) {
return getStartOfMinuteCal(_dt, _tz).getTime();
}
public static Calendar getStartOfMinuteCal(Date _dt, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal;
}
public static Date getEndOfMinute(TimeZone _tz) {
return getEndOfMinute(new Date(), _tz);
}
public static Date getEndOfMinute(Date _dt, TimeZone _tz) {
return getEndOfMinuteCal(_dt, _tz).getTime();
}
public static Calendar getEndOfMinuteCal(Date _dt, TimeZone _tz) {
Calendar cal = getStartOfMinuteCal(_dt, _tz);
cal.add(Calendar.MINUTE, 1);
return cal;
}
public static Date getStartOfHour(TimeZone _tz) {
return getStartOfHour(new Date(), _tz);
}
public static Date getStartOfHour(Date _dt, TimeZone _tz) {
return getStartOfHourCal(_dt, _tz).getTime();
}
public static Calendar getStartOfHourCal(Date _dt, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal;
}
public static Date getEndOfHour(TimeZone _tz) {
return getEndOfHour(new Date(), _tz);
}
public static Date getEndOfHour(Date _dt, TimeZone _tz) {
return getEndOfHourCal(_dt, _tz).getTime();
}
public static Calendar getEndOfHourCal(Date _dt, TimeZone _tz) {
Calendar cal = getStartOfHourCal(_dt, _tz);
cal.add(Calendar.HOUR_OF_DAY, 1);
return cal;
}
public static Date getStartOfWeek(TimeZone _tz) {
return getStartOfWeek(new Date(), _tz);
}
public static Date getStartOfWeek(Date _dt, TimeZone _tz) {
return getStartOfWeekCal(_dt, _tz).getTime();
}
public static Calendar getStartOfWeekCal(Date _dt, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
return cal;
}
public static Date getEndOfWeek(TimeZone _tz) {
return getEndOfWeek(new Date(), _tz);
}
public static Date getEndOfWeek(Date _dt, TimeZone _tz) {
return getEndOfWeekCal(_dt, _tz).getTime();
}
public static Calendar getEndOfWeekCal(Date _dt, TimeZone _tz) {
Calendar cal = getStartOfWeekCal(_dt, _tz);
cal.add(Calendar.DAY_OF_YEAR, 7);
return cal;
}
public static Date getStartOfMonth(TimeZone _tz) {
return getStartOfMonth(new Date(), _tz);
}
public static Date getStartOfMonth(Date _dt, TimeZone _tz) {
return getStartOfMonthCal(_dt, _tz).getTime();
}
public static Calendar getStartOfMonthCal(Date _dt, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.DAY_OF_MONTH, 1);
return cal;
}
public static Date getEndOfMonth(TimeZone _tz) {
return getEndOfMonth(new Date(), _tz);
}
public static Date getEndOfMonth(Date _dt, TimeZone _tz) {
return getEndOfMonthCal(_dt, _tz).getTime();
}
public static Calendar getEndOfMonthCal(Date _dt, TimeZone _tz) {
Calendar cal = getStartOfMonthCal(_dt, _tz);
cal.add(Calendar.MONTH, 1);
return cal;
}
public static Date getStartOfYear(TimeZone _tz) {
return getStartOfYear(new Date(), _tz);
}
public static Date getStartOfYear(Date _dt, TimeZone _tz) {
return getStartOfYearCal(_dt, _tz).getTime();
}
public static Calendar getStartOfYearCal(Date _dt, TimeZone _tz) {
Calendar cal = toCalendar(_dt, _tz);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.DAY_OF_YEAR, 1);
return cal;
}
public static Date getEndOfYear(TimeZone _tz) {
return getEndOfYear(new Date(), _tz);
}
public static Date getEndOfYear(Date _dt, TimeZone _tz) {
return getEndOfYearCal(_dt, _tz).getTime();
}
public static Calendar getEndOfYearCal(Date _dt, TimeZone _tz) {
Calendar cal = getStartOfYearCal(_dt, _tz);
cal.add(Calendar.YEAR, 1);
return cal;
}
}

View File

@@ -0,0 +1,147 @@
package com.lanternsoftware.util;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import com.lanternsoftware.util.tracing.TraceLog;
import com.lanternsoftware.util.tracing.TraceTags;
import com.lanternsoftware.util.tracing.TracerConfig;
import com.lanternsoftware.util.tracing.ITracer;
import com.lanternsoftware.util.tracing.TraceContext;
import com.lanternsoftware.util.tracing.TraceDuration;
import org.slf4j.Logger;
public class DebugTimer {
private final Logger LOG;
private final String name;
private final TraceContext context;
private Date start;
private TraceDuration duration;
private TraceTags tags;
private List<TraceLog> logs;
private final boolean suppressLocalLogs;
private static ITracer tracer = null;
private static TracerConfig config;
private static final ThreadLocal<TraceContext> traceContexts = new ThreadLocal<>();
public DebugTimer(String _name) {
this(null, _name, null, false);
}
public DebugTimer(TraceContext _parent, String _name) {
this(_parent, _name, null, false);
}
public DebugTimer(String _name, Logger _log) {
this(null, _name, _log, false);
}
public DebugTimer(String _context, String _name) {
this(TraceContext.deserialize(_context), _name, null, false);
}
public DebugTimer(String _context, String _name, Logger _log) {
this(TraceContext.deserialize(_context), _name, _log, false);
}
public DebugTimer(TraceContext _parent, String _name, Logger _log) {
this(_parent, _name, _log, false);
}
public DebugTimer(TraceContext _parent, String _name, Logger _log, boolean _suppressLocalLogs) {
TraceContext parent = _parent;
name = _name;
LOG = _log;
suppressLocalLogs = _suppressLocalLogs;
start = new Date();
if ((parent == null) && (config != null) && config.isUseThreadContext()) {
parent = traceContexts.get();
traceContexts.set(getContext());
}
context = parent;
}
public static void setTracerConfig(TracerConfig _config) {
config = _config;
if (tracer == null) {
Iterator<ITracer> iter = ServiceLoader.load(ITracer.class).iterator();
if (iter.hasNext()) {
tracer = iter.next();
}
}
tracer.config(config);
}
private ITracer getTracer() {
if (config == null)
return null;
return tracer;
}
public void tag(String _name, String _value) {
if (tags == null)
tags = TraceTags.tag(_name, _value);
else
tags.put(_name, _value);
}
public void log(String _event) {
if (logs == null)
logs = new ArrayList<>();
logs.add(new TraceLog(traceDuration().currentTimeOffset(), _event));
}
private TraceDuration traceDuration() {
if (duration != null)
return duration;
ITracer t = getTracer();
duration = (t == null)?new TraceDuration(start):t.createDuration(context, name, start);
return duration;
}
public void start() {
if (duration == null)
start = new Date();
traceDuration().start();
}
public TraceContext stop() {
traceDuration().stop();
return print();
}
public void stopDoNotPrint() {
traceDuration().stop();
}
public long duration() {
return traceDuration().duration();
}
public TraceContext getContext() {
return traceDuration().getContext();
}
public TraceContext print() {
StringBuilder b = new StringBuilder(name);
b.append(": ");
b.append(traceDuration().duration());
b.append("ms");
TraceContext newContext = traceDuration().getContext();
ITracer t = getTracer();
if (t != null)
t.trace(name, duration, tags, logs);
if (!suppressLocalLogs && ((config == null) || !config.isSuppressLocalLog())) {
if (LOG != null)
LOG.debug(b.toString());
else
System.out.println(b.toString());
}
traceContexts.set(context);
return newContext;
}
}

View File

@@ -0,0 +1,7 @@
package com.lanternsoftware.util;
import java.util.List;
public interface IAggregator<T, V> {
List<V> aggregate(T _t);
}

View File

@@ -0,0 +1,5 @@
package com.lanternsoftware.util;
public interface IEditor<T> {
void edit(T _t);
}

View File

@@ -0,0 +1,5 @@
package com.lanternsoftware.util;
public interface IEquals<T> {
boolean equals(T _t1, T _t2);
}

View File

@@ -0,0 +1,5 @@
package com.lanternsoftware.util;
public interface IFilter<T> {
boolean isFiltered(T _t);
}

View File

@@ -0,0 +1,5 @@
package com.lanternsoftware.util;
public interface IQualifier<T> {
boolean qualifies(T _t);
}

View File

@@ -0,0 +1,5 @@
package com.lanternsoftware.util;
public interface ISupplier<T> {
T get();
}

View File

@@ -0,0 +1,5 @@
package com.lanternsoftware.util;
public interface ITransformer<T, V> {
V transform(T _t);
}

View File

@@ -0,0 +1,6 @@
package com.lanternsoftware.util;
public abstract class LanternFiles {
public static final String SOURCE_PATH = "C:\\lantern\\wc\\opensource\\LanternPowerMonitor\\";
public static final String OPS_PATH = "D:\\zwave\\";
}

View File

@@ -0,0 +1,23 @@
package com.lanternsoftware.util;
public class MapUtils {
private static final double RADIUS_EARTH = 6371000;
/**
* @return Distance between the two points in meters
*/
public static double distance(double _latitude1, double _longitude1, double _latitude2, double _longitude2)
{
double latitude = Math.toRadians(_latitude2 - _latitude1);
double longitude = Math.toRadians(_longitude2 - _longitude1);
double a = Math.sin(latitude / 2) * Math.sin(latitude / 2) + Math.cos(Math.toRadians(_latitude1)) * Math.cos(Math.toRadians(_latitude2)) * Math.sin(longitude / 2) * Math.sin(longitude / 2);
return RADIUS_EARTH * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}
/**
* @return Time in ms to travel from one point to another as the crow flies at the given speed
*/
public static long travelTime(double _latitude1, double _longitude1, double _latitude2, double _longitude2, double _speedMetersPerSecond) {
return (long)(1000*distance(_latitude1, _longitude1, _latitude2, _longitude2)/_speedMetersPerSecond);
}
}

View File

@@ -0,0 +1,84 @@
package com.lanternsoftware.util;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class MemoryStats {
public static long size(Object _o) {
return size(_o, new HashSet<Integer>());
}
private static long size(Object _o, Set<Integer> _counted) {
int hash = System.identityHashCode(_o);
if (_counted.contains(hash))
return 0;
_counted.add(hash);
long size = 0;
for (Field f : allFields(_o.getClass())) {
if (Modifier.isStatic(f.getModifiers()) || Modifier.isTransient(f.getModifiers()))
continue;
f.setAccessible(true);
try {
Object child = f.get(_o);
if (child != null) {
if (f.getType().equals(String.class))
size += ((String)child).length();
else if (f.getType().equals(Date.class))
size += 8;
else if (f.getType().equals(Double.class) || f.getType().equals(Double.TYPE))
size += 8;
else if (f.getType().equals(Float.class) || f.getType().equals(Float.TYPE))
size += 4;
else if (f.getType().equals(Long.class) || f.getType().equals(Long.TYPE))
size += 8;
else if (f.getType().equals(Integer.class) || f.getType().equals(Integer.TYPE))
size += 4;
else if (f.getType().equals(Short.class) || f.getType().equals(Short.TYPE))
size += 2;
else if (f.getType().equals(Byte.class) || f.getType().equals(Byte.TYPE))
size += 1;
else if (f.getType().equals(Character.class) || f.getType().equals(Character.TYPE))
size += 1;
else if (f.getType().equals(Boolean.class) || f.getType().equals(Boolean.TYPE))
size += 1;
else if (f.getType().equals(byte[].class))
size += ((byte[])child).length;
else if (f.getType().equals(char[].class))
size += ((char[])child).length;
else if (Collection.class.isAssignableFrom(f.getType())) {
for (Object childElement : ((Collection)child)) {
size += size(childElement, _counted);
}
}
else if (Map.class.isAssignableFrom(f.getType())) {
Set<Entry<?, ?>> entries = ((Map)child).entrySet();
for (Entry<?, ?> childElement : entries) {
size += size(childElement.getKey(), _counted);
size += size(childElement.getValue(), _counted);
}
}
else
size += size(child, _counted);
}
} catch (IllegalAccessException _e) {
}
}
return size;
}
private static List<Field> allFields(Class _c) {
if (_c == null)
return Collections.emptyList();
List<Field> fields = CollectionUtils.asArrayList(_c.getDeclaredFields());
fields.addAll(allFields(_c.getSuperclass()));
return fields;
}
}

View File

@@ -0,0 +1,397 @@
package com.lanternsoftware.util;
import org.apache.commons.codec.binary.Hex;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class NullUtils {
public static boolean isNotEqual(Object a, Object b) {
return !isEqual(a, b);
}
public static boolean isEqual(Object a, Object b) {
if (a != null)
return (b != null) && a.equals(b);
return (b == null);
}
public static <T> boolean isNotEqual(T a, T b, IEquals<T> _equals) {
return !isEqual(a, b, _equals);
}
public static <T> boolean isEqual(T a, T b, IEquals<T> _equals) {
if (a != null)
return (b != null) && _equals.equals(a, b);
return (b == null);
}
public static boolean equalsIgnoreCase(String a, String b) {
if (a != null)
return a.equalsIgnoreCase(b);
return (b == null);
}
public static int length(String _val) {
if (_val == null)
return 0;
return _val.length();
}
public static boolean isEmpty(String _sVal) {
return (_sVal == null) || (_sVal.length() == 0);
}
public static boolean isAnyEmpty(String... _vals) {
if (_vals == null)
return true;
for (String val : _vals) {
if (isEmpty(val))
return true;
}
return false;
}
public static boolean isNotEmpty(String _sVal) {
return !isEmpty(_sVal);
}
public static boolean isAnyNotEmpty(String... _vals) {
if (_vals == null)
return false;
for (String val : _vals) {
if (isNotEmpty(val))
return true;
}
return false;
}
public static boolean isAnyNull(Object... _o) {
if ((_o == null) || (_o.length == 0))
return false;
for (Object o : _o) {
if (o == null)
return true;
}
return false;
}
public static boolean isOneOf(Object _o, Object... _values) {
if ((_o == null) || (_values == null) || (_values.length == 0))
return false;
for (Object o : _values) {
if (_o.equals(o))
return true;
}
return false;
}
public static String trim(String _val) {
if (_val == null)
return null;
return _val.trim();
}
public static String toString(byte[] _arrBytes) {
if (_arrBytes == null)
return null;
try {
return new String(_arrBytes, "UTF-8");
}
catch (UnsupportedEncodingException e) {
return null;
}
}
public static byte[] toByteArray(String _value) {
if (_value == null)
return null;
try {
return _value.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e) {
return null;
}
}
public static int toInteger(String _value) {
try {
return Integer.valueOf(makeNotNull(_value));
}
catch (NumberFormatException _e) {
return 0;
}
}
public static long toLong(String _value) {
try {
return Long.valueOf(makeNotNull(_value));
}
catch (NumberFormatException _e) {
return 0;
}
}
public static double toDouble(String _value) {
try {
return Double.valueOf(makeNotNull(_value));
}
catch (NumberFormatException _e) {
return 0.0;
}
}
public static float toFloat(String _value) {
try {
return Float.valueOf(makeNotNull(_value));
}
catch (NumberFormatException _e) {
return 0f;
}
}
public static String urlEncode(String _url) {
try {
return URLEncoder.encode(makeNotNull(_url), "UTF-8");
}
catch (UnsupportedEncodingException e) {
return _url;
}
}
public static String urlDecode(String _url) {
try {
return URLDecoder.decode(makeNotNull(_url), "UTF-8");
}
catch (UnsupportedEncodingException e) {
return _url;
}
}
public static String makeNotNull(String _value) {
if (_value != null)
return _value;
return "";
}
public static String after(String _value, String _search) {
if (_value == null)
return "";
int iPos = _value.lastIndexOf(_search);
if (iPos < 0)
return "";
return iPos < _value.length() - _search.length() ? _value.substring(iPos + _search.length()) : "";
}
public static <T extends Enum<T>> T toEnum(Class<T> _enumType, String _sValue) {
return toEnum(_enumType, _sValue, null);
}
public static <T extends Enum<T>> T toEnum(Class<T> _enumType, String _sValue, T _default) {
T e = null;
try {
e = Enum.valueOf(_enumType, _sValue);
}
catch (Throwable t) {
return _default;
}
return e;
}
public static <T extends Enum<T>> List<T> toEnums(Class<T> _enumType, Collection<String> _values) {
List<T> listEnums = new ArrayList<T>();
for (String value : CollectionUtils.makeNotNull(_values)) {
T e = toEnum(_enumType, value, null);
if (e != null)
listEnums.add(e);
}
return listEnums;
}
public static <T extends Comparable<T>> int compare(T a, T b) {
return compare(a, b, true);
}
public static <T extends Comparable<T>> int compare(T a, T b, boolean _bNullsFirst) {
if (a != null) {
if (b != null)
return a.compareTo(b);
else
return _bNullsFirst ? 1 : -1;
}
if (b != null)
return _bNullsFirst ? -1 : 1;
return 0;
}
public static int min(int... values) {
int iMin = Integer.MAX_VALUE;
for (int value : values) {
if (value < iMin)
iMin = value;
}
return iMin;
}
public static String[] cleanSplit(String _sValue, String _sRegex) {
if (_sValue == null)
return new String[0];
return removeEmpties(_sValue.split(_sRegex));
}
public static String[] removeEmpties(String[] _arr) {
if (_arr == null)
return new String[0];
int valid = 0;
for (String s : _arr) {
if (NullUtils.isNotEmpty(s))
valid++;
}
if (valid == _arr.length)
return _arr;
String[] ret = new String[valid];
valid = 0;
for (String s : _arr) {
if (NullUtils.isNotEmpty(s))
ret[valid++] = s;
}
return ret;
}
public static String wrap(String _input, int _lineLength) {
return wrap(_input, _lineLength, false);
}
public static String wrap(String _input, int _lineLength, boolean carriageReturn) {
if (_input == null)
return null;
StringBuilder output = new StringBuilder();
int i = 0;
while (i < _input.length()) {
if ((i + _lineLength) > _input.length())
output.append(_input.substring(i, _input.length()));
else {
output.append(_input.substring(i, i + _lineLength));
if (carriageReturn)
output.append("\r");
output.append("\n");
}
i += _lineLength;
}
return output.toString();
}
public static <T> Class<? extends T> getClass(String _className, Class<T> _superClass) {
try {
return Class.forName(_className).asSubclass(_superClass);
}
catch (ClassNotFoundException _e) {
return null;
}
}
public static String terminateWith(String _value, String _suffix) {
if (_value == null)
return _suffix;
if (_value.endsWith(_suffix))
return _value;
return _value + _suffix;
}
public static String toUpperCase(String _value) {
if (_value == null)
return null;
return _value.toUpperCase();
}
public static String toLowerCase(String _value) {
if (_value == null)
return null;
return _value.toLowerCase();
}
public static Map<String, List<String>> parseQueryParams(String _queryString) {
Map<String, List<String>> queryParameters = new HashMap<>();
if (isEmpty(_queryString)) {
return queryParameters;
}
String[] parameters = _queryString.split("&");
for (String parameter : parameters) {
String[] keyValuePair = parameter.split("=");
if (keyValuePair.length > 1)
CollectionUtils.addToMultiMap(keyValuePair[0], keyValuePair[1], queryParameters);
}
return queryParameters;
}
public static String toQueryString(Map<String, List<String>> _queryParameters) {
StringBuilder queryString = null;
for (Entry<String, List<String>> entry : CollectionUtils.makeNotNull(_queryParameters).entrySet()) {
for (String param : CollectionUtils.makeNotNull(entry.getValue())) {
if (NullUtils.isEmpty(param))
continue;
if (queryString == null)
queryString = new StringBuilder();
else
queryString.append("&");
queryString.append(entry.getKey());
queryString.append("=");
queryString.append(param);
}
}
return queryString == null?"":queryString.toString();
}
public static String toHex(String _sValue)
{
return toHex(toByteArray(_sValue));
}
public static String toHexBytes(byte[] _btData)
{
List<String> bytes = new ArrayList<>(_btData.length);
for (byte b : _btData) {
bytes.add(String.format("%02X ", b));
}
return CollectionUtils.delimit(bytes, " ");
}
public static String toHex(byte[] _btData)
{
try
{
return new String(Hex.encodeHex(_btData));
}
catch (Exception e)
{
return "";
}
}
public static byte[] fromHex(String _sValue)
{
try
{
return Hex.decodeHex(makeNotNull(_sValue).toCharArray());
}
catch (Exception e)
{
return null;
}
}
public static int bound(int _value, int _min, int _max) {
if (_value < _min)
return _min;
if (_value > _max)
return _max;
return _value;
}
}

View File

@@ -0,0 +1,147 @@
package com.lanternsoftware.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class ResourceLoader {
protected static final Logger LOG = LoggerFactory.getLogger(ResourceLoader.class);
public static String getStringResource(Class clazz, String _sResourceFileName) {
String sReply = null;
InputStream stream = null;
try {
stream = clazz.getResourceAsStream(_sResourceFileName);
if (stream != null)
sReply = IOUtils.toString(stream);
}
catch (Exception e) {
LOG.error("Failed to load resource: " + _sResourceFileName, e);
}
finally {
IOUtils.closeQuietly(stream);
}
return sReply == null ? "" : sReply;
}
public static byte[] getByteArrayResource(Class clazz, String _sResourceFileName) {
byte[] btReply = null;
InputStream stream = null;
try {
stream = clazz.getResourceAsStream(_sResourceFileName);
if (stream != null)
btReply = IOUtils.toByteArray(stream);
}
catch (IOException e) {
LOG.error("Failed to load resource: " + _sResourceFileName, e);
}
finally {
IOUtils.closeQuietly(stream);
}
return btReply;
}
public static String loadFileAsString(String _fileName) {
return loadFileAsString(new File(_fileName));
}
public static String loadFileAsString(File _file) {
return NullUtils.toString(loadFile(_file));
}
public static List<String> loadFileLines(String _fileName) {
return loadFileLines(new File(_fileName));
}
public static List<String> loadFileLines(File _file) {
if ((_file == null) || !_file.exists())
return null;
FileReader is = null;
try {
is = new FileReader(_file);
BufferedReader reader = new BufferedReader(is);
List<String> lines = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null)
{
lines.add(line);
}
return lines;
}
catch (Throwable t) {
LOG.error("Failed to load file: " + _file.getAbsolutePath(), t);
return Collections.emptyList();
}
finally {
IOUtils.closeQuietly(is);
}
}
public static byte[] loadFile(String _fileName) {
return loadFile(new File(_fileName));
}
public static byte[] loadFile(File _file) {
if ((_file == null) || !_file.exists())
return null;
InputStream is = null;
try {
is = new FileInputStream(_file);
return IOUtils.toByteArray(is);
}
catch (Throwable t) {
LOG.error("Failed to load file: " + _file.getAbsolutePath(), t);
return null;
}
finally {
IOUtils.closeQuietly(is);
}
}
public static void writeFile(String _sFile, String _data) {
writeFile(_sFile, NullUtils.toByteArray(_data));
}
public static void writeFile(String _sFile, byte[] _btData) {
FileOutputStream os = null;
try {
os = new FileOutputStream(_sFile, false);
os.write(_btData);
}
catch (Throwable t) {
LOG.error("Failed to write file: " + _sFile, t);
}
finally {
IOUtils.closeQuietly(os);
}
}
public static void writeFileLines(String _sFile, List<String> _lines) {
FileOutputStream os = null;
try {
os = new FileOutputStream(_sFile, false);
for (String line : CollectionUtils.makeNotNull(_lines)) {
os.write(NullUtils.toByteArray(line));
os.write((char)10);
}
}
catch (Throwable t) {
LOG.error("Failed to write file: " + _sFile, t);
}
finally {
IOUtils.closeQuietly(os);
}
}
}

View File

@@ -0,0 +1,51 @@
package com.lanternsoftware.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class ZipUtils {
private static final Logger LOG = LoggerFactory.getLogger(ZipUtils.class);
public static byte[] zip(byte[] _btData) {
if (_btData == null)
return null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream stream = null;
try {
stream = new GZIPOutputStream(out);
stream.write(_btData);
IOUtils.closeQuietly(stream);
return out.toByteArray();
}
catch (IOException e) {
IOUtils.closeQuietly(stream);
LOG.error("Failed to zip data", e);
return null;
}
}
public static byte[] unzip(byte[] _btData) {
if ((_btData == null) || (_btData.length == 0))
return null;
ByteArrayInputStream in = new ByteArrayInputStream(_btData);
GZIPInputStream stream = null;
try {
stream = new GZIPInputStream(in);
return IOUtils.toByteArray(stream);
}
catch (IOException e) {
LOG.error("Failed to unzip data", e);
return null;
}
finally {
IOUtils.closeQuietly(stream);
}
}
}

View File

@@ -0,0 +1,132 @@
package com.lanternsoftware.util.concurrency;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
public abstract class ConcurrencyUtils
{
private static final Object m_mutex = new Object();
private static Map<String, String> mapMutexes = null;
public static void sleep(long _lDuration)
{
try
{
Thread.sleep(_lDuration);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static void wait(Object _object)
{
try
{
synchronized(_object)
{
_object.wait();
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static void wait(Object _object, int _iTimeout)
{
try
{
synchronized(_object)
{
_object.wait(_iTimeout);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static void notify(Object _object)
{
try
{
synchronized(_object)
{
_object.notify();
}
}
catch (IllegalMonitorStateException e)
{
e.printStackTrace();
}
}
public static void notifyAll(Object _object)
{
try
{
synchronized(_object)
{
_object.notifyAll();
}
}
catch (IllegalMonitorStateException e)
{
e.printStackTrace();
}
}
public static String getMutex(String _sKey)
{
synchronized (m_mutex)
{
if (mapMutexes == null)
mapMutexes = new HashMap<String, String>();
String sMutex = mapMutexes.get(_sKey);
if (sMutex != null)
return sMutex;
mapMutexes.put(_sKey, _sKey);
return _sKey;
}
}
public static void destroy()
{
if (mapMutexes != null)
{
mapMutexes.clear();
mapMutexes = null;
}
}
public static void getAll(Future<?>... _futures)
{
if (_futures == null)
return;
getAll(Arrays.asList(_futures));
}
public static void getAll(Collection<Future<?>> _collFutures)
{
if (_collFutures == null)
return;
for (Future<?> f : _collFutures)
{
try
{
f.get();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,16 @@
package com.lanternsoftware.util.concurrency;
import java.util.concurrent.Callable;
public abstract class Execution implements Callable<ExecutionResult> {
public abstract void run() throws Exception;
public final ExecutionResult call(){
try {
run();
}
catch (Exception _e) {
return new ExecutionResult(_e);
}
return new ExecutionResult(null);
}
}

View File

@@ -0,0 +1,13 @@
package com.lanternsoftware.util.concurrency;
public class ExecutionResult {
private final Exception e;
public ExecutionResult(Exception _e) {
e = _e;
}
public Exception getException() {
return e;
}
}

View File

@@ -0,0 +1,88 @@
package com.lanternsoftware.util.concurrency;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lanternsoftware.util.CollectionUtils;
public abstract class ExecutionUtil {
private static final Logger LOG = LoggerFactory.getLogger(ExecutionUtil.class);
public static void waitForExecution(Collection<Future<ExecutionResult>> futures) throws Exception {
Exception e = null;
for (Future<ExecutionResult> f : futures) {
ExecutionResult result = f.get();
if (result.getException() != null)
e = result.getException();
}
if (e != null)
throw e;
}
public static void waitForExecution(Logger _logger, Collection<Future<?>> futures) {
for (Future<?> f : futures) {
try {
f.get();
}
catch (Exception _e) {
_logger.error("Exception occurred during execution", _e);
}
}
}
public static void waitForExecution(Future<ExecutionResult>... futures) throws Exception {
Exception e = null;
for (Future<ExecutionResult> f : futures) {
ExecutionResult result = f.get();
if (result.getException() != null)
e = result.getException();
}
if (e != null)
throw e;
}
public static void waitForExecution(Logger _logger, Future<?>... futures) {
for (Future<?> f : futures) {
try {
f.get();
}
catch (Exception _e) {
_logger.error("Exception occurred during execution", _e);
}
}
}
public static <T> T get(Future<T> _futures) {
return CollectionUtils.getFirst(getAll(Collections.singletonList(_futures)));
}
public static <T> List<T> getAll(Future<T>... _futures) {
return getAll(Arrays.asList(_futures));
}
public static <T> List<T> getAll(Collection<Future<T>> _futures) {
return getAll(_futures, false);
}
public static <T> List<T> getAll(Collection<Future<T>> _futures, boolean _includeNulls) {
List<T> ret = new ArrayList<>();
for (Future<T> future : CollectionUtils.makeNotNull(_futures)) {
try {
T t = future.get();
if (_includeNulls || (t != null))
ret.add(t);
}
catch (Exception e) {
LOG.error("Exception while getting future", e);
}
}
return ret;
}
}

View File

@@ -0,0 +1,13 @@
package com.lanternsoftware.util.concurrency;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public abstract class ExecutorUtil {
public static ThreadPoolExecutor fixedThreadPool(int _threadCount) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(_threadCount, _threadCount,60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
executor.allowCoreThreadTimeOut(true);
return executor;
}
}

View File

@@ -0,0 +1,284 @@
package com.lanternsoftware.util.cryptography;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.LongBuffer;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lanternsoftware.util.CollectionUtils;
public class AESTool {
private static final Logger LOG = LoggerFactory.getLogger(AESTool.class);
private final SecretKey key;
private final static SecureRandom rng = rng();
private final byte[] iv;
private static SecureRandom rng() {
try {
SecureRandom rng = SecureRandom.getInstance("SHA1PRNG");
rng.generateSeed(16);
return rng;
} catch (NoSuchAlgorithmException e) {
LOG.error("Failed to initialize SecureRandom with SHA1PRNG", e);
return null;
}
}
public static byte[] randomIV() {
return rng.generateSeed(16);
}
/**
* @return a randomly generated AES secret key
*/
public static SecretKey generateRandomSecretKey() {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(Base64.encodeBase64String(new SecureRandom().generateSeed(32)).toCharArray(), new SecureRandom().generateSeed(32), 65536, 256);
SecretKey key = factory.generateSecret(spec);
return new SecretKeySpec(key.getEncoded(), "AES");
} catch (Exception e) {
LOG.error("Failed to generate a random AES secret key", e);
return null;
}
}
public static void printRandomSecretKey() {
SecretKey key = generateRandomSecretKey();
byte[] btKey = key.getEncoded();
StringBuilder builder = null;
for (long lValue : toLongs(btKey)) {
if (builder == null)
builder = new StringBuilder("new AESTool(");
else
builder.append(",");
builder.append(lValue);
builder.append("L");
}
builder.append(");");
System.out.println(builder.toString());
}
/**
* @param _btKey the encoded form of a {@link SecretKey} object. See the {@link SecretKey#getEncoded()} method.
*/
public AESTool(byte[] _btKey) {
this(new SecretKeySpec(_btKey, "AES"));
}
/**
* @param _btKey the encoded form of a {@link SecretKey} object. See the {@link SecretKey#getEncoded()} method.
* @param _iv the initialization vector to use. If this is set, every call of encrypt for a given input will produce the same output. If null is passed, every call of encrypt for a given input will generate a random IV and the output will be different each time (recommended).
*/
public AESTool(byte[] _btKey, byte[] _iv) {
this(new SecretKeySpec(_btKey, "AES"), _iv);
}
/**
* @param _arrKey the encoded form of a {@link SecretKey} object converted to an array of long values using the {@link AESTool#toLongs(byte[])} method. See the {@link SecretKey#getEncoded()} method.
*/
public AESTool(long... _arrKey) {
this(new SecretKeySpec(toByteArray(_arrKey), "AES"));
}
/**
* @param _arrKey the encoded form of a {@link SecretKey} object converted to an array of long values using the {@link AESTool#toLongs(byte[])} method. See the {@link SecretKey#getEncoded()} method.
* @param _iv the initialization vector to use. If this is set, every call of encrypt for a given input will produce the same output. If null is passed, every call of encrypt for a given input will generate a random IV and the output will be different each time (recommended).
*/
public AESTool(byte[] _iv, long... _arrKey) {
this(new SecretKeySpec(toByteArray(_arrKey), "AES"), _iv);
}
public AESTool(SecretKey _key) {
this(_key, null);
}
public AESTool(SecretKey _key, byte[] _iv) {
key = _key;
if ((_iv != null) && (_iv.length != 16))
throw new RuntimeException("Initialization Vector must be null or exactly 16 bytes in length");
iv = _iv;
}
/**
* @param _data a string to be encrypted with this tool's secret key
* @return the encrypted data as a base64 encoded string
*/
public String encryptToBase64(String _data) {
return encryptToBase64(toByteArray(_data));
}
/**
* @param _btData the binary data to be encrypted with this tool's secret key
* @return the encrypted data as a base64 encoded string
*/
public String encryptToBase64(byte[] _btData) {
if (_btData == null)
return null;
return Base64.encodeBase64String(encrypt(_btData));
}
/**
* @param _data a string to be encrypted with this tool's secret key
* @return the encrypted data as a url safe base64 encoded string
*/
public String encryptToUrlSafeBase64(String _data) {
return encryptToUrlSafeBase64(toByteArray(_data));
}
/**
* @param _btData the binary data to be encrypted with this tool's secret key
* @return the encrypted data as a url safe base64 encoded string
*/
public String encryptToUrlSafeBase64(byte[] _btData) {
if (_btData == null)
return null;
return Base64.encodeBase64URLSafeString(encrypt(_btData));
}
/**
* @param _data a string to be encrypted with this tool's secret key
* @return the encrypted data in binary form
*/
public byte[] encrypt(String _data) {
return encrypt(toByteArray(_data));
}
/**
* @param _btData the binary data to be encrypted with this tool's secret key
* @return the encrypted data in binary form
*/
public byte[] encrypt(byte[] _btData) {
if (_btData == null)
return null;
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] btIV = (iv != null) ? iv : randomIV();
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(btIV));
if (iv != null)
return cipher.doFinal(_btData);
else {
byte[] btSalt = rng.generateSeed(16);
return CollectionUtils.merge(btIV, cipher.doFinal(CollectionUtils.merge(btSalt, _btData)));
}
} catch (Exception e) {
LOG.error("Failed to encrypt data", e);
return null;
}
}
/**
* @param _base64 the base64 encoded representation of the aes encrypted byte array to be decrypted with this tool's
* secret key
* @return the decrypted byte array transformed to a string.
*/
public String decryptFromBase64ToString(String _base64) {
return toString(decryptFromBase64(_base64));
}
/**
* @param _base64 the base64 encoded representation of the aes encrypted byte array to be decrypted with this tool's
* secret key
* @return the decrypted byte array
*/
public byte[] decryptFromBase64(String _base64) {
return _base64 == null ? null : decrypt(Base64.decodeBase64(_base64));
}
/**
* @param _btData the encrypted byte array to be decrypted with this tool's secret key
* @return the decrypted byte array transformed to a string
*/
public String decryptToString(byte[] _btData) {
return toString(decrypt(_btData));
}
/**
* @param _btData the encrypted byte array to be decrypted with this tool's secret key
* @return the decrypted byte array
*/
public byte[] decrypt(byte[] _btData) {
if (_btData == null)
return null;
try {
Cipher decipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
if (iv == null) {
decipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(Arrays.copyOfRange(_btData, 0, 16)));
byte[] btData = decipher.doFinal(Arrays.copyOfRange(_btData, 16, _btData.length));
return Arrays.copyOfRange(btData, 16, btData.length);
} else {
decipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
return decipher.doFinal(_btData);
}
} catch (Exception e) {
LOG.error("Failed to decrypt data", e);
return null;
}
}
/**
* @param _btData a byte array to convert to an array of longs
* @return the array of long values that contains the data from the byte array.
*/
public static long[] toLongs(byte[] _btData) {
if (_btData == null)
return null;
long[] lData = new long[_btData.length / 8];
LongBuffer data = ByteBuffer.wrap(_btData).order(ByteOrder.BIG_ENDIAN).asLongBuffer();
data.get(lData);
return lData;
}
/**
* @param _arrLongs an array of longs to convert into a byte array representing the same data
* @return the converted byte array
*/
public static byte[] toByteArray(long... _arrLongs) {
ByteBuffer input = ByteBuffer.allocate(_arrLongs.length * 8).order(ByteOrder.BIG_ENDIAN);
for (long lInput : _arrLongs) {
input.putLong(lInput);
}
return input.array();
}
/**
* Handles and logs the missing encoding exception that will never happen.
*
* @param _btString the UTF-8 encoded representation of a string
* @return the String object created from the byte array
*/
public static String toString(byte[] _btString) {
if (_btString == null)
return null;
return new String(_btString, StandardCharsets.UTF_8);
}
/**
* Handles and logs the missing encoding exception that will never happen.
*
* @param _value the string to turn into a byte array
* @return the UTF-8 encoded byte array representation of the string
*/
public static byte[] toByteArray(String _value) {
if (_value == null)
return null;
return _value.getBytes(StandardCharsets.UTF_8);
}
}

View File

@@ -0,0 +1,220 @@
package com.lanternsoftware.util.cryptography;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import com.lanternsoftware.util.NullUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lanternsoftware.util.CollectionUtils;
public abstract class RSAUtils {
private static final Logger LOG = LoggerFactory.getLogger(RSAUtils.class);
public static KeyPair generateRandomRSAKeyPair() {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
return keyPairGenerator.genKeyPair();
}
catch (NoSuchAlgorithmException _e) {
LOG.error("Failed to generate RSA key pair", _e);
return null;
}
}
public static String toString(RSAPrivateKey _key) {
if (_key == null)
return null;
StringBuilder b = new StringBuilder(Base64.encodeBase64String(_key.getModulus().toByteArray()));
b.append(",");
b.append(Base64.encodeBase64String(_key.getPrivateExponent().toByteArray()));
return b.toString();
}
public static String toString(RSAPublicKey _key) {
if (_key == null)
return null;
StringBuilder b = new StringBuilder(Base64.encodeBase64String(_key.getModulus().toByteArray()));
b.append(",");
b.append(Base64.encodeBase64String(_key.getPublicExponent().toByteArray()));
return b.toString();
}
public static String toPEM(RSAPublicKey _key) {
StringBuilder pem = new StringBuilder("-----BEGIN PUBLIC KEY-----\r\n");
pem.append(NullUtils.wrap(Base64.encodeBase64String(_key.getEncoded()), 64, true));
pem.append("\r\n-----END PUBLIC KEY-----");
return pem.toString();
}
public static String toPEM(Certificate _cert) {
try {
StringBuilder pem = new StringBuilder("-----BEGIN CERTIFICATE-----\r\n");
pem.append(NullUtils.wrap(Base64.encodeBase64String(_cert.getEncoded()), 64, true));
pem.append("\r\n-----END CERTIFICATE-----");
return pem.toString();
} catch (CertificateEncodingException _e) {
LOG.error("Failed to generate certificate PEM", _e);
return null;
}
}
public static String toPEM(RSAPrivateKey _key) {
StringBuilder pem = new StringBuilder("-----BEGIN RSA PRIVATE KEY-----\r\n");
pem.append(NullUtils.wrap(Base64.encodeBase64String(_key.getEncoded()), 64, true));
pem.append("\r\n-----END RSA PRIVATE KEY-----");
return pem.toString();
}
public static RSAPrivateKey toPrivateKey(String _privateKey64) {
try {
String[] parts = NullUtils.makeNotNull(_privateKey64).split(",");
if (CollectionUtils.size(parts) == 2) {
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(new BigInteger(Base64.decodeBase64(parts[0])), new BigInteger(Base64.decodeBase64(parts[1])));
return (RSAPrivateKey) fact.generatePrivate(keySpec);
}
}
catch (Exception _e) {
LOG.error("Failed to generate RSA private key", _e);
}
return null;
}
public static RSAPublicKey toPublicKey(String _publicKey64) {
try {
String[] parts = NullUtils.makeNotNull(_publicKey64).split(",");
if (CollectionUtils.size(parts) == 2) {
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(new BigInteger(Base64.decodeBase64(parts[0])), new BigInteger(Base64.decodeBase64(parts[1])));
return (RSAPublicKey) fact.generatePublic(keySpec);
}
}
catch (Exception _e) {
LOG.error("Failed to generate RSA public key", _e);
}
return null;
}
public static RSAPublicKey fromPEMtoPublicKey(String _pem) {
if (_pem == null)
return null;
String pem = _pem.replaceAll("(-+BEGIN PUBLIC KEY-+|-+END PUBLIC KEY-+|\\r|\\n)", "");
X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decodeBase64(pem));
try {
KeyFactory fact = KeyFactory.getInstance("RSA");
return (RSAPublicKey) fact.generatePublic(spec);
}
catch (Exception _e) {
LOG.error("Failed to generate RSA public key", _e);
return null;
}
}
public static Certificate fromPEMtoCertificate(String _pem) {
String pem = _pem.replaceAll("(-+BEGIN CERTIFICATE-+|-+END CERTIFICATE-+|\\r|\\n)", "");
ByteArrayInputStream is = null;
try {
is = new ByteArrayInputStream(Base64.decodeBase64(pem));
CertificateFactory cf = CertificateFactory.getInstance("X.509");
return cf.generateCertificate(is);
}
catch (Exception _e) {
LOG.error("Failed to generate RSA certificate", _e);
return null;
}
finally {
IOUtils.closeQuietly(is);
}
}
public static Certificate loadCert(String _keystoreFileName, String _keystorePassword, String _certAlias) {
return loadCert(loadKeystore(_keystoreFileName, _keystorePassword), _certAlias);
}
public static Certificate loadCert(InputStream _is, String _keystorePassword, String _certAlias) {
return loadCert(loadKeystore(_is, _keystorePassword), _certAlias);
}
public static Certificate loadCert(KeyStore _keystore, String _certAlias) {
try {
return _keystore.getCertificate(_certAlias);
}
catch (Exception e) {
LOG.error("Failed to load certificate {}", e.getMessage(), e);
return null;
}
}
public static PrivateKey loadPrivateKey(String _keystoreFileName, String _password, String _certAlias) {
return loadPrivateKey(_keystoreFileName, _password, _password, _certAlias);
}
public static PrivateKey loadPrivateKey(InputStream _is, String _password, String _certAlias) {
return loadPrivateKey(_is, _password, _password, _certAlias);
}
public static PrivateKey loadPrivateKey(String _keystoreFileName, String _keystorePassword, String _certPassword, String _certAlias) {
return getPrivateKey(loadKeystore(_keystoreFileName, _keystorePassword), _certPassword, _certAlias);
}
public static PrivateKey loadPrivateKey(InputStream _is, String _keystorePassword, String _certPassword, String _certAlias) {
return getPrivateKey(loadKeystore(_is, _keystorePassword), _certPassword, _certAlias);
}
public static PrivateKey getPrivateKey(KeyStore _keystore, String _certPassword, String _certAlias) {
try {
return (PrivateKey) _keystore.getKey(_certAlias, _certPassword.toCharArray());
}
catch (Exception e) {
LOG.error("Failed to load key: {}", e.getMessage(), e);
return null;
}
}
public static KeyStore loadKeystore(String _keystoreFileName, String _keystorePassword) {
try {
return loadKeystore(new FileInputStream(_keystoreFileName), _keystorePassword);
}
catch (Exception e) {
LOG.error("Failed to load keystore: {}", e.getMessage(), e);
return null;
}
}
public static KeyStore loadKeystore(InputStream _is, String _keystorePassword) {
try {
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(_is, _keystorePassword.toCharArray());
return keystore;
}
catch (Exception e) {
LOG.error("Failed to load keystore: {}", e.getMessage(), e);
return null;
}
finally {
IOUtils.closeQuietly(_is);
}
}
}

View File

@@ -0,0 +1,102 @@
package com.lanternsoftware.util.csv;
import com.lanternsoftware.util.CollectionUtils;
import com.lanternsoftware.util.NullUtils;
import java.util.ArrayList;
import java.util.List;
public class CSV {
public final int columns;
public final int rows;
private final List<String> header;
private final List<CSVCell[]> data;
public CSV() {
this(null, null, 0);
}
public CSV(List<String> _header, List<List<String>> _data, int _columnCount) {
header = _header;
if (_data == null) {
columns = 0;
rows = 0;
data = new ArrayList<>(0);
}
else {
rows = _data.size();
columns = _columnCount;
data = new ArrayList<>(rows);
for (List<String> listSourceRow : _data) {
CSVCell[] row = new CSVCell[columns];
int iCol = 0;
for (String sCol : CollectionUtils.makeNotNull(listSourceRow)) {
row[iCol] = new CSVCell(sCol, sCol);
iCol++;
}
while (iCol < columns) {
row[iCol] = new CSVCell("", "");
iCol++;
}
data.add(row);
}
}
}
public CSV(List<String> _header, List<List<CSVCell>> _data) {
header = _header;
if (_data == null) {
columns = 0;
rows = 0;
data = new ArrayList<>(0);
}
else {
rows = _data.size();
data = new ArrayList<>(rows);
int iMaxColumn = CollectionUtils.size(header);
for (List<CSVCell> listSourceRow : _data) {
iMaxColumn = Math.max(iMaxColumn, CollectionUtils.size(listSourceRow));
}
columns = iMaxColumn;
for (List<CSVCell> listSourceRow : _data) {
CSVCell[] row = new CSVCell[columns];
int iCol = 0;
for (CSVCell cell : CollectionUtils.makeNotNull(listSourceRow)) {
row[iCol] = cell == null ? new CSVCell("", "") : cell;
iCol++;
}
while (iCol < columns) {
row[iCol] = new CSVCell("", "");
iCol++;
}
data.add(row);
}
}
}
public String cell(int _row, int _column) {
if ((_row < 0) || (_row >= rows) || (_column < 0) || (_column >= columns))
return "";
CSVCell cell = data.get(_row)[_column];
if ((cell == null) || (cell.display == null))
return "";
return cell.display;
}
public List<String> getHeaders() {
return header;
}
public String getHeader(int _column) {
return NullUtils.makeNotNull(CollectionUtils.get(header, _column));
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
}

View File

@@ -0,0 +1,59 @@
package com.lanternsoftware.util.csv;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.lanternsoftware.util.NullUtils;
public class CSVCell implements Comparable<CSVCell> {
public final String display;
public final Object comparable;
public final boolean reverseSort;
public CSVCell(String _display) {
this(_display, _display);
}
public CSVCell(String _display, Object _comparable) {
this(_display, _comparable, false);
}
public CSVCell(String _display, Object _comparable, boolean _reverseSort) {
display = _display;
comparable = _comparable;
reverseSort = _reverseSort;
}
@Override
public int compareTo(CSVCell _o) {
if (_o == null)
return 1;
Object type = (comparable == null) ? _o.comparable : comparable;
if (type instanceof String)
return NullUtils.compare((String) comparable, (String) _o.comparable, false);
if (type instanceof Date)
return NullUtils.compare((Date) comparable, (Date) _o.comparable, false);
if (type instanceof Integer)
return NullUtils.compare((Integer) comparable, (Integer) _o.comparable, false);
if (type instanceof Long)
return NullUtils.compare((Long) comparable, (Long) _o.comparable, false);
if (type instanceof Double)
return NullUtils.compare((Double) comparable, (Double) _o.comparable, false);
if (type instanceof Boolean)
return NullUtils.compare((Boolean) comparable, (Boolean) _o.comparable, false);
if (type instanceof Float)
return NullUtils.compare((Float) comparable, (Float) _o.comparable, false);
return 0;
}
public static List<CSVCell> asList(String... _data) {
if (_data == null)
return new ArrayList<CSVCell>(0);
List<CSVCell> listCells = new ArrayList<CSVCell>(_data.length);
for (String data : _data) {
listCells.add(new CSVCell(data));
}
return listCells;
}
}

View File

@@ -0,0 +1,132 @@
package com.lanternsoftware.util.csv;
import org.apache.commons.io.IOUtils;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public abstract class CSVReader
{
public static CSV loadCSVFromFile(String _filename)
{
return loadCSVFromFile(_filename, false);
}
public static CSV loadCSVFromFile(String _filename, boolean _firstRowIsHeader)
{
FileInputStream is = null;
try
{
int iMaxColumns = 0;
List<List<String>> listLines = new LinkedList<List<String>>();
is = new FileInputStream(_filename);
BufferedReader r = new BufferedReader(new InputStreamReader(is));
List<String> listHeader = null;
List<String> listCurLine = new ArrayList<String>();
String sRemainder = null;
String sLine = r.readLine();
while (sLine != null)
{
if (sRemainder == null)
sRemainder = parseLine(sLine, listCurLine);
else
sRemainder = parseLine(sRemainder+sLine, listCurLine);
if (sRemainder == null)
{
if (_firstRowIsHeader && (listHeader == null))
listHeader = listCurLine;
else
listLines.add(listCurLine);
iMaxColumns = Math.max(iMaxColumns, listCurLine.size());
listCurLine = new ArrayList<String>();
}
sLine = r.readLine();
}
return new CSV(listHeader, listLines, iMaxColumns);
}
catch (Throwable t)
{
t.printStackTrace();
return null;
}
finally
{
IOUtils.closeQuietly(is);
}
}
public static CSV parseCSV(String _csv)
{
return parseCSV(_csv, false);
}
public static CSV parseCSV(String _csv, boolean _bFirstRowIsHeader)
{
_csv = _csv.replace("\r","");
int iMaxColumns = 0;
List<List<String>> listLines = new LinkedList<List<String>>();
List<String> listHeader = null;
List<String> listCurLine = new ArrayList<String>();
String sRemainder = null;
for (String sLine : _csv.split("\n"))
{
if (sRemainder == null)
sRemainder = parseLine(sLine, listCurLine);
else
sRemainder = parseLine(sRemainder+sLine, listCurLine);
if (sRemainder == null)
{
if (_bFirstRowIsHeader && (listHeader == null))
listHeader = listCurLine;
else
listLines.add(listCurLine);
iMaxColumns = Math.max(iMaxColumns, listCurLine.size());
listCurLine = new ArrayList<String>();
}
}
return new CSV(listHeader, listLines, iMaxColumns);
}
public static String parseLine(String _sLine, List<String> _listCurLine)
{
int i=0;
while (i < _sLine.length())
{
if (_sLine.charAt(i) == '"')
{
int iPos = _sLine.indexOf("\",",i+1);
if (iPos < 0)
{
if (!_sLine.endsWith("\""))
return _sLine.substring(i);
else
{
_listCurLine.add(_sLine.substring(i+1, _sLine.length()-1));
return null;
}
}
else
{
_listCurLine.add(_sLine.substring(i+1, iPos));
i = iPos+2;
}
}
else
{
int iPos = _sLine.indexOf(",",i);
if (iPos < 0)
{
_listCurLine.add(_sLine.substring(i));
return null;
}
_listCurLine.add(_sLine.substring(i, iPos));
i = iPos+1;
}
}
return null;
}
}

View File

@@ -0,0 +1,528 @@
package com.lanternsoftware.util.email;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EmailValidator {
private static final String SPECIAL_CHARS = "\\p{Cntrl}\\(\\)<>@,;:'\\\\\\\"\\.\\[\\]";
private static final String VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]";
private static final String QUOTED_USER = "(\"[^\"]*\")";
private static final String WORD = "((" + VALID_CHARS + "|')+|" + QUOTED_USER + ")";
private static final String LEGAL_ASCII_REGEX = "^\\p{ASCII}+$";
private static final String EMAIL_REGEX = "^\\s*?(.+)@(.+?)\\s*$";
private static final String IP_DOMAIN_REGEX = "^\\[(.*)\\]$";
private static final String USER_REGEX = "^\\s*" + WORD + "(\\." + WORD + ")*$";
private static final Pattern MATCH_ASCII_PATTERN = Pattern.compile(LEGAL_ASCII_REGEX);
private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX);
private static final Pattern IP_DOMAIN_PATTERN = Pattern.compile(IP_DOMAIN_REGEX);
private static final Pattern USER_PATTERN = Pattern.compile(USER_REGEX);
private static final String IPV4_REGEX = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";
private final RegexValidator ipv4Validator = new RegexValidator(IPV4_REGEX);
private static final String DOMAIN_LABEL_REGEX = "\\p{Alnum}(?>[\\p{Alnum}-]*\\p{Alnum})*";
private static final String TOP_LABEL_REGEX = "\\p{Alpha}{2,}";
private static final String DOMAIN_NAME_REGEX = "^(?:" + DOMAIN_LABEL_REGEX + "\\.)+" + "(" + TOP_LABEL_REGEX + ")$";
/** RegexValidator for matching domains. */
private final RegexValidator domainRegex = new RegexValidator(DOMAIN_NAME_REGEX);
private static final String[] INFRASTRUCTURE_TLDS = new String[] { "arpa", "root" };
private static final String[] GENERIC_TLDS = new String[] { "aero", // air transport industry
"asia", // Pan-Asia/Asia Pacific
"biz", // businesses
"cat", // Catalan linguistic/cultural community
"com", // commercial enterprises
"coop", // cooperative associations
"info", // informational sites
"jobs", // Human Resource managers
"mobi", // mobile products and services
"museum", // museums, surprisingly enough
"name", // individuals' sites
"net", // internet support infrastructure/business
"org", // noncommercial organizations
"pro", // credentialed professionals and entities
"tel", // contact data for businesses and individuals
"travel", // entities in the travel industry
"gov", // United States Government
"edu", // accredited postsecondary US education entities
"mil", // United States Military
"int" // organizations established by international treaty
};
private static final String[] COUNTRY_CODE_TLDS = new String[] { "ac", // Ascension Island
"ad", // Andorra
"ae", // United Arab Emirates
"af", // Afghanistan
"ag", // Antigua and Barbuda
"ai", // Anguilla
"al", // Albania
"am", // Armenia
"an", // Netherlands Antilles
"ao", // Angola
"aq", // Antarctica
"ar", // Argentina
"as", // American Samoa
"at", // Austria
"au", // Australia (includes Ashmore and Cartier Islands and Coral Sea Islands)
"aw", // Aruba
"ax", // Åland
"az", // Azerbaijan
"ba", // Bosnia and Herzegovina
"bb", // Barbados
"bd", // Bangladesh
"be", // Belgium
"bf", // Burkina Faso
"bg", // Bulgaria
"bh", // Bahrain
"bi", // Burundi
"bj", // Benin
"bm", // Bermuda
"bn", // Brunei Darussalam
"bo", // Bolivia
"br", // Brazil
"bs", // Bahamas
"bt", // Bhutan
"bv", // Bouvet Island
"bw", // Botswana
"by", // Belarus
"bz", // Belize
"ca", // Canada
"cc", // Cocos (Keeling) Islands
"cd", // Democratic Republic of the Congo (formerly Zaire)
"cf", // Central African Republic
"cg", // Republic of the Congo
"ch", // Switzerland
"ci", // Côte d'Ivoire
"ck", // Cook Islands
"cl", // Chile
"cm", // Cameroon
"cn", // China, mainland
"co", // Colombia
"cr", // Costa Rica
"cu", // Cuba
"cv", // Cape Verde
"cx", // Christmas Island
"cy", // Cyprus
"cz", // Czech Republic
"de", // Germany
"dj", // Djibouti
"dk", // Denmark
"dm", // Dominica
"do", // Dominican Republic
"dz", // Algeria
"ec", // Ecuador
"ee", // Estonia
"eg", // Egypt
"er", // Eritrea
"es", // Spain
"et", // Ethiopia
"eu", // European Union
"fi", // Finland
"fj", // Fiji
"fk", // Falkland Islands
"fm", // Federated States of Micronesia
"fo", // Faroe Islands
"fr", // France
"ga", // Gabon
"gb", // Great Britain (United Kingdom)
"gd", // Grenada
"ge", // Georgia
"gf", // French Guiana
"gg", // Guernsey
"gh", // Ghana
"gi", // Gibraltar
"gl", // Greenland
"gm", // The Gambia
"gn", // Guinea
"gp", // Guadeloupe
"gq", // Equatorial Guinea
"gr", // Greece
"gs", // South Georgia and the South Sandwich Islands
"gt", // Guatemala
"gu", // Guam
"gw", // Guinea-Bissau
"gy", // Guyana
"hk", // Hong Kong
"hm", // Heard Island and McDonald Islands
"hn", // Honduras
"hr", // Croatia (Hrvatska)
"ht", // Haiti
"hu", // Hungary
"id", // Indonesia
"ie", // Ireland (Éire)
"il", // Israel
"im", // Isle of Man
"in", // India
"io", // British Indian Ocean Territory
"iq", // Iraq
"ir", // Iran
"is", // Iceland
"it", // Italy
"je", // Jersey
"jm", // Jamaica
"jo", // Jordan
"jp", // Japan
"ke", // Kenya
"kg", // Kyrgyzstan
"kh", // Cambodia (Khmer)
"ki", // Kiribati
"km", // Comoros
"kn", // Saint Kitts and Nevis
"kp", // North Korea
"kr", // South Korea
"kw", // Kuwait
"ky", // Cayman Islands
"kz", // Kazakhstan
"la", // Laos (currently being marketed as the official domain for Los Angeles)
"lb", // Lebanon
"lc", // Saint Lucia
"li", // Liechtenstein
"lk", // Sri Lanka
"lr", // Liberia
"ls", // Lesotho
"lt", // Lithuania
"lu", // Luxembourg
"lv", // Latvia
"ly", // Libya
"ma", // Morocco
"mc", // Monaco
"md", // Moldova
"me", // Montenegro
"mg", // Madagascar
"mh", // Marshall Islands
"mk", // Republic of Macedonia
"ml", // Mali
"mm", // Myanmar
"mn", // Mongolia
"mo", // Macau
"mp", // Northern Mariana Islands
"mq", // Martinique
"mr", // Mauritania
"ms", // Montserrat
"mt", // Malta
"mu", // Mauritius
"mv", // Maldives
"mw", // Malawi
"mx", // Mexico
"my", // Malaysia
"mz", // Mozambique
"na", // Namibia
"nc", // New Caledonia
"ne", // Niger
"nf", // Norfolk Island
"ng", // Nigeria
"ni", // Nicaragua
"nl", // Netherlands
"no", // Norway
"np", // Nepal
"nr", // Nauru
"nu", // Niue
"nz", // New Zealand
"om", // Oman
"pa", // Panama
"pe", // Peru
"pf", // French Polynesia With Clipperton Island
"pg", // Papua New Guinea
"ph", // Philippines
"pk", // Pakistan
"pl", // Poland
"pm", // Saint-Pierre and Miquelon
"pn", // Pitcairn Islands
"pr", // Puerto Rico
"ps", // Palestinian territories (PA-controlled West Bank and Gaza Strip)
"pt", // Portugal
"pw", // Palau
"py", // Paraguay
"qa", // Qatar
"re", // Réunion
"ro", // Romania
"rs", // Serbia
"ru", // Russia
"rw", // Rwanda
"sa", // Saudi Arabia
"sb", // Solomon Islands
"sc", // Seychelles
"sd", // Sudan
"se", // Sweden
"sg", // Singapore
"sh", // Saint Helena
"si", // Slovenia
"sj", // Svalbard and Jan Mayen Islands Not in use (Norwegian dependencies; see .no)
"sk", // Slovakia
"sl", // Sierra Leone
"sm", // San Marino
"sn", // Senegal
"so", // Somalia
"sr", // Suriname
"st", // São Tomé and Príncipe
"su", // Soviet Union (deprecated)
"sv", // El Salvador
"sy", // Syria
"sz", // Swaziland
"tc", // Turks and Caicos Islands
"td", // Chad
"tf", // French Southern and Antarctic Lands
"tg", // Togo
"th", // Thailand
"tj", // Tajikistan
"tk", // Tokelau
"tl", // East Timor (deprecated old code)
"tm", // Turkmenistan
"tn", // Tunisia
"to", // Tonga
"tp", // East Timor
"tr", // Turkey
"tt", // Trinidad and Tobago
"tv", // Tuvalu
"tw", // Taiwan, Republic of China
"tz", // Tanzania
"ua", // Ukraine
"ug", // Uganda
"uk", // United Kingdom
"um", // United States Minor Outlying Islands
"us", // United States of America
"uy", // Uruguay
"uz", // Uzbekistan
"va", // Vatican City State
"vc", // Saint Vincent and the Grenadines
"ve", // Venezuela
"vg", // British Virgin Islands
"vi", // U.S. Virgin Islands
"vn", // Vietnam
"vu", // Vanuatu
"wf", // Wallis and Futuna
"ws", // Samoa (formerly Western Samoa)
"ye", // Yemen
"yt", // Mayotte
"yu", // Serbia and Montenegro (originally Yugoslavia)
"za", // South Africa
"zm", // Zambia
"zw", // Zimbabwe
};
private static final List<String> INFRASTRUCTURE_TLD_LIST = Arrays.asList(INFRASTRUCTURE_TLDS);
private static final List<String> GENERIC_TLD_LIST = Arrays.asList(GENERIC_TLDS);
private static final Set<String> COUNTRY_CODE_TLD_LIST = new HashSet<String>(Arrays.asList(COUNTRY_CODE_TLDS));
private static final EmailValidator EMAIL_VALIDATOR = new EmailValidator();
public static EmailValidator getInstance()
{
return EMAIL_VALIDATOR;
}
public boolean isValid(String email)
{
if (email == null)
return false;
Matcher asciiMatcher = MATCH_ASCII_PATTERN.matcher(email);
if (!asciiMatcher.matches())
return false;
// Check the whole email address structure
Matcher emailMatcher = EMAIL_PATTERN.matcher(email);
if (!emailMatcher.matches())
return false;
if (email.endsWith("."))
return false;
if (!isValidUser(emailMatcher.group(1)))
return false;
if (!isValidDomain(emailMatcher.group(2)))
return false;
return true;
}
protected boolean isValidDomain(String domain)
{
// see if domain is an IP address in brackets
Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain);
if (ipDomainMatcher.matches())
return isValidInet4Address(ipDomainMatcher.group(1));
else
return isValidTldDomain(domain);
}
protected boolean isValidInet4Address(String inet4Address)
{
// verify that address conforms to generic IPv4 format
String[] groups = ipv4Validator.match(inet4Address);
if (groups == null)
return false;
// verify that address subgroups are legal
for (int i = 0; i <= 3; i++)
{
String ipSegment = groups[i];
if (ipSegment == null || ipSegment.length() <= 0)
return false;
int iIpSegment = 0;
try
{
iIpSegment = Integer.parseInt(ipSegment);
}
catch (NumberFormatException e)
{
return false;
}
if (iIpSegment > 255)
return false;
}
return true;
}
protected boolean isValidUser(String user)
{
return USER_PATTERN.matcher(user).matches();
}
protected boolean isValidTldDomain(String domain)
{
String[] groups = domainRegex.match(domain);
if (groups != null && groups.length > 0)
return isValidTld(groups[0]);
return false;
}
protected boolean isValidTld(String tld)
{
return isValidInfrastructureTld(tld) || isValidGenericTld(tld) || isValidCountryCodeTld(tld);
}
protected boolean isValidInfrastructureTld(String iTld)
{
return INFRASTRUCTURE_TLD_LIST.contains(chompLeadingDot(iTld.toLowerCase()));
}
protected boolean isValidGenericTld(String gTld)
{
return GENERIC_TLD_LIST.contains(chompLeadingDot(gTld.toLowerCase()));
}
protected boolean isValidCountryCodeTld(String ccTld)
{
return COUNTRY_CODE_TLD_LIST.contains(chompLeadingDot(ccTld.toLowerCase()));
}
private String chompLeadingDot(String str)
{
if (str.startsWith("."))
return str.substring(1);
else
return str;
}
private class RegexValidator implements Serializable
{
private static final long serialVersionUID = -8832409930574867162L;
private final Pattern[] patterns;
/** Construct a <i>case sensitive</i> validator for a single regular expression.
*
* @param regex
* The regular expression this validator will validate against */
public RegexValidator(String regex)
{
this(regex, true);
}
/** Construct a validator for a single regular expression with the specified case sensitivity.
*
* @param regex
* The regular expression this validator will validate against
* @param caseSensitive
* when <code>true</code> matching is <i>case sensitive</i>, otherwise matching is <i>case in-sensitive</i> */
public RegexValidator(String regex, boolean caseSensitive)
{
this(new String[] { regex }, caseSensitive);
}
/** Construct a validator that matches any one of the set of regular expressions with the specified case sensitivity.
*
* @param regexs
* The set of regular expressions this validator will validate against
* @param caseSensitive
* when <code>true</code> matching is <i>case sensitive</i>, otherwise matching is <i>case in-sensitive</i> */
public RegexValidator(String[] regexs, boolean caseSensitive)
{
if (regexs == null || regexs.length == 0)
{
throw new IllegalArgumentException("Regular expressions are missing");
}
patterns = new Pattern[regexs.length];
int flags = (caseSensitive ? 0 : Pattern.CASE_INSENSITIVE);
for (int i = 0; i < regexs.length; i++)
{
if (regexs[i] == null || regexs[i].length() == 0)
{
throw new IllegalArgumentException("Regular expression[" + i + "] is missing");
}
patterns[i] = Pattern.compile(regexs[i], flags);
}
}
/** Validate a value against the set of regular expressions returning the array of matched groups.
*
* @param value
* The value to validate.
* @return String array of the <i>groups</i> matched if valid or <code>null</code> if invalid */
public String[] match(String value)
{
if (value == null)
{
return null;
}
for (int i = 0; i < patterns.length; i++)
{
Matcher matcher = patterns[i].matcher(value);
if (matcher.matches())
{
int count = matcher.groupCount();
String[] groups = new String[count];
for (int j = 0; j < count; j++)
{
groups[j] = matcher.group(j + 1);
}
return groups;
}
}
return null;
}
/** Provide a String representation of this validator.
*
* @return A String representation of this validator */
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append("RegexValidator{");
for (int i = 0; i < patterns.length; i++)
{
if (i > 0)
{
buffer.append(",");
}
buffer.append(patterns[i].pattern());
}
buffer.append("}");
return buffer.toString();
}
}
}

View File

@@ -0,0 +1,116 @@
package com.lanternsoftware.util.hash;
import java.security.MessageDigest;
import com.lanternsoftware.util.NullUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lanternsoftware.util.CollectionUtils;
public abstract class AbstractHashTool {
private final Logger LOG = LoggerFactory.getLogger(getClass());
protected final MessageDigest digest;
protected final byte[] staticSalt;
protected final boolean prependSalt;
protected final int iterations;
public AbstractHashTool(String _algorithm, String _staticSalt, boolean _prependSalt, int _iterationCount) {
prependSalt = _prependSalt;
MessageDigest digestInstance = null;
try {
digestInstance = MessageDigest.getInstance(_algorithm);
}
catch (Exception e) {
LOG.error("Failed to create digest: " + _algorithm, e);
}
digest = digestInstance;
staticSalt = NullUtils.toByteArray(_staticSalt);
iterations = Math.max(1, _iterationCount);
}
/**
* @param _value a string value to hash using the static salt and algorithm of this hash tool
* @return the hex encoded hashed value
*/
public synchronized String hashHex(String _value) {
return hashHex(_value, null);
}
/**
* @param _value a string value to hash using the static salt and algorithm of this hash tool
* @param _salt a salt to use for this hash operation along with the static salt of this hash tool
* @return the hex encoded hashed value
*/
public synchronized String hashHex(String _value, String _salt) {
return new String(Hex.encodeHex(hash(_value, _salt)));
}
/**
* @param _value a string value to hash using the static salt and algorithm of this hash tool
* @return the base64 encoded hashed value
*/
public synchronized String hash64(String _value) {
return hash64(_value, null);
}
/**
* @param _value a string value to hash using the static salt and algorithm of this hash tool
* @param _salt a salt to use for this hash operation along with the static salt of this hash tool
* @return the base64 encoded hashed value
*/
public synchronized String hash64(String _value, String _salt) {
return new String(Base64.encodeBase64(hash(_value, _salt)));
}
/**
* @param _value a string value to hash using the static salt and algorithm of this hash tool
* @return the hashed value
*/
public synchronized byte[] hash(String _value) {
return hash(_value, null);
}
/**
* @param _value a string value to hash using the static salt and algorithm of this hash tool
* @param _salt a salt to use for this hash operation along with the static salt of this hash tool
* @return the hashed value
*/
public synchronized byte[] hash(String _value, String _salt) {
byte[] btValue = NullUtils.toByteArray(_value);
byte[] btSalt = NullUtils.toByteArray(_salt);
for (int i = 0; i < iterations; i++)
btValue = hash(salt(btValue, btSalt));
return btValue;
}
/**
* @param _value a byte array to hash using the static salt and algorithm of this hash tool
* @return the base64 encoded hashed value
*/
public synchronized String hash64(byte[] _value) {
return new String(Base64.encodeBase64(hash(_value)));
}
/**
* @param _value a byte array to hash using the static salt and algorithm of this hash tool
* @return the hashed value
*/
public synchronized byte[] hash(byte[] _value) {
return digest.digest(_value);
}
/**
* @param _value a byte array to hash using the static salt and algorithm of this hash tool
* @param _salt a salt to use for this hash operation along with the static salt of this hash tool
* @return the hashed value
*/
public synchronized byte[] salt(byte[] _value, byte[] _salt) {
if (prependSalt)
return CollectionUtils.merge(staticSalt, _salt, _value);
return CollectionUtils.merge(_value, staticSalt, _salt);
}
}

View File

@@ -0,0 +1,27 @@
package com.lanternsoftware.util.hash;
public class MD5HashTool extends AbstractHashTool {
/**
* Creates an MD5 hash tool with no static salt that performs only one hash iteration
*/
public MD5HashTool() {
this(null, 1);
}
/**
* Creates an MD5 hash tool with the specified static salt that performs only one hash iteration
* @param _salt the salt to attach each time a hash is performed with this tool
*/
public MD5HashTool(String _salt) {
this(_salt, 1);
}
/**
* Creates an MD5 hash tool with the specified static salt that performs the specified number of iterations each time a hash is performed
* @param _salt the salt to attach each time a hash is performed with this tool
* @param _iterations the number of times to hash values
*/
public MD5HashTool(String _salt, int _iterations) {
super("MD5", _salt, false, _iterations);
}
}

View File

@@ -0,0 +1,27 @@
package com.lanternsoftware.util.hash;
public class SHA1HashTool extends AbstractHashTool {
/**
* Creates an SHA-1 hash tool with no static salt that performs only one hash iteration
*/
public SHA1HashTool() {
this(null, 1);
}
/**
* Creates an SHA-1 hash tool with the specified static salt that performs only one hash iteration
* @param _salt the salt to attach each time a hash is performed with this tool
*/
public SHA1HashTool(String _salt) {
this(_salt, 1);
}
/**
* Creates an SHA-1 hash tool with the specified static salt that performs the specified number of iterations each time a hash is performed
* @param _salt the salt to attach each time a hash is performed with this tool
* @param _iterations the number of times to hash values
*/
public SHA1HashTool(String _salt, int _iterations) {
super("SHA-1", _salt, true, _iterations);
}
}

View File

@@ -0,0 +1,27 @@
package com.lanternsoftware.util.hash;
public class SHA512HashTool extends AbstractHashTool {
/**
* Creates an SHA-512 hash tool with no static salt that performs only one hash iteration
*/
public SHA512HashTool() {
this(null, 1);
}
/**
* Creates an SHA-512 hash tool with the specified static salt that performs only one hash iteration
* @param _salt the salt to attach each time a hash is performed with this tool
*/
public SHA512HashTool(String _salt) {
this(_salt, 1);
}
/**
* Creates an SHA-512 hash tool with the specified static salt that performs the specified number of iterations each time a hash is performed
* @param _salt the salt to attach each time a hash is performed with this tool
* @param _iterations the number of times to hash values
*/
public SHA512HashTool(String _salt, int _iterations) {
super("SHA-512", _salt, true, _iterations);
}
}

View File

@@ -0,0 +1,10 @@
package com.lanternsoftware.util.tracing;
import java.util.Date;
import java.util.List;
public interface ITracer {
void config(TracerConfig _config);
TraceDuration createDuration(TraceContext _parent, String _name, Date _start);
void trace(String _name, TraceDuration _duration, TraceTags _tags, List<TraceLog> _logs);
}

View File

@@ -0,0 +1,32 @@
package com.lanternsoftware.util.tracing;
import java.util.HashMap;
import java.util.Map;
import com.lanternsoftware.util.NullUtils;
public class TraceContext extends HashMap<String, String> {
public String serialize() {
StringBuilder s = null;
for (Map.Entry<String, String> e : entrySet()) {
if (s == null)
s = new StringBuilder();
else
s.append("~");
s.append(e.getKey());
s.append(".");
s.append(e.getValue());
}
return (s == null)?"":s.toString();
}
public static TraceContext deserialize(String _context) {
TraceContext context = new TraceContext();
for (String key : NullUtils.cleanSplit(_context, "~")) {
String[] parts = NullUtils.cleanSplit(key, "\\.");
if (parts.length == 2)
context.put(parts[0], parts[1]);
}
return context.isEmpty()?null:context;
}
}

View File

@@ -0,0 +1,39 @@
package com.lanternsoftware.util.tracing;
import java.util.Date;
public class TraceDuration {
private long start;
private long curStart;
private long duration = 0;
public TraceDuration(Date _start) {
start = curStart = _start.getTime();
}
public void start() {
curStart = new Date().getTime();
if (duration == 0)
start = curStart;
}
public void stop() {
duration += (new Date().getTime()-curStart);
}
public Date currentTimeOffset() {
return new Date(start + duration + (new Date().getTime()-curStart));
}
public long duration() {
return duration;
}
public long end() {
return start + duration;
}
public TraceContext getContext() {
return null;
}
}

View File

@@ -0,0 +1,8 @@
package com.lanternsoftware.util.tracing;
public enum TraceFrequencyType {
ALL,
PERCENTAGE,
MAX_TRACES_PER_SECOND,
REMOTE_CONTROLLED
}

View File

@@ -0,0 +1,21 @@
package com.lanternsoftware.util.tracing;
import java.util.Date;
public class TraceLog {
private final Date timeStamp;
private final String event;
public TraceLog(Date _timeStamp, String _event) {
timeStamp = _timeStamp;
event = _event;
}
public Date getTimeStamp() {
return timeStamp;
}
public String getEvent() {
return event;
}
}

View File

@@ -0,0 +1,5 @@
package com.lanternsoftware.util.tracing;
public interface TraceSpan {
void setTag(String _name, String _value);
}

View File

@@ -0,0 +1,16 @@
package com.lanternsoftware.util.tracing;
import java.util.HashMap;
public class TraceTags extends HashMap<String, String> {
public static TraceTags tag(String _name, String _value) {
TraceTags tags = new TraceTags();
tags.put(_name, _value);
return tags;
}
public TraceTags withTag(String _name, String _value) {
put(_name, _value);
return this;
}
}

View File

@@ -0,0 +1,77 @@
package com.lanternsoftware.util.tracing;
public class TracerConfig {
private final String appName;
private final String endpoint;
private final boolean suppressLocalLog;
private TraceFrequencyType frequencyType;
private double frequency;
private boolean useThreadContext = false;
public TracerConfig(String _appName, String _endpoint) {
this(_appName, _endpoint, true);
}
public TracerConfig(String _appName, String _endpoint, boolean _suppressLocalLog) {
appName = _appName;
endpoint = _endpoint;
suppressLocalLog = _suppressLocalLog;
frequencyType = TraceFrequencyType.ALL;
frequency = 0.0;
}
public TracerConfig withFrequency(TraceFrequencyType _type, double _frequency) {
frequencyType = _type;
frequency = _frequency;
return this;
}
public TracerConfig tracePercentage(double _percentage) {
return withFrequency(TraceFrequencyType.PERCENTAGE, _percentage);
}
public TracerConfig traceMaximumPerSecond(int _max) {
return withFrequency(TraceFrequencyType.MAX_TRACES_PER_SECOND, _max);
}
public TracerConfig traceRateControlledRemotely() {
return withFrequency(TraceFrequencyType.REMOTE_CONTROLLED, 0.0);
}
public TracerConfig traceAll() {
return withFrequency(TraceFrequencyType.ALL, 1.0);
}
public TracerConfig useThreadContext(boolean _useThreadContext) {
setUseThreadContext(_useThreadContext);
return this;
}
public String getAppName() {
return appName;
}
public String getEndpoint() {
return endpoint;
}
public boolean isSuppressLocalLog() {
return suppressLocalLog;
}
public TraceFrequencyType getFrequencyType() {
return frequencyType;
}
public double getFrequency() {
return frequency;
}
public boolean isUseThreadContext() {
return useThreadContext;
}
public void setUseThreadContext(boolean _useThreadContext) {
useThreadContext = _useThreadContext;
}
}

View File

@@ -0,0 +1,99 @@
package com.lanternsoftware.util.xml;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.lanternsoftware.util.CollectionUtils;
import com.lanternsoftware.util.NullUtils;
public class XmlNode
{
private String content;
private final Map<String, String> attributes = new HashMap<String, String>();
private final Map<String, List<XmlNode>> children = new HashMap<String, List<XmlNode>>();
public String getContent()
{
return content;
}
public void setContent(String _content)
{
content = _content;
}
public Map<String, String> getAttributes()
{
return attributes;
}
public Map<String, List<XmlNode>> getChildren()
{
return children;
}
public void addChild(String _name, XmlNode _node)
{
CollectionUtils.addToMultiMap(_name, _node, children);
}
public XmlNode getChild(List<String> _path)
{
if (CollectionUtils.isEmpty(_path))
return this;
XmlNode node = CollectionUtils.getFirst(children.get(CollectionUtils.getFirst(_path)));
if (node == null)
return null;
return node.getChild(_path.subList(1, _path.size()));
}
public List<XmlNode> getChildren(List<String> _path)
{
if (CollectionUtils.size(_path) == 1)
return CollectionUtils.makeNotNull(children.get(_path.get(0)));
List<XmlNode> nodes = new ArrayList<XmlNode>();
for (XmlNode node : CollectionUtils.makeNotNull(children.get(CollectionUtils.getFirst(_path))))
{
nodes.addAll(node.getChildren(_path.subList(1, _path.size())));
}
return nodes;
}
public XmlNode getChild(List<String> _path, String _attributeName, String _attributeValue)
{
for (XmlNode node : getChildren(_path))
{
if (NullUtils.isEqual(node.getAttributes().get(_attributeName), _attributeValue))
return node;
}
return null;
}
public String getChildContent(List<String> _path, String _attributeName, String _attributeValue)
{
XmlNode node = getChild(_path, _attributeName, _attributeValue);
if (node == null)
return null;
return node.getContent();
}
public String getChildAttribute(List<String> _path, String _attributeName)
{
XmlNode child = getChild(_path);
if (child == null)
return null;
return child.getAttributes().get(_attributeName);
}
public String getChildContent(List<String> _path)
{
XmlNode node = getChild(_path);
if (node == null)
return null;
return node.getContent();
}
}

View File

@@ -0,0 +1,83 @@
package com.lanternsoftware.util.xml;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Stack;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import com.lanternsoftware.util.NullUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class XmlParser {
protected static final Logger LOG = LoggerFactory.getLogger(XmlParser.class);
public static XmlNode loadXmlFile(String _filePath) {
FileInputStream is = null;
try {
is = new FileInputStream(_filePath);
return parseXml(is);
}
catch (Exception _e) {
LOG.error("Failed to load xml file", _e);
return null;
}
finally {
IOUtils.closeQuietly(is);
}
}
public static XmlNode parseXml(InputStream _is) {
XMLStreamReader reader = null;
try {
XmlNode node = null;
StringBuilder content = null;
Stack<XmlNode> stack = new Stack<XmlNode>();
reader = XMLInputFactory.newInstance().createXMLStreamReader(_is);
while (reader.hasNext()) {
switch (reader.next()) {
case XMLStreamConstants.START_ELEMENT: {
node = new XmlNode();
content = new StringBuilder();
for (int i = 0; i < reader.getAttributeCount(); i++) {
node.getAttributes().put(reader.getAttributeLocalName(i), reader.getAttributeValue(i));
}
stack.push(node);
break;
}
case XMLStreamConstants.CHARACTERS: {
content.append(NullUtils.makeNotNull(reader.getText()));
break;
}
case XMLStreamConstants.END_ELEMENT: {
node = stack.pop();
if (stack.empty())
return node;
stack.peek().addChild(reader.getLocalName(), node);
if (content != null)
node.setContent(content.toString().trim());
break;
}
}
}
}
catch (Exception _e) {
LOG.error("Failed to parse XML", _e);
}
finally {
try {
reader.close();
}
catch (XMLStreamException _e) {
LOG.error("Failed to close XML stream", _e);
}
IOUtils.closeQuietly(_is);
}
return null;
}
}