View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.datadictionary.validation.constraint;
17  
18  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
19  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
20  import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
21  import org.kuali.rice.krad.messages.MessageService;
22  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
23  import org.kuali.rice.krad.uif.UifConstants;
24  
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  /**
29   * Validation pattern for matching fixed point numbers, optionally matching negative numbers
30   *
31   * <p>
32   * Only allows a numeric value where the precision property represents the maximum number of
33   * total numbers allowed, and scale represents the minimum numbers after the decimal point.
34   * The decimal places are implied to be 0 if not included and still count towards total
35   * numbers allowed.
36   * </p>
37   *
38   * @author Kuali Rice Team (rice.collab@kuali.org)
39   */
40  @BeanTag(name = "fixedPointPatternConstraint", parent = "FixedPointPatternConstraint")
41  public class FixedPointPatternConstraint extends ValidDataPatternConstraint {
42  
43      protected boolean allowNegative;
44      protected int precision;
45      protected int scale;
46  
47      /**
48       * Overriding retrieval of
49       *
50       * @see org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersPatternConstraint#getRegexString()
51       */
52      @Override
53      protected String getRegexString() {
54          StringBuilder regex = new StringBuilder();
55  
56          if (getPrecision() < 0 || getScale() < 0 || getPrecision() - getScale() < 0){
57              throw new RuntimeException("Precision and scale cannot be negative AND scale cannot be greater than "
58                      + "precision for FixedPointPatternConstraints!");
59          }
60  
61          if (isAllowNegative()) {
62              regex.append("-?");
63          }
64          // final pattern will be: -?([0-9]{0,p-s}\.[0-9]{1,s}|[0-9]{1,p-s}) where p = precision, s=scale
65  
66          regex.append("(");
67          if(getPrecision() - getScale() > 0){
68              regex.append("[0-9]{0," + (getPrecision() - getScale()) + "}");
69          }
70          regex.append("\\.");
71          regex.append("[0-9]{1," + getScale() + "}");
72          if(getPrecision() - getScale() > 0){
73              regex.append("|[0-9]{1," + (getPrecision() - getScale()) + "}");
74          }
75          regex.append(")");
76          return regex.toString();
77      }
78  
79      /**
80       * @return the allowNegative
81       */
82      @BeanTagAttribute(name = "allowNegative")
83      public boolean isAllowNegative() {
84          return this.allowNegative;
85      }
86  
87      /**
88       * @param allowNegative the allowNegative to set
89       */
90      public void setAllowNegative(boolean allowNegative) {
91          this.allowNegative = allowNegative;
92      }
93  
94      /**
95       * @return the precision
96       */
97      @BeanTagAttribute(name = "precision")
98      public int getPrecision() {
99          return this.precision;
100     }
101 
102     /**
103      * @param precision the precision to set
104      */
105     public void setPrecision(int precision) {
106         this.precision = precision;
107     }
108 
109     /**
110      * @return the scale
111      */
112     @BeanTagAttribute(name = "scale")
113     public int getScale() {
114         return this.scale;
115     }
116 
117     /**
118      * @param scale the scale to set
119      */
120     public void setScale(int scale) {
121         this.scale = scale;
122     }
123 
124     /**
125      * This overridden method ...
126      *
127      * @see org.kuali.rice.krad.datadictionary.validation.constraint.ValidDataPatternConstraint#getValidationMessageParams()
128      */
129     @Override
130     public List<String> getValidationMessageParams() {
131         if (validationMessageParams == null) {
132             validationMessageParams = new ArrayList<String>();
133             MessageService messageService = KRADServiceLocatorWeb.getMessageService();
134             if (allowNegative) {
135                 validationMessageParams.add(messageService.getMessageText(
136                         UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + "positiveOrNegative"));
137             } else {
138                 validationMessageParams.add(messageService.getMessageText(
139                         UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + "positiveOrZero"));
140             }
141 
142             validationMessageParams.add(Integer.toString(precision));
143             validationMessageParams.add(Integer.toString(scale));
144         }
145         return validationMessageParams;
146     }
147 
148     /**
149      * Validates different requirements of component compiling a series of reports detailing information on errors
150      * found in the component.  Used by the RiceDictionaryValidator.
151      *
152      * @param tracer Record of component's location
153      */
154     @Override
155     public void completeValidation(ValidationTrace tracer) {
156         tracer.addBean("FixedPointPatternConstraint", getMessageKey());
157 
158         if (getPrecision() <= getScale()) {
159             String currentValues[] = {"precision =" + getPrecision(), "scale = " + getScale()};
160             tracer.createError("Precision should greater than Scale", currentValues);
161         }
162 
163         super.completeValidation(tracer.getCopy());
164     }
165 
166 }