View Javadoc
1   /*
2    * Copyright 2011 The Kuali Foundation.
3    * 
4    * Licensed under the Educational Community License, Version 1.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/ecl1.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.ole.sys.batch;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.regex.Matcher;
21  import java.util.regex.Pattern;
22  
23  import org.apache.commons.lang.StringUtils;
24  
25  /**
26   * The abstract parent of flat file specifications which use regexes to determine what line is parsed into what object
27   */
28  public abstract class AbstractRegexSpecificationBase extends AbstractFlatFileSpecificationBase {
29      protected List<String> insignificantRegexPatterns;
30      protected List<Pattern> insignificantPatterns;
31      protected boolean trimLineBeforeMatch;
32      protected boolean fullMatch = true;
33  
34      /**
35       * Matches the given line with an object to parse into, or null if no object could be found
36       * @see org.kuali.ole.sys.batch.FlatFileSpecification#determineClassForLine(java.lang.String)
37       */
38      public Class<?> determineClassForLine(String line) {
39          final String matchLine = trimLine(line);
40          for (FlatFileObjectSpecification objectSpecification : getObjectSpecifications()) {
41              final FlatFileRegexObjectSpecification regexObjectSpecification = (FlatFileRegexObjectSpecification)objectSpecification;
42              final Pattern pattern = regexObjectSpecification.getPattern();
43              if (matches(pattern, matchLine)) {
44                  return regexObjectSpecification.getBusinessObjectClass();
45              }
46          }
47          for (Pattern insignificantPattern : getInsignificantPatterns()) {
48              if (matches(insignificantPattern, matchLine)) return null;
49          }
50          return defaultBusinessObjectClass;
51      }
52      
53      /**
54       * Trims the trailing space only from the given line, though only if trimLineBeforeMatch is true
55       * @param line the line to perhaps trim trailing spaces from
56       * @return the maybe trimmed line
57       */
58      protected String trimLine(String line) {
59          if (isTrimLineBeforeMatch()) {
60              return StringUtils.stripEnd(line, " \t\n\f\r");
61          }
62          return line;
63      }
64  
65      /**
66       * Sets the insignificant regex patterns
67       * @param insignificantRegexPatterns the regex patterns for lines to ignore
68       */
69      public void setInsignificantRegexPatterns(List<String> insignificantRegexPatterns) {
70          this.insignificantRegexPatterns = insignificantRegexPatterns;
71          
72          this.insignificantPatterns = new ArrayList<Pattern>();
73          for (String regexPattern : insignificantRegexPatterns) {
74              final Pattern pattern = Pattern.compile(regexPattern);
75              insignificantPatterns.add(pattern);
76          }
77      }
78      
79      /**
80       * Determines if the given line matches the given pattern, following the full match rule
81       * @param pattern the pattern to match against
82       * @param line the parsed line to match
83       * @return true if the line matches and the line should be parsed by this object specification; false if this line should be given to the next object specification
84       */
85      protected boolean matches(Pattern pattern, String line) {
86          Matcher matcher = pattern.matcher(line);
87          if (fullMatch) {
88              return matcher.matches();
89          } else {
90              return matcher.find();
91          }
92      }
93  
94      /**
95       * @return the List of compiled insignificant patterns
96       */
97      public List<Pattern> getInsignificantPatterns() {
98          return this.insignificantPatterns;
99      }
100 
101     /**
102      * @return whether a parsed line will have trailing spaces removed (and trailing spaces only!)
103      */
104     public boolean isTrimLineBeforeMatch() {
105         return trimLineBeforeMatch;
106     }
107 
108     /**
109      * Sets whether this will strip trailing spaces before parsing the line.  Defaults to false.
110      * @param trimLineBeforeMatch true if trailing spaces should be stripped, false otherwise
111      */
112     public void setTrimLineBeforeMatch(boolean trimLineBeforeMatch) {
113         this.trimLineBeforeMatch = trimLineBeforeMatch;
114     }
115 
116     /**
117      * @return whether the regular expression associated with this object specification will attempt to match the full line or (if false) simply find the pattern somewhere within the line
118      */
119     public boolean isFullMatch() {
120         return fullMatch;
121     }
122 
123     /**
124      * Sets whether the regular expression associated with this object specification will attempt to match against the whole line or search for the pattern within the line.  If true, it will match the full line, and this is the default.
125      * @param fullMatch true if match against the full line should be carried out, false otherwise
126      */
127     public void setFullMatch(boolean fullMatch) {
128         this.fullMatch = fullMatch;
129     }
130 }