View Javadoc

1   /**
2    * Copyright 2010-2013 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.common.jdbc;
17  
18  import java.io.BufferedReader;
19  import java.io.IOException;
20  import java.util.Arrays;
21  import java.util.List;
22  
23  import org.apache.commons.lang3.StringUtils;
24  import org.springframework.util.Assert;
25  
26  public class DefaultSqlReader implements SqlReader {
27  
28  	public static final String DEFAULT_DELIMITER = "/";
29  	public static final DelimiterMode DEFAULT_DELIMITER_MODE = DelimiterMode.OWN_LINE;
30  	public static final LineSeparator DEFAULT_LINE_SEPARATOR = LineSeparator.LF;
31  	public static final List<String> DEFAULT_COMMENT_TOKENS = Arrays.asList("#", "--");
32  	public static final boolean DEFAULT_IS_TRIM = true;
33  	public static final boolean DEFAULT_IS_IGNORE_COMMENTS = true;
34  
35  	String delimiter = DEFAULT_DELIMITER;
36  	DelimiterMode delimiterMode = DEFAULT_DELIMITER_MODE;
37  	LineSeparator lineSeparator = DEFAULT_LINE_SEPARATOR;
38  	boolean trim = DEFAULT_IS_TRIM;
39  	boolean ignoreComments = DEFAULT_IS_IGNORE_COMMENTS;
40  	List<String> commentTokens = DEFAULT_COMMENT_TOKENS;
41  
42  	@Override
43  	public SqlMetaData getMetaData(BufferedReader reader) throws IOException {
44  		Assert.notNull(delimiter, "delimiter is null");
45  		long count = 0;
46  		long size = 0;
47  		String line = reader.readLine();
48  		String trimmedLine = StringUtils.trimToNull(line);
49  		while (line != null) {
50  			size += line.length();
51  			if (isEndOfSqlStatement(trimmedLine, delimiter, delimiterMode)) {
52  				count++;
53  			}
54  			line = reader.readLine();
55  			trimmedLine = StringUtils.trimToNull(line);
56  		}
57  		SqlMetaData smd = new SqlMetaData();
58  		smd.setCount(count);
59  		smd.setSize(size);
60  		return smd;
61  	}
62  
63  	@Override
64  	public List<String> getSql(BufferedReader reader) throws IOException {
65  		Assert.notNull(delimiter, "delimiter is null");
66  		String line = reader.readLine();
67  		String trimmedLine = StringUtils.trimToNull(line);
68  		StringBuilder sb = new StringBuilder();
69  		while (line != null) {
70  			if (isEndOfSqlStatement(trimmedLine, delimiter, delimiterMode)) {
71  				return Arrays.asList(getReturnValue(sb.toString() + line, trim, lineSeparator));
72  			}
73  			if (!ignore(ignoreComments, sb, trimmedLine, commentTokens)) {
74  				sb.append(line + lineSeparator.getValue());
75  			}
76  			line = reader.readLine();
77  			trimmedLine = StringUtils.trimToNull(line);
78  		}
79  
80  		String result = getReturnValue(sb.toString(), trim, lineSeparator);
81  
82  		if (result == null) {
83  			return null;
84  		} else {
85  			return Arrays.asList(result);
86  		}
87  	}
88  
89  	protected String getReturnValue(String sql, boolean trim, LineSeparator lineSeparator) {
90  		if (StringUtils.endsWith(sql, delimiter)) {
91  			int endIndex = sql.length() - delimiter.length();
92  			sql = StringUtils.substring(sql, 0, endIndex);
93  		}
94  		if (trim) {
95  			sql = StringUtils.trimToNull(sql);
96  		}
97  		if (sql == null) {
98  			return null;
99  		} else if (StringUtils.endsWith(sql, lineSeparator.getValue())) {
100 			int endIndex = sql.length() - lineSeparator.getValue().length();
101 			return StringUtils.substring(sql, 0, endIndex);
102 		} else {
103 			return sql;
104 		}
105 	}
106 
107 	protected boolean isEndOfSqlStatement(String trimmedLine, String delimiter, DelimiterMode delimiterMode) {
108 		switch (delimiterMode) {
109 		case END_OF_LINE:
110 			return StringUtils.endsWith(trimmedLine, delimiter);
111 		case OWN_LINE:
112 			return StringUtils.equals(trimmedLine, delimiter);
113 		default:
114 			throw new IllegalArgumentException("Delimiter mode '" + delimiterMode + "' is unknown");
115 		}
116 	}
117 
118 	protected boolean proceed(String line, String trimmedLine, String delimiter, DelimiterMode delimiterMode) {
119 		if (line == null) {
120 			return false;
121 		}
122 		boolean endOfSqlStatement = isEndOfSqlStatement(trimmedLine, delimiter, delimiterMode);
123 		return !endOfSqlStatement;
124 	}
125 
126 	protected boolean ignore(boolean ignoreComments, StringBuilder sql, String trimmedLine, List<String> commentTokens) {
127 		if (!ignoreComments) {
128 			return false;
129 		}
130 		if (!StringUtils.isBlank(sql.toString())) {
131 			return false;
132 		}
133 		boolean isComment = isSqlComment(trimmedLine, commentTokens);
134 		return isComment;
135 	}
136 
137 	protected boolean isSqlComment(String trimmedLine, List<String> commentTokens) {
138 		for (String commentToken : commentTokens) {
139 			if (StringUtils.startsWith(trimmedLine, commentToken)) {
140 				return true;
141 			}
142 		}
143 		return false;
144 	}
145 
146 	public String getDelimiter() {
147 		return delimiter;
148 	}
149 
150 	public void setDelimiter(String delimiter) {
151 		this.delimiter = delimiter;
152 	}
153 
154 	public boolean isTrim() {
155 		return trim;
156 	}
157 
158 	public void setTrim(boolean trim) {
159 		this.trim = trim;
160 	}
161 
162 	public boolean isIgnoreComments() {
163 		return ignoreComments;
164 	}
165 
166 	public void setIgnoreComments(boolean ignoreComments) {
167 		this.ignoreComments = ignoreComments;
168 	}
169 
170 	public LineSeparator getLineSeparator() {
171 		return lineSeparator;
172 	}
173 
174 	public void setLineSeparator(LineSeparator lineSeparator) {
175 		this.lineSeparator = lineSeparator;
176 	}
177 
178 	public DelimiterMode getDelimiterMode() {
179 		return delimiterMode;
180 	}
181 
182 	public void setDelimiterMode(DelimiterMode delimiterMode) {
183 		this.delimiterMode = delimiterMode;
184 	}
185 
186 	public List<String> getCommentTokens() {
187 		return commentTokens;
188 	}
189 
190 	public void setCommentTokens(List<String> commentTokens) {
191 		this.commentTokens = commentTokens;
192 	}
193 
194 }