/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.wicket.markup.html.form.validation; import java.util.HashMap; import java.util.Map; import org.apache.wicket.Component; import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.model.IModel; import org.apache.wicket.util.lang.Args; import org.apache.wicket.util.lang.Classes; import org.apache.wicket.validation.ValidationError; /** * Base class for {@link org.apache.wicket.markup.html.form.validation.IFormValidator}s. * * @author Igor Vaynberg (ivaynberg) */ public abstract class AbstractFormValidator extends Behavior implements IFormValidator { private static final long serialVersionUID = 1L; /** * Can be bound to {@link Form}s only. * * @throws WicketRuntimeException * if component is not a form */ @Override public void bind(Component component) { if (!(component instanceof Form)) { throw new WicketRuntimeException("Behavior " + getClass().getName() + " can only be added to an instance of a Form"); } } /** * Reports an error against validatable using the map returned by {@link #variablesMap()}for * variable interpolations and message key returned by {@link #resourceKey()}. * * @param fc * form component against which the error is reported * */ public void error(FormComponent<?> fc) { error(fc, resourceKey(), variablesMap()); } /** * Reports an error against the validatable using the given resource key * * @param fc * form component against which the error is reported * @param resourceKey * The message resource key to use */ public void error(FormComponent<?> fc, final String resourceKey) { if (resourceKey == null) { throw new IllegalArgumentException("Argument [[resourceKey]] cannot be null"); } error(fc, resourceKey, variablesMap()); } /** * Reports an error against the validatable using the given map for variable interpolations and * message resource key provided by {@link #resourceKey()} * * @param fc * form component against which the error is reported * @param vars * variables for variable interpolation */ public void error(FormComponent<?> fc, final Map<String, Object> vars) { if (vars == null) { throw new IllegalArgumentException("Argument [[vars]] cannot be null"); } error(fc, resourceKey(), vars); } /** * Reports an error against the validatable using the specified resource key and variable map * * @param fc * form component against which the error is reported * @param resourceKey * The message resource key to use * @param vars * The model for variable interpolation */ public void error(FormComponent<?> fc, final String resourceKey, Map<String, Object> vars) { Args.notNull(fc, "fc"); Args.notNull(vars, "vars"); Args.notNull(resourceKey, "resourceKey"); ValidationError error = new ValidationError().addKey(resourceKey); final String defaultKey = Classes.simpleName(getClass()); if (!resourceKey.equals(defaultKey)) { error.addKey(defaultKey); } error.setVariables(vars); fc.error(error); } /** * Gets the default variables for interpolation. These are for every component: * <ul> * <li>${input(n)}: the user's input</li> * <li>${name(n)}: the name of the component</li> * <li>${label(n)}: the label of the component - either comes from FormComponent.labelModel or * resource key [form-id].[form-component-id] in that order</li> * </ul> * * @return a map with the variables for interpolation */ protected Map<String, Object> variablesMap() { FormComponent<?>[] formComponents = getDependentFormComponents(); if (formComponents != null && formComponents.length > 0) { Map<String, Object> args = new HashMap<String, Object>(formComponents.length * 3); for (int i = 0; i < formComponents.length; i++) { final FormComponent<?> formComponent = formComponents[i]; String arg = "label" + i; IModel<?> label = formComponent.getLabel(); if (label != null) { args.put(arg, label.getObject()); } else { args.put( arg, formComponent.getLocalizer().getString(formComponent.getId(), formComponent.getParent(), formComponent.getId())); } args.put("input" + i, formComponent.getInput()); args.put("name" + i, formComponent.getId()); } return args; } else { return new HashMap<String, Object>(2); } } /** * Gets the resource key for validator's error message from the ApplicationSettings class. * * @return the resource key based on the form component */ protected String resourceKey() { return Classes.simpleName(getClass()); } }