package helpers;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;
import javax.swing.filechooser.FileSystemView;
/**
* Global Helpers that are useful for everyone..
*
* @author Quicksilver
*
*/
public final class GH {
// private static final Random rand = new Random();
private static final ThreadLocal<Random> trand = new ThreadLocal<Random>() {
@Override
protected Random initialValue() {
return new Random();
}
};
private static final FileSystemView chooser = FileSystemView.getFileSystemView();
// http://wiki.eclipse.org/index.php/Equinox_Launcher#Startup.jar
// private static final boolean USE_FILE_SYSTEM_VIEW;
// static {
// boolean win = Platform.getOS().equals(Platform.OS_WIN32);
// USE_FILE_SYSTEM_VIEW = !win;
// }
/*
*
* @see java.util.Random#nextInt(int)
*/
public static int nextInt(int n) {
// synchronized(rand) {
return trand.get().nextInt(n);
// }
}
public static int nextInt() {
//synchronized(rand) {
return trand.get().nextInt();
//}
}
private GH() {}
/**
* provided for all the might use it..
* as creating costs memory that is never recovered..
* @return a FileSytemView instance..
*/
public static FileSystemView getFileSystemView() {
return chooser;
}
/**
* emulates behaviour of FileSystemView as good as possible...
* though its not the same..
* -> done as normal FileSystemView has a memory leak on that method..
*/
public static File[] getFiles(File parent,boolean useHidden) {
File[] files;
// if (USE_FILE_SYSTEM_VIEW) {
files = chooser.getFiles(parent, useHidden);
if (files == null) return new File[0];
return files;
// } else {
// files = parent.listFiles();
// if (files == null) return new File[0];
//
// if (useHidden) {
// int k = 0;
// for (int i = 0; i+k < files.length; i++) {
// while (i+k < files.length && files[i+k].isHidden()) {
// k++;
// }
// if (i+k < files.length) {
// files[i] = files[i+k];
// }
// }
//
// if (k != 0) {
// File[] onlyVisible = new File[files.length - k];
// System.arraycopy(files, 0, onlyVisible, 0, onlyVisible.length );
// return onlyVisible;
// }
// }
// return files;
// }
}
@SuppressWarnings("unchecked")
public static <K> K getRandomElement(Collection<K> source) {
if (source.isEmpty()) {
return null;
}
return (K)source.toArray()[nextInt(source.size())];
}
public static <K> K getRandomElement(List<K> source) {
if (source.isEmpty()) {
return null;
}
return source.get(nextInt(source.size()));
}
/**
* closes all provided streams ignoring exceptions
* @param closeable
*/
public static void close(Closeable... closeable) {
for (Closeable c: closeable) {
try {
if (c != null) {
c.close();
}
} catch (IOException e) {
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
public static void close(Socket s) {
try {
if (s != null) {
s.close();
}
} catch (IOException e) {
} catch (RuntimeException e) {
e.printStackTrace();
}
}
public static void copy(File source,File dest) throws IOException {
FileInputStream in = null;
FileChannel sourcec = null;
FileChannel destc = null;
FileOutputStream out = null;
try {
in = new FileInputStream(source);
sourcec = in.getChannel();
out = new FileOutputStream(dest);
destc = out.getChannel();
long left = source.length();
long position= 0;
long count;
while(-1 != (count = sourcec.transferTo(position, Math.min(left,1024*64) , destc))){
position += count;
left -= count;
if (left == 0) {
break;
}
}
destc.force(true);
} catch (IOException ioe) {
throw ioe;
} finally {
GH.close(destc,out,sourcec,in);
}
}
/**
*
* @return A List of All network interfaces that can be used to bind ipv4 sockets to...
* @throws SocketException if getting addresses from machine fails...
*/
public static List<NetworkInterface> getFilteredNIList() throws SocketException {
List<NetworkInterface> nic = new ArrayList<NetworkInterface>();
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while(e.hasMoreElements()) {
NetworkInterface ni = e.nextElement();
Enumeration<InetAddress> e2 = ni.getInetAddresses();
boolean use = false;
while (e2.hasMoreElements()) {
InetAddress ia = e2.nextElement();
if (!ia.isLoopbackAddress() && ia instanceof Inet4Address) {
use = true;
}
}
if (use) {
nic.add(ni);
}
}
return nic;
}
/**
* sleeps ignoring interruption handling..
*
* @param millis - how long to sleep
*/
public static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch(InterruptedException ie) {}
}
/**
* replaces invalid characters in Filenames
*/
public static String replaceInvalidFilename(String filename) {
for (char replace: new char[]{'\\','/','*','?','<','>','|'}) {
filename = filename.replace(replace,'.');
}
filename = filename.replace('\"', '\'');
filename = filename.replace(':', '-');
for (int i = 0; i < filename.length();i++) {
if (filename.charAt(i) < 20) {
filename = filename.substring(0, i)+filename.substring(i+1);
}
}
return filename;
}
/**
* replaces invalid filepath
*/
public static String replaceInvalidFilpath(String filename) {
filename = filename.replace(File.separator.equals("\\")?'/': '\\', '.');
for (char replace: new char[]{'*','?','<','>','|'}) {
filename = filename.replace(replace,'.');
}
filename = filename.replace('\"', '\'');
filename = filename.replace(':', '-');
return filename;
}
/**
*
* @param filename name of the file
* @return ending without the . hello.pdf -> pdf
* empty String if none determined..
*/
public static String getFileEnding(String filename) {
int i= filename.lastIndexOf('.');
if(i != -1) {
return filename.substring(i+1);
} else {
return "";
}
}
/**
* replaces newline characters with \n
* and \ with \\
*
* so it does basic escaping
*
* @param s
* @return
*/
public static String replaces(String s) {
s = s.replace("\\", "\\\\");
s = s.replace("\n", "\\n");
return s;
}
/**
* reverses replacements of replace function
*/
public static String revReplace(String s) {
int i = 0;
while ((i = s.indexOf('\\',i)) != -1) {
if (s.length() > i+1) {
char c = s.charAt(i+1);
if (c == '\\') {
s = s.substring(0, i)+"\\"+s.substring(i+2) ;
} else if (c == 'n') {
s = s.substring(0, i)+"\n"+s.substring(i+2);
}
}
i++;
}
return s;
}
public static boolean isLocaladdress(InetAddress ia) {
return ia.isLoopbackAddress()|| ia.isSiteLocalAddress();
}
/* public static String getStacktrace(Thread t) {
String s = t.getName();
for (StackTraceElement ste:t.getStackTrace()) {
s += "\n"+ste.getFileName()+" Line:"+ste.getLineNumber()+" "+ste.getMethodName();
}
return s;
} */
public static boolean isEmpty(String s) {
return s.length() == 0;
}
public static boolean isNullOrEmpty(String s) {
return s == null || s.length() == 0;
}
/**
*
*help for debugging.. concatenates all .toString() calls in some list fashioned
*way
*/
public static String toString(Object[] arr) {
if (arr == null) {
return "null";
}
return "{"+GH.concat(Arrays.asList(arr), ",", "empty")+"}";
}
/**
*
* @param toFilter what Objects should be filtered..
* @param mayNotContain - tested against o.toString()
* @return all which toString() method did not contain mayNoContain
*/
public static <K> List<K> filter(List<K> toFilter,String... mayNotContain) {
ArrayList<K> s = new ArrayList<K>();
for (K old:toFilter) {
boolean putIn = true;
for (String test:mayNotContain) {
putIn = putIn && !old.toString().contains(test);
}
if (putIn) {
s.add(old);
}
}
return s;
}
public static <K> void sort(List<K> toSort,final String... sortUpIfContains) {
Collections.sort(toSort, new Comparator<K>() {
public int compare(K o1, K o2) {
int k1 = 0,k2 = 0;
for (int i = 0; i < sortUpIfContains.length ; i++) {
if (o1.toString().contains(sortUpIfContains[i])) {
k1+= sortUpIfContains.length-i ;
}
if (o2.toString().contains(sortUpIfContains[i])) {
k2+= sortUpIfContains.length-i;
}
}
return -compareTo(k1, k2);
}
});
}
public static byte[] concatenate(byte[]... arrays) {
int totalsize= 0;
for (byte[] array: arrays) {
totalsize += array.length;
}
byte[] all = new byte[totalsize];
int currentpos = 0;
for (byte[] array: arrays) {
System.arraycopy(array, 0, all, currentpos, array.length);
currentpos += array.length;
}
return all;
}
public static int compareTo(int a , int b) {
return (a < b ? -1 : (a==b ? 0 : 1));
}
public static int compareTo(long a , long b) {
return (a<b ? -1 : (a==b ? 0 : 1));
}
public static int compareTo(byte a , byte b) {
return (a < b ? -1 : (a==b ? 0 : 1));
}
public static int unsingedCompareTo(byte a,byte b) {
return compareTo(a & 0xff , b & 0xff);
}
/**
*
* same as concat with empty string for an empty iterable
*/
public static String concat(Iterable<?> terms,String between) {
return concat(terms,between,"");
}
/**
* concatenates each term in collection using .toString()
* and puts between each string "between"
*
* if the map is empty it will return the empty map string instead...
*
*/
public static String concat(Iterable<?> terms,String between,String emptyMap) {
StringBuilder ret = new StringBuilder();
for (Object o: terms) {
if (ret.length() != 0) {
ret.append(between);
}
ret.append(o.toString());
}
if (ret.length() == 0) {
return emptyMap;
} else {
return ret.toString();
}
}
public static String concat(Object[] terms,String between,String emptyMap) {
return concat(Arrays.asList(terms), between, emptyMap);
}
public static String coalesce(String... s) {
for (String sp:s) {
if (sp != null) {
return sp;
}
}
return "";
}
/**
*
* @return a string representing all stacktraces..
*/
public static String getAllStackTraces() {
ThreadMXBean threadBean =
ManagementFactory.getThreadMXBean();
String newLine = System.getProperty("line.separator");
String s = "";
for (Entry<Thread,StackTraceElement[]> e :Thread.getAllStackTraces().entrySet()) {
s += newLine+newLine;
Thread d = e.getKey();
ThreadInfo ti = threadBean.getThreadInfo(d.getId());
s += String.format("%s , state: %s ,id: %s",d.toString(),d.getState().toString(),d.getId())+newLine;
String lock= ti.getLockName();
if (lock != null) {
s += String.format("Lock: %s, Count: %s,Time: %s, Owner: %s ",
lock,ti.getBlockedCount(),ti.getBlockedTime(),ti.getLockOwnerId());
s += newLine;
}
s += concat(Arrays.asList(e.getValue()),newLine,"empty");
}
return s+newLine;
}
/**
*
* @param s the string to search
* @param what what char to be searched
* @return the number of occurences of what in s
*/
public static int getOccurences(String s , char what) {
int count = 0,pos = 0;
while (-1 != (pos = s.indexOf(what, pos))) {
count++;
pos++;
}
return count;
}
/**
*
* @param input
* @param start
* @param length
* @return array of size length containing all bytes from start
*/
public static byte[] subarray(byte[] input,int start,int length) {
byte[] ret = new byte[length];
System.arraycopy(input, start, ret, 0, length);
return ret;
}
/**
* tries to give a measure of distance ...
* the higher the distance the further the strings are away from each other..
*
* @param a
* @param b
* @return
*/
public static int distance(String a, String b) {
int lengthDist = Math.abs(a.length()-b.length());
int dist = 0;
int lastHit = 0;
for (int i=0; i < a.length();i++) {
int posB = b.indexOf(a.charAt(i));
if (posB != -1) {
boolean fullHit = b.length() > lastHit+1 && b.charAt(lastHit+1) == a.charAt(i);
if (fullHit) {
lastHit = lastHit+1;
dist-=1;
} else {
lastHit = posB; //dist+= 0; -> no distance change here..
}
} else {
dist++;
}
}
return lengthDist+dist;
}
private static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw ) {
final StringBuilder hex = new StringBuilder( 2 * raw.length );
for ( final byte b : raw ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
/**
* creates hash with provided algorithm..
* throwing illegalStateException if unsuccessful
*
* @param tohash bytes to hash
* @param alg what algorithm to use
* @return the digest output
*/
public static byte[] getHash(byte[] tohash,String alg) {
MessageDigest md;
try {
md = MessageDigest.getInstance( alg );
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException(e);
}
byte[] raw = md.digest(tohash);
return raw;
}
/**
* increments the mapped counter
* @param <K> - any value..
* @param mappedCounter -
* @param k - against what this counter is mapped. if not found counter is create with value 0
* @param increment - value to increment by
*/
public static <K> void incrementMappedCounter(Map<K,Integer> mappedCounters,K k, int increment) {
int i = getValueOfMappedCounter(mappedCounters,k);
i += increment;
mappedCounters.put(k, i);
}
public static <K> int getValueOfMappedCounter(Map<K,Integer> mappedCounters,K k) {
Integer i = mappedCounters.get(k);
if (i == null) {
i = 0;
}
return i;
}
/**
* switches the provided chars against each other in the provided string
*
*/
public static String switchChars(String in,char a,char b) {
StringBuilder sb = new StringBuilder(in);
int axorb = a^b; //yeah we do it the clever way sorry KISS ...
for (int i=0 ; i < sb.length(); i++) {
int c = sb.charAt(i);
if (c == a || c == b) {
sb.setCharAt(i, (char)(c ^ axorb));
}
}
return sb.toString();
}
public static void copy(InputStream in,OutputStream out) throws IOException {
byte[] b = new byte[4096];
int read;
while (-1 != (read = in.read(b, 0, b.length))) {
out.write(b, 0, read);
}
}
public static int[] toArray(List<Integer> ints) {
int[] intar = new int[ints.size()];
for (int i = 0 ; i < intar.length; i++) {
intar[i] = ints.get(i);
}
return intar;
}
public static List<Integer> fromArray(int[] ints) {
List<Integer> intList = new ArrayList<Integer>(ints.length);
for (int i : ints) {
intList.add(i);
}
return intList;
}
public static BitSet toSet(byte[] bytes) {
int ammountBits = bytes.length * 8;
BitSet bits = new BitSet(ammountBits);
for (int i = 0; i < ammountBits; i++) {
bits.set(i, getBit(bytes, i));
}
return bits;
}
public static boolean getBit(byte[] source,int position) {
byte b = source[position /8];
int bitpos = 1 << (position % 8);
return (bitpos & b) != 0;
}
public static byte[] toBytes(BitSet bits,int ammountBits) {
byte[] bytes = new byte[ammountBits/8 ];
for (int i = 0; i < bytes.length; i++) {
int num = 0;
for (int j=0; j < 8; j++ ) {
if (bits.get(i*8+j)) {
num += 1 << j;
}
}
bytes[i] = (byte)num;
}
return bytes;
}
public static byte[] toBytes(BitSet bits) {
int ammountBits = bits.length() ;
return toBytes(bits, ammountBits + (ammountBits%8 == 0 ?0:1));
}
public static boolean containsIgnoreCase(String s,String contains) {
return s.toLowerCase().contains(contains.toLowerCase());
}
public static double parseDoubleSecure(String s) {
if (isNullOrEmpty(s)) {
return 0;
} else if (s.contains("2.2250738585072012e-308")) { // bug circumvention in java
return 0;
} else {
return Double.parseDouble(s);
}
}
}