001package gwt.material.design.client.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 com.google.gwt.editor.client.Editor; 024import com.google.gwt.editor.client.EditorError; 025import com.google.gwt.event.logical.shared.ValueChangeEvent; 026import com.google.gwt.event.shared.EventBus; 027import com.google.gwt.event.shared.GwtEvent; 028import com.google.gwt.event.shared.HandlerRegistration; 029import com.google.gwt.event.shared.SimpleEventBus; 030import com.google.gwt.user.client.ui.HasValue; 031import com.google.gwt.user.client.ui.Widget; 032import gwt.material.design.client.base.error.ErrorHandler; 033import gwt.material.design.client.base.validator.HasValidators; 034import gwt.material.design.client.base.validator.ValidationChangedEvent; 035import gwt.material.design.client.base.validator.ValidationChangedEvent.ValidationChangedHandler; 036import gwt.material.design.client.base.validator.Validator; 037import gwt.material.design.client.base.validator.ValidatorWrapper; 038 039import java.util.ArrayList; 040import java.util.List; 041import java.util.Set; 042import java.util.TreeSet; 043 044/** 045 * Default validator mixin. Contains all of the validation logic. 046 * 047 * @param <W> the generic type 048 * @param <V> the value type 049 * @author Steven Jardine 050 */ 051public class ValidatorMixin<W extends Widget & HasValue<V> & Editor<V>, V> implements HasValidators<V> { 052 053 protected ErrorHandler errorHandler; 054 055 private EventBus eventBus; 056 057 protected W inputWidget; 058 059 private Boolean valid = null; 060 061 private boolean validateOnBlur; 062 063 protected Set<ValidatorWrapper<V>> validators = new TreeSet<>(); 064 065 /** 066 * Instantiates a new abstract validator mixin. 067 * 068 * @param inputWidget the input widget 069 * @param errorHandler the error handler 070 */ 071 public ValidatorMixin(W inputWidget, ErrorHandler errorHandler) { 072 this.inputWidget = inputWidget; 073 this.errorHandler = errorHandler; 074 eventBus = new SimpleEventBus(); 075 076 setupValueChangeValidation(); 077 } 078 079 protected HandlerRegistration setupValueChangeValidation() { 080 return inputWidget.addHandler(event -> { 081 validate(false); 082 }, ValueChangeEvent.getType()); 083 } 084 085 @Override 086 public HandlerRegistration addValidationChangedHandler(ValidationChangedHandler handler) { 087 return eventBus.addHandler(ValidationChangedEvent.getType(), handler); 088 } 089 090 @Override 091 public void addValidator(Validator<V> validator) { 092 validators.add(new ValidatorWrapper<>(validator, validators.size())); 093 } 094 095 @Override 096 public void fireEvent(GwtEvent<?> event) { 097 eventBus.fireEvent(event); 098 } 099 100 /** 101 * @return the inputWidget 102 */ 103 public W getInputWidget() { 104 return inputWidget; 105 } 106 107 @Override 108 public boolean isValidateOnBlur() { 109 return validateOnBlur; 110 } 111 112 @Override 113 public boolean removeValidator(Validator<V> validator) { 114 for (ValidatorWrapper<V> wrapper : validators) { 115 if (wrapper.getValidator().equals(validator)) { 116 return validators.remove(wrapper); 117 } 118 } 119 return false; 120 } 121 122 @Override 123 public void reset() { 124 if (errorHandler != null) { 125 errorHandler.clearErrors(); 126 } 127 } 128 129 /** 130 * Sets the error handler. 131 * 132 * @param errorHandler the new error handler 133 */ 134 public void setErrorHandler(ErrorHandler errorHandler) { 135 this.errorHandler = errorHandler; 136 } 137 138 @Override 139 public void setValidateOnBlur(boolean vob) { 140 validateOnBlur = vob; 141 } 142 143 @Override 144 public void setValidators(@SuppressWarnings("unchecked") Validator<V>... newValidators) { 145 validators.clear(); 146 for (Validator<V> validator : newValidators) { 147 addValidator(validator); 148 } 149 } 150 151 @Override 152 public boolean validate() { 153 return validate(true); 154 } 155 156 /** 157 * {@inheritDoc} 158 */ 159 @Override 160 public boolean validate(boolean show) { 161 Boolean oldValid = valid; 162 valid = true; 163 if (errorHandler != null && !validators.isEmpty()) { 164 List<EditorError> errors = new ArrayList<>(); 165 for (ValidatorWrapper<V> wrapper : validators) { 166 Validator<V> validator = wrapper.getValidator(); 167 List<EditorError> result = validator.validate(inputWidget, inputWidget.getValue()); 168 if (result != null && !result.isEmpty()) { 169 errors.addAll(result); 170 valid = false; 171 } 172 } 173 if (show) { 174 if (errors.size() > 0) { 175 errorHandler.showErrors(errors); 176 } else { 177 errorHandler.clearErrors(); 178 } 179 } 180 } 181 if (valid != oldValid) { 182 eventBus.fireEvent(new ValidationChangedEvent(valid)); 183 } 184 return valid; 185 } 186}