|
From: <be...@us...> - 2010-03-26 21:09:18
|
Revision: 314
http://objectlabkit.svn.sourceforge.net/objectlabkit/?rev=314&view=rev
Author: benoitx
Date: 2010-03-26 21:09:11 +0000 (Fri, 26 Mar 2010)
Log Message:
-----------
First cut for the utils module.
Added Paths:
-----------
trunk/utils/
trunk/utils/pom.xml
trunk/utils/src/
trunk/utils/src/main/
trunk/utils/src/main/java/
trunk/utils/src/main/java/net/
trunk/utils/src/main/java/net/objectlab/
trunk/utils/src/main/java/net/objectlab/kit/
trunk/utils/src/main/java/net/objectlab/kit/console/
trunk/utils/src/main/java/net/objectlab/kit/console/ConsoleMenu.java
trunk/utils/src/main/java/net/objectlab/kit/console/Repeater.java
trunk/utils/src/main/java/net/objectlab/kit/util/
trunk/utils/src/main/java/net/objectlab/kit/util/Average.java
trunk/utils/src/main/java/net/objectlab/kit/util/BigDecimalUtil.java
trunk/utils/src/main/java/net/objectlab/kit/util/BooleanUtil.java
trunk/utils/src/main/java/net/objectlab/kit/util/CaseTreatment.java
trunk/utils/src/main/java/net/objectlab/kit/util/CollectionUtil.java
trunk/utils/src/main/java/net/objectlab/kit/util/IntegerUtil.java
trunk/utils/src/main/java/net/objectlab/kit/util/ObjectHolder.java
trunk/utils/src/main/java/net/objectlab/kit/util/ObjectUtil.java
trunk/utils/src/main/java/net/objectlab/kit/util/Pair.java
trunk/utils/src/main/java/net/objectlab/kit/util/Quadruplet.java
trunk/utils/src/main/java/net/objectlab/kit/util/StringUtil.java
trunk/utils/src/main/java/net/objectlab/kit/util/Sum.java
trunk/utils/src/main/java/net/objectlab/kit/util/Triplet.java
trunk/utils/src/main/java/net/objectlab/kit/util/WeightedAverage.java
trunk/utils/src/test/
trunk/utils/src/test/java/
trunk/utils/src/test/java/net/
trunk/utils/src/test/java/net/objectlab/
trunk/utils/src/test/java/net/objectlab/kit/
trunk/utils/src/test/java/net/objectlab/kit/util/
Added: trunk/utils/pom.xml
===================================================================
--- trunk/utils/pom.xml (rev 0)
+++ trunk/utils/pom.xml 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,39 @@
+<?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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>net.objectlab.kit.util</groupId>
+ <artifactId>utils</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>ObjectLab Kit - General Utilities</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ <version>1.6</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Added: trunk/utils/src/main/java/net/objectlab/kit/console/ConsoleMenu.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/console/ConsoleMenu.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/console/ConsoleMenu.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,433 @@
+package net.objectlab.kit.console;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.joda.time.LocalDate;
+
+/**
+ * @author Benoit Xhenseval
+ *
+ */
+public class ConsoleMenu {
+ private static final int EXIT_CODE = 0;
+
+ private static final int SCREEN_COLUMNS = 110;
+
+ private static final int COL = 10;
+
+ private static final PrintStream OUT = System.out;
+
+ // ~ Instance fields
+ // ------------------------------------------------------------------------------------------------
+
+ private final List<String> menu = new ArrayList<String>();
+
+ private final List<String> methods = new ArrayList<String>();
+
+ private final List<Boolean> askForRepeat = new ArrayList<Boolean>();
+
+ private final Repeater target;
+
+ private int screenColumns = SCREEN_COLUMNS;
+
+ // ~ Constructors
+ // ---------------------------------------------------------------------------------------------------
+
+ /**
+ * @param containingObject
+ * the object that will be called back once an option is chosen
+ * in the menu
+ */
+ public ConsoleMenu(final Repeater containingObject) {
+ target = containingObject;
+ }
+
+ // ~ Methods
+ // --------------------------------------------------------------------------------------------------------
+
+ /**
+ * add an entry in the menu, sequentially
+ *
+ * @param menuDisplay
+ * how the entry will be displayed in the menu
+ * @param methodName
+ * name of the public method
+ * @parem askForRepeat call back for repeat
+ */
+ public void addMenuItem(final String menuDisplay, final String methodName, final boolean repeat) {
+ menu.add(menuDisplay);
+ methods.add(methodName);
+ askForRepeat.add(Boolean.valueOf(repeat));
+ }
+
+ public void setScreenColumns(final int width) {
+ screenColumns = width;
+ }
+
+ /**
+ * display the menu, the application goes into a loop which provides the
+ * menu and fires the entries selected. It automatically adds an entry to
+ * exit.
+ */
+ public void displayMenu() {
+ while (true) {
+ ConsoleMenu.println("");
+ ConsoleMenu.println("Menu Options");
+
+ final int size = menu.size();
+
+ displayMenu(size);
+
+ int opt = -1;
+
+ do {
+ opt = ConsoleMenu.getInt("Enter your choice:", -1);
+ } while (((opt <= 0) || (opt > methods.size())) && (opt != EXIT_CODE));
+
+ if (opt == EXIT_CODE) {
+ ConsoleMenu.println("Exiting menu");
+ try {
+ final Method meth = target.getClass().getMethod("tearDown", new Class[0]);
+ if (meth != null) {
+ meth.invoke(target, new Object[0]);
+ }
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+
+ return;
+ }
+
+ // now call the method
+ final String method = methods.get(opt - 1);
+ final Boolean repeat = askForRepeat.get(opt - 1);
+
+ try {
+ final Method meth = target.getClass().getMethod(method, new Class[0]);
+ if (repeat) {
+ target.repeat(meth);
+ } else {
+ meth.invoke(target, new Object[0]);
+ }
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void displayMenu(final int size) {
+ for (int i = 0; i < (size / 2); i++) {
+ final StringBuffer line = new StringBuffer();
+ final String col1 = menu.get(i);
+
+ if ((i + 1) < COL) {
+ line.append(" ");
+ }
+
+ final int pos = i + 1;
+ line.append(" ").append(pos).append(") ").append(col1);
+
+ while (line.length() < (screenColumns / 2)) {
+ line.append(" ");
+ }
+
+ if ((i + (size / 2)) < size) {
+ final String col2 = menu.get(i + (size / 2));
+ final int position = i + 1 + (size / 2);
+ line.append(" ").append(position).append(") ").append(col2);
+ }
+
+ ConsoleMenu.println(line.toString());
+ }
+
+ if (size % 2 != 0) {
+ final StringBuffer line = new StringBuffer();
+ final String col1 = menu.get(size - 1);
+
+ if (size < COL) {
+ line.append(" ");
+ }
+
+ line.append(" ").append(size).append(") ").append(col1);
+
+ while (line.length() < (screenColumns / 2)) {
+ line.append(" ");
+ }
+
+ line.append(" ").append(EXIT_CODE).append(") ").append("Exit");
+ ConsoleMenu.println(line.toString());
+ } else {
+ ConsoleMenu.println(" " + EXIT_CODE + ") Exit");
+ }
+ }
+
+ /**
+ * Gets an int from the System.in
+ *
+ * @param title
+ * for the command line
+ * @return int as entered by the user of the console app
+ */
+ public static int getInt(final String title, final int defaultValue) {
+ int opt = -1;
+
+ do {
+ try {
+ final String val = ConsoleMenu.getString(title + " (default:" + defaultValue + ")");
+ if (val.length() == 0) {
+ opt = defaultValue;
+ } else {
+ opt = Integer.parseInt(val);
+ }
+ } catch (final NumberFormatException e) {
+ opt = -1;
+ }
+ } while (opt == -1);
+
+ return opt;
+ }
+
+ /**
+ * Gets a boolean from the System.in
+ *
+ * @param title
+ * for the command line
+ * @return boolean as selected by the user of the console app
+ */
+ public static boolean getBoolean(final String title, final boolean defaultValue) {
+ final String val = ConsoleMenu.selectOne(title, new String[] { "Yes", "No" }, new String[] { Boolean.TRUE.toString(),
+ Boolean.FALSE.toString() }, defaultValue ? 1 : 2);
+
+ return Boolean.valueOf(val);
+ }
+
+ /**
+ * Gets an BigDecimal from the System.in
+ *
+ * @param title
+ * for the command line
+ * @return int as entered by the user of the console app
+ */
+ public static BigDecimal getBigDecimal(final String title, final BigDecimal defaultValue) {
+ BigDecimal opt = null;
+
+ do {
+ try {
+ final String val = ConsoleMenu.getString(title + " (default:" + defaultValue + ")");
+ if (val.length() == 0) {
+ opt = defaultValue;
+ } else {
+ opt = new BigDecimal(val);
+ }
+ } catch (final NumberFormatException e) {
+ opt = null;
+ }
+ } while (opt == null && defaultValue != null);
+
+ return opt;
+ }
+
+ public static Date getDate(final String title, final Date defaultValue) {
+ final SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy");
+ final String date = ConsoleMenu.getString(title + "(dd-MM-yyyy" + (defaultValue != null ? ", default:" + fmt.format(defaultValue) : "") + ")");
+ try {
+ if (date == null || date.length() == 0) {
+ return defaultValue;
+ }
+ return fmt.parse(date);
+ } catch (final ParseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static LocalDate getYMD(final String title, final LocalDate defaultValue) {
+ final Date dateStr = ConsoleMenu.getDate(title, (defaultValue != null ? defaultValue.toDateMidnight().toDate() : null));
+ if (dateStr != null) {
+ return new LocalDate(dateStr);
+ }
+ return null;
+ }
+
+ /**
+ * Gets a String from the System.in
+ *
+ * @param msg
+ * for the command line
+ * @return String as entered by the user of the console app
+ */
+ public static String getString(final String msg) {
+ ConsoleMenu.print(msg);
+
+ BufferedReader bufReader = null;
+ String opt = null;
+
+ try {
+ bufReader = new BufferedReader(new InputStreamReader(System.in));
+ opt = bufReader.readLine();
+ } catch (final IOException ex) {
+ ex.printStackTrace();
+ System.exit(1);
+ }
+
+ return opt;
+ }
+
+ /**
+ * Gets a String from the System.in
+ *
+ * @param msg
+ * for the command line
+ * @return String as entered by the user of the console app
+ */
+ public static String getString(final String msg, final String defaultVal) {
+ String s = getString(msg + "(default:" + defaultVal + "):");
+ if (StringUtils.isBlank(s)) {
+ s = defaultVal;
+ }
+
+ return s;
+ }
+
+ /**
+ * Generates a menu with a list of options and return the value selected.
+ *
+ * @param title
+ * for the command line
+ * @param optionNames
+ * name for each option
+ * @param optionValues
+ * value for each option
+ * @return String as selected by the user of the console app
+ */
+ public static String selectOne(final String title, final String[] optionNames, final String[] optionValues, final int defaultOption) {
+ if (optionNames.length != optionValues.length) {
+ throw new IllegalArgumentException("option names and values must have same length");
+ }
+
+ ConsoleMenu.println("Please chose " + title + " (default:" + defaultOption + ")");
+
+ for (int i = 0; i < optionNames.length; i++) {
+ ConsoleMenu.println(i + 1 + ") " + optionNames[i]);
+ }
+
+ int choice = 0;
+
+ do {
+ choice = ConsoleMenu.getInt("Your Choice 1-" + optionNames.length + ": ", defaultOption);
+ } while ((choice <= 0) || (choice > optionNames.length));
+
+ return optionValues[choice - 1];
+ }
+
+ /**
+ * @param prompt
+ * The prompt to display to the user.
+ * @return The password as entered by the user.
+ */
+ public static String getPassword(final String prompt) {
+ try {
+ // password holder
+ final StringBuffer password = new StringBuffer();
+ final PasswordHidingThread maskingthread = new PasswordHidingThread(prompt);
+ final Thread thread = new Thread(maskingthread);
+ thread.start();
+
+ // block until enter is pressed
+ while (true) {
+ char c = (char) System.in.read();
+
+ // assume enter pressed, stop masking
+ maskingthread.stopMasking();
+
+ if (c == '\r') {
+ c = (char) System.in.read();
+
+ if (c == '\n') {
+ break;
+ }
+ continue;
+ } else if (c == '\n') {
+ break;
+ } else {
+ // store the password
+ password.append(c);
+ }
+ }
+
+ return password.toString();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ // ~ Inner Classes
+ // --------------------------------------------------------------------------------------------------
+
+ /**
+ * This class attempts to erase characters echoed to the console.
+ */
+ static class PasswordHidingThread extends Thread {
+ private boolean stop = false;
+
+ private final String prompt;
+
+ /**
+ * @param prompt
+ * The prompt displayed to the user
+ */
+ public PasswordHidingThread(final String prompt) {
+ this.prompt = prompt;
+ }
+
+ /**
+ * Begin masking until asked to stop.
+ */
+ @Override
+ public void run() {
+ while (!stop) {
+ try {
+ // attempt masking at this rate
+ Thread.sleep(1);
+ } catch (final InterruptedException iex) {
+ iex.printStackTrace();
+ }
+
+ if (!stop) {
+ ConsoleMenu.print("\r" + prompt + " \r" + prompt);
+ }
+
+ System.out.flush();
+ }
+ }
+
+ /**
+ * Instruct the thread to stop masking.
+ */
+ public void stopMasking() {
+ this.stop = true;
+ }
+ }
+
+ private static void println(final String txt) {
+ OUT.println(txt);
+ }
+
+ private static void print(final String txt) {
+ OUT.print(txt);
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/console/Repeater.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/console/Repeater.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/console/Repeater.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,7 @@
+package net.objectlab.kit.console;
+
+import java.lang.reflect.Method;
+
+public interface Repeater {
+ void repeat(Method target);
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/Average.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/Average.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/Average.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,46 @@
+package net.objectlab.kit.util;
+
+import java.math.BigDecimal;
+
+/**
+ * @author Benoit
+ *
+ */
+public final class Average {
+ private Sum sum = new Sum();
+ private int count = 0;
+
+ public Average() {
+ }
+
+ public Average(final BigDecimal start) {
+ sum = new Sum(start);
+ }
+
+ public Average(final int scale) {
+ BigDecimal bd = new BigDecimal(0);
+ sum = new Sum(bd.setScale(scale));
+ }
+
+ public void add(BigDecimal val) {
+ sum.add(val);
+ count++;
+ }
+
+ public BigDecimal getTotal() {
+ return sum.getTotal();
+ }
+
+ public int getDataPoints() {
+ return count;
+ }
+
+ public BigDecimal getAverage() {
+ return BigDecimalUtil.divide(getTotal(), new BigDecimal(count), BigDecimal.ROUND_HALF_UP);
+ }
+
+ @Override
+ public String toString() {
+ return StringUtil.concatWithSpaces("Total:", getTotal(), "Points", getDataPoints(), "Avg:", getAverage());
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/BigDecimalUtil.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/BigDecimalUtil.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/BigDecimalUtil.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,649 @@
+package net.objectlab.kit.util;
+
+import java.math.BigDecimal;
+import java.text.NumberFormat;
+
+/**
+ * @author Benoit Xhenseval
+ *
+ */
+public final class BigDecimalUtil {
+ private static final double ROUNDING_UP_FLOAT = 0.5d;
+ private static final int MAX_SCALE_FOR_INVERSE = 20;
+ private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
+
+ private BigDecimalUtil() {
+ }
+
+ /**
+ * Return the inverse of value, using scale
+ */
+ public static BigDecimal inverse(final BigDecimal value, final int scale) {
+ if (isNotZero(value)) {
+ return BigDecimal.ONE.divide(value, scale, BigDecimal.ROUND_HALF_UP);
+ }
+ return null;
+ }
+
+ /**
+ * Return the inverse of value
+ */
+ public static BigDecimal inverse(final BigDecimal value) {
+ if (isNotZero(value)) {
+ return BigDecimal.ONE.setScale(MAX_SCALE_FOR_INVERSE).divide(value, BigDecimal.ROUND_HALF_UP);
+ }
+ return null;
+ }
+
+ /**
+ * @return true if value !=null and <> 0.
+ */
+ public static boolean isNotZero(final BigDecimal value) {
+ return value != null && value.signum() != 0;
+ }
+
+ /**
+ * @return true if value !=null and 0.
+ */
+ public static boolean isZero(final BigDecimal value) {
+ return value != null && value.signum() == 0;
+ }
+
+ /**
+ * @return true if value !=null and <0.
+ */
+ public static boolean isNegative(final BigDecimal value) {
+ return value != null && value.signum() == -1;
+ }
+
+ /**
+ * @return true if value !=null and >0.
+ */
+ public static boolean isStrictlyPositive(final BigDecimal value) {
+ return value != null && value.signum() == 1;
+ }
+
+ /**
+ * @return true if value ==null OR 0.
+ */
+ public static boolean isNullOrZero(final BigDecimal value) {
+ return value == null || value.signum() == 0;
+ }
+
+ /**
+ * @return true if val1 == val2 (ignoring scale and null are treated as 0)
+ */
+ public static boolean isSameValue(final BigDecimal val1, final BigDecimal val2) {
+ return val1 == null && val2 == null || val1 != null && val2 != null && val1.compareTo(val2) == 0;
+ }
+
+ /**
+ * @return true if val1 == val2 (ignoring scale and null are treated as 0)
+ */
+ public static boolean isSameValueTreatNullAsZero(final BigDecimal val1, final BigDecimal val2) {
+ return val1 == null && val2 == null || signum(val1) == 0 && signum(val2) == 0 || val1 != null && val2 != null && val1.compareTo(val2) == 0;
+ }
+
+ /**
+ * Add 2 BigDecimal safely (i.e. handles nulls)
+ */
+ public static BigDecimal add(final BigDecimal v1, final BigDecimal v2) {
+ BigDecimal total = v1;
+ if (v1 != null && v2 != null) {
+ total = v1.add(v2);
+ } else if (v2 != null) {
+ total = v2;
+ }
+ return total;
+ }
+
+ /**
+ * Add n BigDecimal safely (i.e. handles nulls)
+ */
+ public static BigDecimal add(final BigDecimal start, final BigDecimal... values) {
+ BigDecimal total = start;
+ for (final BigDecimal v : values) {
+ total = add(total, v);
+ }
+ return total;
+ }
+
+ /**
+ * Subtract n BigDecimal safely (i.e. handles nulls)
+ */
+ public static BigDecimal subtract(final BigDecimal start, final BigDecimal... values) {
+ BigDecimal total = start;
+ for (final BigDecimal v : values) {
+ total = subtract(total, v);
+ }
+ return total;
+ }
+
+ /**
+ * Subtract 2 BigDecimal safely (i.e. handles nulls) v1 - v2
+ */
+ public static BigDecimal subtract(final BigDecimal v1, final BigDecimal v2) {
+ BigDecimal diff = v1;
+ if (v1 != null && v2 != null) {
+ diff = v1.subtract(v2);
+ } else if (v2 != null) {
+ diff = v2.negate();
+ }
+ return diff;
+ }
+
+ /**
+ * @return numerator / denominator if they are not null and the denominator is not zero, it returns null otherwise.
+ */
+ public static BigDecimal divide(final BigDecimal numerator, final BigDecimal denominator, final int rounding) {
+ BigDecimal diff = null;
+ if (numerator != null && isNotZero(denominator)) {
+ diff = numerator.divide(denominator, rounding);
+ }
+ return diff;
+ }
+
+ public static BigDecimal calculateWeight(final BigDecimal value, final BigDecimal total) {
+ return BigDecimalUtil.setScale(BigDecimalUtil.divide(BigDecimalUtil.setScale(value, 9), BigDecimalUtil.setScale(total, 9),
+ BigDecimal.ROUND_HALF_UP), 9);
+ }
+
+ /**
+ * @return numerator / denominator if they are not null and the denominator is not zero, it returns null otherwise.
+ */
+ public static BigDecimal divide(final int numeratorScale, final BigDecimal numerator, final BigDecimal denominator, final int rounding) {
+ BigDecimal diff = null;
+ if (numerator != null && isNotZero(denominator)) {
+ diff = numerator.setScale(numeratorScale).divide(denominator, rounding);
+ }
+ return diff;
+ }
+
+ /**
+ * @return numerator / denominator if they are not null and the denominator is not zero, it returns null otherwise.
+ */
+ public static BigDecimal divide(final BigDecimal numerator, final BigDecimal denominator, final int scale, final int rounding) {
+ BigDecimal diff = null;
+ if (numerator != null && isNotZero(denominator)) {
+ diff = numerator.divide(denominator, rounding);
+ }
+ return BigDecimalUtil.setScale(diff, scale, rounding);
+ }
+
+ public static BigDecimal multiply(final BigDecimal value, final BigDecimal multiplicand) {
+ BigDecimal diff = null;
+ if (value != null && multiplicand != null) {
+ diff = value.multiply(multiplicand);
+ }
+ return diff;
+ }
+
+ public static BigDecimal multiply(final BigDecimal value, final BigDecimal... multiplicand) {
+ BigDecimal diff = null;
+ if (value != null && multiplicand != null) {
+ diff = value;
+ for (final BigDecimal bd : multiplicand) {
+ if (bd != null) {
+ diff = diff.multiply(bd);
+ }
+ }
+ }
+ return diff;
+ }
+
+ /**
+ * Returns the ABS of the value, handles null.
+ */
+ public static BigDecimal abs(final BigDecimal value) {
+ return value != null ? value.abs() : null;
+ }
+
+ /**
+ * Returns the negate of the value, handles null.
+ */
+ public static BigDecimal negate(final BigDecimal value) {
+ return value != null ? value.negate() : null;
+ }
+
+ /**
+ * Returns the negate of the value if condition is true, handles null.
+ */
+ public static BigDecimal negateIfTrue(final boolean condition, final BigDecimal value) {
+ return condition ? negate(value) : value;
+ }
+
+ /**
+ * @return false if the ABS value match!
+ */
+ public static boolean isNotSameAbsValue(final BigDecimal v1, final BigDecimal v2) {
+ return !isSameAbsValue(v1, v2);
+ }
+
+ /**
+ * @return false if the value match!
+ */
+ public static boolean isNotSameValue(final BigDecimal v1, final BigDecimal v2) {
+ return !isSameValue(v1, v2);
+ }
+
+ /**
+ * @return true if the ABS value match!
+ */
+ public static boolean isSameAbsValue(final BigDecimal v1, final BigDecimal v2) {
+ return isSameValue(abs(v1), abs(v2));
+ }
+
+ /**
+ * @return 1 if v1 > v2 or v2==null and v2!=null
+ * @return 0 if v1 == v2 or v1==null and v2==null
+ * @return -1 if v1 < v2 or v1==null and v2!=null
+ */
+ public static int compareTo(final BigDecimal v1, final BigDecimal v2) {
+ int ret = 1;
+ if (v1 != null && v2 != null) {
+ ret = v1.compareTo(v2);
+ } else if (v1 == null && v2 == null) {
+ ret = 0;
+ } else if (v1 == null) {
+ ret = -1;
+ }
+ return ret;
+ }
+
+ /**
+ * @return true if the ABS(v1) > ABS(v2)
+ */
+ public static int absCompareTo(final BigDecimal v1, final BigDecimal v2) {
+ return compareTo(abs(v1), abs(v2));
+ }
+
+ /**
+ * @return true if the ABS( ABS(v1) - ABS(v2) )
+ */
+ public static BigDecimal absDiff(final BigDecimal v1, final BigDecimal v2) {
+ return abs(subtract(abs(v1), abs(v2)));
+ }
+
+ /**
+ * Safe shift (check for null), shift RIGHT if shift>0.
+ */
+ public static BigDecimal movePoint(final BigDecimal v1, final int shift) {
+ return v1 == null ? null : v1.movePointRight(shift);
+ }
+
+ /**
+ * returns a new BigDecimal with correct scale after being round to n dec places.
+ *
+ * @param bd value
+ * @param numberOfDecPlaces number of dec place to round to
+ * @param finalScale final scale of result (typically numberOfDecPlaces < finalScale);
+ * @return new bd or null
+ */
+ public static BigDecimal roundTo(final BigDecimal bd, final int numberOfDecPlaces, final int finalScale) {
+ return setScale(setScale(bd, numberOfDecPlaces, BigDecimal.ROUND_HALF_UP), finalScale);
+ }
+
+ /**
+ * returns a new BigDecimal with correct scale.
+ *
+ * @param bd
+ * @return new bd or null
+ */
+ public static BigDecimal setScale(final BigDecimal bd, final int scale) {
+ return setScale(bd, scale, BigDecimal.ROUND_HALF_UP);
+ }
+
+ /**
+ * returns a new BigDecimal with correct Scale.
+ *
+ * @param bd
+ * @return new bd or null
+ */
+ public static BigDecimal setScale(final BigDecimal bd, final Integer scale) {
+ return setScale(bd, scale, BigDecimal.ROUND_HALF_UP);
+ }
+
+ /**
+ * returns a new BigDecimal with correct Scales.PERCENT_SCALE. This is used
+ * by the table renderer.
+ *
+ * @param bd
+ * @return new bd or null
+ */
+ public static BigDecimal setScale(final BigDecimal bd, final Integer scale, final int rounding) {
+ if (bd != null && scale != null) {
+ return bd.setScale(scale, rounding);
+ }
+ return null;
+ }
+
+ /**
+ * If value is null return 0 otherwise the signum().
+ * @param value
+ * @return
+ */
+ public static int signum(final BigDecimal value) {
+ return value == null ? 0 : value.signum();
+ }
+
+ /**
+ * @return true if both v1/v2 are null or same sign.
+ */
+ public static boolean isSameSignum(final BigDecimal v1, final BigDecimal v2) {
+ return signum(v1) == signum(v2);
+ }
+
+ /**
+ * @return true if both v1.signum() != v2.signum() and NOT zero.
+ */
+ public static boolean hasSignedFlippedAndNotZero(final BigDecimal v1, final BigDecimal v2) {
+ final int v1Sign = signum(v1);
+ final int v2Sign = signum(v2);
+ return v1Sign != v2Sign && v1Sign != 0 && v2Sign != 0;
+ }
+
+ /**
+ * @return true if v1.signum() != v2.signum().
+ */
+ public static boolean hasSignedChanged(final BigDecimal v1, final BigDecimal v2) {
+ return signum(v1) != signum(v2);
+ }
+
+ /**
+ * @param bd
+ * @param lowerLimit
+ * @param upperLimit
+ * @return true if outside the range
+ */
+ public static boolean isOutsideRange(final BigDecimal bd, final BigDecimal lowerLimit, final BigDecimal upperLimit) {
+ // TODO Auto-generated method stub
+ return !isInsideInclusiveRange(bd, lowerLimit, upperLimit);
+ }
+
+ /**
+ * @param bd
+ * @param lowerLimit
+ * @param upperLimit
+ * @return true if inside the inclusive range
+ */
+ public static boolean isInsideInclusiveRange(final BigDecimal bd, final BigDecimal lowerLimit, final BigDecimal upperLimit) {
+ return ObjectUtil.noneNull(bd, lowerLimit, upperLimit) && bd.compareTo(lowerLimit) >= 0 && bd.compareTo(upperLimit) <= 0;
+ }
+
+ /**
+ * @return o1 if not null, otherwise fallBack
+ */
+ public static BigDecimal assignNonNull(final BigDecimal o1, final BigDecimal fallBack) {
+ return o1 != null ? o1 : fallBack;
+ }
+
+ /**
+ * Calculate the weight of the constituent and add it to the running weighted value.
+ * runningWeightedVal + valueToAdd * weightForValueToAdd / totalWeight
+ * @param runningWeightedVal
+ * @param valueToAdd
+ * @param weightForValueToAdd
+ * @param totalWeight
+ * @return
+ */
+ public static BigDecimal addWeightedConstituent(final BigDecimal runningWeightedVal, final BigDecimal valueToAdd, final BigDecimal weightForValueToAdd,
+ final BigDecimal totalWeight) {
+ return BigDecimalUtil.add(runningWeightedVal, BigDecimalUtil.divide(BigDecimalUtil
+ .multiply(valueToAdd, BigDecimalUtil.abs(weightForValueToAdd)), BigDecimalUtil.abs(totalWeight), BigDecimal.ROUND_HALF_UP));
+ }
+
+ /**
+ * @return true if all values are either null or zero
+ */
+ public static boolean allNullOrZero(final BigDecimal... values) {
+ for (final BigDecimal bd : values) {
+ if (!isNullOrZero(bd)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * return a Number formatted or empty string if null.
+ * @param bd
+ */
+ public static String format(final BigDecimal bd) {
+ return bd != null ? NUMBER_FORMAT.format(bd) : "";
+ }
+
+ /**
+ * return a Number formatted or empty string if null.
+ * @param bd
+ */
+ public static String percentFormat(final BigDecimal bd) {
+ return bd != null ? NUMBER_FORMAT.format(bd.movePointRight(2)) : "";
+ }
+
+ /**
+ * true if ABS((startValue-newValue)/startValue) <= abs(thresholdPercent)
+ * @param startValue
+ * @param newValue
+ * @param thresholdPercent
+ * @return
+ */
+ public static boolean movedInsideThresholdPercentage(final BigDecimal startValue, final BigDecimal newValue, final BigDecimal thresholdPercent) {
+ return !movedStrictlyOutsideThresholdPercentage(startValue, newValue, thresholdPercent);
+ }
+
+ /**
+ * true if ABS((startValue-newValue)/startValue) > abs(thresholdPercent)
+ * @param startValue
+ * @param newValue
+ * @param thresholdPercent
+ * @return
+ */
+ public static boolean movedStrictlyOutsideThresholdPercentage(final BigDecimal startValue, final BigDecimal newValue, final BigDecimal thresholdPercent) {
+ final BigDecimal s = BigDecimalUtil.setScale(startValue, 10);
+ final BigDecimal n = BigDecimalUtil.setScale(newValue, 10);
+ final BigDecimal diff = BigDecimalUtil.divide(BigDecimalUtil.subtract(s, n), s, BigDecimal.ROUND_HALF_UP);
+ // diff = BigDecimalUtil.safeAbsDiff(diff, MagicNumbers.ONE);
+
+ return BigDecimalUtil.absCompareTo(diff, thresholdPercent) > 0;
+ }
+
+ private static double roundUp(final double n, final int p) {
+ double retval;
+
+ if (Double.isNaN(n) || Double.isInfinite(n)) {
+ retval = Double.NaN;
+ } else {
+ if (p != 0) {
+ final double temp = Math.pow(10, p);
+ final double nat = Math.abs(n * temp);
+
+ retval = sign(n) * (nat == (long) nat ? nat / temp : Math.round(nat + ROUNDING_UP_FLOAT) / temp);
+ } else {
+ final double na = Math.abs(n);
+ retval = sign(n) * (na == (long) na ? na : (long) na + 1);
+ }
+ }
+
+ return retval;
+ }
+
+ /**
+ * Returns a value rounded to p digits after decimal.
+ * If p is negative, then the number is rounded to
+ * places to the left of the decimal point. eg.
+ * 10.23 rounded to -1 will give: 10. If p is zero,
+ * the returned value is rounded to the nearest integral
+ * value.
+ * <p>If n is negative, the resulting value is obtained
+ * as the round-up value of absolute value of n multiplied
+ * by the sign value of n (@see MathX.sign(double d)).
+ * Thus, -0.8 rounded-down to p=0 will give 0 not -1.
+ * <p>If n is NaN, returned value is NaN.
+ * @param n
+ * @param p
+ * @return
+ */
+ private static double roundDown(final double n, final int p) {
+ double retval;
+
+ if (Double.isNaN(n) || Double.isInfinite(n)) {
+ retval = Double.NaN;
+ } else {
+ if (p != 0) {
+ final double temp = Math.pow(10, p);
+ retval = sign(n) * Math.round(Math.abs(n) * temp - ROUNDING_UP_FLOAT) / temp;
+ } else {
+ retval = (long) n;
+ }
+ }
+
+ return retval;
+ }
+
+ private static short sign(final double d) {
+ return (short) (d == 0 ? 0 : d < 0 ? -1 : 1);
+ }
+
+ /**
+ * Returns a value rounded-up to p digits after decimal.
+ * If p is negative, then the number is rounded to
+ * places to the left of the decimal point. eg.
+ * 10.23 rounded to -1 will give: 20. If p is zero,
+ * the returned value is rounded to the nearest integral
+ * value.
+ * <p>If n is negative, the resulting value is obtained
+ * as the round-up value of absolute value of n multiplied
+ * by the sign value of n (@see MathX.sign(double d)).
+ * Thus, -0.2 rounded-up to p=0 will give -1 not 0.
+ * <p>If n is NaN, returned value is NaN.
+ * @param n
+ * @param p
+ * @return
+ */
+ public static BigDecimal roundUp(final BigDecimal n, final int p) {
+ if (n == null) {
+ return null;
+ }
+ final int scale = n.scale();
+ return BigDecimalUtil.setScale(new BigDecimal(roundUp(n.doubleValue(), p)), scale);
+ }
+
+ /**
+ * Returns a value rounded to p digits after decimal.
+ * If p is negative, then the number is rounded to
+ * places to the left of the decimal point. eg.
+ * 10.23 rounded to -1 will give: 10. If p is zero,
+ * the returned value is rounded to the nearest integral
+ * value.
+ * <p>If n is negative, the resulting value is obtained
+ * as the round-up value of absolute value of n multiplied
+ * by the sign value of n (@see MathX.sign(double d)).
+ * Thus, -0.8 rounded-down to p=0 will give 0 not -1.
+ * <p>If n is NaN, returned value is NaN.
+ * @param n
+ * @param p
+ * @return
+ */
+ public static BigDecimal roundDown(final BigDecimal n, final int p) {
+ if (n == null) {
+ return null;
+ }
+ final int scale = n.scale();
+ return BigDecimalUtil.setScale(new BigDecimal(roundDown(n.doubleValue(), p)), scale);
+ }
+
+ public static BigDecimal roundUpForIncrement(final BigDecimal n, final BigDecimal increment) {
+ if (n == null) {
+ return null;
+ }
+ final int scale = n.scale();
+ final int p = (int) (increment != null ? -Math.log10(increment.abs().doubleValue()) : 0);
+ return BigDecimalUtil.setScale(new BigDecimal(roundUp(n.doubleValue(), p)), scale);
+ }
+
+ public static BigDecimal roundDownForIncrement(final BigDecimal n, final BigDecimal increment) {
+ if (n == null) {
+ return null;
+ }
+ final int p = (int) (increment != null ? -Math.log10(increment.abs().doubleValue()) : 0);
+ final int scale = n.scale();
+ return BigDecimalUtil.setScale(new BigDecimal(roundDown(n.doubleValue(), p)), scale);
+ }
+
+ /**
+ * Return minimum if the value is < minimum.
+ */
+ public static BigDecimal ensureMin(final BigDecimal minimum, final BigDecimal value) {
+ return BigDecimalUtil.compareTo(minimum, value) == 1 ? minimum : value;
+ }
+
+ /**
+ * Return a negative amount based on amount.
+ */
+ public static BigDecimal forceNegative(final BigDecimal amount) {
+ return BigDecimalUtil.negate(BigDecimalUtil.abs(amount));
+ }
+
+ /**
+ * Return a negative amount based on amount if true, otherwise return the ABS.
+ */
+ public static BigDecimal forceNegativeIfTrue(final boolean condition, final BigDecimal amount) {
+ return condition ? BigDecimalUtil.negate(BigDecimalUtil.abs(amount)) : BigDecimalUtil.abs(amount);
+ }
+
+ /**
+ * @return return the min amount
+ */
+ public static BigDecimal min(final BigDecimal v1, final BigDecimal v2) {
+ if (v1 == null) {
+ return v2;
+ } else if (v2 == null) {
+ return v1;
+ }
+ return v1.compareTo(v2) <= 0 ? v1 : v2;
+ }
+
+ /**
+ * @return return the max amount
+ */
+ public static BigDecimal max(final BigDecimal... v1) {
+ if (v1 == null) {
+ return null;
+ }
+ BigDecimal max = null;
+ for (BigDecimal bd : v1) {
+ max = BigDecimalUtil.compareTo(max, bd) >= 0 ? max : bd;
+ }
+ return max;
+ }
+
+ /**
+ * Move by 2 DEC place to the left and take the long value, this
+ * takes care of values like 0.18 in fractions.
+ */
+ public static long longForFraction(final BigDecimal v) {
+ if (v == null) {
+ return 0L;
+ }
+ return BigDecimalUtil.movePoint(v, 2).longValue();
+ }
+
+ /**
+ * @return true if abs(abs(v1)-abs(v2)) < abs(threshold)
+ */
+ public static boolean isDiffMoreThanAbsThreshold(final BigDecimal v1, final BigDecimal v2, final BigDecimal threshold) {
+ final BigDecimal diff = BigDecimalUtil.absDiff(v1, v2);
+ return BigDecimalUtil.compareTo(diff, BigDecimalUtil.abs(threshold)) > 0;
+ }
+
+ public static double doubleValue(final BigDecimal val) {
+ return val != null ? val.doubleValue() : 0.0;
+ }
+
+ /**
+ * @return true if value !=null and <=0.
+ */
+ public static boolean isZeroOrLess(BigDecimal value) {
+ return value != null && value.signum() <= 0;
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/BooleanUtil.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/BooleanUtil.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/BooleanUtil.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,29 @@
+package net.objectlab.kit.util;
+
+public final class BooleanUtil {
+ private BooleanUtil() {
+ }
+
+ public static boolean isTrueOrNull(final Boolean b) {
+ return b == null ? true : b;
+ }
+
+ public static boolean isFalseOrNull(final Boolean b) {
+ return b == null ? true : !b;
+ }
+
+ public static boolean isTrue(final Boolean b) {
+ return b == null ? false : b;
+ }
+
+ /**
+ * @return true if string is Y,y,YES,yes,TRUE,true,T,t
+ */
+ public static boolean isTrue(final String str) {
+ return str == null ? false : StringUtil.equalsAnyIgnoreCase(str, "yes", "y", "TRUE", "t");
+ }
+
+ public static boolean isFalse(final Boolean b) {
+ return b == null ? true : !b;
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/CaseTreatment.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/CaseTreatment.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/CaseTreatment.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,5 @@
+package net.objectlab.kit.util;
+
+public enum CaseTreatment {
+ UPPER_CASE, LOWER_CASE, UNCHANGED
+}
\ No newline at end of file
Added: trunk/utils/src/main/java/net/objectlab/kit/util/CollectionUtil.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/CollectionUtil.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/CollectionUtil.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,92 @@
+package net.objectlab.kit.util;
+
+import java.util.Collection;
+
+/**
+ * @author Benoit Xhenseval
+ *
+ */
+public final class CollectionUtil {
+ private CollectionUtil() {
+ }
+
+ /**
+ * @return true if collection null or empty.
+ */
+ public static boolean isEmpty(final Collection<?> col) {
+ return col == null || col.isEmpty();
+ }
+
+ /**
+ * @return true if collection not empty (null safe).
+ */
+ public static boolean isNotEmpty(final Collection<?> col) {
+ return col != null && !col.isEmpty();
+ }
+
+ /**
+ * @return true if collection has only 1 item (null safe).
+ */
+ public static boolean hasOneItem(final Collection<?> col) {
+ return col != null && col.size() == 1;
+ }
+
+ /**
+ * @return true if array not empty (null safe).
+ */
+ public static boolean isNotEmpty(final Object[] array) {
+ return array != null && array.length > 0;
+ }
+
+ /**
+ * @return size of collection if not null, otherwise 0.
+ */
+ public static int size(final Collection<?> col) {
+ return col != null ? col.size() : 0;
+ }
+
+ /**
+ * @return true if collection is not null and contains the items
+ */
+ public static boolean contains(final Collection<?> collection, final Object item) {
+ return collection != null && collection.contains(item) ? true : false;
+ }
+
+ /**
+ * @return true if collection is not null and contains the items
+ */
+ public static boolean containsAny(final Collection<?> collection, final Object... items) {
+ if (collection != null) {
+ for (Object item : items) {
+ boolean b = collection.contains(item);
+ if (b) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return true if none of the collections are empty or null
+ */
+ public static boolean noneEmpty(final Collection... collections) {
+ for (final Collection col : collections) {
+ if (isEmpty(col)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean sameContent(final Collection c1, final Collection c2) {
+ boolean same = c1 != null && c2 != null || c1 == c2 || c1 == null && c2 == null;
+ if (same && c1 != null) {
+ same = c1.size() == c2.size();
+ if (same) {
+ same = c1.equals(c2);
+ }
+ }
+ return same;
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/IntegerUtil.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/IntegerUtil.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/IntegerUtil.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,91 @@
+package net.objectlab.kit.util;
+
+/**
+ * @author Benoit Xhenseval
+ *
+ */
+public final class IntegerUtil {
+ private IntegerUtil() {
+ }
+
+ /**
+ * @return true if value !=null and <> 0.
+ */
+ public static boolean isNotZero(final Integer value) {
+ return value != null && value.intValue() != 0;
+ }
+
+ /**
+ * @return true if value !=null and 0.
+ */
+ public static boolean isZero(final Integer value) {
+ return value != null && value.intValue() == 0;
+ }
+
+ /**
+ * @return true if value ==null OR 0.
+ */
+ public static boolean isNullOrZero(final Integer value) {
+ return value == null || value.intValue() == 0;
+ }
+
+ /**
+ * @return true if val1 == val2 (ignoring scale)
+ */
+ public static boolean isSameValue(final Integer val1, final Integer val2) {
+ return val1 == null && val2 == null || val1 != null && val2 != null && val1.compareTo(val2) == 0;
+ }
+
+ /**
+ * @return true if val1 != val2 (ignoring scale)
+ */
+ public static boolean isNotSameValue(final Integer val1, final Integer val2) {
+ return !isSameValue(val1, val2);
+ }
+
+ /**
+ * Add 2 BigDecimal safely (i.e. handles nulls)
+ */
+ public static Integer safeAdd(final Integer v1, final Integer v2) {
+ Integer total = v1;
+ if (v1 != null && v2 != null) {
+ total = v1 + v2;
+ } else if (v2 != null) {
+ total = v2;
+ }
+ return total;
+ }
+
+ public static int safeSignum(final Integer v) {
+ if (v != null) {
+ return v.intValue() > 0 ? 1 : v.intValue() < 0 ? -1 : 0;
+ }
+ return 0;
+ }
+
+ public static int safeCompare(final Integer id, final Integer id2) {
+ int ret = -1;
+ if (id != null && id2 != null) {
+ ret = id.compareTo(id2);
+ } else if (id == null && id2 == null) {
+ ret = 0;
+ } else if (id != null) {
+ ret = 1;
+ }
+ return ret;
+ }
+
+ /**
+ * Return the value unless it is null, in which case it returns the default value.
+ * @param value
+ * @param defaultValueIfNull
+ * @return
+ */
+ public static Integer assign(final Integer value, final Integer defaultValueIfNull) {
+ return value != null ? value : defaultValueIfNull;
+ }
+
+ public static boolean isNotZeroOrNegative(final Integer id) {
+ return id != null && id.intValue() > 0;
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/ObjectHolder.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/ObjectHolder.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/ObjectHolder.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,24 @@
+package net.objectlab.kit.util;
+
+/**
+ * @author Benoit Xhenseval
+ *
+ */
+public class ObjectHolder<T> {
+ private T value;
+
+ public ObjectHolder() {
+ }
+
+ public ObjectHolder(final T value) {
+ this.value = value;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public void setValue(final T value) {
+ this.value = value;
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/ObjectUtil.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/ObjectUtil.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/ObjectUtil.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,133 @@
+package net.objectlab.kit.util;
+
+import java.math.BigDecimal;
+
+public final class ObjectUtil {
+ private ObjectUtil() {
+ }
+
+ /**
+ * Return true if i1 equals (according to {@link Integer#equals(Object)}) 12.
+ * Also returns true if 11 is null and 12 is null! Is safe on either 11 or 12 being null.
+ */
+ public static boolean equals(final Integer i1, final Integer i2) {
+ if (i1 == null) {
+ return i2 == null;
+ }
+ return i1.equals(i2);
+ }
+
+ /**
+ * Return true if bd1 has the same value (according to
+ * {@link BigDecimalUtil#isSameValue(BigDecimal, BigDecimal)}, which takes care of different scales)
+ * as bd2.
+ * Also returns true if bd1 is null and bd2 is null! Is safe on either bd1 or bd2 being null.
+ */
+ public static boolean equals(final BigDecimal bd1, final BigDecimal bd2) {
+ if (bd1 == null) {
+ return bd2 == null;
+ }
+ return BigDecimalUtil.isSameValue(bd1, bd2);
+ }
+
+ /**
+ * Return true if o1 equals (according to {@link Object#equals(Object)}) o2.
+ * Also returns true if o1 is null and o2 is null! Is safe on either o1 or o2 being null.
+ */
+ public static boolean equals(final Object o1, final Object o2) {
+ if (o1 == null) {
+ return o2 == null;
+ }
+ return o1.equals(o2);
+ }
+
+ /**
+ * Return true if o1 equals (according to {@link Object#equals(Object)} any of the given objects.
+ * Also returns true if o1 is null and any of the given objects is null as well!
+ */
+ public static boolean equalsAny(final Object o1, final Object... o2s) {
+ for (final Object o2 : o2s) {
+ if (o1 == null) {
+ if (o2 == null) {
+ return true;
+ }
+ continue;
+ }
+ // o1 != null
+ if (o1.equals(o2)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return true if o1 equals (according to {@link Object#equals(Object)} ALL of the given objects.
+ */
+ public static boolean equalsAll(final Object o1, final Object... o2s) {
+ for (final Object o2 : o2s) {
+ if (o1 == null) {
+ if (o2 != null) {
+ return false;
+ }
+ continue;
+ }
+ // o1 != null
+ if (!o1.equals(o2)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return true if o1 does NOT equal (according to {@link Object#equals(Object)} any of the given objects.
+ * Also returns false if o1 is null and any of the given objects is null as well!
+ */
+ public static boolean notEqualsAny(final Object o1, final Object... o2s) {
+ return !equalsAny(o1, o2s);
+ }
+
+ /**
+ * Return true if any of the given objects are null.
+ */
+ public static boolean anyNull(final Object... o1s) {
+ for (final Object o1 : o1s) {
+ if (o1 == null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return true if ALL of the given objects are null.
+ */
+ public static boolean allNull(final Object... o1s) {
+ for (final Object o1 : o1s) {
+ if (o1 != null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return true if at least one of the given objects is not null.
+ */
+ public static boolean atLeastOneNotNull(final Object... o1s) {
+ for (final Object o1 : o1s) {
+ if (o1 != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return true if NONE of the given objects are null.
+ */
+ public static boolean noneNull(final Object... o1s) {
+ return !anyNull(o1s);
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/Pair.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/Pair.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/Pair.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,84 @@
+package net.objectlab.kit.util;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.builder.StandardToStringStyle;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+public class Pair<E1, E2> implements Serializable {
+
+ private static final int MULTIPLIER = 31;
+ private static final long serialVersionUID = 1L;
+ private E1 element1;
+ private E2 element2;
+
+ public static <E1, E2> Pair<E1, E2> create(final E1 element1, final E2 element2) {
+ return new Pair<E1, E2>(element1, element2);
+ }
+
+ public Pair(final E1 element1, final E2 element2) {
+ this.element1 = element1;
+ this.element2 = element2;
+ }
+
+ public Pair() {
+ }
+
+ public E1 getElement1() {
+ return element1;
+ }
+
+ public E2 getElement2() {
+ return element2;
+ }
+
+ public void setElement1(final E1 element1) {
+ this.element1 = element1;
+ }
+
+ public void setElement2(final E2 element2) {
+ this.element2 = element2;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ result = MULTIPLIER * result + ((element1 == null) ? 0 : element1.hashCode());
+ result = MULTIPLIER * result + ((element2 == null) ? 0 : element2.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Pair other = (Pair) obj;
+ if (element1 == null) {
+ if (other.element1 != null) {
+ return false;
+ }
+ } else if (!element1.equals(other.element1)) {
+ return false;
+ }
+ if (element2 == null) {
+ if (other.element2 != null) {
+ return false;
+ }
+ } else if (!element2.equals(other.element2)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this, new StandardToStringStyle());
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/Quadruplet.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/Quadruplet.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/Quadruplet.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,90 @@
+package net.objectlab.kit.util;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.StandardToStringStyle;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+/**
+ * @author xhensevalb
+ *
+ */
+public class Quadruplet<E1, E2, E3, E4> implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private static final int HASH_INITIAL_VAL = 17;
+ private static final int MULTIPLIER = 31;
+ private E1 element1;
+ private E2 element2;
+ private E3 element3;
+ private E4 element4;
+
+ public E1 getElement1() {
+ return element1;
+ }
+
+ public static <E1, E2, E3, E4> Quadruplet<E1, E2, E3, E4> create(final E1 element1, final E2 element2, final E3 element3, final E4 element4) {
+ return new Quadruplet<E1, E2, E3, E4>(element1, element2, element3, element4);
+ }
+
+ public Quadruplet(final E1 element1, final E2 element2, final E3 element3, final E4 element4) {
+ super();
+ this.element1 = element1;
+ this.element2 = element2;
+ this.element3 = element3;
+ this.element4 = element4;
+ }
+
+ public void setElement1(final E1 element1) {
+ this.element1 = element1;
+ }
+
+ public E2 getElement2() {
+ return element2;
+ }
+
+ public void setElement2(final E2 element2) {
+ this.element2 = element2;
+ }
+
+ public E3 getElement3() {
+ return element3;
+ }
+
+ public void setElement3(final E3 element3) {
+ this.element3 = element3;
+ }
+
+ public E4 getElement4() {
+ return element4;
+ }
+
+ public void setElement4(final E4 element4) {
+ this.element4 = element4;
+ }
+
+ @Override
+ public boolean equals(final Object rhs) {
+ if (rhs == null) {
+ return false;
+ }
+ if (!(rhs instanceof Quadruplet)) {
+ return false;
+ }
+ final Quadruplet that = (Quadruplet) rhs;
+
+ return new EqualsBuilder().append(element1, that.element1).append(element2, that.element2).append(element3, that.element3).append(element4,
+ that.element4).isEquals();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder(HASH_INITIAL_VAL, MULTIPLIER).append(element1).append(element2).append(element3).append(element4).toHashCode();
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this, new StandardToStringStyle());
+ }
+}
Added: trunk/utils/src/main/java/net/objectlab/kit/util/StringUtil.java
===================================================================
--- trunk/utils/src/main/java/net/objectlab/kit/util/StringUtil.java (rev 0)
+++ trunk/utils/src/main/java/net/objectlab/kit/util/StringUtil.java 2010-03-26 21:09:11 UTC (rev 314)
@@ -0,0 +1,488 @@
+package net.objectlab.kit.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.StandardToStringStyle;
+
+/**
+ * @aut...
[truncated message content] |