001    /**
002     * Copyright 2005-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.krad.datadictionary.validation.constraint;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.rice.krad.datadictionary.parse.BeanTag;
020    import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
021    import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
022    import org.kuali.rice.krad.uif.UifConstants;
023    
024    import java.util.ArrayList;
025    import java.util.List;
026    import java.util.regex.Pattern;
027    
028    /**
029     * Pattern for matching any character in the given list (String)
030     *
031     * @author Kuali Rice Team (rice.collab@kuali.org)
032     */
033    @BeanTag(name = "charsetPatternConstraint-bean", parent = "CharsetPatternConstraint")
034    public class CharsetPatternConstraint extends ValidCharactersPatternConstraint {
035        protected String validChars;
036    
037        /**
038         * @return String containing all valid chars for this charset
039         */
040        @BeanTagAttribute(name = "validChars")
041        public String getValidChars() {
042            return validChars;
043        }
044    
045        /**
046         * @param validChars for this charset
047         */
048        public void setValidChars(String validChars) {
049            if (StringUtils.isEmpty(validChars)) {
050                throw new IllegalArgumentException("invalid (empty) validChars");
051            }
052    
053            this.validChars = validChars;
054        }
055    
056        /**
057         * Escapes every special character I could think of, to limit potential misuse of this pattern.
058         *
059         * @see org.kuali.rice.krad.datadictionary.validation.ValidationPattern#getRegexString()
060         */
061        protected String getRegexString() {
062            if (StringUtils.isEmpty(validChars)) {
063                throw new IllegalStateException("validChars is empty");
064            }
065    
066            // filter out and escape chars which would confuse the pattern-matcher
067            Pattern filteringChars = Pattern.compile("([\\-\\[\\]\\{\\}\\$\\.\\^\\(\\)\\*\\&\\|])");
068            String filteredChars = filteringChars.matcher(validChars).replaceAll("\\\\$1");
069    
070            StringBuffer regexString = new StringBuffer("[");
071            regexString.append(filteredChars);
072            if (filteredChars.endsWith("\\")) {
073                regexString.append("\\");
074            }
075            regexString.append("]");
076    
077            return regexString.toString();
078        }
079    
080        /**
081         * @see org.kuali.rice.krad.datadictionary.validation.constraint.BaseConstraint#getMessageKey()
082         */
083        @Override
084        public String getMessageKey() {
085            String messageKey = super.getMessageKey();
086            if (StringUtils.isNotEmpty(messageKey)) {
087                return messageKey;
088            }
089    
090            return (UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + "charsetPattern");
091        }
092    
093        /**
094         * Parameters to be used in the string retrieved by this constraint's messageKey
095         *
096         * @return the validationMessageParams
097         */
098        public List<String> getValidationMessageParams() {
099            if (validationMessageParams == null) {
100                validationMessageParams = new ArrayList<String>();
101                if (StringUtils.isNotBlank(validChars)) {
102                    validationMessageParams.add(validChars);
103                }
104    
105            }
106            return this.validationMessageParams;
107        }
108    
109        /**
110         * Validates different requirements of component compiling a series of reports detailing information on errors
111         * found in the component.  Used by the RiceDictionaryValidator.
112         *
113         * @param tracer Record of component's location
114         * @return A list of ErrorReports detailing errors found within the component and referenced within it
115         */
116        @Override
117        public void completeValidation(ValidationTrace tracer) {
118            tracer.addBean("CharsetPatternConstraint", getMessageKey());
119    
120            if (getValidChars() == null) {
121                String currentValues[] = {"validChars =" + getValidChars()};
122                tracer.createError("ValidChars must be set", currentValues);
123            }
124    
125            super.completeValidation(tracer.getCopy());
126        }
127    }