Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / sqlQueryValidation / SQLQueryValidation.java @ 27352

History | View | Annotate | Download (7.12 KB)

1 9663 ppiqueras
package com.iver.cit.gvsig.sqlQueryValidation;
2
3
import java.io.ByteArrayInputStream;
4
5
import Zql.ZqlParser;
6
7
import com.iver.andami.PluginServices;
8
9
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
10
 *
11
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
12
 *
13
 * This program is free software; you can redistribute it and/or
14
 * modify it under the terms of the GNU General Public License
15
 * as published by the Free Software Foundation; either version 2
16
 * of the License, or (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
26
 *
27
 * For more information, contact:
28
 *
29
 *  Generalitat Valenciana
30
 *   Conselleria d'Infraestructures i Transport
31
 *   Av. Blasco Ib??ez, 50
32
 *   46010 VALENCIA
33
 *   SPAIN
34
 *
35
 *      +34 963862235
36
 *   gvsig@gva.es
37
 *      www.gvsig.gva.es
38
 *
39
 *    or
40
 *
41
 *   IVER T.I. S.A
42
 *   Salamanca 50
43
 *   46005 Valencia
44
 *   Spain
45
 *
46
 *   +34 963163400
47
 *   dac@iver.es
48
 */
49
50
/**
51
 * Class for validate a complete query or the sentence of a query from WHERE
52
 *
53
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
54
 */
55
public class SQLQueryValidation {
56
        private String query;
57
        private boolean onlyWhereStatement;
58
        private int[] errorPosition; //[0] -> line, [1] -> column        ( (-1, -1) -> no error ) ( (-2, -2) -> error: query = null)
59
        private String errorMessage;
60
        private String errorPositionAsMessage;
61
        private String token;
62 9706 ppiqueras
        private final String preQuery = "SELECT a FROM b WHERE ";
63 9663 ppiqueras
        private final int preQueryLenght = preQuery.length();
64
65
        /**
66
         * Default constructor with a parameter
67
         *
68
         * @param _query The query to validate
69
         * @param _onlyWhereStatement If the query is only the part of WHERE ... in a query
70
         */
71
        public SQLQueryValidation(String _query, boolean _onlyWhereStatement) {
72
                query = new String(_query);
73
                onlyWhereStatement = _onlyWhereStatement;
74
75
                // By default no error position
76
                errorPosition = new int[2];
77
                errorPosition[0] = -1;
78
                errorPosition[1] = -1;
79
80
                errorPositionAsMessage = null;
81
82
                // By default no error message
83
                errorMessage = null;
84
85
                // By default no error symbol
86
                token = null;
87
        }
88
89
        /**
90
         * Validates a query
91
         *
92
         * Returns 'null' if there has been some error
93
         */
94
        public boolean validateQuery() {
95
                String completeQuery = new String();
96
97
                // If the query is null -> error
98
                if (query == null)        {
99
                        errorPosition[0] = -2;
100
                        errorPosition[1] = -2;
101
                        defineErrorPositionAsMessageAttribute(errorPosition);
102
                        errorMessage = new String( PluginServices.getText(null, "queryIsNull"));
103
104
                        return false;
105
                }
106
107
                // If no query itsn't considered as a error
108
                if ((query.compareTo("")) == 0) {
109
                        errorPosition[0] = -1;
110
                        errorPosition[1] = -1;
111
                        defineErrorPositionAsMessageAttribute(errorPosition);
112
                        errorMessage = null;
113
114
                        return true;
115
                }
116
117 9674 ppiqueras
                // Converts all apostrophes between aphostrophes to double inverted commas ( " )
118
                int index = 0;
119
                boolean is_word = false; // by default isn't a word
120
                String formatted_query = new String();
121
                char c;
122
123
                while (index < query.length()) {
124
                        c = query.charAt(index);
125
                        if (c == '\'') {
126
                                if (is_word == false) {
127
                                        if ((index > 0) && ((query.charAt(index-1) == ' ') || (query.charAt(index-1) == '(')) ) {
128
                                                is_word = true;
129
                                        }
130
131
                                        formatted_query += c;
132
                                }
133
                                else {
134
                                        if (index == (query.length() -1)) {
135
//                                                is_word = false;
136
                                                formatted_query += c;
137
                                        }
138
                                        else {
139
                                                if (((query.charAt(index+1) == ' ') || (query.charAt(index+1) == ')')) ) {
140
                                                        is_word = false;
141
                                                        formatted_query += c;
142
                                                }
143
                                                else {
144
                                                        formatted_query += "\""; // Convert ' to "
145
                                                }
146
                                        }
147
                                }
148
                        }
149
                        else {
150
                                formatted_query += c;
151
                        }
152
153
                        index ++;
154
                }
155
156
                // Converts all ocurrences of the symbol " ( double inverted commas ) to space because Zql doesn't support that symbol
157 9663 ppiqueras
                if (onlyWhereStatement)
158 9674 ppiqueras
                        completeQuery = preQuery + formatted_query.trim().replaceAll("\"", " ");
159 9663 ppiqueras
                else
160 9674 ppiqueras
                        completeQuery = formatted_query.trim().replaceAll("\"", " ");
161 9663 ppiqueras
162
                if ((completeQuery.length() > 0) && (completeQuery.charAt(completeQuery.length() - 1) != ';'))
163
                        completeQuery += ";";
164
165
                try {
166
                        // Starts the parser
167
                        ZqlParser p = new ZqlParser();
168
                        p.initParser(new ByteArrayInputStream(completeQuery.getBytes()));
169
170
                        // Analyzes the query
171
                        p.readStatement();
172
173
                        // If arrives here -> there has been no errors
174
                        errorPosition[0] = -1;
175
                        errorPosition[1] = -1;
176
                        defineErrorPositionAsMessageAttribute(errorPosition);
177
                        errorMessage = null;
178
                        return true;
179
                } catch (Exception e) {
180
                        // Defines the error message
181
                        errorMessage = e.getMessage();
182
183
                        // Get the token that produced the error
184
                        int ini_pos = e.getMessage().indexOf('\"') +1;
185
                        token = new String(errorMessage.substring(ini_pos, errorMessage.indexOf('\"', ini_pos)));
186
187
                        // Get the line an column where the syntax error starts
188
                        String line = new String(errorMessage.substring(e.getMessage().indexOf("line"), errorMessage.indexOf(',')));
189
                        line = line.substring(line.indexOf(' ')+1, line.length());
190
191
                        String column = new String(e.getMessage().substring(errorMessage.indexOf("column"), errorMessage.indexOf('.')));
192
                        column = column.substring(column.indexOf(' ')+1, column.length());
193
194
                        // Get the line an column of the error
195
                        errorPosition[0] = Integer.valueOf(line.trim()).intValue();
196
                        errorPosition[1] = Integer.valueOf(column.trim()).intValue();
197
198
                        if (onlyWhereStatement) {
199
                                this.errorPosition[1] -= this.preQueryLenght; // Substract the lenght of the pre-query added
200
                        }
201
202
                        defineErrorPositionAsMessageAttribute(this.errorPosition);
203
204
                        return false;
205
                }
206
        }
207
208
        /**
209
         * Returns an string with an error message if there has been an error, or 'null' if there hasn't been
210
         *
211
         * @return An string or null
212
         */
213
        public String getErrorMessage() {
214
                return this.errorMessage;
215
        }
216
217
        /**
218
         * Returns an string with a text describing the (first) position of the error
219
         *
220
         * @return An string or null
221
         */
222
        public String getErrorPositionAsMessage() {
223
                return this.errorPositionAsMessage;
224
        }
225
226
        /**
227
         * Returns the error position (line, column) or (-1, -1) if there hasn't been any error
228
         *
229
         * @return An array of 2 integer values (first: line, second: column)
230
         */
231
        public int[] getErrorPosition() {
232
                return errorPosition;
233
        }
234
235
        /**
236
         * Returns the token where the validator failed
237
         *
238
         * @return An string
239
         */
240
        public String getTokenThatProducedTheSyntacticError() {
241
                return token;
242
        }
243
244
        /**
245
         * Creates a message with information about the message
246
         *
247
         * @param position An array with 2 elements: (row, column)
248
         */
249
        private void defineErrorPositionAsMessageAttribute(int position[]) {
250
                // Defines the error message
251
                errorPositionAsMessage = new String( PluginServices.getText(null, "line") + ": " + errorPosition[0] + ", " + PluginServices.getText(null, "column") + ": " + errorPosition[1] );
252
        }
253
}