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     * Expects the object to be a number, and checks that the value not smaller than a specified value.
033     * 
034     * @author Howard Lewis Ship
035     * @since 4.0
036     */
037    public class Min extends BaseValidator
038    {
039        private double _min;
040    
041        public Min()
042        {
043        }
044    
045        public Min(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 (_min > value.doubleValue())
060                throw new ValidatorException(buildMessage(messages, field),
061                        ValidationConstraint.TOO_SMALL);
062        }
063    
064        private String buildMessage(ValidationMessages messages, IFormComponent field)
065        {
066            return messages.formatValidationMessage(
067                    getMessage(),
068                    ValidationStrings.VALUE_TOO_SMALL,
069                    new Object[]
070                    { field.getDisplayName(), new Double(_min) });
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                            + "min:" + _min + ","
089                            + "decimal:" + JSONObject.quote(symbols.getDecimalSeparator())
090                            + "}]"));
091            
092            accumulateProfileProperty(field, profile, 
093                    ValidationConstants.CONSTRAINTS, buildMessage(context, field));
094        }
095    
096        public void setMin(double min)
097        {
098            _min = min;
099        }
100    
101    }