/* * Copyright (C) 2014 Civilian Framework. * * Licensed under the Civilian License (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.civilian-framework.org/license.txt * * 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.civilian.internal.controller.arg.conv; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import org.civilian.Request; import org.civilian.controller.MethodArg; import org.civilian.internal.controller.arg.StringMethodArg; import org.civilian.request.BadRequestException; import org.civilian.type.Type; import org.civilian.type.TypeLib; import org.civilian.type.fn.TypeSerializer; public abstract class SimpleConverter<T> extends Converter<T> { @Override public T getValue(Request request, StringMethodArg arg, TypeSerializer serializer, T defaultValue) throws Exception { T value = null; // s = null -> value = null // s = "" -> value = null possible, for instance for number conversions String s = arg.getValue(request); if (s != null) value = convert(arg, serializer, s); return value != null ? value : defaultValue; } /** * Converts a string parameter into a value. * @param arg the call argument which provided the string value or null if * not called in the context of a argument injection * @param stringValue the value, must not be null. * @throws Exception thrown if conversion throws an error. If arg is not null, * the error is catched and turned into a BadRequestException */ public T convert(MethodArg arg, TypeSerializer serializer, String stringValue) throws Exception { try { return convertImpl(serializer, stringValue); } catch(Exception e) { if (arg != null) { String message = arg.toString() + ": invalid value \"" + stringValue + '"'; throw new BadRequestException(message, e).setErrorValue(stringValue); } else throw e; } } /** * Converts a string parameter into a value. * @param stringValue the value, must not be null. */ protected abstract T convertImpl(TypeSerializer serializer, String stringValue) throws Exception; public T nullValue() { return null; } } class StringConverter extends SimpleConverter<String> { @Override protected String convertImpl(TypeSerializer serializer, String stringValue) throws Exception { return stringValue; } } class TypedConverter<T> extends SimpleConverter<T> { public TypedConverter(Type<T> type, boolean isPrimitive) { type_ = type; isPrimitive_ = isPrimitive; } @Override protected T convertImpl(TypeSerializer serializer, String stringValue) throws Exception { return serializer.parse(type_, stringValue); } @Override public T nullValue() { return isPrimitive_ ? (T)TypeLib.getPrimitiveDefaultValue(type_.getJavaPrimitiveType()) : null; } private Type<T> type_; private boolean isPrimitive_; } class CtorConverter<T> extends SimpleConverter<T> { public CtorConverter(Constructor<T> ctor) { ctor_ = ctor; } @Override protected T convertImpl(TypeSerializer serializer, String stringValue) throws Exception { return ctor_.newInstance(stringValue); } private Constructor<T> ctor_; } class MethodConverter<T> extends SimpleConverter<T> { public MethodConverter(Method method) { method_ = method; } @SuppressWarnings("unchecked") @Override protected T convertImpl(TypeSerializer serializer, String stringValue) throws Exception { return (T)method_.invoke(null, stringValue); } private Method method_; }