001/**
002 * Copyright 2005-2018 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 */
016package org.kuali.rice.krad.datadictionary.validation.constraint;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
020import org.kuali.rice.krad.uif.UifConstants;
021
022import java.text.DecimalFormat;
023import java.text.NumberFormat;
024import java.util.HashSet;
025
026/**
027 * Validation pattern for matching currency type. Extends the FloatingPointPatternConstraint and
028 * adds the currency prefix/suffix to the regex string for validation
029 *
030 * @author Kuali Rice Team (rice.collab@kuali.org)
031 */
032
033public class CurrencyPatternConstraint extends FloatingPointPatternConstraint {
034
035    /**
036     * @see org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersPatternConstraint#getRegexString()
037     */
038    @Override
039    protected String getRegexString() {
040        StringBuilder regexString = new StringBuilder(super.getRegexString());
041
042        NumberFormat formatter = getCurrencyInstanceUsingParseBigDecimal();
043
044        if (!(formatter instanceof DecimalFormat)) {
045            return regexString.toString();
046        }
047
048        String prefix = ((DecimalFormat) formatter).getPositivePrefix();
049        String suffix = ((DecimalFormat) formatter).getPositiveSuffix();
050
051        // Regex special characters need to be escaped if they are part of the prefix/suffix
052        if (prefix != null) {
053            StringBuilder escapedPrefix = new StringBuilder();
054            for (char c : prefix.toCharArray()) {
055                if (UifConstants.JS_REGEX_SPECIAL_CHARS.indexOf(c) != -1) {
056                    escapedPrefix.append("\\");
057                }
058                escapedPrefix.append(c);
059            }
060
061            regexString.insert(0, "(" + escapedPrefix + ")?");
062        }
063
064        if (suffix != null) {
065            StringBuilder escapedSuffix = new StringBuilder();
066            for (char c : suffix.toCharArray()) {
067                if (UifConstants.JS_REGEX_SPECIAL_CHARS.indexOf(c) != -1) {
068                    escapedSuffix.append("\\");
069                }
070                escapedSuffix.append(c);
071            }
072
073            regexString.append("(" + escapedSuffix + ")?");
074        }
075
076        return regexString.toString();
077    }
078
079    /**
080     * retrieves a currency formatter instance and sets ParseBigDecimal to true
081     * to fix [KULEDOCS-742]
082     *
083     * @return CurrencyInstance
084     */
085    private NumberFormat getCurrencyInstanceUsingParseBigDecimal() {
086        NumberFormat formatter = NumberFormat.getCurrencyInstance();
087        if (formatter instanceof DecimalFormat) {
088            ((DecimalFormat) formatter).setParseBigDecimal(true);
089        }
090        return formatter;
091    }
092
093}