%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.torque.engine.sql.SQLScanner |
|
|
1 | package org.apache.torque.engine.sql; |
|
2 | ||
3 | /* |
|
4 | * Licensed to the Apache Software Foundation (ASF) under one |
|
5 | * or more contributor license agreements. See the NOTICE file |
|
6 | * distributed with this work for additional information |
|
7 | * regarding copyright ownership. The ASF licenses this file |
|
8 | * to you under the Apache License, Version 2.0 (the |
|
9 | * "License"); you may not use this file except in compliance |
|
10 | * with the License. You may obtain a copy of the License at |
|
11 | * |
|
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
13 | * |
|
14 | * Unless required by applicable law or agreed to in writing, |
|
15 | * software distributed under the License is distributed on an |
|
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
17 | * KIND, either express or implied. See the License for the |
|
18 | * specific language governing permissions and limitations |
|
19 | * under the License. |
|
20 | */ |
|
21 | ||
22 | import java.io.IOException; |
|
23 | import java.io.Reader; |
|
24 | import java.util.List; |
|
25 | import java.util.ArrayList; |
|
26 | ||
27 | /** |
|
28 | * A simple Scanner implementation that scans an |
|
29 | * sql file into usable tokens. Used by SQLToAppData. |
|
30 | * |
|
31 | * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a> |
|
32 | * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> |
|
33 | * @author <a href="mailto:andyhot@di.uoa.gr">Andreas Andreou</a> |
|
34 | * @version $Id: SQLScanner.java 473814 2006-11-11 22:30:30Z tv $ |
|
35 | */ |
|
36 | public class SQLScanner |
|
37 | { |
|
38 | /** white spaces */ |
|
39 | private static final String WHITE = "\f\r\t\n "; |
|
40 | /** alphabetic characters */ |
|
41 | private static final String ALFA |
|
42 | = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
|
43 | /** numbers */ |
|
44 | private static final String NUMER = "0123456789"; |
|
45 | /** alphanumeric */ |
|
46 | private static final String ALFANUM = ALFA + NUMER; |
|
47 | /** special characters */ |
|
48 | private static final String SPECIAL = ";(),'"; |
|
49 | /** comment */ |
|
50 | private static final char COMMENT_POUND = '#'; |
|
51 | /** comment */ |
|
52 | private static final char COMMENT_SLASH = '/'; |
|
53 | /** comment */ |
|
54 | private static final char COMMENT_STAR = '*'; |
|
55 | /** comment */ |
|
56 | private static final char COMMENT_DASH = '-'; |
|
57 | ||
58 | /** the input reader */ |
|
59 | private Reader in; |
|
60 | /** character */ |
|
61 | private int chr; |
|
62 | /** token */ |
|
63 | private String token; |
|
64 | /** list of tokens */ |
|
65 | private List tokens; |
|
66 | /** line */ |
|
67 | private int line; |
|
68 | /** column */ |
|
69 | private int col; |
|
70 | ||
71 | /** |
|
72 | * Creates a new scanner with no Reader |
|
73 | */ |
|
74 | public SQLScanner() |
|
75 | { |
|
76 | 0 | this(null); |
77 | 0 | } |
78 | ||
79 | /** |
|
80 | * Creates a new scanner with an Input Reader |
|
81 | * |
|
82 | * @param input the input reader |
|
83 | */ |
|
84 | public SQLScanner(Reader input) |
|
85 | 7 | { |
86 | 7 | setInput(input); |
87 | 7 | } |
88 | ||
89 | /** |
|
90 | * Set the Input |
|
91 | * |
|
92 | * @param input the input reader |
|
93 | */ |
|
94 | public void setInput(Reader input) |
|
95 | { |
|
96 | 7 | in = input; |
97 | 7 | } |
98 | ||
99 | ||
100 | /** |
|
101 | * Reads the next character and increments the line and column counters. |
|
102 | * |
|
103 | * @throws IOException If an I/O error occurs |
|
104 | */ |
|
105 | private void readChar() throws IOException |
|
106 | { |
|
107 | 7511 | boolean wasLine = (char) chr == '\r'; |
108 | 7511 | chr = in.read(); |
109 | 7511 | if ((char) chr == '\n' || (class="keyword">char) chr == '\r' || (class="keyword">char) chr == '\f') |
110 | { |
|
111 | 189 | col = 0; |
112 | 189 | if (!wasLine || (char) chr != '\n') |
113 | { |
|
114 | 189 | line++; |
115 | 81 | } |
116 | } |
|
117 | else |
|
118 | { |
|
119 | 7322 | col++; |
120 | } |
|
121 | 7511 | } |
122 | ||
123 | /** |
|
124 | * Scans an identifier. |
|
125 | * |
|
126 | * @throws IOException If an I/O error occurs |
|
127 | */ |
|
128 | private void scanIdentifier () throws IOException |
|
129 | { |
|
130 | 91 | token = ""; |
131 | 91 | char c = (class="keyword">char) chr; |
132 | 476 | while (chr != -1 && WHITE.indexOf(c) == -1 && SPECIAL.indexOf(c) == -1) |
133 | { |
|
134 | 385 | token = token + (char) chr; |
135 | 385 | readChar(); |
136 | 385 | c = (char) chr; |
137 | 165 | } |
138 | 91 | int start = col - token.length(); |
139 | 91 | tokens.add(new Token(token, line, start)); |
140 | 91 | } |
141 | ||
142 | /** |
|
143 | * Scans an identifier which had started with the negative sign. |
|
144 | * |
|
145 | * @throws IOException If an I/O error occurs |
|
146 | */ |
|
147 | private void scanNegativeIdentifier () throws IOException |
|
148 | { |
|
149 | 0 | token = "-"; |
150 | 0 | char c = (class="keyword">char) chr; |
151 | 0 | while (chr != -1 && WHITE.indexOf(c) == -1 && SPECIAL.indexOf(c) == -1) |
152 | { |
|
153 | 0 | token = token + (char) chr; |
154 | 0 | readChar(); |
155 | 0 | c = (char) chr; |
156 | } |
|
157 | 0 | int start = col - token.length(); |
158 | 0 | tokens.add(new Token(token, line, start)); |
159 | 0 | } |
160 | ||
161 | /** |
|
162 | * Scan the input Reader and returns a list of tokens. |
|
163 | * |
|
164 | * @return a list of tokens |
|
165 | * @throws IOException If an I/O error occurs |
|
166 | */ |
|
167 | public List scan () throws IOException |
|
168 | { |
|
169 | 7 | line = 1; |
170 | 7 | col = 0; |
171 | 7 | boolean inComment = false; |
172 | 7 | boolean inCommentSlashStar = false; |
173 | 7 | boolean inCommentDash = false; |
174 | ||
175 | boolean inNegative; |
|
176 | ||
177 | 7 | tokens = new ArrayList(); |
178 | 7 | readChar(); |
179 | 6594 | while (chr != -1) |
180 | { |
|
181 | 6587 | char c = (class="keyword">char) chr; |
182 | 6587 | inNegative = false; |
183 | ||
184 | 6587 | if (c == COMMENT_DASH) |
185 | { |
|
186 | 623 | readChar(); |
187 | 623 | if ((char) chr == COMMENT_DASH) |
188 | { |
|
189 | 602 | inCommentDash = true; |
190 | 258 | } |
191 | else |
|
192 | { |
|
193 | 21 | inNegative = true; |
194 | 21 | c = (char) chr; |
195 | } |
|
196 | } |
|
197 | ||
198 | 6587 | if (inCommentDash) |
199 | { |
|
200 | 5992 | if (c == '\n' || c == '\r') |
201 | { |
|
202 | 126 | inCommentDash = false; |
203 | } |
|
204 | 5992 | readChar(); |
205 | 2568 | } |
206 | 595 | else if (c == COMMENT_POUND) |
207 | { |
|
208 | 21 | inComment = true; |
209 | 21 | readChar(); |
210 | 9 | } |
211 | 574 | else if (c == COMMENT_SLASH) |
212 | { |
|
213 | 0 | readChar(); |
214 | 0 | if ((char) chr == COMMENT_STAR) |
215 | { |
|
216 | 0 | inCommentSlashStar = true; |
217 | } |
|
218 | } |
|
219 | 574 | else if (inComment || inCommentSlashStar) |
220 | { |
|
221 | 273 | if (c == '*') |
222 | { |
|
223 | 0 | readChar(); |
224 | 0 | if ((char) chr == COMMENT_SLASH) |
225 | { |
|
226 | 0 | inCommentSlashStar = false; |
227 | } |
|
228 | } |
|
229 | 273 | else if (c == '\n' || c == '\r') |
230 | { |
|
231 | 14 | inComment = false; |
232 | } |
|
233 | 273 | readChar(); |
234 | 117 | } |
235 | 301 | else if (ALFANUM.indexOf(c) >= 0) |
236 | { |
|
237 | 91 | if (inNegative) |
238 | { |
|
239 | 0 | scanNegativeIdentifier(); |
240 | } |
|
241 | else |
|
242 | { |
|
243 | 91 | scanIdentifier(); |
244 | } |
|
245 | 39 | } |
246 | 210 | else if (SPECIAL.indexOf(c) >= 0) |
247 | { |
|
248 | 63 | tokens.add(new Token("" + c, line, col)); |
249 | 63 | readChar(); |
250 | 27 | } |
251 | else |
|
252 | { |
|
253 | 147 | readChar(); |
254 | } |
|
255 | 3764 | } |
256 | 7 | return tokens; |
257 | } |
|
258 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |