
org.apache.tapestry.ioc.util.TimePeriod Maven / Gradle / Ivy
// Copyright 2007 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.ioc.util;
import org.apache.tapestry.ioc.internal.util.CollectionFactory;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Used to represent a period of time, specifically as a configuration value. This is often
* used to specify timeouts.
*
* TimePeriods are parsed from strings.
*
* The string specifys a number of terms. The values of all the terms are summed together to form
* the total time period. Each term consists of a number followed by a unit.
* Units (from largest to smallest) are:
*
* - d
- day
*
- h
- hour
*
- m
- minute
*
- s
- second
*
- ms
- millisecond
*
* Example: "2 h 30 m". By convention, terms are specified largest to smallest. A term without a unit is assumed to be milliseconds. Units are case insensitive ("h" or "H"
* are treated the same).
*/
public class TimePeriod
{
private static final Map UNITS = CollectionFactory.newCaseInsensitiveMap();
private static final long MILLISECOND = 1000l;
static
{
UNITS.put("ms", 1l);
UNITS.put("s", MILLISECOND);
UNITS.put("m", 60 * MILLISECOND);
UNITS.put("h", 60 * 60 * MILLISECOND);
UNITS.put("d", 24 * 60 * 60 * MILLISECOND);
}
private static final Pattern PATTERN = Pattern.compile("\\s*(\\d+)\\s*([a-z]*)", Pattern.CASE_INSENSITIVE);
private final long _milliseconds;
/**
* Creates a TimePeriod for a string.
*
* @param input the string specifying the amount of time in the period
*/
public TimePeriod(String input)
{
_milliseconds = parseMilliseconds(input);
}
public long milliseconds()
{
return _milliseconds;
}
public long seconds()
{
return _milliseconds / MILLISECOND;
}
static long parseMilliseconds(String input)
{
long milliseconds = 0l;
Matcher matcher = PATTERN.matcher(input);
matcher.useAnchoringBounds(true);
// TODO: Notice non matching characters and reject input, including at end
int lastMatchEnd = -1;
while (matcher.find())
{
int start = matcher.start();
if (lastMatchEnd + 1 < start)
{
String invalid = input.substring(lastMatchEnd + 1, start);
throw new RuntimeException(UtilMessages.invalidTimePeriodInput(invalid, input));
}
lastMatchEnd = matcher.end();
long count = Long.parseLong(matcher.group(1));
String units = matcher.group(2);
if (units.length() == 0)
{
milliseconds += count;
continue;
}
Long unitValue = UNITS.get(units);
if (unitValue == null)
throw new RuntimeException(UtilMessages.invalidTimePeriodUnit(units, input, UNITS.keySet()));
milliseconds += count * unitValue;
}
if (lastMatchEnd + 1 < input.length())
{
String invalid = input.substring(lastMatchEnd + 1);
throw new RuntimeException(UtilMessages.invalidTimePeriodInput(invalid, input));
}
return milliseconds;
}
@Override
public String toString()
{
return String.format("TimePeriod[%d ms]", _milliseconds);
}
@Override
public boolean equals(Object obj)
{
if (obj == null) return false;
if (obj instanceof TimePeriod)
{
TimePeriod tp = (TimePeriod) obj;
return _milliseconds == tp._milliseconds;
}
return false;
}
}