All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wicketstuff.jsr303.BeanValidator Maven / Gradle / Ivy

There is a newer version: 6.30.0
Show newest version
package org.wicketstuff.jsr303;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.validation.ConstraintViolation;

import org.apache.wicket.Application;
import org.apache.wicket.Component;
import org.apache.wicket.Localizer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.ValidationErrorFeedback;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.util.string.interpolator.MapVariableInterpolator;
import org.apache.wicket.validation.IErrorMessageSource;
import org.apache.wicket.validation.IValidationError;

/**
 * BeanValidator is not actually a Wicket IValidator. The reason for this is the fact, that values
 * must have been written back into the Bean for it to be able to validate. This is supposed to be
 * used manually within the onSubmit call of a form, for example. It may report the error to the
 * component being passed on construction.
 */
public class BeanValidator
{
	private final Form context;

	public BeanValidator(final Form contextOrNull)
	{
		context = contextOrNull;
	}

	public  boolean isValid(final U e)
	{
		if (e == null)
		{
			return true;
		}

		JSR303Validation.getInstance();
		final Set> s = JSR303Validation.getValidator().validate(e);
		if (s.isEmpty())
		{
			return true;
		}

		for (final ConstraintViolation v : s)
		{
			if (context != null)
			{
				final IValidationError ve = new ViolationErrorBuilder.Bean(v).createError();
				context.error(new ValidationErrorFeedback(ve,
					ve.getErrorMessage(new MessageSource())));
			}
		}
		return false;
	}

	class MessageSource implements IErrorMessageSource
	{
		private final Set triedKeys = new LinkedHashSet();

		// basically copied from FormComponent, suggestions welcome

		public String getMessage(String key, java.util.Map vars) {

			// Use the following log4j config for detailed logging on the
			// property resolution
			// process
			// log4j.logger.org.apache.wicket.resource.loader=DEBUG
			// log4j.logger.org.apache.wicket.Localizer=DEBUG

			final Localizer localizer = context.getLocalizer();

			// retrieve prefix that will be used to construct message keys
			final String prefix = context.getValidatorKeyPrefix();
			String message = null;

			// first try the full form of key [form-component-id].[key]
			String resource = context.getId() + "." + prefix(prefix, key);
			message = getString(localizer, resource, context);

			// if not found, try a more general form (without prefix)
			// [form-component-id].[prefix].[key]
			if (Strings.isEmpty(message) && Strings.isEmpty(prefix))
			{
				resource = context.getId() + "." + key;
				message = getString(localizer, resource, context);
			}

			// If not found try a more general form [prefix].[key]
			if (Strings.isEmpty(message))
			{
				resource = prefix(prefix, key);
				message = getString(localizer, resource, context);
			}

			// If not found try the most general form [key]
			if (Strings.isEmpty(message))
			{
				// Try a variation of the resource key
				message = getString(localizer, key, context);
			}

			// convert empty string to null in case our default value of "" was
			// returned from localizer
			if (Strings.isEmpty(message))
			{
				message = null;
			} else {
				message = substitute(message, vars);
			}
			return message;
		}

		private String prefix(final String prefix, final String key)
		{
			if (!Strings.isEmpty(prefix))
			{
				return prefix + "." + key;
			}
			else
			{
				return key;
			}
		}

		/**
		 * @param localizer
		 * @param key
		 * @param component
		 * @return string
		 */
		private String getString(final Localizer localizer, final String key,
			final Component component)
		{
			triedKeys.add(key);

			// Note: It is important that the default value of "" is
			// provided to getString() not to throw a MissingResourceException
			// or to
			// return a default string like "[Warning: String ..."
			return localizer.getString(key, component, "");
		}

		private String substitute(final String string, final Map vars)
			throws IllegalStateException
		{
			return new MapVariableInterpolator(string, vars, Application.get()
				.getResourceSettings()
				.getThrowExceptionOnMissingResource()).toString();
		}

	}
}