001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright 2005-2011 The ConQAT Project                                   |
004|                                                                          |
005| Licensed under the Apache License, Version 2.0 (the "License");          |
006| you may not use this file except in compliance with the License.         |
007| 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+-------------------------------------------------------------------------*/
017package org.conqat.engine.commons;
018
019import java.nio.charset.Charset;
020import java.text.ParseException;
021import java.text.SimpleDateFormat;
022import java.util.Arrays;
023import java.util.Collection;
024import java.util.Date;
025import java.util.Objects;
026import java.util.regex.Pattern;
027import java.util.regex.PatternSyntaxException;
028
029import org.conqat.engine.core.core.ConQATException;
030import org.conqat.lib.commons.reflect.ReflectionUtils;
031import org.conqat.lib.commons.reflect.TypeConversionException;
032
033/**
034 * Collection of utility methods.
035 * 
036 * @author deissenb
037 */
038public class CommonUtils {
039
040        /** Default date format. */
041        public static final String DEFAULT_DATE_FORMAT_PATTERN = "yyyy-MM-dd";
042
043        /**
044         * Create {@link SimpleDateFormat} from pattern string. In contrast to the
045         * constructor of {@link SimpleDateFormat} this raises a
046         * {@link ConQATException} for invalid patterns.
047         */
048        public static SimpleDateFormat createDateFormat(String pattern) throws ConQATException {
049                try {
050                        return new SimpleDateFormat(pattern);
051                } catch (IllegalArgumentException e) {
052                        throw new ConQATException("Illegal date pattern: " + pattern, e);
053                }
054        }
055
056        /**
057         * This method parses a date string using the specified format pattern. See
058         * {@link SimpleDateFormat} for pattern syntax.
059         * 
060         * @throws ConQATException
061         *             if an illegal format string was supplied or the date string
062         *             does not match the given format.
063         */
064        public static Date parseDate(String dateString, String formatString) throws ConQATException {
065                SimpleDateFormat format = createDateFormat(formatString);
066                try {
067                        return format.parse(dateString);
068                } catch (ParseException e) {
069                        throw new ConQATException("Illegal date format for '" + dateString + "'.", e);
070                }
071        }
072
073        /**
074         * Wraps {@link Pattern#compile(String)} to produce {@link ConQATException}s
075         * instead of {@link PatternSyntaxException}s.
076         */
077        public static Pattern compilePattern(String regex) throws ConQATException {
078                try {
079                        return Pattern.compile(regex);
080                } catch (PatternSyntaxException e) {
081                        throw wrapPatternSyntaxException(e);
082                }
083        }
084
085        /**
086         * Wraps {@link Pattern#compile(String)} to produce {@link ConQATException}s
087         * instead of {@link PatternSyntaxException}s.
088         */
089        public static Pattern compilePattern(String regex, String message) throws ConQATException {
090                try {
091                        return Pattern.compile(regex);
092                } catch (PatternSyntaxException e) {
093                        throw new ConQATException(message, e);
094                }
095        }
096
097        /**
098         * Wraps {@link Pattern#compile(String, int)} to produce
099         * {@link ConQATException}s instead of {@link PatternSyntaxException}s.
100         */
101        public static Pattern compilePattern(String regex, int flags) throws ConQATException {
102                try {
103                        return Pattern.compile(regex, flags);
104                } catch (PatternSyntaxException e) {
105                        throw wrapPatternSyntaxException(e);
106                }
107        }
108
109        /** Wraps a {@link PatternSyntaxException} into a {@link ConQATException} */
110        public static ConQATException wrapPatternSyntaxException(PatternSyntaxException e) {
111                return new ConQATException("Illegal regular expression: ", e);
112        }
113
114        /**
115         * Get an encoding for the specified name. This throws a
116         * {@link ConQATException} if the encoding is not supported.
117         */
118        public static Charset obtainEncoding(String encodingName) throws ConQATException {
119                if (!Charset.isSupported(encodingName)) {
120                        throw new ConQATException("Unsupported encoding: " + encodingName);
121                }
122                return Charset.forName(encodingName);
123        }
124
125        /**
126         * Converts a String value to an object of the specified type and wraps the
127         * Exceptions into a {@link ConQATException}
128         */
129        public static Object convertTo(String valueString, String typeName) throws ConQATException {
130                try {
131                        return ReflectionUtils.convertTo(valueString, typeName);
132                } catch (ClassNotFoundException e) {
133                        throw new ConQATException("Could not resolve type: " + typeName, e);
134                } catch (TypeConversionException e) {
135                        throw new ConQATException("Could not convert value: " + valueString, e);
136                }
137        }
138
139        /**
140         * Returns the input. Returns the provided default value in case the input
141         * is <code>null</code>.
142         */
143        public static <T> T defaultIfNull(T input, T defaultValue) {
144                if (input == null) {
145                        return defaultValue;
146                }
147                return input;
148        }
149
150        /** Check if obj is equal to one of the provided objects. */
151        @SafeVarargs
152        public static <T> boolean isOneOf(T obj, T... others) {
153                Objects.requireNonNull(others);
154                return isOneOf(obj, Arrays.asList(others));
155        }
156
157        /** Check if obj is equal to one of the provided objects. */
158        public static <T> boolean isOneOf(T obj, Collection<T> others) {
159                Objects.requireNonNull(others);
160
161                for (Object otherObj : others) {
162                        if (Objects.equals(obj, otherObj)) {
163                                return true;
164                        }
165                }
166
167                return false;
168        }
169}