View Javadoc

1   /**
2    * Copyright 2005-2012 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 java.util.ArrayList;
19  import java.util.Arrays;
20  import java.util.Collections;
21  import java.util.List;
22  
23  import org.apache.commons.lang.StringUtils;
24  import org.kuali.rice.core.api.CoreConstants;
25  import org.kuali.rice.core.api.config.property.ConfigContext;
26  import org.kuali.rice.core.api.config.property.ConfigurationService;
27  import org.kuali.rice.krad.service.KRADServiceLocator;
28  import org.kuali.rice.krad.uif.UifConstants;
29  
30  /**
31   * DatePatternConstraint constrains a field to only allow dates which are part of the formats
32   * defined in the system. Constraining a field all these formats is often not appropriate for
33   * fields, and you may want to constrain the input to a subset of the allowed formats in the system.
34   * This can be done by setting the allowed formats to this subset (see BasicDatePatternConstraint
35   * bean for example)
36   * 
37   * @author Kuali Rice Team (rice.collab@kuali.org)
38   */
39  public class DatePatternConstraint extends ValidDataPatternConstraint {
40  
41      private List<String> allowedFormats;
42  
43      /**
44       * Returns a regex representing all the allowed formats in the system. If allowedFormats is
45       * supplied, returns a regex representing only those formats.
46       * 
47       * @see org.kuali.rice.krad.datadictionary.validation.constraint.ValidDataPatternConstraint#getRegexString()
48       */
49      @Override
50      protected String getRegexString() {
51          List<String> dateFormatParams =
52                  parseConfigValues(ConfigContext.getCurrentContextConfig().getProperty(
53                          CoreConstants.STRING_TO_DATE_FORMATS));
54          if (allowedFormats != null && !allowedFormats.isEmpty()) {
55              if (dateFormatParams.containsAll(allowedFormats)) {
56                  dateFormatParams = allowedFormats;
57              } else {
58                  //throw new Exception("Some of these formats do not exist in configured allowed date formats: " + allowedFormats.toString());
59              }
60          }
61  
62          if (dateFormatParams.isEmpty()) {
63              //exception
64          }
65          String regex = "";
66          int i = 0;
67          for (String format : dateFormatParams) {
68              if (i == 0) {
69                  regex = "(^" + convertDateFormatToRegex(format.trim()) + "$)";
70              } else {
71                  regex = regex + "|(^" + convertDateFormatToRegex(format.trim()) + "$)";
72              }
73              i++;
74          }
75          return regex;
76      }
77  
78      /**
79       * Converts a date format supplied to the appropriate date format regex equivalent
80       * 
81       * @param format
82       * @return
83       */
84      private String convertDateFormatToRegex(String format) {
85          format = format.replace("\\", "\\\\")
86                  .replace(".", "\\.")
87                  .replace("-", "\\-")
88                  .replace("+", "\\+")
89                  .replace("(", "\\(")
90                  .replace(")", "\\)")
91                  .replace("[", "\\[")
92                  .replace("]", "\\]")
93                  .replace("|", "\\|")
94                  .replace("yyyy", "((19|2[0-9])[0-9]{2})")
95                  .replace("yy", "([0-9]{2})")
96                  .replaceAll("M{4,}", "([@]+)") //"(January|February|March|April|May|June|July|August|September|October|November|December)")
97                  .replace("MMM", "([@]{3})") //"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)")
98                  .replace("MM", "(0[1-9]|1[012])")
99                  .replace("M", "(0?[1-9]|1[012])")
100                 .replace("dd", "(0[1-9]|[12][0-9]|3[01])")
101                 .replace("d", "(0?[1-9]|[12][0-9]|3[01])")
102                 .replace("hh", "(1[0-2]|0[1-9])")
103                 .replace("h", "(1[0-2]|0?[1-9])")
104                 .replace("HH", "(2[0-3]|1[0-9]|0[0-9])")
105                 .replace("H", "(2[0-3]|1[0-9]|0?[0-9])")
106                 .replace("kk", "(2[0-4]|1[0-9]|0[1-9])")
107                 .replace("k", "(2[0-4]|1[0-9]|0?[1-9])")
108                 .replace("KK", "(1[01]|0[0-9])")
109                 .replace("K", "(1[01]|0?[0-9])")
110                 .replace("mm", "([0-5][0-9])")
111                 .replace("m", "([1-5][0-9]|0?[0-9])")
112                 .replace("ss", "([0-5][0-9])")
113                 .replace("s", "([1-5][0-9]|0?[0-9])")
114                 .replace("SSS", "([0-9][0-9][0-9])")
115                 .replace("SS", "([0-9][0-9][0-9]?)")
116                 .replace("S", "([0-9][0-9]?[0-9]?)")
117                 .replaceAll("E{4,}", "([@]+)")//"(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)")
118                 .replaceAll("E{1,3}", "([@]{3})")//"(Mon|Tue|Wed|Thu|Fri|Sat|Sun)")
119                 .replace("DDD", "(3[0-6][0-5]|[1-2][0-9][0-9]|0[0-9][1-9])")
120                 .replace("DD", "(3[0-6][0-5]|[1-2][0-9][0-9]|0?[0-9][1-9])")
121                 .replace("D", "(3[0-6][0-5]|[1-2][0-9][0-9]|0?[0-9]?[1-9])")
122                 .replace("F", "([1-5])")
123                 .replace("ww", "(5[0-3]|[1-4][0-9]|0[1-9])")
124                 .replace("w", "(5[0-3]|[1-4][0-9]|[1-9])")
125                 .replace("W", "([1-5])")
126                 .replaceAll("z{4,}", "([@]+)")
127                 .replaceAll("z{1,3}", "([@]{1,4})")
128                 .replaceAll("a{1,}", "([aApP][mM])")
129                 .replaceAll("G{1,}", "([aA][dD]|[bB][cC])")
130                 .replace(" ", "\\s")
131                 .replace("@", "a-zA-Z");
132 
133         return format;
134 
135     }
136 
137     /**
138      * 
139      * The dateTime config vars are ';' seperated.
140      * 
141      * @param configValue
142      * @return
143      */
144     private List<String> parseConfigValues(String configValue) {
145         if (configValue == null || "".equals(configValue)) {
146             return Collections.emptyList();
147         }
148         return Arrays.asList(configValue.split(";"));
149     }
150 
151     /**
152      * @return the allowedFormats
153      */
154     public List<String> getAllowedFormats() {
155         return this.allowedFormats;
156     }
157 
158     /**
159      * Sets the alloweFormats for this constraint, this must be a subset of the system configured
160      * formats for a date - this list should be used for most fields where you are expecting a user
161      * to enter a date in a specific format
162      * @param allowedFormats the allowedFormats to set
163      */
164     public void setAllowedFormats(List<String> allowedFormats) {
165         this.allowedFormats = allowedFormats;
166     }
167 
168     /**
169      * This overridden method ...
170      * 
171      * @see org.kuali.rice.krad.datadictionary.validation.constraint.ValidDataPatternConstraint#getValidationMessageParams()
172      */
173     @Override
174     public List<String> getValidationMessageParams() {
175         if (validationMessageParams == null) {
176             validationMessageParams = new ArrayList<String>();
177             if (allowedFormats != null && !allowedFormats.isEmpty()) {
178                 validationMessageParams.add(StringUtils.join(allowedFormats, ", "));
179             } else {
180                 List<String> dateFormatParams =
181                         parseConfigValues(ConfigContext.getCurrentContextConfig().getProperty(
182                                 CoreConstants.STRING_TO_DATE_FORMATS));
183                 validationMessageParams.add(StringUtils.join(dateFormatParams, ", "));
184             }
185         }
186         return validationMessageParams;
187     }
188 
189 }