001 /** 002 * Copyright 2010-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.common.jdbc; 017 018 import java.io.BufferedReader; 019 import java.io.IOException; 020 import java.util.Arrays; 021 import java.util.List; 022 023 import org.apache.commons.lang3.StringUtils; 024 import org.springframework.util.Assert; 025 026 public class DefaultSqlReader implements SqlReader { 027 028 public static final String DEFAULT_DELIMITER = "/"; 029 public static final DelimiterMode DEFAULT_DELIMITER_MODE = DelimiterMode.OWN_LINE; 030 public static final LineSeparator DEFAULT_LINE_SEPARATOR = LineSeparator.LF; 031 public static final List<String> DEFAULT_COMMENT_TOKENS = Arrays.asList(new String[] { "#", "--" }); 032 public static final boolean DEFAULT_IS_TRIM = true; 033 public static final boolean DEFAULT_IS_IGNORE_COMMENTS = true; 034 035 String delimiter = DEFAULT_DELIMITER; 036 DelimiterMode delimiterMode = DEFAULT_DELIMITER_MODE; 037 LineSeparator lineSeparator = DEFAULT_LINE_SEPARATOR; 038 boolean trim = DEFAULT_IS_TRIM; 039 boolean ignoreComments = DEFAULT_IS_IGNORE_COMMENTS; 040 List<String> commentTokens = DEFAULT_COMMENT_TOKENS; 041 042 @Override 043 public String getSqlStatement(BufferedReader reader) throws IOException { 044 Assert.notNull(delimiter, "delimiter is null"); 045 String line = reader.readLine(); 046 String trimmedLine = StringUtils.trimToNull(line); 047 StringBuilder sb = new StringBuilder(); 048 while (proceed(line, trimmedLine, delimiter, delimiterMode)) { 049 if (!ignore(ignoreComments, sb, trimmedLine, commentTokens)) { 050 sb.append(line + lineSeparator.getValue()); 051 } 052 line = reader.readLine(); 053 trimmedLine = StringUtils.trimToNull(line); 054 } 055 return getReturnValue(sb.toString(), trim, lineSeparator); 056 } 057 058 protected String getReturnValue(String sql, boolean trim, LineSeparator lineSeparator) { 059 if (trim) { 060 sql = StringUtils.trimToNull(sql); 061 } 062 if (sql == null) { 063 return null; 064 } else if (StringUtils.endsWith(sql, lineSeparator.getValue())) { 065 int endIndex = sql.length() - lineSeparator.getValue().length(); 066 return StringUtils.substring(sql, 0, endIndex); 067 } else { 068 return sql; 069 } 070 } 071 072 protected boolean isEndOfSqlStatement(String trimmedLine, String delimiter, DelimiterMode delimiterMode) { 073 switch (delimiterMode) { 074 case END_OF_LINE: 075 return StringUtils.endsWith(trimmedLine, delimiter); 076 case OWN_LINE: 077 return StringUtils.equals(trimmedLine, delimiter); 078 default: 079 throw new IllegalArgumentException("Delimiter mode '" + delimiterMode + "' is unknown"); 080 } 081 } 082 083 protected boolean proceed(String line, String trimmedLine, String delimiter, DelimiterMode delimiterMode) { 084 return line != null && !isEndOfSqlStatement(trimmedLine, delimiter, delimiterMode); 085 } 086 087 protected boolean ignore(boolean ignoreComments, StringBuilder sql, String trimmedLine, List<String> commentTokens) { 088 return ignoreComments && StringUtils.isBlank(sql.toString()) && isSqlComment(trimmedLine, commentTokens); 089 } 090 091 protected boolean isSqlComment(String trimmedLine, List<String> commentTokens) { 092 for (String commentToken : commentTokens) { 093 if (StringUtils.startsWith(trimmedLine, commentToken)) { 094 return true; 095 } 096 } 097 return false; 098 } 099 100 public String getDelimiter() { 101 return delimiter; 102 } 103 104 public void setDelimiter(String delimiter) { 105 this.delimiter = delimiter; 106 } 107 108 public boolean isTrim() { 109 return trim; 110 } 111 112 public void setTrim(boolean trim) { 113 this.trim = trim; 114 } 115 116 public boolean isIgnoreComments() { 117 return ignoreComments; 118 } 119 120 public void setIgnoreComments(boolean ignoreComments) { 121 this.ignoreComments = ignoreComments; 122 } 123 124 public LineSeparator getLineSeparator() { 125 return lineSeparator; 126 } 127 128 public void setLineSeparator(LineSeparator lineSeparator) { 129 this.lineSeparator = lineSeparator; 130 } 131 132 public DelimiterMode getDelimiterMode() { 133 return delimiterMode; 134 } 135 136 public void setDelimiterMode(DelimiterMode delimiterMode) { 137 this.delimiterMode = delimiterMode; 138 } 139 140 public List<String> getCommentTokens() { 141 return commentTokens; 142 } 143 144 public void setCommentTokens(List<String> commentTokens) { 145 this.commentTokens = commentTokens; 146 } 147 148 }