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 @ 40596

History | View | Annotate | Download (6.87 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
/**
34
 * Class for validate a complete query or the sentence of a query from WHERE 
35
 *
36
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
37
 */
38
public class SQLQueryValidation {
39
        private String query;
40
        private boolean onlyWhereStatement;
41
        private int[] errorPosition; //[0] -> line, [1] -> column        ( (-1, -1) -> no error ) ( (-2, -2) -> error: query = null)
42
        private String errorMessage;
43
        private String errorPositionAsMessage;
44
        private String token;
45
        private final String preQuery = "SELECT a FROM b WHERE ";
46
        private final int preQueryLenght = preQuery.length();
47
        
48
        /**
49
         * Default constructor with a parameter
50
         * 
51
         * @param _query The query to validate
52
         * @param _onlyWhereStatement If the query is only the part of WHERE ... in a query
53
         */
54
        public SQLQueryValidation(String _query, boolean _onlyWhereStatement) {
55
                query = new String(_query);
56
                onlyWhereStatement = _onlyWhereStatement;
57
                
58
                // By default no error position
59
                errorPosition = new int[2];
60
                errorPosition[0] = -1;
61
                errorPosition[1] = -1;
62
                
63
                errorPositionAsMessage = null;
64
                
65
                // By default no error message
66
                errorMessage = null;
67
                
68
                // By default no error symbol
69
                token = null;
70
        }
71
                
72
        /**
73
         * Validates a query
74
         * 
75
         * Returns 'null' if there has been some error
76
         */
77
        public boolean validateQuery() {
78
                String completeQuery = new String();
79
                
80
                // If the query is null -> error 
81
                if (query == null)        {
82
                        errorPosition[0] = -2;
83
                        errorPosition[1] = -2;
84
                        defineErrorPositionAsMessageAttribute(errorPosition);
85
                        errorMessage = new String( PluginServices.getText(null, "queryIsNull"));
86
                        
87
                        return false;
88
                }
89
                
90
                // If no query itsn't considered as a error
91
                if ((query.compareTo("")) == 0) {
92
                        errorPosition[0] = -1;
93
                        errorPosition[1] = -1;
94
                        defineErrorPositionAsMessageAttribute(errorPosition);
95
                        errorMessage = null;
96
                        
97
                        return true;
98
                }
99

    
100
                // Converts all apostrophes between aphostrophes to double inverted commas ( " )
101
                int index = 0;
102
                boolean is_word = false; // by default isn't a word
103
                String formatted_query = new String();
104
                char c;
105
                
106
                while (index < query.length()) {
107
                        c = query.charAt(index);
108
                        if (c == '\'') {
109
                                if (is_word == false) {
110
                                        if ((index > 0) && ((query.charAt(index-1) == ' ') || (query.charAt(index-1) == '(')) ) {
111
                                                is_word = true;
112
                                        }
113
                                        
114
                                        formatted_query += c;
115
                                }
116
                                else {
117
                                        if (index == (query.length() -1)) {
118
//                                                is_word = false;
119
                                                formatted_query += c;
120
                                        }
121
                                        else {
122
                                                if (((query.charAt(index+1) == ' ') || (query.charAt(index+1) == ')')) ) {
123
                                                        is_word = false;
124
                                                        formatted_query += c;
125
                                                }
126
                                                else {
127
                                                        formatted_query += "\""; // Convert ' to "
128
                                                }
129
                                        }
130
                                }
131
                        }
132
                        else {
133
                                formatted_query += c;
134
                        }
135
                        
136
                        index ++;
137
                }                
138
                
139
                // Converts all ocurrences of the symbol " ( double inverted commas ) to space because Zql doesn't support that symbol
140
                if (onlyWhereStatement)
141
                        completeQuery = preQuery + formatted_query.trim().replaceAll("\"", " ");
142
                else
143
                        completeQuery = formatted_query.trim().replaceAll("\"", " ");
144

    
145
                if ((completeQuery.length() > 0) && (completeQuery.charAt(completeQuery.length() - 1) != ';'))
146
                        completeQuery += ";";
147

    
148
                try {
149
                        // Starts the parser
150
                        ZqlParser p = new ZqlParser();
151
                        p.initParser(new ByteArrayInputStream(completeQuery.getBytes()));
152
              
153
                        // Analyzes the query
154
                        p.readStatement();
155
                        
156
                        // If arrives here -> there has been no errors
157
                        errorPosition[0] = -1;
158
                        errorPosition[1] = -1;
159
                        defineErrorPositionAsMessageAttribute(errorPosition);
160
                        errorMessage = null;
161
                        return true;
162
                } catch (Exception e) {
163
                        // Defines the error message
164
                        errorMessage = e.getMessage();
165
                        
166
                        // Get the token that produced the error
167
                        int ini_pos = e.getMessage().indexOf('\"') +1;
168
                        token = new String(errorMessage.substring(ini_pos, errorMessage.indexOf('\"', ini_pos)));
169

    
170
                        // Get the line an column where the syntax error starts
171
                        String line = new String(errorMessage.substring(e.getMessage().indexOf("line"), errorMessage.indexOf(',')));
172
                        line = line.substring(line.indexOf(' ')+1, line.length());
173
                        
174
                        String column = new String(e.getMessage().substring(errorMessage.indexOf("column"), errorMessage.indexOf('.')));
175
                        column = column.substring(column.indexOf(' ')+1, column.length());                        
176

    
177
                        // Get the line an column of the error
178
                        errorPosition[0] = Integer.valueOf(line.trim()).intValue();                        
179
                        errorPosition[1] = Integer.valueOf(column.trim()).intValue();
180
                        
181
                        if (onlyWhereStatement) {
182
                                this.errorPosition[1] -= this.preQueryLenght; // Substract the lenght of the pre-query added
183
                        }
184
                        
185
                        defineErrorPositionAsMessageAttribute(this.errorPosition);
186

    
187
                        return false;
188
                }
189
        }
190
        
191
        /**
192
         * Returns an string with an error message if there has been an error, or 'null' if there hasn't been
193
         * 
194
         * @return An string or null
195
         */
196
        public String getErrorMessage() {
197
                return this.errorMessage;
198
        }
199
        
200
        /**
201
         * Returns an string with a text describing the (first) position of the error
202
         * 
203
         * @return An string or null
204
         */
205
        public String getErrorPositionAsMessage() {
206
                return this.errorPositionAsMessage;
207
        }
208
        
209
        /**
210
         * Returns the error position (line, column) or (-1, -1) if there hasn't been any error
211
         * 
212
         * @return An array of 2 integer values (first: line, second: column) 
213
         */
214
        public int[] getErrorPosition() {
215
                return errorPosition;
216
        }
217
        
218
        /**
219
         * Returns the token where the validator failed
220
         * 
221
         * @return An string
222
         */
223
        public String getTokenThatProducedTheSyntacticError() {
224
                return token;
225
        }
226
        
227
        /**
228
         * Creates a message with information about the message
229
         * 
230
         * @param position An array with 2 elements: (row, column)
231
         */
232
        private void defineErrorPositionAsMessageAttribute(int position[]) {
233
                // Defines the error message
234
                errorPositionAsMessage = new String( PluginServices.getText(null, "line") + ": " + errorPosition[0] + ", " + PluginServices.getText(null, "column") + ": " + errorPosition[1] );
235
        }
236
}