001    // Copyright 2004, 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.valid;
016    
017    import java.util.HashMap;
018    import java.util.Map;
019    
020    import org.apache.tapestry.IMarkupWriter;
021    import org.apache.tapestry.IRequestCycle;
022    import org.apache.tapestry.form.IFormComponent;
023    
024    /**
025     * Simple validation of strings, to enforce required, and minimum length
026     * (maximum length is enforced in the client browser, by setting a maximum input
027     * length on the text field).
028     * 
029     * @author Howard Lewis Ship
030     * @since 1.0.8
031     */
032    
033    public class StringValidator extends BaseValidator
034    {
035    
036        private int _minimumLength;
037    
038        private String _minimumLengthMessage;
039    
040        /** @since 2.2 * */
041    
042        private String _scriptPath = "/org/apache/tapestry/valid/StringValidator.script";
043    
044        public StringValidator()
045        {
046        }
047    
048        /**
049         * Initializes the StringValidator with properties defined by the
050         * initializer.
051         * 
052         * @since 4.0
053         */
054    
055        public StringValidator(String initializer)
056        {
057            super(initializer);
058        }
059    
060        public String toString(IFormComponent field, Object value)
061        {
062            if (value == null) return null;
063    
064            return value.toString();
065        }
066    
067        public Object toObject(IFormComponent field, String input)
068            throws ValidatorException
069        {
070            if (checkRequired(field, input)) return null;
071    
072            if (_minimumLength > 0 && input.length() < _minimumLength)
073                throw new ValidatorException(buildMinimumLengthMessage(field),
074                        ValidationConstraint.MINIMUM_WIDTH);
075    
076            return input;
077        }
078    
079        public int getMinimumLength()
080        {
081            return _minimumLength;
082        }
083    
084        public void setMinimumLength(int minimumLength)
085        {
086            _minimumLength = minimumLength;
087        }
088    
089        /**
090         * @since 2.2
091         */
092    
093        public void renderValidatorContribution(IFormComponent field,
094                IMarkupWriter writer, IRequestCycle cycle)
095        {
096            if (!isClientScriptingEnabled()) return;
097    
098            if (!(isRequired() || _minimumLength > 0)) return;
099    
100            Map symbols = new HashMap();
101    
102            if (isRequired())
103                symbols.put("requiredMessage", buildRequiredMessage(field));
104    
105            if (_minimumLength > 0)
106                symbols.put("minimumLengthMessage",
107                        buildMinimumLengthMessage(field));
108    
109            processValidatorScript(_scriptPath, cycle, field, symbols);
110        }
111    
112        /**
113         * @since 2.2
114         */
115    
116        public String getScriptPath()
117        {
118            return _scriptPath;
119        }
120    
121        /**
122         * Allows a developer to use the existing validation logic with a different
123         * client-side script. This is often sufficient to allow
124         * application-specific error presentation (perhaps by using DHTML to update
125         * the content of a &lt;span&gt; tag, or to use a more sophisticated pop-up
126         * window than <code>window.alert()</code>).
127         * 
128         * @since 2.2
129         */
130    
131        public void setScriptPath(String scriptPath)
132        {
133            _scriptPath = scriptPath;
134        }
135    
136        /** @since 3.0 */
137        public String getMinimumLengthMessage()
138        {
139            return _minimumLengthMessage;
140        }
141    
142        /**
143         * Overrides the <code>field-too-short</code> bundle key. Parameter {0} is
144         * the minimum length. Parameter {1} is the display name of the field.
145         * 
146         * @since 3.0
147         */
148    
149        public void setMinimumLengthMessage(String string)
150        {
151            _minimumLengthMessage = string;
152        }
153    
154        /** @since 3.0 */
155    
156        protected String buildMinimumLengthMessage(IFormComponent field)
157        {
158            String pattern = getPattern(_minimumLengthMessage, "field-too-short",
159                    field.getPage().getLocale());
160    
161            return formatString(pattern, Integer.toString(_minimumLength), field
162                    .getDisplayName());
163        }
164    
165    }