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 org.apache.tapestry.IMarkupWriter;
018    import org.apache.tapestry.IRequestCycle;
019    import org.apache.tapestry.form.FormComponentContributorContext;
020    import org.apache.tapestry.form.IFormComponent;
021    import org.apache.tapestry.form.ValidationMessages;
022    import org.apache.tapestry.json.JSONLiteral;
023    import org.apache.tapestry.json.JSONObject;
024    import org.apache.tapestry.valid.ValidationConstants;
025    import org.apache.tapestry.valid.ValidationConstraint;
026    import org.apache.tapestry.valid.ValidationStrings;
027    import org.apache.tapestry.valid.ValidatorException;
028    import org.apache.oro.text.regex.Perl5Compiler;
029    
030    /**
031     * Validates a user input string against a regular expression pattern.
032     * 
033     * @author Howard Lewis Ship
034     * @since 4.0
035     * @see org.apache.tapestry.util.RegexpMatcher
036     */
037    public class Pattern extends BaseValidator
038    {
039        // It is expectd that each Pattern instance will be used by a single component instance,
040        // and therefore be restricted to a single thread.
041    
042        private String _pattern;
043        private String _quotedPattern;
044        private java.util.regex.Pattern _compiledPattern;
045    
046        public Pattern()
047        {
048        }
049    
050        public Pattern(String initializer)
051        {
052            super(initializer);
053        }
054    
055        public void validate(IFormComponent field, ValidationMessages messages, Object object)
056                throws ValidatorException
057        {
058            String input = object.toString();
059    
060            if (! _compiledPattern.matcher(input).matches() )
061                throw new ValidatorException(buildMessage(messages, field),
062                        ValidationConstraint.PATTERN_MISMATCH);
063        }
064    
065        private String buildMessage(ValidationMessages messages, IFormComponent field)
066        {
067            return messages.formatValidationMessage(
068                    getMessage(),
069                    ValidationStrings.PATTERN_MISMATCH,
070                    new Object[]
071                    {field.getDisplayName(), _pattern });
072        }
073        
074        public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
075                FormComponentContributorContext context, IFormComponent field)
076        {
077           JSONObject profile = context.getProfile();
078            
079            if (!profile.has(ValidationConstants.CONSTRAINTS)) {
080                profile.put(ValidationConstants.CONSTRAINTS, new JSONObject());
081            }
082            JSONObject cons = profile.getJSONObject(ValidationConstants.CONSTRAINTS);
083            
084            accumulateProperty(cons, field.getClientId(), 
085                    new JSONLiteral("[tapestry.form.validation.isValidPattern,\""
086                            + _quotedPattern + "\"]"));
087            
088            accumulateProfileProperty(field, profile, 
089                    ValidationConstants.CONSTRAINTS, buildMessage(context, field));
090        }
091    
092        public void setPattern(String pattern)
093        {
094            _pattern = pattern;
095            _compiledPattern = java.util.regex.Pattern.compile(pattern);
096            _quotedPattern =  Perl5Compiler.quotemeta(_pattern);
097        }
098    
099        public String getPattern()
100        {
101            return _pattern;
102        }
103    }