1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 }