001// Copyright 2009-2013 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014package org.apache.tapestry5.beanvalidator.modules; 015 016import org.apache.tapestry5.MarkupWriter; 017import org.apache.tapestry5.beanvalidator.*; 018import org.apache.tapestry5.internal.beanvalidator.*; 019import org.apache.tapestry5.ioc.Configuration; 020import org.apache.tapestry5.ioc.MappedConfiguration; 021import org.apache.tapestry5.ioc.OrderedConfiguration; 022import org.apache.tapestry5.ioc.ServiceBinder; 023import org.apache.tapestry5.ioc.annotations.Local; 024import org.apache.tapestry5.ioc.services.PropertyShadowBuilder; 025import org.apache.tapestry5.ioc.services.ThreadLocale; 026import org.apache.tapestry5.services.FieldValidatorDefaultSource; 027import org.apache.tapestry5.services.javascript.DataConstants; 028import org.apache.tapestry5.services.javascript.JavaScriptSupport; 029 030import javax.validation.MessageInterpolator; 031import javax.validation.Validator; 032import javax.validation.ValidatorFactory; 033import javax.validation.constraints.*; 034import javax.validation.groups.Default; 035import java.util.Map; 036 037/** 038 * Module for JSR-303 services. 039 * 040 * @since 5.2.0.0 041 */ 042public class BeanValidatorModule 043{ 044 045 private static final String MODULE_NAME = "t5/beanvalidator/beanvalidator-validation"; 046 047 public static void bind(final ServiceBinder binder) 048 { 049 binder.bind(FieldValidatorDefaultSource.class, BeanFieldValidatorDefaultSource.class).withSimpleId(); 050 binder.bind(BeanValidatorGroupSource.class, BeanValidationGroupSourceImpl.class); 051 binder.bind(BeanValidatorSource.class, BeanValidatorSourceImpl.class); 052 binder.bind(ClientConstraintDescriptorSource.class, ClientConstraintDescriptorImpl.class); 053 } 054 055 public static void contributeServiceOverride( 056 MappedConfiguration<Class, Object> configuration, 057 @Local FieldValidatorDefaultSource source) 058 { 059 configuration.add(FieldValidatorDefaultSource.class, source); 060 } 061 062 public static Validator buildBeanValidator(ValidatorFactory validatorFactory, PropertyShadowBuilder propertyShadowBuilder) 063 { 064 return propertyShadowBuilder.build(validatorFactory, "validator", Validator.class); 065 } 066 067 068 public static ValidatorFactory buildValidatorFactory(BeanValidatorSource beanValidatorSource, PropertyShadowBuilder propertyShadowBuilder) 069 { 070 return propertyShadowBuilder.build(beanValidatorSource, "validatorFactory", ValidatorFactory.class); 071 } 072 073 public static void contributeBeanValidatorGroupSource( 074 final Configuration<Class> configuration) 075 { 076 configuration.add(Default.class); 077 } 078 079 public static void contributeBeanValidatorSource( 080 final OrderedConfiguration<BeanValidatorConfigurer> configuration, final ThreadLocale threadLocale) 081 { 082 configuration.add("LocaleAwareMessageInterpolator", new BeanValidatorConfigurer() 083 { 084 public void configure(javax.validation.Configuration<?> configuration) 085 { 086 MessageInterpolator defaultInterpolator = configuration.getDefaultMessageInterpolator(); 087 088 configuration.messageInterpolator(new MessageInterpolatorImpl(defaultInterpolator, threadLocale)); 089 } 090 }); 091 } 092 093 public static void contributeClientConstraintDescriptorSource(final JavaScriptSupport javaScriptSupport, 094 final Configuration<ClientConstraintDescriptor> configuration) 095 { 096 configuration.add(new BaseCCD(Max.class, "value") 097 { 098 public void applyClientValidation(MarkupWriter writer, String message, Map<String, Object> attributes) 099 { 100 javaScriptSupport.require("t5/core/validation"); 101 writer.attributes( 102 "data-validate", true, 103 "data-validate-max", attributes.get("value"), 104 "data-max-message", message); 105 106 } 107 }); 108 109 configuration.add(new BaseCCD(Min.class, "value") 110 { 111 public void applyClientValidation(MarkupWriter writer, String message, Map<String, Object> attributes) 112 { 113 javaScriptSupport.require("t5/core/validation"); 114 writer.attributes( 115 DataConstants.VALIDATION_ATTRIBUTE, true, 116 "data-validate-min", attributes.get("value"), 117 "data-min-message", message); 118 119 } 120 }); 121 122 configuration.add(new BaseCCD(NotNull.class) 123 { 124 public void applyClientValidation(MarkupWriter writer, String message, Map<String, Object> attributes) 125 { 126 javaScriptSupport.require("t5/core/validation"); 127 writer.attributes( 128 DataConstants.VALIDATION_ATTRIBUTE, true, 129 "data-optionality", "required", 130 "data-required-message", message); 131 } 132 }); 133 134 configuration.add(new BaseCCD(Null.class) 135 { 136 public void applyClientValidation(MarkupWriter writer, String message, Map<String, Object> attributes) 137 { 138 javaScriptSupport.require(MODULE_NAME); 139 writer.attributes( 140 DataConstants.VALIDATION_ATTRIBUTE, true, 141 "data-optionality", "prohibited", 142 "data-prohibited-message", message); 143 } 144 }); 145 146 configuration.add(new BaseCCD(Pattern.class, "regexp") 147 { 148 public void applyClientValidation(MarkupWriter writer, String message, Map<String, Object> attributes) 149 { 150 javaScriptSupport.require(MODULE_NAME); 151 writer.attributes( 152 DataConstants.VALIDATION_ATTRIBUTE, true, 153 "data-validate-regexp", attributes.get("regexp"), 154 "data-regexp-message", message); 155 } 156 }); 157 158 configuration.add(new BaseCCD(Size.class, "min", "max") 159 { 160 public void applyClientValidation(MarkupWriter writer, String message, Map<String, Object> attributes) 161 { 162 javaScriptSupport.require(MODULE_NAME); 163 writer.attributes( 164 DataConstants.VALIDATION_ATTRIBUTE, true, 165 "data-range-message", message); 166 167 int min = (Integer) attributes.get("min"); 168 169 if (min != 0) 170 { 171 writer.attributes("data-range-min", min); 172 } 173 174 int max = (Integer) attributes.get("max"); 175 176 if (max != Integer.MAX_VALUE) 177 { 178 writer.attributes("data-range-max", max); 179 } 180 } 181 }); 182 } 183}