001package org.gwtbootstrap3.client.ui.base.mixin; 002 003/* 004 * #%L 005 * GwtBootstrap3 006 * %% 007 * Copyright (C) 2013 - 2015 GwtBootstrap3 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import java.util.ArrayList; 024import java.util.List; 025import java.util.Set; 026import java.util.TreeSet; 027 028import org.gwtbootstrap3.client.ui.form.error.ErrorHandler; 029import org.gwtbootstrap3.client.ui.form.validator.HasValidators; 030import org.gwtbootstrap3.client.ui.form.validator.ValidationChangedEvent; 031import org.gwtbootstrap3.client.ui.form.validator.ValidationChangedEvent.ValidationChangedHandler; 032import org.gwtbootstrap3.client.ui.form.validator.Validator; 033import org.gwtbootstrap3.client.ui.form.validator.ValidatorWrapper; 034 035import com.google.gwt.editor.client.Editor; 036import com.google.gwt.editor.client.EditorError; 037import com.google.gwt.event.dom.client.BlurEvent; 038import com.google.gwt.event.dom.client.BlurHandler; 039import com.google.gwt.event.logical.shared.ValueChangeEvent; 040import com.google.gwt.event.logical.shared.ValueChangeHandler; 041import com.google.gwt.event.shared.GwtEvent; 042import com.google.gwt.user.client.ui.HasValue; 043import com.google.gwt.user.client.ui.Widget; 044import com.google.web.bindery.event.shared.EventBus; 045import com.google.web.bindery.event.shared.HandlerRegistration; 046import com.google.web.bindery.event.shared.SimpleEventBus; 047 048/** 049 * Abstract validator mixin. Contains all of the validation logic. 050 * 051 * @param <W> the generic type 052 * @param <V> the value type 053 * 054 * @author Steven Jardine 055 */ 056public class DefaultValidatorMixin<W extends Widget & HasValue<V> & Editor<V>, V> implements HasValidators<V> { 057 058 protected ErrorHandler errorHandler; 059 060 private EventBus eventBus; 061 062 private W inputWidget; 063 064 private Boolean valid = null; 065 066 private boolean validateOnBlur; 067 068 protected Set<ValidatorWrapper<V>> validators = new TreeSet<ValidatorWrapper<V>>(); 069 070 /** 071 * Instantiates a new abstract validator mixin. 072 * 073 * @param inputWidget the input widget 074 * @param errorHandler the error handler 075 */ 076 public DefaultValidatorMixin(W inputWidget, ErrorHandler errorHandler) { 077 this.inputWidget = inputWidget; 078 this.errorHandler = errorHandler; 079 eventBus = new SimpleEventBus(); 080 081 setupBlurValidation(); 082 setupValueChangeValidation(); 083 } 084 085 protected HandlerRegistration setupBlurValidation() { 086 return inputWidget.addDomHandler(new BlurHandler() { 087 @Override 088 public void onBlur(BlurEvent event) { 089 validate(validateOnBlur); 090 } 091 }, BlurEvent.getType()); 092 } 093 094 protected HandlerRegistration setupValueChangeValidation() { 095 return inputWidget.addHandler(new ValueChangeHandler<V>() { 096 @Override 097 public void onValueChange(ValueChangeEvent<V> event) { 098 validate(false); 099 } 100 }, ValueChangeEvent.getType()); 101 } 102 103 @Override 104 public HandlerRegistration addValidationChangedHandler(ValidationChangedHandler handler) { 105 return eventBus.addHandler(ValidationChangedEvent.getType(), handler); 106 } 107 108 /** {@inheritDoc} */ 109 @Override 110 public void addValidator(Validator<V> validator) { 111 validators.add(new ValidatorWrapper<V>(validator, validators.size())); 112 } 113 114 @Override 115 public void fireEvent(GwtEvent<?> event) { 116 eventBus.fireEvent(event); 117 } 118 119 /** 120 * @return the inputWidget 121 */ 122 public W getInputWidget() { 123 return inputWidget; 124 } 125 126 /** {@inheritDoc} */ 127 @Override 128 public boolean getValidateOnBlur() { 129 return validateOnBlur; 130 } 131 132 /** {@inheritDoc} */ 133 @Override 134 public boolean removeValidator(Validator<V> validator) { 135 for (ValidatorWrapper<V> wrapper : validators) { 136 if (wrapper.getValidator().equals(validator)) { return validators.remove(wrapper); } 137 } 138 return false; 139 } 140 141 /** {@inheritDoc} */ 142 @Override 143 public void reset() { 144 if (errorHandler != null) { 145 errorHandler.clearErrors(); 146 } 147 } 148 149 /** 150 * Sets the error handler. 151 * 152 * @param errorHandler the new error handler 153 */ 154 public void setErrorHandler(ErrorHandler errorHandler) { 155 this.errorHandler = errorHandler; 156 } 157 158 /** {@inheritDoc} */ 159 @Override 160 public void setValidateOnBlur(boolean vob) { 161 validateOnBlur = vob; 162 } 163 164 /** {@inheritDoc} */ 165 @Override 166 public void setValidators(@SuppressWarnings("unchecked") Validator<V>... newValidators) { 167 validators.clear(); 168 for (Validator<V> validator : newValidators) { 169 addValidator(validator); 170 } 171 } 172 173 /** {@inheritDoc} */ 174 @Override 175 public boolean validate() { 176 return validate(true); 177 } 178 179 /** {@inheritDoc} */ 180 @Override 181 public boolean validate(boolean show) { 182 Boolean oldValid = valid; 183 valid = true; 184 if (errorHandler != null && !validators.isEmpty()) { 185 List<EditorError> errors = new ArrayList<EditorError>(); 186 for (ValidatorWrapper<V> wrapper : validators) { 187 Validator<V> validator = wrapper.getValidator(); 188 List<EditorError> result = validator.validate(inputWidget, inputWidget.getValue()); 189 if (result != null && !result.isEmpty()) { 190 errors.addAll(result); 191 valid = false; 192 } 193 } 194 if (show) { 195 if (errors.size() > 0) { 196 errorHandler.showErrors(errors); 197 } else { 198 errorHandler.clearErrors(); 199 } 200 } 201 } 202 if (valid != oldValid) { 203 eventBus.fireEvent(new ValidationChangedEvent(valid)); 204 } 205 return valid; 206 } 207 208}