001    /**
002     * Copyright 2005-2012 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.kns.datadictionary.validation.fieldlevel;
017    
018    import org.kuali.rice.krad.datadictionary.exporter.ExportMap;
019    import org.kuali.rice.krad.datadictionary.validation.FieldLevelValidationPattern;
020    
021    /**
022     * Validation pattern for matching fixed point numbers, optionally matching negative numbers
023     * 
024     * 
025     */
026    public class FixedPointValidationPattern extends FieldLevelValidationPattern {
027        public static final String PATTERN_TYPE_PRECISION = "fixedPoint.precision";
028        public static final String PATTERN_TYPE_SCALE = "fixedPoint.scale";
029    
030        protected boolean allowNegative;
031        protected int precision;
032        protected int scale;
033    
034        /**
035         * @return Returns the precision.
036         */
037        public int getPrecision() {
038            return precision;
039        }
040    
041        /**
042         * @param precision The precision to set.
043         */
044        public void setPrecision(int precision) {
045            this.precision = precision;
046        }
047    
048        /**
049         * @return Returns the scale.
050         */
051        public int getScale() {
052            return scale;
053        }
054    
055        /**
056         * @param scale The scale to set.
057         */
058        public void setScale(int scale) {
059            this.scale = scale;
060        }
061    
062        /**
063         * @return allowNegative
064         */
065        public boolean getAllowNegative() {
066            return allowNegative;
067        }
068    
069        /**
070         * @param allowNegative
071         */
072        public void setAllowNegative(boolean allowNegative) {
073            this.allowNegative = allowNegative;
074        }
075    
076        /**
077         * Adds special handling to account for optional allowNegative and dynamic precision, scale
078         * 
079         * @see org.kuali.rice.krad.datadictionary.validation.ValidationPattern#getRegexString()
080         */
081        @Override
082            protected String getRegexString() {     
083            final StringBuilder regex = new StringBuilder();
084    
085            if (allowNegative) {
086                regex.append("-?");
087            }
088            // final patter will be: -?([0-9]{0,p-s}\.[0-9]{1,s}|[0-9]{1,p-s}) where p = precision, s=scale
089            regex.append("(");
090            regex.append("[0-9]{0," + (getPrecision() - getScale()) + "}");
091            regex.append("\\.");
092            regex.append("[0-9]{1," + getScale() + "}");
093            regex.append("|[0-9]{1," + (getPrecision() - getScale()) + "}");
094            regex.append(")");
095            return regex.toString();
096        }
097    
098        /**
099         * @see org.kuali.rice.krad.datadictionary.validation.FieldLevelValidationPattern#getPatternTypeName()
100         */
101        @Override
102            protected String getPatternTypeName() {
103            return "fixedPoint";
104        }
105    
106    
107        /**
108         * @see org.kuali.rice.krad.datadictionary.validation.ValidationPattern#buildExportMap(java.lang.String)
109         */
110        @Override
111            public ExportMap buildExportMap(String exportKey) {
112            ExportMap exportMap = super.buildExportMap(exportKey);
113    
114            if (allowNegative) {
115                exportMap.set("allowNegative", "true");
116            }
117            exportMap.set("precision", Integer.toString(precision));
118            exportMap.set("scale", Integer.toString(scale));
119    
120            return exportMap;
121        }
122    
123            /**
124             * @see org.kuali.rice.krad.datadictionary.validation.FieldLevelValidationPattern#getValidationErrorMessageKey()
125             */
126            @Override
127            public String getValidationErrorMessageKey() {
128                    StringBuilder buf = new StringBuilder();
129                    buf.append("error.format.").append(getClass().getName());
130                    if (allowNegative) {
131                            buf.append(".allowNegative");
132                    }
133                    return buf.toString();
134            }
135    
136            /**
137             * This overridden method ...
138             * 
139             * @see org.kuali.rice.krad.datadictionary.validation.ValidationPattern#getValidationErrorMessageParameters(java.lang.String)
140             */
141            @Override
142            public String[] getValidationErrorMessageParameters(String attributeLabel) {
143                    return new String[] {attributeLabel, String.valueOf(precision), String.valueOf(scale)};
144            }
145            
146            @Override
147            public void completeValidation() throws ValidationPatternException {
148                    super.completeValidation();
149                    
150            final boolean valid =
151                    (getPrecision() >= 1) &&
152                    (getScale() >= 0) &&
153                    (getPrecision() >= getScale());
154            
155            if (!valid) {
156                    throw new ValidationPatternException("The precision must be >= 1.  The scale must be >= 0.  The precision must be >= scale. Precision: " + getPrecision() + " Scale: " + getScale());
157            }
158            }
159    }