/src/main/java/org/andya/confluence/utils/MathUtils.java
Java | 168 lines | 111 code | 12 blank | 45 comment | 43 complexity | 4b9425dc755fd9a32376dc35b8d219da MD5 | raw file
- /*
- * Copyright (c) 2006, 2007 Andy Armstrong, Kelsey Grant and other contributors.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * The names of contributors may not
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- package org.andya.confluence.utils;
-
- import com.atlassian.renderer.v2.macro.MacroException;
-
- import java.util.List;
-
- /**
- * Useful math utilities for use in macros.
- */
- public class MathUtils {
- /**
- * Parse a string as a number in the following order: 1. If the value is in
- * Confluence duration format return a {@link Duration}. 2. If the value is
- * an Integer return an integer. 3. If all else fails try to parse the
- * number as a double.
- */
- public static Number parseNumber(String value) {
- Duration duration = Duration.parseDuration(value);
- if (duration != null)
- return duration;
- try {
- // clean the value by stripping out non digits.
- // this lets people put $ signs and other misc units into
- // integer fields safely.
- char[] chars = value.toCharArray();
- StringBuffer out = new StringBuffer();
- for (int i = 0; i < chars.length; i++) {
- char c = chars[i];
- if (c >= '0' && c <= '9') {
- out.append(c);
- } else if (c == '.' || c == '-') {
- out.append(c);
- }
- }
-
- value = out.toString();
-
- int intValue = Integer.parseInt(value);
- return new Integer(intValue);
- } catch (NumberFormatException e) {
- try {
- double doubleValue = Double.parseDouble(value);
- return new Double(doubleValue);
- } catch (NumberFormatException e2) {
- return null;
- }
- }
- }
-
- /** Converts a number to the best string representation. */
- public static String toString(Number number) {
- if (number instanceof Duration)
- return ((Duration) number).getDurationString();
- else if (number instanceof Integer)
- return Integer.toString(number.intValue());
- else
- return Double.toString(number.doubleValue());
- }
-
- /** Apply the specified function to a list of values. */
- public static Number doCalculation(String function, List<Number> values)
- throws MacroException {
- function = function.trim().toLowerCase();
- if ("sum".equals(function))
- return sum(values);
- else if ("avg".equals(function) || "average".equals(function))
- return average(values);
- else if ("min".equals(function) || "minimum".equals(function))
- return min(values);
- else if ("max".equals(function) || "maximum".equals(function))
- return max(values);
- throw new MacroException("Unknown function \"" + function + "\"");
- }
-
- /** Calculate the sum of a list of numbers. */
- public static Number sum(List<Number> values) {
- double sum = 0;
- boolean integerOnly = true;
- boolean duration = false;
- for (Number number : values) {
- if (number instanceof Double)
- integerOnly = false;
- else if (number instanceof Duration)
- duration = true;
- sum += number.doubleValue();
- }
- if (duration)
- return new Duration((long) sum);
- if (integerOnly)
- return new Integer((int) sum);
- return new Double(sum);
- }
-
- /** Calculate the average of a list of numbers. */
- public static Number average(List<Number> values) {
- Number total = sum(values);
- double average = total.doubleValue() / values.size();
- if (total instanceof Duration)
- return new Duration((long) average);
- return new Double(average);
- }
-
- /** Calculate the minimum of a list of numbers. */
- public static Number min(List<Number> values) {
- double min = Double.MAX_VALUE;
- boolean integerOnly = true;
- boolean duration = false;
- for (Number number : values) {
- if (number instanceof Duration)
- duration = true;
- else if (number instanceof Double)
- integerOnly = false;
- min = Math.min(min, number.doubleValue());
- }
- if (duration)
- return new Duration((long) min);
- else if (integerOnly)
- return new Integer((int) min);
- return new Double(min);
- }
-
- /** Calculate the maximum of a list of numbers. */
- public static Number max(List<Number> values) {
- double max = Double.MIN_VALUE;
- boolean integerOnly = true;
- boolean duration = false;
- for (Number number : values) {
- if (number instanceof Duration)
- duration = true;
- else if (number instanceof Double)
- integerOnly = false;
- max = Math.max(max, number.doubleValue());
- }
- if (duration)
- return new Duration((long) max);
- if (integerOnly)
- return new Integer((int) max);
- return new Double(max);
- }
- }