001/* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 1.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/ecl1.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.ole.sys.batch; 017 018import java.util.ArrayList; 019import java.util.List; 020import java.util.regex.Matcher; 021import java.util.regex.Pattern; 022 023import org.apache.commons.lang.StringUtils; 024 025/** 026 * The abstract parent of flat file specifications which use regexes to determine what line is parsed into what object 027 */ 028public abstract class AbstractRegexSpecificationBase extends AbstractFlatFileSpecificationBase { 029 protected List<String> insignificantRegexPatterns; 030 protected List<Pattern> insignificantPatterns; 031 protected boolean trimLineBeforeMatch; 032 protected boolean fullMatch = true; 033 034 /** 035 * Matches the given line with an object to parse into, or null if no object could be found 036 * @see org.kuali.ole.sys.batch.FlatFileSpecification#determineClassForLine(java.lang.String) 037 */ 038 public Class<?> determineClassForLine(String line) { 039 final String matchLine = trimLine(line); 040 for (FlatFileObjectSpecification objectSpecification : getObjectSpecifications()) { 041 final FlatFileRegexObjectSpecification regexObjectSpecification = (FlatFileRegexObjectSpecification)objectSpecification; 042 final Pattern pattern = regexObjectSpecification.getPattern(); 043 if (matches(pattern, matchLine)) { 044 return regexObjectSpecification.getBusinessObjectClass(); 045 } 046 } 047 for (Pattern insignificantPattern : getInsignificantPatterns()) { 048 if (matches(insignificantPattern, matchLine)) return null; 049 } 050 return defaultBusinessObjectClass; 051 } 052 053 /** 054 * Trims the trailing space only from the given line, though only if trimLineBeforeMatch is true 055 * @param line the line to perhaps trim trailing spaces from 056 * @return the maybe trimmed line 057 */ 058 protected String trimLine(String line) { 059 if (isTrimLineBeforeMatch()) { 060 return StringUtils.stripEnd(line, " \t\n\f\r"); 061 } 062 return line; 063 } 064 065 /** 066 * Sets the insignificant regex patterns 067 * @param insignificantRegexPatterns the regex patterns for lines to ignore 068 */ 069 public void setInsignificantRegexPatterns(List<String> insignificantRegexPatterns) { 070 this.insignificantRegexPatterns = insignificantRegexPatterns; 071 072 this.insignificantPatterns = new ArrayList<Pattern>(); 073 for (String regexPattern : insignificantRegexPatterns) { 074 final Pattern pattern = Pattern.compile(regexPattern); 075 insignificantPatterns.add(pattern); 076 } 077 } 078 079 /** 080 * Determines if the given line matches the given pattern, following the full match rule 081 * @param pattern the pattern to match against 082 * @param line the parsed line to match 083 * @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 084 */ 085 protected boolean matches(Pattern pattern, String line) { 086 Matcher matcher = pattern.matcher(line); 087 if (fullMatch) { 088 return matcher.matches(); 089 } else { 090 return matcher.find(); 091 } 092 } 093 094 /** 095 * @return the List of compiled insignificant patterns 096 */ 097 public List<Pattern> getInsignificantPatterns() { 098 return this.insignificantPatterns; 099 } 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}