
ro.pippo.core.ParameterValue Maven / Gradle / Ivy
/*
* Copyright (C) 2014 the original author or authors.
*
* 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 ro.pippo.core;
import ro.pippo.core.util.StringUtils;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* A ParameterValue represents either a single-value path parameter or a
* multi-valued query parameter.
*
* @author Decebal Suiu
* @author James Moger
*/
public class ParameterValue implements Serializable {
private final String[] values;
public ParameterValue(final String... values) {
this.values = values;
}
public boolean toBoolean() {
return toBoolean(false);
}
public boolean toBoolean(boolean defaultValue) {
if (isNull()) {
return defaultValue;
}
switch (values[0]) {
case "yes":
case "on":
return true;
default:
try {
return Integer.parseInt(values[0]) > 0;
} catch (NumberFormatException e) {
// NaN
}
return Boolean.parseBoolean(values[0]);
}
}
public byte toByte() {
return toByte((byte) 0);
}
public byte toByte(byte defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return Byte.parseByte(values[0]);
}
public short toShort() {
return toShort((short) 0);
}
public short toShort(short defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return Short.parseShort(values[0]);
}
public int toInt() {
return toInt(0);
}
public int toInt(int defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return Integer.parseInt(values[0]);
}
public long toLong() {
return toLong(0);
}
public long toLong(long defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return Long.parseLong(values[0]);
}
public float toFloat() {
return toFloat(0);
}
public float toFloat(float defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return Float.parseFloat(values[0]);
}
public double toDouble() {
return toDouble(0);
}
public double toDouble(double defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return Double.parseDouble(values[0]);
}
public BigDecimal toBigDecimal() {
return toBigDecimal(BigDecimal.ZERO);
}
public BigDecimal toBigDecimal(BigDecimal defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return new BigDecimal(Double.parseDouble(values[0]));
}
public UUID toUUID() {
return toUUID(null);
}
public UUID toUUID(UUID defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return UUID.fromString(values[0]);
}
public Character toCharacter() {
return toCharacter((char) 0);
}
public Character toCharacter(Character defaultValue) {
if (isNull() || values[0].length() == 0) {
return defaultValue;
}
return values[0].charAt(0);
}
@Override
public String toString() {
return toString(null);
}
public String toString(String defaultValue) {
if (isNull()) {
return defaultValue;
}
return values[0];
}
public > T toEnum(Class classOfT) {
return toEnum(classOfT, null, true);
}
public > T toEnum(Class classOfT, T defaultValue) {
return toEnum(classOfT, defaultValue, true);
}
public > T toEnum(Class classOfT, T defaultValue, boolean caseSensitive) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
int ordinal = Integer.MIN_VALUE;
try {
// attempt to interpret value as an ordinal
ordinal = Integer.parseInt(values[0]);
} catch (Exception e) {
// do nothing
}
T[] constants = classOfT.getEnumConstants();
for (T constant : constants) {
if (constant.ordinal() == ordinal) {
return constant;
}
if (caseSensitive) {
if (constant.name().equals(values[0])) {
return constant;
}
} else {
if (constant.name().equalsIgnoreCase(values[0])) {
return constant;
}
}
}
return defaultValue;
}
public Set toSet() {
return toSet(new HashSet<>());
}
public Set toSet(Set defaultValue) {
if (isNull()) {
return defaultValue;
}
if (values.length == 1) {
return new HashSet<>(Arrays.asList(values[0].split(",")));
}
return new HashSet<>(Arrays.asList(values));
}
/**
* Converts a string value(s) to a Set of the target type.
*
* @param classOfT
* @return a set of the values
*/
public Set toSet(Class classOfT) {
return (Set) toCollection(HashSet.class, classOfT, null);
}
/**
* Converts a string value(s) to a Set of the target type. You may optionally specify
* a string pattern to assist in the type conversion.
*
* @param classOfT
* @param pattern optional pattern for interpreting the underlying request
* string value. (used for date & time conversions)
* @return a set of the values
*/
public Set toSet(Class classOfT, String pattern) {
return (Set) toCollection(HashSet.class, classOfT, pattern);
}
public List toList() {
return toList(new ArrayList());
}
public List toList(List defaultValue) {
if (isNull()) {
return defaultValue;
}
if (values.length == 1) {
String tmp = values[0];
tmp = StringUtils.removeStart(tmp, "[");
tmp = StringUtils.removeEnd(tmp, "]");
return Arrays.asList(tmp.split("(,|\\|)"));
}
return Arrays.asList(values);
}
public List toList(Class classOfT) {
return toCollection(ArrayList.class, classOfT, null);
}
public List toList(Class classOfT, String pattern) {
return toCollection(ArrayList.class, classOfT, pattern);
}
public Date toDate(String pattern) {
return toDate(null, pattern);
}
public Date toDate(Date defaultValue, String pattern) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
try {
return dateFormat.parse(values[0]);
} catch (ParseException e) {
throw new PippoRuntimeException(e);
}
}
public java.sql.Date toSqlDate() {
return toSqlDate(null);
}
public java.sql.Date toSqlDate(java.sql.Date defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return java.sql.Date.valueOf(values[0]);
}
public Time toSqlTime() {
return toSqlTime(null);
}
public Time toSqlTime(Time defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return Time.valueOf(values[0]);
}
public Timestamp toSqlTimestamp() {
return toSqlTimestamp(null);
}
public Timestamp toSqlTimestamp(Timestamp defaultValue) {
if (isNull() || StringUtils.isNullOrEmpty(values[0])) {
return defaultValue;
}
return Timestamp.valueOf(values[0]);
}
public T to(Class classOfT) {
return to(classOfT, null);
}
/**
* Converts a string value(s) to the target type. You may optionally specify
* a string pattern to assist in the type conversion.
*
* @param classOfT
* @param pattern optional pattern for interpreting the underlying request
* string value. (used for date & time conversions)
* @return an object
*/
@SuppressWarnings("unchecked")
public T to(Class classOfT, String pattern) {
if (classOfT == null) {
return null;
}
if (classOfT.isArray()) {
Class> componentType = classOfT.getComponentType();
Object array;
// cheat by not instantiating a ParameterValue for every value
ParameterValue parameterValue = new ParameterValue(new String[]{"PLACEHOLDER"});
if (values.length == 1) {
// split a single-value list into an array
String tmp = values[0];
tmp = StringUtils.removeStart(tmp, "[");
tmp = StringUtils.removeEnd(tmp, "]");
List list = StringUtils.getList(tmp, "(,|\\|)");
array = Array.newInstance(componentType, list.size());
for (int i = 0; i < list.size(); i++) {
String value = list.get(i);
parameterValue.values[0] = value;
Object object = parameterValue.toObject(componentType, pattern);
Array.set(array, i, object);
}
} else {
array = Array.newInstance(componentType, values.length);
for (int i = 0; i < values.length; i++) {
String value = values[i];
parameterValue.values[0] = value;
Object object = parameterValue.toObject(componentType, pattern);
Array.set(array, i, object);
}
}
return (T) array;
} else {
return (T) toObject(classOfT, pattern);
}
}
/**
* Converts a string value(s) to the target collection type. You may optionally specify
* a string pattern to assist in the type conversion.
*
* @param collectionClass
* @param classOfT
* @param pattern optional pattern for interpreting the underlying request
* string value. (used for date & time conversions)
* @return a collection of the values
*/
@SuppressWarnings("unchecked")
public , T> X toCollection(Class extends Collection> collectionClass, Class classOfT, String pattern) {
if (collectionClass == null || classOfT == null) {
return null;
}
try {
// reflectively instantiate the target collection type using the default constructor
Constructor> constructor = collectionClass.getConstructor();
X collection = (X) constructor.newInstance();
// cheat by not instantiating a ParameterValue for every value
ParameterValue parameterValue = new ParameterValue(new String[]{"PLACEHOLDER"});
List list;
if (values.length == 1) {
String tmp = values[0];
tmp = StringUtils.removeStart(tmp, "[");
tmp = StringUtils.removeEnd(tmp, "]");
list = StringUtils.getList(tmp, "(,|\\|)");
} else {
list = Arrays.asList(values);
}
for (String value : list) {
parameterValue.values[0] = value;
T t = (T) parameterValue.toObject(classOfT, pattern);
collection.add(t);
}
return collection;
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new PippoRuntimeException(e, "Failed to create collection");
}
}
@SuppressWarnings("unchecked")
private Object toObject(Class> type, String pattern) {
if (type == String.class) {
return toString();
}
if ((type == Boolean.TYPE) || (type == Boolean.class)) {
return toBoolean();
}
if ((type == Byte.TYPE) || (type == Byte.class)) {
return toByte();
}
if ((type == Short.TYPE) || (type == Short.class)) {
return toShort();
}
if ((type == Integer.TYPE) || (type == Integer.class)) {
return toInt();
}
if ((type == Long.TYPE) || (type == Long.class)) {
return toLong();
}
if ((type == Float.TYPE) || (type == Float.class)) {
return toFloat();
}
if ((type == Double.TYPE) || (type == Double.class)) {
return toDouble();
}
if ((type == Character.TYPE) || (type == Character.class)) {
return toCharacter();
}
if (type == BigDecimal.class) {
return toBigDecimal();
}
if (type == UUID.class) {
return toUUID();
}
if (type.isEnum()) {
return toEnum((Class extends Enum>) type);
}
if (pattern == null) {
// no defined pattern, use type defaults
if (type == java.sql.Date.class) {
return toSqlDate();
}
if (type == Time.class) {
return toSqlTime();
}
if (type == Timestamp.class) {
return toSqlTimestamp();
}
} else {
if (Date.class.isAssignableFrom(type)) {
Date date = toDate(pattern);
if (type == Date.class) {
return date;
} else if (type == java.sql.Date.class) {
return new java.sql.Date(date.getTime());
} else if (type == Time.class) {
return new Time(date.getTime());
} else if (type == Timestamp.class) {
return new Timestamp(date.getTime());
}
}
}
throw new PippoRuntimeException("Cannot convert '{}' to type '{}'", toString(), type);
}
public boolean isNull() {
return values == null || values.length == 0 || values[0] == null;
}
public boolean isEmpty() {
return values == null || values.length == 0 || StringUtils.isNullOrEmpty(values[0]);
}
public boolean isMultiValued() {
return values != null && values.length > 1;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy