001    // Copyright 2005 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    
015    package org.apache.tapestry.form.validator;
016    
017    import java.text.DecimalFormatSymbols;
018    
019    import org.apache.tapestry.IMarkupWriter;
020    import org.apache.tapestry.IRequestCycle;
021    import org.apache.tapestry.form.FormComponentContributorContext;
022    import org.apache.tapestry.form.IFormComponent;
023    import org.apache.tapestry.form.ValidationMessages;
024    import org.apache.tapestry.json.JSONLiteral;
025    import org.apache.tapestry.json.JSONObject;
026    import org.apache.tapestry.valid.ValidationConstants;
027    import org.apache.tapestry.valid.ValidationConstraint;
028    import org.apache.tapestry.valid.ValidationStrings;
029    import org.apache.tapestry.valid.ValidatorException;
030    
031    /**
032     * Validates that the input value is not larger than a particular maximum value.
033     * 
034     * @author Howard Lewis Ship
035     * @since 4.0
036     */
037    public class Max extends BaseValidator
038    {
039        private double _max;
040    
041        public Max()
042        {
043        }
044    
045        public Max(String initializer)
046        {
047            super(initializer);
048        }
049    
050        /**
051         * Does comparison based on the {@link Number#doubleValue()}.
052         */
053    
054        public void validate(IFormComponent field, ValidationMessages messages, Object object)
055                throws ValidatorException
056        {
057            Number value = (Number) object;
058    
059            if (value.doubleValue() > _max)
060                throw new ValidatorException(buildMessage(messages, field),
061                        ValidationConstraint.TOO_LARGE);
062        }
063    
064        private String buildMessage(ValidationMessages messages, IFormComponent field)
065        {
066            return messages.formatValidationMessage(
067                    getMessage(),
068                    ValidationStrings.VALUE_TOO_LARGE,
069                    new Object[]
070                    { field.getDisplayName(), new Double(_max) });
071        }
072    
073        public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
074                FormComponentContributorContext context, IFormComponent field)
075        {
076            JSONObject profile = context.getProfile();
077            
078            if (!profile.has(ValidationConstants.CONSTRAINTS)) {
079                profile.put(ValidationConstants.CONSTRAINTS, new JSONObject());
080            }
081            JSONObject cons = profile.getJSONObject(ValidationConstants.CONSTRAINTS);
082            
083            // TODO: Should find some way to provide this globally and cache.
084            DecimalFormatSymbols symbols = new DecimalFormatSymbols(context.getLocale());
085            
086            accumulateProperty(cons, field.getClientId(), 
087                    new JSONLiteral("[dojo.validate.isInRange,{"
088                            + "max:" + _max + ","
089                            + "decimal:" + JSONObject.quote(symbols.getDecimalSeparator())
090                            + "}]"));
091            
092            accumulateProfileProperty(field, profile, 
093                    ValidationConstants.CONSTRAINTS, buildMessage(context, field));
094        }
095    
096        public void setMax(double max)
097        {
098            _max = max;
099        }
100    
101    }