net.lucubrators.honeycomb.defaultimpl.engine.DefaultBindingMapper Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 2010 Alois Glomann [email protected]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package net.lucubrators.honeycomb.defaultimpl.engine;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import net.lucubrators.honeycomb.core.bind.DontBind;
import net.lucubrators.honeycomb.core.constraint.ConstraintAttribute;
import net.lucubrators.honeycomb.core.constraint.ConstraintAttributes;
import net.lucubrators.honeycomb.core.controller.FormObjectHolder;
import net.lucubrators.honeycomb.core.controller.FormObjectProvider;
import net.lucubrators.honeycomb.core.conversion.exceptions.ConversionException;
import net.lucubrators.honeycomb.core.engine.Bindables;
import net.lucubrators.honeycomb.core.messages.Messages;
import net.lucubrators.honeycomb.core.shared.Model;
import net.lucubrators.honeycomb.core.shared.annotations.CombAttribute;
import net.lucubrators.honeycomb.core.shared.annotations.CombAttributes;
import net.lucubrators.honeycomb.core.shared.annotations.Param;
import net.lucubrators.honeycomb.defaultimpl.conversion.HoneycombConverter;
import net.lucubrators.honeycomb.defaultimpl.engine.exceptions.UnknownArgumentMappingException;
import net.lucubrators.honeycomb.defaultimpl.reflect.MethodArgument;
import net.lucubrators.honeycomb.defaultimpl.util.Utils;
/**
* Default implementation of a {@link BindingMapper}
*
* - ServletRequest
* - ServletResponse
* - {@link Param}
* - {@link CombAttribute}
* - {@link CombAttributes}
* - {@link ConstraintAttribute} if the method is a constraint
* - {@link ConstraintAttributes} if the method is a constraint
* - {@link Model}
* - {@link Messages}
* - the form object (not for methods with {@link FormObjectProvider})
* - {@link DontBind} (not for methods with {@link FormObjectProvider})
*
*
* Currently it tries to convert {@link Param}, {@link CombAttribute} and
* {@link ConstraintAttribute}parameters to the desired type.
* For {@link Param} the fallBack will be used if the paramter is not available
* or conversion fails. The other two will just fail, if you provided not
* covertable values.
* Conversion is dependent on the provided {@link HoneycombConverter}
* */
public class DefaultBindingMapper implements BindingMapper {
private HoneycombConverter honeycombConverter;
public Object map(MethodArgument methodArgument, Bindables bindables) {
List annotations = methodArgument.getAnnotations();
Type reflectionType = methodArgument.getType();
Class> argumentClass = methodArgument.getArgumentClass();
if (ServletRequest.class.isAssignableFrom(argumentClass)) {
return bindables.getRequest();
}
if (ServletResponse.class.isAssignableFrom(argumentClass)) {
return bindables.getResponse();
}
if (Model.class == argumentClass) {
return bindables.getModel();
}
if (Messages.class == argumentClass) {
return bindables.getMessages();
}
if (Utils.hasAnnotation(Param.class, annotations)) {
Param param = Utils.getAnnotation(Param.class, annotations);
return convertParameter(param, argumentClass, reflectionType, bindables.getRequest());
}
if (Utils.hasAnnotation(CombAttribute.class, annotations)) {
CombAttribute combAttribute = Utils.getAnnotation(CombAttribute.class, annotations);
Map combAttributes = bindables.getCombAttributes();
if (combAttributes.containsKey(combAttribute.value())) {
String combAttributeValue = combAttributes.get(combAttribute.value());
return convertAttribute(combAttributeValue, argumentClass, reflectionType, bindables.getRequest().getLocale());
}
throw new IllegalArgumentException("Comb does not have an attribute with name: " + combAttribute.value());
}
if (Utils.hasAnnotation(CombAttributes.class, annotations) && Map.class.isAssignableFrom(argumentClass)) {
return bindables.getCombAttributes();
}
if (Utils.hasAnnotation(ConstraintAttribute.class, annotations)) {
ConstraintAttribute constraintAttr = Utils.getAnnotation(ConstraintAttribute.class, annotations);
if (null == bindables.getConstraintHolder()) {
throw new IllegalArgumentException(
"There is no constraint defined for your method. Are you trying to get a constraint attribute in a controller?");
}
Map constraintAttributes = bindables.getConstraintHolder().getAttributes();
if (constraintAttributes.containsKey(constraintAttr.value())) {
return convertAttribute(constraintAttributes.get(constraintAttr.value()), argumentClass, reflectionType, bindables.getRequest().getLocale());
}
throw new IllegalArgumentException("Constraint does not have an attribute with name: " + constraintAttr.value());
}
if (Utils.hasAnnotation(ConstraintAttributes.class, annotations) && Map.class.isAssignableFrom(argumentClass)) {
if (null == bindables.getConstraintHolder()) {
throw new IllegalArgumentException(
"There is no constraint defined for your method. Are you trying to get a constraint attribute in a controller?");
}
return bindables.getConstraintHolder().getAttributes();
}
if (Utils.hasAnnotation(DontBind.class, annotations)) {
FormObjectHolder formObjectHolder = bindables.getFormObjectHolder();
if (null != formObjectHolder) {
return formObjectHolder.getDontBind();
}
return null;
}
if (bindables.getFormObjectHolder() != null && argumentClass == bindables.getFormObjectHolder().getObject().getClass()) {
return bindables.getFormObjectHolder().getObject();
}
throw new UnknownArgumentMappingException("Could not bind methodArgument." + methodArgument);
}
private Object convertOrFailImmediatley(final Object toConvert, final Class> toType, final Type reflectionType, final Locale locale) {
try {
return honeycombConverter.convert(toConvert, toType, reflectionType, locale);
} catch (ConversionException e) {
throw new RuntimeException("Could not converte " + toConvert + " to tpye " + toType, e);
}
}
private Object convertAttribute(Object toConvert, final Class> toType, final Type reflectionType, final Locale locale) {
Object convert = convertOrFailImmediatley(toConvert, toType, reflectionType, locale);
if (convert == null && toType.isPrimitive()) {
throw new RuntimeException("conversion result is null but totype is primitive. Failing here imediately");
}
return convert;
}
private Object convertParameter(final Param param, final Class> toType, final Type reflectionType, final HttpServletRequest request) {
String paramName = param.name();
String[] fallBack = param.fallBack();
String[] parameterValues = request.getParameterValues(paramName);
Locale locale = request.getLocale();
boolean fallbackUsed = false;
Object toConvert = parameterValues;
if (parameterValues == null || parameterValues.length == 0) {
fallbackUsed = true;
parameterValues = fallBack;
toConvert = parameterValues;
}
Object converted = null;
try {
converted = honeycombConverter.convert(toConvert, toType, reflectionType, locale);
} catch (ConversionException e) {
if (!fallbackUsed) {
converted = convertOrFailImmediatley(fallBack, toType, reflectionType, locale);
} else {
throw new RuntimeException("Could not convert request paramter " + paramName + " to type " + toType + ".Fallback was useless: "
+ Arrays.toString(fallBack), e);
}
}
if (converted == null && toType.isPrimitive() && !fallbackUsed) {
converted = convertOrFailImmediatley(fallBack, toType, reflectionType, locale);
}
return converted;
}
public void setHoneycombConverter(HoneycombConverter honeycombConverter) {
this.honeycombConverter = honeycombConverter;
}
protected HoneycombConverter getHoneycombConverter() {
return honeycombConverter;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy