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 getSqlMetaData(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 String getSqlStatement(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 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  		return getReturnValue(sb.toString(), trim, lineSeparator);
80  	}
81  
82  	protected String getReturnValue(String sql, boolean trim, LineSeparator lineSeparator) {
83  		if (StringUtils.endsWith(sql, delimiter)) {
84  			int endIndex = sql.length() - delimiter.length();
85  			sql = StringUtils.substring(sql, 0, endIndex);
86  		}
87  		if (trim) {
88  			sql = StringUtils.trimToNull(sql);
89  		}
90  		if (sql == null) {
91  			return null;
92  		} else if (StringUtils.endsWith(sql, lineSeparator.getValue())) {
93  			int endIndex = sql.length() - lineSeparator.getValue().length();
94  			return StringUtils.substring(sql, 0, endIndex);
95  		} else {
96  			return sql;
97  		}
98  	}
99  
100 	protected boolean isEndOfSqlStatement(String trimmedLine, String delimiter, DelimiterMode delimiterMode) {
101 		switch (delimiterMode) {
102 		case END_OF_LINE:
103 			return StringUtils.endsWith(trimmedLine, delimiter);
104 		case OWN_LINE:
105 			return StringUtils.equals(trimmedLine, delimiter);
106 		default:
107 			throw new IllegalArgumentException("Delimiter mode '" + delimiterMode + "' is unknown");
108 		}
109 	}
110 
111 	protected boolean proceed(String line, String trimmedLine, String delimiter, DelimiterMode delimiterMode) {
112 		if (line == null) {
113 			return false;
114 		}
115 		boolean endOfSqlStatement = isEndOfSqlStatement(trimmedLine, delimiter, delimiterMode);
116 		return !endOfSqlStatement;
117 	}
118 
119 	protected boolean ignore(boolean ignoreComments, StringBuilder sql, String trimmedLine, List<String> commentTokens) {
120 		if (!ignoreComments) {
121 			return false;
122 		}
123 		if (!StringUtils.isBlank(sql.toString())) {
124 			return false;
125 		}
126 		boolean isComment = isSqlComment(trimmedLine, commentTokens);
127 		return isComment;
128 	}
129 
130 	protected boolean isSqlComment(String trimmedLine, List<String> commentTokens) {
131 		for (String commentToken : commentTokens) {
132 			if (StringUtils.startsWith(trimmedLine, commentToken)) {
133 				return true;
134 			}
135 		}
136 		return false;
137 	}
138 
139 	public String getDelimiter() {
140 		return delimiter;
141 	}
142 
143 	public void setDelimiter(String delimiter) {
144 		this.delimiter = delimiter;
145 	}
146 
147 	public boolean isTrim() {
148 		return trim;
149 	}
150 
151 	public void setTrim(boolean trim) {
152 		this.trim = trim;
153 	}
154 
155 	public boolean isIgnoreComments() {
156 		return ignoreComments;
157 	}
158 
159 	public void setIgnoreComments(boolean ignoreComments) {
160 		this.ignoreComments = ignoreComments;
161 	}
162 
163 	public LineSeparator getLineSeparator() {
164 		return lineSeparator;
165 	}
166 
167 	public void setLineSeparator(LineSeparator lineSeparator) {
168 		this.lineSeparator = lineSeparator;
169 	}
170 
171 	public DelimiterMode getDelimiterMode() {
172 		return delimiterMode;
173 	}
174 
175 	public void setDelimiterMode(DelimiterMode delimiterMode) {
176 		this.delimiterMode = delimiterMode;
177 	}
178 
179 	public List<String> getCommentTokens() {
180 		return commentTokens;
181 	}
182 
183 	public void setCommentTokens(List<String> commentTokens) {
184 		this.commentTokens = commentTokens;
185 	}
186 
187 }