001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.converter;
018
019 import java.util.regex.Matcher;
020 import java.util.regex.Pattern;
021
022 import org.apache.camel.Converter;
023 import org.slf4j.Logger;
024 import org.slf4j.LoggerFactory;
025
026 @Converter
027 public final class TimePatternConverter {
028 private static final transient Logger LOG = LoggerFactory.getLogger(TimePatternConverter.class);
029 private static final String NUMBERS_ONLY_STRING_PATTERN = "^[-]?(\\d)+$";
030 private static final String REPLACEMENT_PATTERN = "[our|inute|econd](s)?";
031 private static final String HOUR_REGEX_PATTERN = "((\\d)*(\\d))[h|H]";
032 private static final String MINUTES_REGEX_PATTERN = "((\\d)*(\\d))[m|M]";
033 private static final String SECONDS_REGEX_PATTERN = "((\\d)*(\\d))[s|S]";
034
035 /**
036 * Utility classes should not have a public constructor.
037 */
038 private TimePatternConverter() {
039 }
040
041 @Converter
042 public static long toMilliSeconds(String source) throws IllegalArgumentException {
043 long milliseconds = 0;
044 boolean foundFlag = false;
045 Matcher matcher;
046
047 matcher = createMatcher(NUMBERS_ONLY_STRING_PATTERN, source);
048 if (matcher.find()) {
049 // Note: This will also be used for regular numeric strings.
050 // This String -> long converter will be used for all strings.
051 milliseconds = Long.valueOf(source).longValue();
052 } else {
053 matcher = createMatcher(REPLACEMENT_PATTERN, source);
054 String replacedSource = matcher.replaceAll("");
055
056 LOG.trace("Replaced original source {} to {}", source, replacedSource);
057
058 matcher = createMatcher(HOUR_REGEX_PATTERN, replacedSource);
059 if (matcher.find()) {
060 milliseconds = milliseconds + (3600000 * Long.valueOf(matcher.group(1)).longValue());
061 foundFlag = true;
062 }
063
064 matcher = createMatcher(MINUTES_REGEX_PATTERN, replacedSource);
065 if (matcher.find()) {
066 long minutes = Long.valueOf(matcher.group(1)).longValue();
067 if ((minutes > 59) && foundFlag) {
068 throw new IllegalArgumentException("Minutes should contain a valid value between 0 and 59: " + source);
069 }
070 foundFlag = true;
071 milliseconds = milliseconds + (60000 * minutes);
072 }
073
074 matcher = createMatcher(SECONDS_REGEX_PATTERN, replacedSource);
075 if (matcher.find()) {
076 long seconds = Long.valueOf(matcher.group(1)).longValue();
077 if ((seconds > 59) && foundFlag) {
078 throw new IllegalArgumentException("Seconds should contain a valid value between 0 and 59: " + source);
079 }
080 foundFlag = true;
081 milliseconds = milliseconds + (1000 * seconds);
082 }
083
084 // No pattern matched... initiating fallback check and conversion (if required).
085 // The source at this point may contain illegal values or special characters
086 if (!foundFlag) {
087 milliseconds = Long.valueOf(source).longValue();
088 }
089 }
090
091 LOG.trace("source: {} milliseconds: ", source, milliseconds);
092
093 return milliseconds;
094 }
095
096 private static Matcher createMatcher(String regexPattern, String source) {
097 Pattern pattern = Pattern.compile(regexPattern, Pattern.CASE_INSENSITIVE);
098 return pattern.matcher(source);
099 }
100 }