All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xdev.jadoth.Jadoth Maven / Gradle / Ivy

/*
 * XDEV Application Framework - XDEV Application Framework
 * Copyright © 2003 XDEV Software (https://xdev.software)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 */
package com.xdev.jadoth;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
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.Random;
import java.util.RandomAccess;

import com.xdev.jadoth.collections.GrowList;
import com.xdev.jadoth.collections.Snake;
import com.xdev.jadoth.collections.XList;
import com.xdev.jadoth.criteria.AllCriteria;
import com.xdev.jadoth.criteria.AnyCriteria;
import com.xdev.jadoth.criteria.Criterion;
import com.xdev.jadoth.criteria.NotCriterion;
import com.xdev.jadoth.lang.ComparatorSequence;
import com.xdev.jadoth.lang.Equalator;
import com.xdev.jadoth.lang.EqualatorSequence;
import com.xdev.jadoth.lang.functional.Condition;
import com.xdev.jadoth.lang.functional.Predicate;
import com.xdev.jadoth.lang.functional.TCondition;
import com.xdev.jadoth.lang.functional.controlflow.TPredicate;
import com.xdev.jadoth.lang.functional.iterables.ArrayIterable;
import com.xdev.jadoth.lang.functional.iterables.ChainedArraysIterable;
import com.xdev.jadoth.lang.functional.iterables.ChainedIterables;
import com.xdev.jadoth.lang.reference.LinkReference;
import com.xdev.jadoth.lang.reference.Reference;
import com.xdev.jadoth.lang.reference._booleanReference;
import com.xdev.jadoth.lang.reference._byteReference;
import com.xdev.jadoth.lang.reference._charReference;
import com.xdev.jadoth.lang.reference._doubleReference;
import com.xdev.jadoth.lang.reference._floatReference;
import com.xdev.jadoth.lang.reference._intReference;
import com.xdev.jadoth.lang.reference._longReference;
import com.xdev.jadoth.lang.reference._shortReference;
import com.xdev.jadoth.lang.signalthrows.BranchingThrow;
import com.xdev.jadoth.lang.signalthrows.ThrowBreak;
import com.xdev.jadoth.lang.signalthrows.ThrowContinue;
import com.xdev.jadoth.lang.signalthrows.ThrowReturn;
import com.xdev.jadoth.math.JaMath;
import com.xdev.jadoth.util.KeyValue;
import com.xdev.jadoth.util.Pair;
import com.xdev.jadoth.util.file.FileException;
import com.xdev.jadoth.util.file.FolderException;



/**
 * This is a central framework util class containing all the framework's util methods. This approach is made to sustain
 * ease of use in distinction to the countless ambiguous "package.path.util.Util" classes of various other frameworks.
 */
public abstract class Jadoth
{
	  ////////////////
	 // File Utils //
	////////////////

  	/**
	 * Ensure writable file.
	 *
	 * @param parent the parent
	 * @param filename the filename
	 * @return the file
	 */
	public static final File ensureWritableFile(final File parent, final String filename) throws FileException
	{
		return ensureWriteableFile(new File(parent, filename));
	}

	/**
	 * Ensure folder.
	 *
	 * @param folder the f
	 * @return the file
	 */
	public static final File ensureFolder(final File folder) throws FolderException
	{
		boolean success = false;

		try {
			if(folder.exists()) {
				return folder;
			}
			success = folder.mkdirs();
		}
		catch (final Exception e) {
			throw new FolderException(e);
		}
		if(!success){
			throw new FolderException("Folder "+folder+" could not have been created.");
		}

		return folder;
	}

	/**
	 * Ensure writeable file.
	 *
	 * @param file the f
	 * @return the file
	 * @throws FileException if no writability of file could not have been ensured.
	 */
	public static final File ensureWriteableFile(final File file) throws FileException
	{
		try {
			file.createNewFile();
		}
		catch (final Exception e) {
			throw new FileException(e);
		}

		if(!file.canWrite()){
			throw new FileException("Unwritable file: "+file);
		}

		return file;
	}

	/**
	 * Package string to folder path string.
	 *
	 * @param packageString the package string
	 * @return the string
	 */
	public static String packageStringToFolderPathString(final String packageString) {
		return ensureCharAtEnd(packageString.replaceAll("\\.", "/"), '/');
	}

	public static final Appendable appendTextFromFile(final Appendable app, final File file) throws IOException
	{
		final BufferedReader reader = new BufferedReader(new FileReader(file));
		String line = null;

		boolean notEmpty = false;
		try {
			while((line = reader.readLine()) != null) {
				if(notEmpty) app.append('\n'); else notEmpty = true;
				app.append(line);
			}
		}
		finally {
			reader.close();
		}

		return app;
	}

	public static final String readTextFromFile(final File file) throws IOException
	{
		//initialize StringBuilder generously as io accessing etc takes already quite some time in comparison
		return appendTextFromFile(new StringBuilder(50*1024), file).toString();
	}




	public static final  Snake snake()
	{
		return new Snake.Implementation();
	}
	public static final  Snake snake(final E value)
	{
		return new Snake.Implementation(value);
	}
	public static final  Snake snake(final E... values)
	{
		Snake snake = new Snake.Implementation();
		for(final E e : values){
			snake = snake.add(e);
		}
		return snake;
	}


	  //////////////////
	 // String Utils //
	//////////////////

	/**
  	 * Creates the medial capitals string.
  	 *
  	 * @param elements the elements
  	 * @return the string
  	 */
  	public static String createMedialCapitalsString(final String... elements){
		if(elements == null){
			return null;
		}
		if(elements.length == 0){
			return "";
		}
		if(elements.length == 1){
			return elements[0];
		}

		final StringBuilder sb = new StringBuilder(512); //should normally be sufficient for most identifiers
		sb.append(elements[0]);

		for(int i = 1; i < elements.length; i++) {
			final String element = elements[i];
			if(element == null || element.length() == 0) continue;

			final char firstLetter = element.charAt(0);
			if(Character.isUpperCase(firstLetter)){
				//nothing to "camelize"
				sb.append(element).toString();
				continue;
			}

			sb.append(Character.toUpperCase(firstLetter)).append(element.substring(1));
		}
		return sb.toString();
	}
	/**
	 * Explode.
	 *
	 * @param array the array
	 * @param seperator the seperator
	 * @return the string
	 */
	public static final String explode(final Object[] array, final String seperator)
	{
		if(array == null || seperator == null) return null;

		Object o = array[0];
		if(array.length == 1) {
			return o == null ?null :o.toString();
		}

		final StringBuilder explodedString = new StringBuilder(array.length*64)
			.append(o==null?null:o.toString());

		for(int i = 1; i < array.length; i++) {
			o = array[i];
			explodedString.append(seperator).append(o==null?null:o.toString());
		}
		return explodedString.toString();
	}
	/**
	 * Ensure char at start and end.
	 *
	 * @param sb the sb
	 * @param s the s
	 * @param startChar the start char
	 * @param endChar the end char
	 * @return the string builder
	 */
	public static final StringBuilder ensureCharAtStartAndEnd(
		StringBuilder sb,
		final String s,
		final char startChar,
		final char endChar
	)
	{
		final int length = s.length();
		final boolean startOk = s.charAt(0) == endChar;
		final boolean endOk = s.charAt(length-1) == endChar;
		if(sb == null) {
			sb = new StringBuilder(length+2);
		}
		if(!startOk) {
			sb.append(startChar);
		}
		sb.append(s);
		if(!endOk) {
			sb.append(endChar);
		}
		return sb;
	}
	/**
	 * Ensure char at start and end.
	 *
	 * @param s the s
	 * @param startChar the start char
	 * @param endChar the end char
	 * @return the string
	 */
	public static final String ensureCharAtStartAndEnd(
		final String s,
		final char startChar,
		final char endChar
	)
	{
		final int length = s.length();
		final boolean startOk = s.charAt(0) == endChar;
		final boolean endOk = s.charAt(length-1) == endChar;
		if(startOk && endOk) return s;

		final StringBuilder sb = new StringBuilder(length+2);
		if(!startOk) {
			sb.append(startChar);
		}
		sb.append(s);
		if(!endOk) {
			sb.append(endChar);
		}
		return sb.toString();
	}
	/**
	 * Ensure char at end.
	 *
	 * @param s the s
	 * @param c the c
	 * @return the string
	 */
	public static final String ensureCharAtEnd(final String s, final char c)
	{
		if(s.charAt(s.length()-1) == c) {
			return s;
		}
		return s + c;
	}

	public static final boolean isEmpty(final String s)
	{
		return s == null || s.length() == 0;
	}

	/**
	 * To single line.
	 *
	 * @param multiLineString the s
	 * @param lineBreakReplacement the replacement
	 * @return the string
	 */
	public static final String toSingleLine(final String multiLineString, final String lineBreakReplacement)
	{
		return multiLineString.replaceAll("((\\r)?\\n)+", lineBreakReplacement);
	}


	public static final String padSpace(final String s, final int chars)
	{
		final StringBuilder sb = new StringBuilder(chars).append(s);
		for(int i = s.length(); i < chars; i++){
			sb.append(' ');
		}
		return sb.toString();
	}


	/**
	 * Glue.
	 *
	 * @param parts the parts
	 * @return the string
	 */
	public static final String glue(final Object... parts) {
		return concat(' ', parts);
	}

	/**
	 * String list.
	 *
	 * @param parts the parts
	 * @return the string
	 */
	public static final String commaList(final Object... parts) {
		return concat(',', parts);
	}

	public static final String concat(final char concatenator, final Object... parts)
	{
		if(parts == null) return null;

		final StringBuilder sb = new StringBuilder(128);
		final int lastIndex = parts.length-1;
		for (int i = 0; i <= lastIndex ; i++) {
			if(parts[i] == null) {
				continue;
			}
			if(sb.length() > 0) {
				sb.append(concatenator);
			}
			sb.append(parts[i]);
		}
		return sb.toString();
	}

	/**
	 * Concat.
	 *
	 * @param concatenator the concatenator
	 * @param parts the parts
	 * @return the string
	 */
	public static final String concat(final String concatenator, final Object... parts)
	{
		if(parts == null) return null;

		final StringBuilder sb = new StringBuilder(128);
		final int lastIndex = parts.length-1;
		for (int i = 0; i <= lastIndex ; i++) {
			if(parts[i] == null) {
				continue;
			}
			if(sb.length() > 0) {
				sb.append(concatenator);
			}
			sb.append(parts[i]);
		}
		return sb.toString();
	}

	public static final StringBuilder stringBuilder(final Object... elements)
	{
		return appendArray(new StringBuilder(1024), elements);
	}
	public static final StringBuilder stringBuilderSeperated(final char elementSeperator, final Object... elements)
	{
		return appendArraySeperated(new StringBuilder(1024), elementSeperator, elements);
	}
	public static final StringBuilder stringBuilderSeperated(final String elementSeperator, final Object... elements)
	{
		return appendArraySeperated(new StringBuilder(1024), elementSeperator, elements);
	}

	public static final StringBuilder appendArray(final StringBuilder sb, final Object... elements)
	{
		if(elements == null) return sb;

		for(final Object e : elements){
			sb.append(e);
		}
		return sb;
	}
	public static final StringBuilder appendArraySeperated(
		final StringBuilder sb, final char elementSeperator, final Object... elements
	)
	{
		if(elements == null) return sb;

		boolean notFirst = false;
		for(final Object e : elements){
			if(notFirst)
				sb.append(elementSeperator);
			else
				notFirst = true;
			sb.append(e);
		}
		return sb;
	}
	public static final StringBuilder appendArraySeperated(
		final StringBuilder sb, final String elementSeperator, final Object... elements
	)
	{
		if(elementSeperator == null) return appendArray(sb, elements);
		if(elements == null) return sb;

		boolean notFirst = false;
		for(final Object e : elements){
			if(notFirst)
				sb.append(elementSeperator);
			else
				notFirst = true;
			sb.append(e);
		}
		return sb;
	}

//	/**
//	 * Adds the array.
//	 *
//	 * @param sb the sb
//	 * @param array the array
//	 * @param seperator the seperator
//	 * @return the string builder
//	 */
//	public static final StringBuilder addArray(StringBuilder sb, final Object[] array, final String seperator) {
//		if(sb == null) {
//			sb = new StringBuilder(512);
//		}
//		final boolean sep = seperator != null;
//		if(array != null) {
//			for (int i = 0 ; i < array.length; i++) {
//				if(sep && i > 0) {
//					sb.append(seperator);
//				}
//				sb.append(array[i]);
//			}
//		}
//		return sb;
//	}
//	/**
//	 * Adds the array.
//	 *
//	 * @param sb the sb
//	 * @param array the array
//	 * @return the string builder
//	 */
//	public static final StringBuilder addArray(final StringBuilder sb, final Object[] array) {
//		return addArray(sb, array, null);
//	}
//	/**
//	 * Adds the listed array.
//	 *
//	 * @param sb the sb
//	 * @param array the array
//	 * @return the string builder
//	 */
//	public static final StringBuilder addListedArray(final StringBuilder sb, final Object[] array) {
//		return addArray(sb, array, ",");
//	}






	public static final StringBuilder appendIterable(final StringBuilder sb, final Iterable iterable)
	{
		for(final Object e : iterable){
			sb.append(e);
		}
		return sb;
	}
	public static final StringBuilder appendIterableSeperated(
		final StringBuilder sb, final char elementSeperator, final Iterable iterable
	)
	{
		boolean notFirst = false;
		for(final Object e : iterable){
			if(notFirst)
				sb.append(elementSeperator);
			else
				notFirst = true;
			sb.append(e);
		}
		return sb;
	}
	public static final StringBuilder appendIterableSeperated(
		final StringBuilder sb, final String elementSeperator, final Iterable iterable
	)
	{
		if(elementSeperator == null) return appendArray(sb, iterable);

		boolean notFirst = false;
		for(final Object e : iterable){
			if(notFirst)
				sb.append(elementSeperator);
			else
				notFirst = true;
			sb.append(e);
		}
		return sb;
	}



	  //////////////////////
	 //   Thread Utils   //
	//////////////////////

	public static final Thread start(final Runnable r)
	{
		final Thread t = new Thread(r);
		t.start();
		return t;
	}



	  //////////////////////
	 // Collection Utils //
	//////////////////////

	/**
	 * Reduces collection by all elements that meet reductionPredicate.
* Note that NO new collection instance is created but the collection itself is reduced. * * @param * @param collection the collection to be reduced * @param reductionPredicate the predicate determining which elements shall be removed * @return collection itself */ public static , T> C reduce(final C collection, final Predicate reductionPredicate) { for(final T t : collection) { if(reductionPredicate.apply(t)){ collection.remove(t); } } return collection; } public static void reduce(final Iterator iterator, final Predicate reductionPredicate) { while(iterator.hasNext()){ if(reductionPredicate.apply(iterator.next())){ iterator.remove(); } } } public static ArrayList reduce(final ArrayList arrayList, final Predicate reductionPredicate) { for(int i = 0, size = arrayList.size(); i< size; i++){ final T element = arrayList.get(i); if(reductionPredicate.apply(element)){ arrayList.remove(element); } } return arrayList; } public static , T> C filter( final C sourceCollection, final Predicate selectionPredicate, final C targetCollection ) { for(final T t : sourceCollection) { if(selectionPredicate.apply(t)){ targetCollection.add(t); } } return targetCollection; } public static & RandomAccess> L filter( final L list, final Predicate selectionPredicate, final L targetList ) { for(int i = 0, size = list.size(); i< size; i++){ final T element = list.get(i); if(selectionPredicate.apply(element)){ targetList.add(element); } } return targetList; } @SuppressWarnings("unchecked") public static T[] filter(final T[] array, final Predicate selectionPredicate) { final ArrayList tempList = new ArrayList(array.length); for(final T t : array) { if(selectionPredicate.apply(t)){ tempList.add(t); } } return tempList.toArray((T[])Array.newInstance(array.getClass().getComponentType(), tempList.size())); } public static GrowList filter(final GrowList GrowList, final Predicate selectionPredicate) { final GrowList newList = new GrowList(GrowList.size()); for(int i = 0, size = GrowList.size(); i< size; i++){ final T element = GrowList.get(i); if(selectionPredicate.apply(element)){ newList.add(element); } } return newList; } public static ArrayList filter(final ArrayList arrayList, final Predicate selectionPredicate) { final ArrayList newList = new ArrayList(arrayList.size()); for(int i = 0, size = arrayList.size(); i< size; i++){ final T element = arrayList.get(i); if(selectionPredicate.apply(element)){ newList.add(element); } } return newList; } public static , T> C append( final C collectionToEnhance, final Predicate selectionPredicate, final Iterable collectionToAppend ) { for(final T t : collectionToAppend) { if(selectionPredicate.apply(t)){ collectionToEnhance.add(t); } } return collectionToEnhance; } public static , T> C append( final C collectionToEnhance, final Predicate selectionPredicate, final Iterator iterator ) { while(iterator.hasNext()) { final T element = iterator.next(); if(selectionPredicate.apply(element)){ collectionToEnhance.add(element); } } return collectionToEnhance; } public static , T> C append( final C collectionToEnhance, final Predicate selectionPredicate, final T[] arrayToAppend ) { for(final T t : arrayToAppend) { if(selectionPredicate.apply(t)){ collectionToEnhance.add(t); } } return collectionToEnhance; } public static final boolean applies(final Iterable elements, final Predicate predicate) { for(final T t : elements) { if(predicate.apply(t)) return true; } return false; } public static final & RandomAccess> boolean applies( final L list, final Predicate predicate ) { for(int i = 0, size = list.size(); i< size; i++){ if(predicate.apply(list.get(i))) return true; } return false; } public static final boolean applies(final T[] array, final Predicate predicate) { for(final T t : array) { if(predicate.apply(t)) return true; } return false; } public static final T search(final Iterable elements, final Predicate predicate) { for(final T t : elements) { if(predicate.apply(t)) return t; } return null; } public static final & RandomAccess> T search( final L list, final Predicate predicate ) { for(int i = 0, size = list.size(); i< size; i++){ final T element = list.get(i); if(predicate.apply(element)) return element; } return null; } public static final T search(final T[] array, final Predicate predicate) { for(final T t : array) { if(predicate.apply(t)) return t; } return null; } public static final int count(final Iterable collection, final Predicate predicate) { int count = 0; for(final T t : collection) { if(predicate.apply(t)) count++; } return count; } public static final & RandomAccess> int count( final L list, final Predicate predicate ) { int count = 0; for(int i = 0, size = list.size(); i< size; i++){ final T element = list.get(i); if(predicate.apply(element)) count++; } return count; } public static final int count(final T[] array, final Predicate predicate) { int count = 0; for(final T t : array) { if(predicate.apply(t)) count++; } return count; } public static, S extends Map> T mergeInto( final T target, final S... maps ) { for(final S map : maps) { target.putAll(map); } return target; } /** * * @param * @param initialCapacity * @param elements * @return */ public static final ArrayList ArrayList(final T... elements) { if(elements == null || elements.length == 0){ return new ArrayList(); } return addArray(new ArrayList(elements.length), elements); } public static final GrowList GrowList(final T... elements) { if(elements == null || elements.length == 0){ return new GrowList(); } return new GrowList(elements.length).add(elements); } public static final XList JaList(final List list) { return new GrowList(list); } public static final ArrayList ArrayList(final int initialCapacity, final Iterable elements) { return addBatch(new ArrayList(initialCapacity), elements); } public static final LinkedList LinkedList(final T...elements) { return addArray(new LinkedList(), elements); } // public static final StreamList StreamList(final T...elements) // { // return new StreamList().addArray(elements); // } /** * Populate collection. * * @param the generic type * @param c the c * @param elements the elements * @return the collection */ public static final , T> C addArray(final C c, final T... elements) { if(elements != null) { for(final T t : elements){ c.add(t); } } return c; } public static final , T> C addBatch(final C c, final Iterable elements) { if(elements != null) { for(final T t : elements){ c.add(t); } } return c; } @SuppressWarnings("unchecked") public static final T[] newArray(final Class componenType, final int length) { return (T[])Array.newInstance(componenType, length); } @SuppressWarnings("unchecked") public static final T[] replicate(final T element, final int amount) throws NullPointerException { if(element == null) throw new NullPointerException("element may not be null"); if(amount < 0) throw new IllegalArgumentException("amount may not be negative: "+amount); final T[] replicates = (T[])Array.newInstance(element.getClass(), amount); for(int i = 0; i < replicates.length; i++) { replicates[i] = element; } return replicates; } /** * List. * * @param elements the elements * @return the boolean[] */ public static boolean[] booleans(final boolean... elements){ return elements; } /** * List. * * @param elements the elements * @return the byte[] */ public static byte[] bytes(final byte... elements){ return elements; } /** * List. * * @param elements the elements * @return the short[] */ public static short[] shorts(final short... elements){ return elements; } /** * List. * * @param elements the elements * @return the int[] */ public static int[] ints(final int... elements){ return elements; } /** * List. * * @param elements the elements * @return the long[] */ public static long[] longs(final long... elements){ return elements; } /** * List. * * @param elements the elements * @return the float[] */ public static float[] floats(final float... elements){ return elements; } /** * List. * * @param elements the elements * @return the double[] */ public static double[] doubles(final double... elements){ return elements; } /** * List. * * @param elements the elements * @return the char[] */ public static char[] chars(final char... elements){ return elements; } /** * List. * * @param the generic type * @param elements the elements * @return the t[] */ public static T[] array(final T... elements){ return elements; } /** * List. * * @param the generic type * @param elements the elements * @return the t[] */ public static GrowList list(final T... elements) { if(elements == null || elements.length == 0){ return new GrowList(); } return new GrowList(elements.length).add(elements); } public static HashSet set(final T... elements) { if(elements == null || elements.length == 0) return new HashSet(); return addArray(new HashSet(elements.length), elements); } public static HashMap map(final KeyValue... keyValueTuples) { if(keyValueTuples == null || keyValueTuples.length == 0) return new HashMap(); final HashMap map = new HashMap(keyValueTuples.length); for(final KeyValue kv : keyValueTuples){ map.put(kv.key(), kv.value()); } return map; } // public static HashMap map(final KeyValueTuple... keyValueTuples) // { // if(keyValueTuples == null || keyValueTuples.length == 0) return new HashMap(); // final HashMap map = new HashMap(keyValueTuples.length); // // for(final KeyValueTuple kv : keyValueTuples){ // map.put(kv.key(), kv.value()); // } // // return map; // } /** * Alias for the annoying collection.toArray((T[])Array.newInstance(elementType, collection.size())) * * @param the element type parameter of the list * @param collection the collection whose elements shall be copied to an array * @param elementType the type of the elements contained in collection. * @return a new array object of type containing all elements of collection. */ @SuppressWarnings("unchecked") public static final T[] toArray(final Collection collection, final Class elementType) { return collection.toArray((T[])Array.newInstance(elementType, collection.size())); } @SuppressWarnings("unchecked") public static final T[] toArray(final Iterable iterable, final Class elementType) { final ArrayList list = ArrayList(1024, iterable); return list.toArray((T[])Array.newInstance(elementType, list.size())); } public static Iterable iterate(final Iterable... iterables) { return new ChainedIterables(iterables); } public static Iterable iterate(final T[]... arrays) { return new ChainedArraysIterable(arrays); } /** * Wraps array of type T[] in an instance of Iterable * * @param the type of array's elements and of the created Iterable * @param array the array to be wrapped * @return the Iterable wrapping T[] array. */ public static Iterable iterate(final T[] array) { return new ArrayIterable(array); } /////////////////////////////////////////////////////////////////////////// // Language Utils // ///////////////////// public static final T notNull(final T object) { if(object == null){ throw new NullPointerException(); } return object; } /** * Coalesce. * * @param the generic type * @param firstElement the first element * @param secondElement the second element * @return the t */ public static final T coalesce(final T firstElement, final T secondElement) { return firstElement == null ?secondElement :firstElement; } /** * Coalesce. * * @param the generic type * @param elements the elements * @return the t */ public static final T coalesce(final T... elements) { for(final T e : elements){ if(e != null) return e; } return null; } public static KeyValue keyValue(final K key, final V value) { return new KeyValue.Implementation(key, value); } public static Pair pair(final F first, final S second) { return new Pair.Implementation(first, second); } /** * Tries to cast keyValue to Pair * or instantiates a new Pair instance of failure. * @param * @param * @param keyValue * @return */ @SuppressWarnings("unchecked") public static Pair toPair(final KeyValue keyValue) { try { return (Pair)keyValue; } catch(final ClassCastException e) { return new Pair.Implementation(keyValue.key(), keyValue.value()); } } @SuppressWarnings("unchecked") public static KeyValue toKeyValue(final Pair pair) { try { return (KeyValue)pair; } catch(final ClassCastException e) { return new KeyValue.Implementation(pair.first(), pair.second()); } } public static Reference ref(final T object) { return new Reference.Implementation(object); } public static LinkReference linkRef(final T object) { return new LinkReference.Implementation(object); } public static LinkReference chain(final T... objects) { if(objects == null) return null; final LinkReference chain = new LinkReference.Implementation(objects[0]); if(objects.length > 1){ LinkReference loopRef = chain; for(int i = 1; i < objects.length; i++){ loopRef = loopRef.link(objects[i]); } } return chain; } public static _booleanReference ref(final boolean value) { return new _booleanReference(value); } public static _byteReference ref(final byte value) { return new _byteReference(value); } public static _shortReference ref(final short value) { return new _shortReference(value); } public static _intReference ref(final int value) { return new _intReference(value); } public static _longReference ref(final long value) { return new _longReference(value); } public static _floatReference ref(final float value) { return new _floatReference(value); } public static _doubleReference ref(final double value) { return new _doubleReference(value); } public static _charReference ref(final char value) { return new _charReference(value); } public static final AllCriteria all(final Criterion... criteria) { return new AllCriteria(criteria); } public static final AnyCriteria any(final Criterion... criteria) { return new AnyCriteria(criteria); } public static final NotCriterion not(final Criterion criteria) { return new NotCriterion(criteria); } /////////////////////////////////////////////////////////////////////////// // Throwable Utils // ///////////////////// public static final T removeHighestStrackTraceElement(final T throwable) { final StackTraceElement[] stackTrace = throwable.getStackTrace(); final StackTraceElement[] newStackTrace = new StackTraceElement[stackTrace.length - 1]; System.arraycopy(stackTrace, 1, newStackTrace, 0, newStackTrace.length); throwable.setStackTrace(newStackTrace); return throwable; } public static final T removeHighestStrackTraceElement(final T throwable, final int n) { final StackTraceElement[] stackTrace = throwable.getStackTrace(); final StackTraceElement[] newStackTrace = new StackTraceElement[stackTrace.length - n]; System.arraycopy(stackTrace, n, newStackTrace, 0, newStackTrace.length); throwable.setStackTrace(newStackTrace); return throwable; } public static final T removeHighestStrackTraceElementUntil( final T throwable, final Class c, final String methodname ) { final StackTraceElement[] stackTrace = throwable.getStackTrace(); final String cName = c.getName(); int stackTracesToSkip = 0; for(final StackTraceElement ste : stackTrace) { if(ste.getClassName().equals(cName) && ste.getMethodName().equals(methodname)) break; stackTracesToSkip++; } return removeHighestStrackTraceElement(throwable, stackTracesToSkip); } /** * Not implemented yet. DO NOT USE! * @param o1 * @param o2 * @return always false at the moment */ @Deprecated public static final boolean equalContent(final Object o1, final Object o2) { //trivial cases if(o1 == null) return o2 == null; else if(o2 == null) return false; else if(o1 == o2) return true; final Class c = o1.getClass(); if(o2.getClass() != c) return false; /*complex case: * 1.) for each instance field in class c: * - if value1 != value2 return false * 2.) return true */ return false; } /** * Not implemented yet. DO NOT USE! * @param o1 * @param o2 * @return always false at the moment */ @Deprecated public static final boolean equalCommonContent(final Object o1, final Object o2) { //trivial cases if(o1 == null) return o2 == null; else if(o2 == null) return false; else if(o1 == o2) return true; /*complex case: * 1.) determine most specific common class * - if it is Object.class, return false * 2.) for each instance field in commmon class: * - if value1 != value2 return false * 3.) return true */ return false; } public static final E[] shuffle(final E[] array, final int startIndex, final int endIndex) { if(startIndex < 0 || endIndex >= array.length || startIndex > endIndex){ throw new IndexOutOfBoundsException("Range ["+startIndex+';'+endIndex+"] not in [0;"+(array.length-1)+"]."); } final Random r = JaMath.random(); for (int i = endIndex; i > startIndex; i--){ swap(array, i, r.nextInt(i)); } return array; } public static final E[] shuffle(final E[] array) { final Random r = JaMath.random(); for (int i = array.length; i > 1; i--){ swap(array, i-1, r.nextInt(i)); } return array; } private static void swap(final Object[] arr, final int i, final int j) { final Object tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } /** * Instantiates a new {@link Predicate} that delegates calls to the passed {@link Predicate} but inverts the result. *

* Code: !predicate.apply(t) * @param * @param predicate the predicate whose result shall be inverted by the created not-wrapper-predicate * @return a new not-wrapper-predicate for the passed predicate */ public static Condition not(final Predicate predicate) { return new Condition(){ @Override public boolean apply(final T t) { return !predicate.apply(t); } }; } /** * Instantiates a new {@link TPredicate} that delegates calls * to the passed {@link TPredicate} but inverts the result. *

* Code: !predicate.apply(t) * @param * @param predicate the predicate whose result shall be inverted by the created not-wrapper-predicate * @return a new not-wrapper-predicate for the passed predicate */ public static TCondition not(final TPredicate predicate) { return new TCondition(){ @Override public boolean apply(final T t) throws ThrowBreak, ThrowContinue, ThrowReturn { return !predicate.apply(t); } }; } public static final Condition and(final Predicate predicate1, final Predicate predicate2) { return new Condition(){ @Override public boolean apply(final T t) { return predicate1.apply(t) && predicate2.apply(t); } }; } public static final TCondition and(final TPredicate predicate1, final TPredicate predicate2) { return new TCondition(){ @Override public boolean apply(final T t) throws ThrowBreak, ThrowContinue, ThrowReturn { return predicate1.apply(t) && predicate2.apply(t); } }; } /** * Instantiates a new {@link Condition} that wraps the passed predicate as {@link Condition}. * @param * @param predicate * @return a new predicate-wrapper-condition instance. */ public static final Condition condition(final Predicate predicate) { return new Condition(){ @Override public boolean apply(final T t) { return predicate.apply(t); } }; } public static final Condition or(final Predicate predicate1, final Predicate predicate2) { return new Condition(){ @Override public boolean apply(final T t) { return predicate1.apply(t) || predicate2.apply(t); } }; } public static final TCondition or(final TPredicate predicate1, final TPredicate predicate2) { return new TCondition(){ @Override public boolean apply(final T t) throws ThrowBreak, ThrowContinue, ThrowReturn { return predicate1.apply(t) || predicate2.apply(t); } }; } public static final TCondition throwing(final Predicate predicate) { return new TCondition() { @Override public boolean apply(final T t) throws ThrowBreak, ThrowContinue, ThrowReturn { return predicate.apply(t); } }; } public static final Predicate unthrowing(final TPredicate predicate) { return new Predicate() { @Override public boolean apply(final T t) { try { return predicate.apply(t); } catch(final BranchingThrow e) { return false; } } }; } // public static final Comparator EQUALS = new Comparator(){ // @Override // public int compare(final Object o1, final Object o2) // { // if(o1 == o2) return 0; // if(o1 == null) return o2 == null ?0 :-1; // return o1.equals(o2) ?0 :1; // } // }; public static final Equalator chain(final Equalator... equalators) { return new EqualatorSequence(equalators); } public static final Comparator chain(final Comparator... comparators) { return new ComparatorSequence(comparators); } public static final Equalator equalator(final Comparator comparator) { return new Equalator(){ @Override public boolean equal(final E object1, final E object2){ return comparator.compare(object1, object2) == 0; } }; } public static final Equalator equality(final Class type) { return new Equalator(){ @Override public boolean equal(final E o1, final E o2){ return o1 == null ?o2 == null :o1.equals(o2); } }; } public static final Equalator EQUALS = new Equalator(){ @Override public boolean equal(final Object o1, final Object o2) { // if(o1 == o2) return true; //leave that to .equals() implementation if(o1 == null) return o2 == null; return o1.equals(o2); } }; private Jadoth(){} }