001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.markup.html.form.validation; 018 019import java.util.HashMap; 020import java.util.Map; 021 022import org.apache.wicket.Component; 023import org.apache.wicket.WicketRuntimeException; 024import org.apache.wicket.behavior.Behavior; 025import org.apache.wicket.markup.html.form.Form; 026import org.apache.wicket.markup.html.form.FormComponent; 027import org.apache.wicket.model.IModel; 028import org.apache.wicket.util.lang.Args; 029import org.apache.wicket.util.lang.Classes; 030import org.apache.wicket.validation.ValidationError; 031 032 033/** 034 * Base class for {@link org.apache.wicket.markup.html.form.validation.IFormValidator}s. 035 * 036 * @author Igor Vaynberg (ivaynberg) 037 */ 038public abstract class AbstractFormValidator extends Behavior implements IFormValidator 039{ 040 private static final long serialVersionUID = 1L; 041 042 /** 043 * Can be bound to {@link Form}s only. 044 * 045 * @throws WicketRuntimeException 046 * if component is not a form 047 */ 048 @Override 049 public void bind(Component component) 050 { 051 if (!(component instanceof Form)) 052 { 053 throw new WicketRuntimeException("Behavior " + getClass().getName() 054 + " can only be added to an instance of a Form"); 055 } 056 } 057 058 /** 059 * Reports an error against validatable using the map returned by {@link #variablesMap()}for 060 * variable interpolations and message key returned by {@link #resourceKey()}. 061 * 062 * @param fc 063 * form component against which the error is reported 064 * 065 */ 066 public void error(FormComponent<?> fc) 067 { 068 error(fc, resourceKey(), variablesMap()); 069 } 070 071 /** 072 * Reports an error against the validatable using the given resource key 073 * 074 * @param fc 075 * form component against which the error is reported 076 * @param resourceKey 077 * The message resource key to use 078 */ 079 public void error(FormComponent<?> fc, final String resourceKey) 080 { 081 if (resourceKey == null) 082 { 083 throw new IllegalArgumentException("Argument [[resourceKey]] cannot be null"); 084 } 085 error(fc, resourceKey, variablesMap()); 086 } 087 088 /** 089 * Reports an error against the validatable using the given map for variable interpolations and 090 * message resource key provided by {@link #resourceKey()} 091 * 092 * @param fc 093 * form component against which the error is reported 094 * @param vars 095 * variables for variable interpolation 096 */ 097 public void error(FormComponent<?> fc, final Map<String, Object> vars) 098 { 099 if (vars == null) 100 { 101 throw new IllegalArgumentException("Argument [[vars]] cannot be null"); 102 } 103 error(fc, resourceKey(), vars); 104 } 105 106 /** 107 * Reports an error against the validatable using the specified resource key and variable map 108 * 109 * @param fc 110 * form component against which the error is reported 111 * @param resourceKey 112 * The message resource key to use 113 * @param vars 114 * The model for variable interpolation 115 */ 116 public void error(FormComponent<?> fc, final String resourceKey, Map<String, Object> vars) 117 { 118 Args.notNull(fc, "fc"); 119 Args.notNull(vars, "vars"); 120 Args.notNull(resourceKey, "resourceKey"); 121 122 ValidationError error = new ValidationError().addKey(resourceKey); 123 final String defaultKey = Classes.simpleName(getClass()); 124 if (!resourceKey.equals(defaultKey)) 125 { 126 error.addKey(defaultKey); 127 } 128 129 error.setVariables(vars); 130 fc.error(error); 131 } 132 133 /** 134 * Gets the default variables for interpolation. These are for every component: 135 * <ul> 136 * <li>${input(n)}: the user's input</li> 137 * <li>${name(n)}: the name of the component</li> 138 * <li>${label(n)}: the label of the component - either comes from FormComponent.labelModel or 139 * resource key [form-id].[form-component-id] in that order</li> 140 * </ul> 141 * 142 * @return a map with the variables for interpolation 143 */ 144 protected Map<String, Object> variablesMap() 145 { 146 FormComponent<?>[] formComponents = getDependentFormComponents(); 147 148 if (formComponents != null && formComponents.length > 0) 149 { 150 Map<String, Object> args = new HashMap<String, Object>(formComponents.length * 3); 151 for (int i = 0; i < formComponents.length; i++) 152 { 153 final FormComponent<?> formComponent = formComponents[i]; 154 155 String arg = "label" + i; 156 IModel<?> label = formComponent.getLabel(); 157 if (label != null) 158 { 159 args.put(arg, label.getObject()); 160 } 161 else 162 { 163 args.put( 164 arg, 165 formComponent.getLocalizer().getString(formComponent.getId(), 166 formComponent.getParent(), formComponent.getId())); 167 } 168 169 args.put("input" + i, formComponent.getInput()); 170 args.put("name" + i, formComponent.getId()); 171 } 172 return args; 173 } 174 else 175 { 176 return new HashMap<String, Object>(2); 177 } 178 } 179 180 /** 181 * Gets the resource key for validator's error message from the ApplicationSettings class. 182 * 183 * @return the resource key based on the form component 184 */ 185 protected String resourceKey() 186 { 187 return Classes.simpleName(getClass()); 188 } 189}