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.translator;
016    
017    import java.text.DecimalFormat;
018    import java.text.DecimalFormatSymbols;
019    import java.text.Format;
020    import java.util.Locale;
021    
022    import org.apache.hivemind.util.PropertyUtils;
023    import org.apache.tapestry.IMarkupWriter;
024    import org.apache.tapestry.IRequestCycle;
025    import org.apache.tapestry.TapestryUtils;
026    import org.apache.tapestry.form.FormComponentContributorContext;
027    import org.apache.tapestry.form.IFormComponent;
028    import org.apache.tapestry.valid.ValidationConstraint;
029    import org.apache.tapestry.valid.ValidationStrings;
030    
031    /**
032     * A {@link java.text.DecimalFormat}-based {@link Translator} implementation.
033     * 
034     * @author Paul Ferraro
035     * @since 4.0
036     */
037    public class NumberTranslator extends FormatTranslator
038    {
039        private boolean _omitZero = true;
040    
041        public NumberTranslator()
042        {
043        }
044    
045        protected String formatObject(IFormComponent field, Locale locale, Object object)
046        {
047            Number number = (Number) object;
048    
049            if (_omitZero)
050            {
051                if (number.doubleValue() == 0)
052    
053                    return "";
054            }
055    
056            return super.formatObject(field, locale, object);
057        }
058    
059        // Needed until HIVEMIND-134 fix is available
060        public NumberTranslator(String initializer)
061        {
062            PropertyUtils.configureProperties(this, initializer);
063        }
064    
065        /**
066         * @see org.apache.tapestry.form.AbstractFormComponentContributor#defaultScript()
067         */
068        protected String defaultScript()
069        {
070            return "/org/apache/tapestry/form/translator/NumberTranslator.js";
071        }
072    
073        /**
074         * @see org.apache.tapestry.form.translator.FormatTranslator#defaultPattern()
075         */
076        protected String defaultPattern()
077        {
078            return "#";
079        }
080    
081        /**
082         * @see org.apache.tapestry.form.translator.FormatTranslator#getFormat(java.util.Locale)
083         */
084        protected Format getFormat(Locale locale)
085        {
086            return getDecimalFormat(locale);
087        }
088    
089        public DecimalFormat getDecimalFormat(Locale locale)
090        {
091            return new DecimalFormat(getPattern(), new DecimalFormatSymbols(locale));
092        }
093    
094        /**
095         * @see org.apache.tapestry.form.translator.FormatTranslator#getMessageKey()
096         */
097        protected String getMessageKey()
098        {
099            return ValidationStrings.INVALID_NUMBER;
100        }
101    
102        /**
103         * @see org.apache.tapestry.form.translator.AbstractTranslator#getMessageParameters(java.util.Locale,
104         *      java.lang.String)
105         */
106        protected Object[] getMessageParameters(Locale locale, String label)
107        {
108            String pattern = getDecimalFormat(locale).toLocalizedPattern();
109    
110            return new Object[]
111            { label, pattern };
112        }
113    
114        /**
115         * @see org.apache.tapestry.form.FormComponentContributor#renderContribution(org.apache.tapestry.IMarkupWriter,
116         *      org.apache.tapestry.IRequestCycle, FormComponentContributorContext,
117         *      org.apache.tapestry.form.IFormComponent)
118         */
119        public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
120                FormComponentContributorContext context, IFormComponent field)
121        {
122            super.renderContribution(writer, cycle, context, field);
123    
124            String message = TapestryUtils.enquote(buildMessage(context, field, getMessageKey()));
125    
126            context.addSubmitHandler("function(event) { Tapestry.validate_number(event, '"
127                    + field.getClientId() + "', " + message + "); }");
128        }
129    
130        /**
131         * @see org.apache.tapestry.form.translator.FormatTranslator#getConstraint()
132         */
133        protected ValidationConstraint getConstraint()
134        {
135            return ValidationConstraint.NUMBER_FORMAT;
136        }
137    
138        /**
139         * If true (which is the default for the property), then values that are 0 are rendered to an
140         * empty string, not "0" or "0.00". This is useful in most cases where the field is optional; it
141         * allow the field to render blank when no value is present.
142         */
143    
144        public void setOmitZero(boolean omitZero)
145        {
146            _omitZero = omitZero;
147        }
148    
149    }