org.springframework.webflow.validation.BeanValidationHintResolver Maven / Gradle / Ivy
/*
* Copyright 2008-2012 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 org.springframework.webflow.validation;
import java.util.ArrayList;
import java.util.List;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.webflow.execution.FlowExecutionException;
/**
* A JSR-303 (Bean Validation) implementation of {@link ValidationHintResolver}
* that resolves String-based hints to a {@code Class>} array.
*
* @author Rossen Stoyanchev
* @since 2.4
*/
public class BeanValidationHintResolver implements ValidationHintResolver {
/**
* Resolve each hint as a fully qualified class name or the name of an inner
* {@code Class} in the model type or the model or its parent types.
*
* @param model the model object
* @param flowId the current flow id
* @param stateId the current view state id
* @param hints the hints to resolve
*
* @return the resolved hints or {@code null}
* @throws FlowExecutionException if a hint is unresolved
*
* @see #handleUnresolvedHint(Object, String, String, String)
*/
public Class>[] resolveValidationHints(Object model, String flowId, String stateId, String[] hints)
throws FlowExecutionException {
if (ObjectUtils.isEmpty(hints)) {
return null;
}
List> result = new ArrayList<>();
for (String hint : hints) {
if (hint.equalsIgnoreCase("Default")) {
hint = "javax.validation.groups.Default";
}
Class> resolvedHint = toClass(hint);
if ((resolvedHint == null) && (model != null)) {
resolvedHint = findInnerClass(model.getClass(), StringUtils.capitalize(hint));
}
if (resolvedHint == null) {
resolvedHint = handleUnresolvedHint(model, flowId, stateId, hint);
}
if (resolvedHint != null) {
result.add(resolvedHint);
}
}
return result.toArray(new Class>[result.size()]);
}
private Class> toClass(String hint) {
try {
return Class.forName(hint);
}
catch (ClassNotFoundException e) {
// Ignore
}
return null;
}
private Class> findInnerClass(Class> targetClass, String hint) {
try {
return Class.forName(targetClass.getName() + "$" + hint);
}
catch (ClassNotFoundException e) {
Class> superClass = targetClass.getSuperclass();
if (superClass != null) {
return findInnerClass(superClass, hint);
}
}
return null;
}
/**
* Invoked when a hint could not be resolved. This implementation raises a
* {@link FlowExecutionException}.
*
* @param model the model object that will be validated using the hints
* @param flowId the current flow id
* @param stateId the current state id
* @param hint the hint
* @return the resolved hint
*
* @throws FlowExecutionException
*/
protected Class> handleUnresolvedHint(Object model, String flowId, String stateId, String hint)
throws FlowExecutionException {
throw new FlowExecutionException(flowId, stateId, "Failed to resolve validation hint [" + hint + "]");
}
}