Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / sqlQueryValidation / SQLQueryValidation.java @ 40558

History | View | Annotate | Download (8.06 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.sqlQueryValidation;
25

    
26
import java.io.ByteArrayInputStream;
27

    
28
import org.gvsig.andami.PluginServices;
29

    
30
import Zql.ZqlParser;
31

    
32

    
33
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
34
 *
35
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
36
 *
37
 * This program is free software; you can redistribute it and/or
38
 * modify it under the terms of the GNU General Public License
39
 * as published by the Free Software Foundation; either version 2
40
 * of the License, or (at your option) any later version.
41
 *
42
 * This program is distributed in the hope that it will be useful,
43
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
44
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
45
 * GNU General Public License for more details.
46
 *
47
 * You should have received a copy of the GNU General Public License
48
 * along with this program; if not, write to the Free Software
49
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
50
 *
51
 * For more information, contact:
52
 *
53
 *  Generalitat Valenciana
54
 *   Conselleria d'Infraestructures i Transport
55
 *   Av. Blasco Ib??ez, 50
56
 *   46010 VALENCIA
57
 *   SPAIN
58
 *
59
 *      +34 963862235
60
 *   gvsig@gva.es
61
 *      www.gvsig.gva.es
62
 *
63
 *    or
64
 *
65
 *   IVER T.I. S.A
66
 *   Salamanca 50
67
 *   46005 Valencia
68
 *   Spain
69
 *
70
 *   +34 963163400
71
 *   dac@iver.es
72
 */
73

    
74
/**
75
 * Class for validate a complete query or the sentence of a query from WHERE 
76
 *
77
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
78
 */
79
public class SQLQueryValidation {
80
        private String query;
81
        private boolean onlyWhereStatement;
82
        private int[] errorPosition; //[0] -> line, [1] -> column        ( (-1, -1) -> no error ) ( (-2, -2) -> error: query = null)
83
        private String errorMessage;
84
        private String errorPositionAsMessage;
85
        private String token;
86
        private final String preQuery = "SELECT a FROM b WHERE ";
87
        private final int preQueryLenght = preQuery.length();
88
        
89
        /**
90
         * Default constructor with a parameter
91
         * 
92
         * @param _query The query to validate
93
         * @param _onlyWhereStatement If the query is only the part of WHERE ... in a query
94
         */
95
        public SQLQueryValidation(String _query, boolean _onlyWhereStatement) {
96
                query = new String(_query);
97
                onlyWhereStatement = _onlyWhereStatement;
98
                
99
                // By default no error position
100
                errorPosition = new int[2];
101
                errorPosition[0] = -1;
102
                errorPosition[1] = -1;
103
                
104
                errorPositionAsMessage = null;
105
                
106
                // By default no error message
107
                errorMessage = null;
108
                
109
                // By default no error symbol
110
                token = null;
111
        }
112
                
113
        /**
114
         * Validates a query
115
         * 
116
         * Returns 'null' if there has been some error
117
         */
118
        public boolean validateQuery() {
119
                String completeQuery = new String();
120
                
121
                // If the query is null -> error 
122
                if (query == null)        {
123
                        errorPosition[0] = -2;
124
                        errorPosition[1] = -2;
125
                        defineErrorPositionAsMessageAttribute(errorPosition);
126
                        errorMessage = new String( PluginServices.getText(null, "queryIsNull"));
127
                        
128
                        return false;
129
                }
130
                
131
                // If no query itsn't considered as a error
132
                if ((query.compareTo("")) == 0) {
133
                        errorPosition[0] = -1;
134
                        errorPosition[1] = -1;
135
                        defineErrorPositionAsMessageAttribute(errorPosition);
136
                        errorMessage = null;
137
                        
138
                        return true;
139
                }
140

    
141
                // Converts all apostrophes between aphostrophes to double inverted commas ( " )
142
                int index = 0;
143
                boolean is_word = false; // by default isn't a word
144
                String formatted_query = new String();
145
                char c;
146
                
147
                while (index < query.length()) {
148
                        c = query.charAt(index);
149
                        if (c == '\'') {
150
                                if (is_word == false) {
151
                                        if ((index > 0) && ((query.charAt(index-1) == ' ') || (query.charAt(index-1) == '(')) ) {
152
                                                is_word = true;
153
                                        }
154
                                        
155
                                        formatted_query += c;
156
                                }
157
                                else {
158
                                        if (index == (query.length() -1)) {
159
//                                                is_word = false;
160
                                                formatted_query += c;
161
                                        }
162
                                        else {
163
                                                if (((query.charAt(index+1) == ' ') || (query.charAt(index+1) == ')')) ) {
164
                                                        is_word = false;
165
                                                        formatted_query += c;
166
                                                }
167
                                                else {
168
                                                        formatted_query += "\""; // Convert ' to "
169
                                                }
170
                                        }
171
                                }
172
                        }
173
                        else {
174
                                formatted_query += c;
175
                        }
176
                        
177
                        index ++;
178
                }                
179
                
180
                // Converts all ocurrences of the symbol " ( double inverted commas ) to space because Zql doesn't support that symbol
181
                if (onlyWhereStatement)
182
                        completeQuery = preQuery + formatted_query.trim().replaceAll("\"", " ");
183
                else
184
                        completeQuery = formatted_query.trim().replaceAll("\"", " ");
185

    
186
                if ((completeQuery.length() > 0) && (completeQuery.charAt(completeQuery.length() - 1) != ';'))
187
                        completeQuery += ";";
188

    
189
                try {
190
                        // Starts the parser
191
                        ZqlParser p = new ZqlParser();
192
                        p.initParser(new ByteArrayInputStream(completeQuery.getBytes()));
193
              
194
                        // Analyzes the query
195
                        p.readStatement();
196
                        
197
                        // If arrives here -> there has been no errors
198
                        errorPosition[0] = -1;
199
                        errorPosition[1] = -1;
200
                        defineErrorPositionAsMessageAttribute(errorPosition);
201
                        errorMessage = null;
202
                        return true;
203
                } catch (Exception e) {
204
                        // Defines the error message
205
                        errorMessage = e.getMessage();
206
                        
207
                        // Get the token that produced the error
208
                        int ini_pos = e.getMessage().indexOf('\"') +1;
209
                        token = new String(errorMessage.substring(ini_pos, errorMessage.indexOf('\"', ini_pos)));
210

    
211
                        // Get the line an column where the syntax error starts
212
                        String line = new String(errorMessage.substring(e.getMessage().indexOf("line"), errorMessage.indexOf(',')));
213
                        line = line.substring(line.indexOf(' ')+1, line.length());
214
                        
215
                        String column = new String(e.getMessage().substring(errorMessage.indexOf("column"), errorMessage.indexOf('.')));
216
                        column = column.substring(column.indexOf(' ')+1, column.length());                        
217

    
218
                        // Get the line an column of the error
219
                        errorPosition[0] = Integer.valueOf(line.trim()).intValue();                        
220
                        errorPosition[1] = Integer.valueOf(column.trim()).intValue();
221
                        
222
                        if (onlyWhereStatement) {
223
                                this.errorPosition[1] -= this.preQueryLenght; // Substract the lenght of the pre-query added
224
                        }
225
                        
226
                        defineErrorPositionAsMessageAttribute(this.errorPosition);
227

    
228
                        return false;
229
                }
230
        }
231
        
232
        /**
233
         * Returns an string with an error message if there has been an error, or 'null' if there hasn't been
234
         * 
235
         * @return An string or null
236
         */
237
        public String getErrorMessage() {
238
                return this.errorMessage;
239
        }
240
        
241
        /**
242
         * Returns an string with a text describing the (first) position of the error
243
         * 
244
         * @return An string or null
245
         */
246
        public String getErrorPositionAsMessage() {
247
                return this.errorPositionAsMessage;
248
        }
249
        
250
        /**
251
         * Returns the error position (line, column) or (-1, -1) if there hasn't been any error
252
         * 
253
         * @return An array of 2 integer values (first: line, second: column) 
254
         */
255
        public int[] getErrorPosition() {
256
                return errorPosition;
257
        }
258
        
259
        /**
260
         * Returns the token where the validator failed
261
         * 
262
         * @return An string
263
         */
264
        public String getTokenThatProducedTheSyntacticError() {
265
                return token;
266
        }
267
        
268
        /**
269
         * Creates a message with information about the message
270
         * 
271
         * @param position An array with 2 elements: (row, column)
272
         */
273
        private void defineErrorPositionAsMessageAttribute(int position[]) {
274
                // Defines the error message
275
                errorPositionAsMessage = new String( PluginServices.getText(null, "line") + ": " + errorPosition[0] + ", " + PluginServices.getText(null, "column") + ": " + errorPosition[1] );
276
        }
277
}