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.validation; 018 019import java.util.ArrayList; 020import java.util.Collections; 021import java.util.Iterator; 022import java.util.List; 023 024import org.apache.wicket.Component; 025import org.apache.wicket.behavior.Behavior; 026import org.apache.wicket.event.IEvent; 027import org.apache.wicket.markup.ComponentTag; 028import org.apache.wicket.markup.head.IHeaderResponse; 029import org.apache.wicket.util.lang.Args; 030 031/** 032 * A compound {@link IValidator}. Once an error is reported against the {@link IValidatable} being 033 * checked, the rest of the validator chain is ignored. 034 * 035 * @author Igor Vaynberg (ivaynberg) 036 * @param <T> 037 * type of validatable 038 * @since 1.2.6 039 */ 040public class CompoundValidator<T> extends Behavior implements IValidator<T> 041{ 042 private static final long serialVersionUID = 1L; 043 044 private final List<IValidator<T>> validators = new ArrayList<IValidator<T>>(2); 045 046 /** 047 * Constructor. 048 */ 049 public CompoundValidator() 050 { 051 } 052 053 /** 054 * Adds an <code>IValidator</code> to the chain of validators. 055 * 056 * @param validator 057 * an <code>IValidator</code> to be added 058 * @return this <code>ValidationError</code> for chaining purposes 059 */ 060 public final CompoundValidator<T> add(IValidator<T> validator) 061 { 062 Args.notNull(validator, "validator"); 063 064 validators.add(validator); 065 return this; 066 } 067 068 /** 069 * @see IValidator#validate(IValidatable) 070 */ 071 @Override 072 public final void validate(IValidatable<T> validatable) 073 { 074 Iterator<IValidator<T>> it = validators.iterator(); 075 while (it.hasNext() && validatable.isValid()) 076 { 077 it.next().validate(validatable); 078 } 079 } 080 081 /** 082 * Gets an unmodifiable list of the registered validators. 083 * 084 * @return unmodifiable list of delegate {@link IValidator}s inside this one 085 */ 086 public final List<IValidator<T>> getValidators() 087 { 088 return Collections.unmodifiableList(validators); 089 } 090 091 @Override 092 public void beforeRender(Component component) 093 { 094 for (IValidator<T> validator : validators) { 095 if (validator instanceof Behavior) { 096 ((Behavior)validator).beforeRender(component); 097 } 098 } 099 } 100 101 @Override 102 public void afterRender(Component component) 103 { 104 for (IValidator<T> validator : validators) { 105 if (validator instanceof Behavior) { 106 ((Behavior)validator).afterRender(component); 107 } 108 } 109 } 110 111 @Override 112 public void bind(Component component) 113 { 114 for (IValidator<T> validator : validators) { 115 if (validator instanceof Behavior) { 116 ((Behavior)validator).bind(component); 117 } 118 } 119 } 120 121 @Override 122 public void unbind(Component component) 123 { 124 for (IValidator<T> validator : validators) { 125 if (validator instanceof Behavior) { 126 ((Behavior)validator).unbind(component); 127 } 128 } 129 } 130 131 @Override 132 public void detach(Component component) 133 { 134 for (IValidator<T> validator : validators) { 135 if (validator instanceof Behavior) { 136 ((Behavior)validator).detach(component); 137 } 138 } 139 } 140 141 @Override 142 public void onException(Component component, RuntimeException exception) 143 { 144 for (IValidator<T> validator : validators) { 145 if (validator instanceof Behavior) { 146 ((Behavior)validator).onException(component, exception); 147 } 148 } 149 } 150 151 @Override 152 public boolean getStatelessHint(Component component) 153 { 154 for (IValidator<T> validator : validators) { 155 if (validator instanceof Behavior && ((Behavior)validator).getStatelessHint(component) == false) { 156 return false; 157 } 158 } 159 return super.getStatelessHint(component); 160 } 161 162 @Override 163 public void onComponentTag(Component component, ComponentTag tag) 164 { 165 for (IValidator<T> validator : validators) { 166 if (validator instanceof Behavior) { 167 ((Behavior)validator).onComponentTag(component, tag); 168 } 169 } 170 } 171 172 @Override 173 public void renderHead(Component component, IHeaderResponse response) 174 { 175 for (IValidator<T> validator : validators) { 176 if (validator instanceof Behavior) { 177 ((Behavior)validator).renderHead(component, response); 178 } 179 } 180 } 181 182 @Override 183 public void onConfigure(Component component) 184 { 185 for (IValidator<T> validator : validators) { 186 if (validator instanceof Behavior) { 187 ((Behavior)validator).onConfigure(component); 188 } 189 } 190 } 191 192 @Override 193 public void onEvent(Component component, IEvent<?> event) 194 { 195 for (IValidator<T> validator : validators) { 196 if (validator instanceof Behavior) { 197 ((Behavior)validator).onEvent(component, event); 198 } 199 } 200 } 201 202 @Override 203 public void onRemove(Component component) 204 { 205 for (IValidator<T> validator : validators) { 206 if (validator instanceof Behavior) { 207 ((Behavior)validator).onRemove(component); 208 } 209 } 210 } 211}