package com.github.dynamicextensionsalfresco.webscripts.arguments; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import com.github.dynamicextensionsalfresco.webscripts.annotations.RequestParam; import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptResponse; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * {@link ArgumentResolver} that handles parameters annotated with {@link RequestParam}. * * @author Laurens Fridael */ public class RequestParamArgumentResolver implements ArgumentResolver<Object, RequestParam> { /* Dependencies */ private final StringValueConverter stringValueConverter; /* Main operations */ RequestParamArgumentResolver(final StringValueConverter stringValueConverter) { Assert.notNull(stringValueConverter); this.stringValueConverter = stringValueConverter; } @Override public boolean supports(Class<?> parameterType, final Class<? extends Annotation> annotationType) { if (parameterType.isArray()) { parameterType = parameterType.getComponentType(); } return getStringValueConverter().isSupportedType(parameterType) && RequestParam.class.equals(annotationType); } @Override public Object resolveArgument(final Class<?> parameterType, final RequestParam requestParam, final String name, final WebScriptRequest request, final WebScriptResponse response) { Assert.notNull(requestParam, "RequestParam annotation cannot be null."); String parameterName = requestParam.value(); if (StringUtils.hasText(parameterName) == false) { parameterName = name; } if (StringUtils.hasText(parameterName) == false) { throw new RuntimeException( "Cannot determine name of request parameter. Specify the name using the @RequestParam annotation."); } final Object parameter; if (parameterType.isArray() == false) { parameter = handleSingleParameter(parameterType, requestParam, request, parameterName); } else if (StringUtils.hasText(requestParam.delimiter())) { parameter = handleDelimitedParameter(parameterType, requestParam, request, parameterName); } else { parameter = handleMultipleParameters(parameterType, requestParam, request, parameterName); } return parameter; } /* Utility operations */ private Object handleSingleParameter(final Class<?> parameterType, final RequestParam requestParam, final WebScriptRequest request, final String parameterName) { final String parameterValue = request.getParameter(parameterName); Object value = null; if (parameterValue != null) { value = getStringValueConverter().convertStringValue(parameterType, parameterValue); } else { if (StringUtils.hasText(requestParam.defaultValue())) { value = getStringValueConverter().convertStringValue(parameterType, requestParam.defaultValue()); } if (requestParam.required() && value == null) { throw new IllegalStateException(String.format("Request parameter not available: %s", parameterName)); } } return value; } private Object handleDelimitedParameter(final Class<?> parameterType, final RequestParam requestParam, final WebScriptRequest request, final String parameterName) { String parameterValue = request.getParameter(parameterName); if (parameterValue == null) { if (StringUtils.hasText(requestParam.defaultValue())) { parameterValue = requestParam.defaultValue(); } else if (requestParam.required()) { throw new IllegalStateException(String.format("Request parameter not available: %s", parameterName)); } } if (parameterValue != null) { final String[] parameterValues = parameterValue.split(requestParam.delimiter()); return convertToArray(parameterType.getComponentType(), parameterValues); } else { return null; } } private Object handleMultipleParameters(final Class<?> parameterType, final RequestParam requestParam, final WebScriptRequest request, final String parameterName) { String[] parameterValues = request.getParameterValues(parameterName); if (parameterValues == null) { if (requestParam.required()) { throw new IllegalStateException(String.format("Request parameter not available: %s", parameterName)); } else { parameterValues = new String[] { requestParam.defaultValue() }; } } return convertToArray(parameterType.getComponentType(), parameterValues); } private Object[] convertToArray(final Class<?> arrayComponentType, final String[] parameterValues) { final Object[] values = (Object[]) Array.newInstance(arrayComponentType, parameterValues.length); for (int i = 0; i < parameterValues.length; i++) { values[i] = getStringValueConverter().convertStringValue(arrayComponentType, parameterValues[i]); } return values; } /* Dependencies */ protected StringValueConverter getStringValueConverter() { return stringValueConverter; } }