001    // Copyright 2009, 2010, 2011 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.
014    package org.apache.tapestry5.beanvalidator;
015    
016    import org.apache.tapestry5.Asset;
017    import org.apache.tapestry5.MarkupWriter;
018    import org.apache.tapestry5.RenderSupport;
019    import org.apache.tapestry5.internal.beanvalidator.*;
020    import org.apache.tapestry5.ioc.Configuration;
021    import org.apache.tapestry5.ioc.MappedConfiguration;
022    import org.apache.tapestry5.ioc.OrderedConfiguration;
023    import org.apache.tapestry5.ioc.ServiceBinder;
024    import org.apache.tapestry5.ioc.annotations.Local;
025    import org.apache.tapestry5.ioc.services.PropertyShadowBuilder;
026    import org.apache.tapestry5.ioc.services.ThreadLocale;
027    import org.apache.tapestry5.services.*;
028    
029    import javax.validation.MessageInterpolator;
030    import javax.validation.Validator;
031    import javax.validation.ValidatorFactory;
032    import javax.validation.constraints.*;
033    import javax.validation.groups.Default;
034    
035    /**
036     * Module for JSR-303 services.
037     *
038     * @since 5.2.0.0
039     */
040    public class BeanValidatorModule
041    {
042        public static void bind(final ServiceBinder binder)
043        {
044            binder.bind(FieldValidatorDefaultSource.class, BeanFieldValidatorDefaultSource.class).withSimpleId();
045            binder.bind(BeanValidatorGroupSource.class, BeanValidationGroupSourceImpl.class);
046            binder.bind(BeanValidatorSource.class, BeanValidatorSourceImpl.class);
047            binder.bind(ClientConstraintDescriptorSource.class, ClientConstraintDescriptorImpl.class);
048        }
049    
050        public static void contributeServiceOverride(
051                MappedConfiguration<Class, Object> configuration,
052                @Local FieldValidatorDefaultSource source)
053        {
054            configuration.add(FieldValidatorDefaultSource.class, source);
055        }
056    
057        public static Validator buildBeanValidator(ValidatorFactory validatorFactory, PropertyShadowBuilder propertyShadowBuilder)
058        {
059            return propertyShadowBuilder.build(validatorFactory, "validator", Validator.class);
060        }
061    
062    
063        public static ValidatorFactory buildValidatorFactory(BeanValidatorSource beanValidatorSource, PropertyShadowBuilder propertyShadowBuilder)
064        {
065            return propertyShadowBuilder.build(beanValidatorSource, "validatorFactory", ValidatorFactory.class);
066        }
067    
068        public static void contributeBeanValidatorGroupSource(
069                final Configuration<Class> configuration)
070        {
071            configuration.add(Default.class);
072        }
073    
074        public static void contributeBeanValidatorSource(
075                final OrderedConfiguration<BeanValidatorConfigurer> configuration, final ThreadLocale threadLocale)
076        {
077            configuration.add("LocaleAwareMessageInterpolator", new BeanValidatorConfigurer()
078            {
079                public void configure(javax.validation.Configuration<?> configuration)
080                {
081                    MessageInterpolator defaultInterpolator = configuration.getDefaultMessageInterpolator();
082    
083                    configuration.messageInterpolator(new MessageInterpolatorImpl(defaultInterpolator, threadLocale));
084                }
085            });
086        }
087    
088        public static void contributeClientConstraintDescriptorSource(
089                final Configuration<ClientConstraintDescriptor> configuration)
090        {
091            configuration.add(new ClientConstraintDescriptor(Max.class, "maxnumber", "value"));
092            configuration.add(new ClientConstraintDescriptor(Min.class, "minnumber", "value"));
093            configuration.add(new ClientConstraintDescriptor(NotNull.class, "notnull"));
094            configuration.add(new ClientConstraintDescriptor(Null.class, "isnull"));
095            configuration.add(new ClientConstraintDescriptor(Pattern.class, "pattern", "regexp"));
096            configuration.add(new ClientConstraintDescriptor(Size.class, "size", "min", "max"));
097        }
098    
099        public void contributeMarkupRenderer(
100                OrderedConfiguration<MarkupRendererFilter> configuration,
101    
102                final AssetSource assetSource,
103    
104                final ThreadLocale threadLocale,
105    
106                final Environment environment)
107        {
108            MarkupRendererFilter injectBeanValidatorScript = new MarkupRendererFilter()
109            {
110                public void renderMarkup(MarkupWriter writer, MarkupRenderer renderer)
111                {
112                    RenderSupport renderSupport = environment.peek(RenderSupport.class);
113    
114                    Asset validators = assetSource.getAsset(null, "org/apache/tapestry5/beanvalidator/tapestry-beanvalidator.js",
115                            threadLocale.getLocale());
116    
117                    renderSupport.addScriptLink(validators);
118    
119                    renderer.renderMarkup(writer);
120                }
121            };
122    
123    
124            configuration.add("BeanValidatorScript", injectBeanValidatorScript, "after:*");
125        }
126    
127    }