
ninja.params.ParamParsers Maven / Gradle / Ivy
/**
* Copyright (C) 2012-2016 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 ninja.params;
import java.lang.reflect.Array;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.joda.time.LocalDateTime;
import ninja.validation.ConstraintViolation;
import ninja.validation.IsDate;
import ninja.validation.IsEnum;
import ninja.validation.IsFloat;
import ninja.validation.IsInteger;
import ninja.validation.Validation;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
* Built in parsers for parameters
*
* @author James Roper
* @author Jonathan Lannoy
*/
@Singleton
public class ParamParsers {
private static final Map, ParamParser>> PARAM_PARSERS =
ImmutableMap., ParamParser>>builder()
.put(Integer.class, new IntegerParamParser())
.put(int.class, new PrimitiveIntegerParamParser())
.put(Boolean.class, new BooleanParamParser())
.put(boolean.class, new PrimitiveBooleanParamParser())
.put(Long.class, new LongParamParser())
.put(long.class, new PrimitiveLongParamParser())
.put(Float.class, new FloatParamParser())
.put(float.class, new PrimitiveFloatParamParser())
.put(Double.class, new DoubleParamParser())
.put(double.class, new PrimitiveDoubleParamParser())
.put(String.class, new StringParamParser())
.put(Byte.class, new ByteParamParser())
.put(byte.class, new PrimitiveByteParamParser())
.put(Short.class, new ShortParamParser())
.put(short.class, new PrimitiveShortParamParser())
.put(Character.class, new CharacterParamParser())
.put(char.class, new PrimitiveCharacterParamParser())
.put(Date.class, new DateParamParser())
.build();
private final Set customParsers;
@Inject
public ParamParsers(Set customParsers) {
this.customParsers = customParsers;
}
public ParamParser> getParamParser(Class> targetType) {
for(ParamParser parser : customParsers) {
if(targetType.isAssignableFrom(parser.getParsedType())) {
return parser;
}
}
if (targetType.isArray()) {
// check for array of registered types
Class> componentType = targetType.getComponentType();
ParamParser> componentParser = getParamParser(componentType);
if (componentParser != null) {
// return CSV parser
return new CsvParamParser(targetType, componentParser);
}
}
if (targetType.isEnum()) {
return new GenericEnumParamParser((Class) targetType);
}
return PARAM_PARSERS.get(targetType);
}
/**
* Registering enums is not anymore needed, the EnumParser will handle all possible enum values, ignoring case.
*/
@Deprecated
public static > void unregisterEnum(final Class enumClass) {
// Not anymore used
}
/**
* Registering enums is not anymore needed, the EnumParser will handle all possible enum values, ignoring case.
*/
@Deprecated
public static > void registerEnum(final Class enumClass) {
// Not anymore used
}
/**
* Registering enums is not anymore needed, the EnumParser will handle all possible enum values, ignoring case.
*/
@Deprecated
public static > void registerEnum(final Class enumClass, final boolean caseSensitive) {
// Not anymore used
}
public ArrayParamParser> getArrayParser(Class> targetType) {
if (targetType.isArray()) {
// check for array of registered types
Class> componentType = targetType.getComponentType();
ParamParser> componentParser = getParamParser(componentType);
if (componentParser != null) {
// return multi-valued parameter parser
return new ArrayParamParser(targetType, componentParser);
}
}
return null;
}
public ListParamParser> getListParser(Class> targetInnerType) {
ParamParser> componentParser = getParamParser(targetInnerType);
if (componentParser != null) {
// return multi-valued parameter parser
return new ListParamParser(targetInnerType, componentParser);
}
return null;
}
public static class PrimitiveIntegerParamParser implements ParamParser {
@Override
public Integer parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return 0;
} else {
try {
return Integer.parseInt(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsInteger.KEY, field, IsInteger.MESSAGE, parameterValue));
return 0;
}
}
}
@Override
public Class getParsedType() {
return Integer.class;
}
}
public static class IntegerParamParser implements ParamParser {
@Override
public Integer parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
try {
return Integer.parseInt(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsInteger.KEY, field, IsInteger.MESSAGE, parameterValue));
return null;
}
}
}
@Override
public Class getParsedType() {
return Integer.class;
}
}
public static class BooleanParamParser implements ParamParser {
@Override
public Boolean parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
return Boolean.parseBoolean(parameterValue);
}
}
@Override
public Class getParsedType() {
return Boolean.class;
}
}
public static class PrimitiveBooleanParamParser implements ParamParser {
@Override
public Boolean parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return false;
} else {
return Boolean.parseBoolean(parameterValue);
}
}
@Override
public Class getParsedType() {
return Boolean.class;
}
}
public static class LongParamParser implements ParamParser {
@Override
public Long parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
try {
return Long.parseLong(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsInteger.KEY, field, IsInteger.MESSAGE, parameterValue));
return null;
}
}
}
@Override
public Class getParsedType() {
return Long.class;
}
}
public static class PrimitiveLongParamParser implements ParamParser {
@Override
public Long parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return 0L;
} else {
try {
return Long.parseLong(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsInteger.KEY, field, IsInteger.MESSAGE, parameterValue));
return 0L;
}
}
}
@Override
public Class getParsedType() {
return Long.class;
}
}
public static class FloatParamParser implements ParamParser {
@Override
public Float parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
try {
return Float.parseFloat(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsFloat.KEY, field, IsFloat.MESSAGE, parameterValue));
return null;
}
}
}
@Override
public Class getParsedType() {
return Float.class;
}
}
public static class PrimitiveFloatParamParser implements ParamParser {
@Override
public Float parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return 0f;
} else {
try {
return Float.parseFloat(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsFloat.KEY, field, IsFloat.MESSAGE, parameterValue));
return 0f;
}
}
}
@Override
public Class getParsedType() {
return Float.class;
}
}
public static class DoubleParamParser implements ParamParser {
@Override
public Double parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
try {
return Double.parseDouble(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsFloat.KEY, field, IsFloat.MESSAGE, parameterValue));
return null;
}
}
}
@Override
public Class getParsedType() {
return Double.class;
}
}
public static class PrimitiveDoubleParamParser implements ParamParser {
@Override
public Double parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return 0d;
} else {
try {
return Double.parseDouble(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsFloat.KEY, field, IsFloat.MESSAGE, parameterValue));
return 0d;
}
}
}
@Override
public Class getParsedType() {
return Double.class;
}
}
public static class StringParamParser implements ParamParser {
@Override
public String parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || validation.hasFieldViolation(field)) {
return null;
} else {
return parameterValue;
}
}
@Override
public Class getParsedType() {
return String.class;
}
}
public static class ByteParamParser implements ParamParser {
@Override
public Byte parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
try {
return Byte.parseByte(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsInteger.KEY, field, IsInteger.MESSAGE, parameterValue));
return null;
}
}
}
@Override
public Class getParsedType() {
return Byte.class;
}
}
public static class PrimitiveByteParamParser implements ParamParser {
@Override
public Byte parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return 0;
} else {
try {
return Byte.parseByte(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsInteger.KEY, field, IsInteger.MESSAGE, parameterValue));
return 0;
}
}
}
@Override
public Class getParsedType() {
return Byte.class;
}
}
public static class ShortParamParser implements ParamParser {
@Override
public Short parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
try {
return Short.parseShort(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsInteger.KEY, field, IsInteger.MESSAGE, parameterValue));
return null;
}
}
}
@Override
public Class getParsedType() {
return Short.class;
}
}
public static class PrimitiveShortParamParser implements ParamParser {
@Override
public Short parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return 0;
} else {
try {
return Short.parseShort(parameterValue);
} catch (NumberFormatException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsInteger.KEY, field, IsInteger.MESSAGE, parameterValue));
return 0;
}
}
}
@Override
public Class getParsedType() {
return Short.class;
}
}
public static class CharacterParamParser implements ParamParser {
@Override
public Character parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
return parameterValue.charAt(0);
}
}
@Override
public Class getParsedType() {
return Character.class;
}
}
public static class PrimitiveCharacterParamParser implements ParamParser {
@Override
public Character parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return '\0';
} else {
return parameterValue.charAt(0);
}
}
@Override
public Class getParsedType() {
return Character.class;
}
}
public static class GenericEnumParamParser> implements ParamParser {
private Class targetType;
public GenericEnumParamParser(Class targetType) {
this.targetType = targetType;
}
@Override
public E parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
// Equals ignore case will keep backward compatibility
for (E value : getParsedType().getEnumConstants()) {
if (value.name().equalsIgnoreCase(parameterValue)) {
return value;
}
}
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsEnum.KEY, field, IsEnum.MESSAGE, new Object[] {parameterValue, getParsedType().getName()}));
return null;
}
}
@Override
public Class getParsedType() {
return targetType;
}
}
public static class DateParamParser implements ParamParser {
@Override
public Date parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
try {
return new LocalDateTime(parameterValue).toDate();
} catch (IllegalArgumentException e) {
validation.addFieldViolation(field, ConstraintViolation.createForFieldWithDefault(
IsDate.KEY, field, IsDate.MESSAGE, parameterValue));
return null;
}
}
}
@Override
public Class getParsedType() {
return Date.class;
}
}
/**
* Parses a single string value as a CSV array of registered types.
*/
public static class CsvParamParser implements ParamParser {
private final Class arrayType;
private final ParamParser itemParser;
public CsvParamParser(Class arrayType, ParamParser parser) {
this.arrayType = arrayType;
this.itemParser = parser;
}
@Override
public T[] parseParameter(String field, String parameterValue, Validation validation) {
if (parameterValue == null || parameterValue.isEmpty() || validation.hasFieldViolation(field)) {
return null;
} else {
// split the string value as a csv
String [] values = parameterValue.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
// parse the individual values as the target item type
Class itemType = (Class) arrayType.getComponentType();
T[] array = (T[]) Array.newInstance(itemType, values.length);
for (int i = 0; i < values.length; i++) {
T t = itemParser.parseParameter(field, values[i], validation);
Array.set(array, i, t);
}
if (validation.hasFieldViolation(field)) {
return null;
}
return array;
}
}
@Override
public Class getParsedType() {
return arrayType;
}
}
/**
* Parses a multi-valued parameter as an array of registered types.
*/
public static class ArrayParamParser {
private final Class arrayType;
private final ParamParser itemParser;
public ArrayParamParser(Class arrayType, ParamParser parser) {
this.arrayType = arrayType;
this.itemParser = parser;
}
public T[] parseParameter(String field, String[] parameterValues, Validation validation) {
if (parameterValues == null || validation.hasFieldViolation(field)) {
return null;
} else {
// parse the individual values as the target item type
Class itemType = getItemType();
T[] array;
try {
array = (T[]) Array.newInstance(itemType, parameterValues.length);
} catch(ClassCastException e) {
return null;
}
for (int i = 0; i < parameterValues.length; i++) {
T t = itemParser.parseParameter(field, parameterValues[i], validation);
Array.set(array, i, t);
}
if (validation.hasFieldViolation(field)) {
return null;
}
return array;
}
}
public Class getArrayType() {
return arrayType;
}
public Class getItemType() {
return (Class) arrayType.getComponentType();
}
}
public static class ListParamParser {
private final Class itemType;
private final ParamParser itemParser;
public ListParamParser(Class itemType, ParamParser parser) {
this.itemType = itemType;
this.itemParser = parser;
}
public List parseParameter(String field, String[] parameterValues, Validation validation) {
if (parameterValues == null || validation.hasFieldViolation(field)) {
return null;
} else {
List list = Lists.newArrayList();
for (int i = 0; i < parameterValues.length; i++) {
list.add(itemParser.parseParameter(field, parameterValues[i], validation));
}
if (validation.hasFieldViolation(field)) {
return null;
}
return list;
}
}
public Class getItemType() {
return itemType;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy