From 8929c055214be729a1a15b3eb6a72cddf1b2393a Mon Sep 17 00:00:00 2001 From: Gilles Sadowski Date: Fri, 9 Sep 2011 23:01:59 +0000 Subject: [PATCH] New constructor that enables one to customize the behaviour at counter exhaustion (namely, select which exception to throw). git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1167387 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/commons/math/util/Incrementor.java | 75 +++++++++++++++---- .../commons/math/util/IncrementorTest.java | 15 ++++ 2 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/apache/commons/math/util/Incrementor.java b/src/main/java/org/apache/commons/math/util/Incrementor.java index f3719d72e..83a2a05f6 100644 --- a/src/main/java/org/apache/commons/math/util/Incrementor.java +++ b/src/main/java/org/apache/commons/math/util/Incrementor.java @@ -19,8 +19,12 @@ package org.apache.commons.math.util; import org.apache.commons.math.exception.MaxCountExceededException; /** - * Utility that increments a counter until a maximum is reached, at which - * point it will throw an exception. + * Utility that increments a counter until a maximum is reached, at + * which point, the instance will by default throw a + * {@link MaxCountExceededException}. + * However, the user is able to override this behaviour by defining a + * custom {@link MaxCountExceededCallback callback}, in order to e.g. + * select which exception must be thrown. * * @version $Id$ * @since 3.0 @@ -33,7 +37,11 @@ public class Incrementor { /** * Current count. */ - private int count; + private int count = 0; + /** + * Function called at counter exhaustion. + */ + private final MaxCountExceededCallback maxCountCallback; /** * Default constructor. @@ -50,12 +58,30 @@ public class Incrementor { * @param max Maximal count. */ public Incrementor(int max) { - maximalCount = max; - count = 0; + this(max, + new MaxCountExceededCallback() { + /** {@inheritDoc} */ + public void trigger(int max) { + throw new MaxCountExceededException(max); + } + }); } /** - * Set the upper limit for the counter. + * Defines a maximal count and a callback method to be triggered at + * counter exhaustion. + * + * @param max Maximal count. + * @param cb Function to be called when the maximal count has been reached. + */ + public Incrementor(int max, + MaxCountExceededCallback cb) { + maximalCount = max; + maxCountCallback = cb; + } + + /** + * Sets the upper limit for the counter. * This does not automatically reset the current count to zero (see * {@link #resetCount()}). * @@ -66,7 +92,7 @@ public class Incrementor { } /** - * Get the upper limit of the counter. + * Gets the upper limit of the counter. * * @return the counter upper limit. */ @@ -75,7 +101,7 @@ public class Incrementor { } /** - * Get the current count. + * Gets the current count. * * @return the current count. */ @@ -84,7 +110,7 @@ public class Incrementor { } /** - * Check whether a single increment is allowed. + * Checks whether a single increment is allowed. * * @return {@code false} if the next call to {@link #incrementCount(int) * incrementCount} will trigger a {@code MaxCountExceededException}, @@ -95,7 +121,7 @@ public class Incrementor { } /** - * Perform multiple increments. + * Performs multiple increments. * See the other {@link #incrementCount() incrementCount} method). * * @param value Number of increments. @@ -108,20 +134,41 @@ public class Incrementor { } /** - * Add one to the current iteration count. + * Adds one to the current iteration count. + * At counter exhaustion, this method will call the + * {@link MaxCountExceededCallback#trigger(int) trigger} method of the + * callback object passed to the + * {@link #Incrementor(int,MaxCountExceededCallback) constructor}. + * If not explictly set, a default callback is used that will throw + * a {@code MaxCountExceededException}. * - * @throws MaxCountExceededException at counter exhaustion. + * @throws MaxCountExceededException at counter exhaustion, unless a + * custom {@link MaxCountExceededCallback callback} has been set at + * construction. */ public void incrementCount() { if (++count > maximalCount) { - throw new MaxCountExceededException(maximalCount); + maxCountCallback.trigger(maximalCount); } } /** - * Reset the counter to 0. + * Resets the counter to 0. */ public void resetCount() { count = 0; } + + /** + * Defines a method to be called at counter exhaustion. + * The {@link #trigger(int) trigger} method should usually throw an exception. + */ + public interface MaxCountExceededCallback { + /** + * Function called when the maximal count has been reached. + * + * @param maximalCount Maximal count. + */ + void trigger(int maximalCount); + } } diff --git a/src/test/java/org/apache/commons/math/util/IncrementorTest.java b/src/test/java/org/apache/commons/math/util/IncrementorTest.java index 68c625450..dc40ee71a 100644 --- a/src/test/java/org/apache/commons/math/util/IncrementorTest.java +++ b/src/test/java/org/apache/commons/math/util/IncrementorTest.java @@ -14,6 +14,7 @@ package org.apache.commons.math.util; import org.apache.commons.math.exception.MaxCountExceededException; +import org.apache.commons.math.exception.TooManyEvaluationsException; import org.junit.Assert; import org.junit.Test; @@ -96,6 +97,20 @@ public class IncrementorTest { i.incrementCount(); } + @Test(expected=TooManyEvaluationsException.class) + public void testAlternateException() { + final Incrementor.MaxCountExceededCallback cb + = new Incrementor.MaxCountExceededCallback() { + /** {@inheritDoc} */ + public void trigger(int max) { + throw new TooManyEvaluationsException(max); + } + }; + + final Incrementor i = new Incrementor(0, cb); + i.incrementCount(); + } + @Test public void testReset() { final Incrementor i = new Incrementor();