diff options
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search/query/ParameterParser.java')
-rw-r--r-- | container-search/src/main/java/com/yahoo/search/query/ParameterParser.java | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/ParameterParser.java b/container-search/src/main/java/com/yahoo/search/query/ParameterParser.java new file mode 100644 index 00000000000..a27e1bfde55 --- /dev/null +++ b/container-search/src/main/java/com/yahoo/search/query/ParameterParser.java @@ -0,0 +1,88 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.query; + +import static com.yahoo.container.util.Util.quote; + +/** + * Wrapper class to avoid code duplication of common parsing requirements. + * + * @author <a href="steinar@yahoo-inc.com">Steinar Knutsen</a> + */ +public class ParameterParser { + + /** + * Tries to return the given object as a Long. If it is a Number, treat it + * as a number of seconds, i.e. get a Long representation and multiply by + * 1000. If it has a String representation, try to parse this as a floating + * point number, followed by by an optional unit (seconds and an SI prefix, + * a couple of valid examples are "s" and "ms". Only a very small subset of + * SI prefixes are supported). If no unit is given, seconds are assumed. + * + * @param value + * some representation of a number of seconds + * @param defaultValue + * returned if value is null + * @return value as a number of milliseconds + * @throws NumberFormatException + * if value is not a Number instance and its String + * representation cannot be parsed as a number followed + * optionally by time unit + */ + public static Long asMilliSeconds(Object value, Long defaultValue) { + if (value == null) { + return defaultValue; + } + if (value instanceof Number) { + Number n = (Number) value; + return Long.valueOf(n.longValue() * 1000L); + } + return parseTime(value.toString()); + } + + private static Long parseTime(String time) throws NumberFormatException { + + time = time.trim(); + try { + int unitOffset = findUnitOffset(time); + double measure = Double.valueOf(time.substring(0, unitOffset)); + double multiplier = parseUnit(time.substring(unitOffset)); + return Long.valueOf((long) (measure * multiplier)); + } catch (RuntimeException e) { + throw new IllegalArgumentException("Error parsing " + quote(time), e); + } + } + + private static int findUnitOffset(String time) { + int unitOffset = 0; + while (unitOffset < time.length()) { + char c = time.charAt(unitOffset); + if (c == '.' || (c >= '0' && c <= '9')) { + unitOffset += 1; + } else { + break; + } + } + if (unitOffset == 0) { + throw new NumberFormatException("Invalid number " + quote(time)); + } + return unitOffset; + } + + private static double parseUnit(String unit) { + unit = unit.trim(); + final double multiplier; + if ("ks".equals(unit)) { + multiplier = 1e6d; + } else if ("s".equals(unit)) { + multiplier = 1000.0d; + } else if ("ms".equals(unit)) { + multiplier = 1.0d; + } else if ("\u00B5s".equals(unit)) { + // microseconds + multiplier = 1e-3d; + } else { + multiplier = 1000.0d; + } + return multiplier; + } +} |