Revision 34026 branches/v2_0_0_prep/extensions/extWFS2/src/org/gvsig/wfs/gui/panels/WFSFilterPanel.java

View differences:

WFSFilterPanel.java
7 7
import java.net.URLEncoder;
8 8
import java.text.DateFormat;
9 9
import java.text.ParseException;
10
import java.util.Comparator;
10 11
import java.util.HashMap;
12
import java.util.Iterator;
11 13
import java.util.Map;
12 14
import java.util.Set;
13 15
import java.util.StringTokenizer;
16
import java.util.TreeSet;
14 17
import java.util.Vector;
15 18

  
16 19
import javax.swing.DefaultListModel;
17
import javax.swing.JLabel;
18 20
import javax.swing.JOptionPane;
19 21
import javax.swing.event.DocumentEvent;
20 22
import javax.swing.event.DocumentListener;
......
24 26
import javax.swing.tree.DefaultTreeModel;
25 27
import javax.swing.tree.TreePath;
26 28

  
27
import org.geotools.filter.DefaultExpression;
29
import org.slf4j.Logger;
30
import org.slf4j.LoggerFactory;
31

  
28 32
import org.gvsig.andami.PluginServices;
29 33
import org.gvsig.andami.messages.NotificationManager;
30 34
import org.gvsig.app.gui.filter.ExpressionDataSource;
31 35
import org.gvsig.app.gui.filter.FilterException;
32 36
import org.gvsig.app.sqlQueryValidation.SQLQueryValidation;
37
import org.gvsig.fmap.dal.feature.Feature;
38
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
39
import org.gvsig.fmap.dal.feature.FeatureStore;
40
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
33 41
import org.gvsig.gui.beans.Messages;
34 42
import org.gvsig.gui.beans.filterPanel.filterQueryPanel.FilterQueryJPanel;
35 43
import org.gvsig.gui.beans.panelGroup.IPanelGroup;
36
import org.gvsig.remoteclient.wfs.schema.XMLElement;
37
import org.gvsig.remoteclient.wfs.schema.type.IXMLType;
44
import org.gvsig.remoteclient.wfs.WFSFeatureField;
45
import org.gvsig.tools.dataTypes.DataTypes;
46
import org.gvsig.tools.dispose.DisposableIterator;
38 47
import org.gvsig.utils.stringNumberUtilities.StringNumberUtilities;
39 48
import org.gvsig.wfs.gui.panels.fieldstree.FieldsTreeTableModel;
40 49
import org.gvsig.wfs.gui.panels.model.WFSSelectedFeature;
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
50
import org.gvsig.xmlschema.lib.api.som.IXSElementDeclaration;
43 51

  
44 52

  
45 53

  
......
93 101
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
94 102
 */
95 103
public class WFSFilterPanel extends FilterQueryJPanel implements IWFSPanel {
96
	private static final long serialVersionUID = -6041218260822015810L;
104
    private static final long serialVersionUID = -6041218260822015810L;
97 105

  
98
	private static Logger logger = LoggerFactory.getLogger(WFSFilterPanel.class);
99
	private ExpressionDataSource model = null;
100
	private FieldsTreeTableModel fieldsTreeTableModel;
101
	private boolean panelAsATabForWFSLayersLoad;
102
	private TreePath currentPath;
103
	private String featureName;
104
	private Map<String, Map<String, String>> allFieldsAndValuesKnownOfCurrentLayer; // This will have all values (not repeated) known of all fields (not repeated)
106
    private static Logger logger = LoggerFactory.getLogger(WFSFilterPanel.class);
107
    private ExpressionDataSource model = null;
108
    private FieldsTreeTableModel fieldsTreeTableModel;
109
    private boolean panelAsATabForWFSLayersLoad;
110
    private TreePath currentPath;
111
    private String featureName;
112
    private Map<String, Map<String, String>> allFieldsAndValuesKnownOfCurrentLayer; // This will have all values (not repeated) known of all fields (not repeated)
105 113

  
106
	///// GUI METHODS ////
114
    private FLyrVect selectedLayer = null;
107 115

  
108
	/**
109
	 * This method initializes
110
	 *
111
	 * @param parent A reference to the parent container component of this component
112
	 */
113
	public WFSFilterPanel() {
114
		super();
115
		currentPath = null;
116
		featureName = null;
117
		allFieldsAndValuesKnownOfCurrentLayer = new HashMap<String, Map<String, String>>(); // Initial capacity = 0
116
    ///// GUI METHODS ////
118 117

  
119
		// At beginning, the JList is disabled (and its set a particular color for user could knew it)
120
		super.getValuesJList().setEnabled(false);
121
		getValuesJList().setBackground(new Color(220, 220, 220));
122
	}
118
    /**
119
     * This method initializes
120
     *
121
     * @param parent A reference to the parent container component of this component
122
     */
123
    public WFSFilterPanel() {
124
        super();
125
        currentPath = null;
126
        featureName = null;
127
        allFieldsAndValuesKnownOfCurrentLayer = new HashMap<String, Map<String, String>>(); // Initial capacity = 0
123 128

  
124
	/*
125
	 *  (non-Javadoc)
126
	 * @see org.gvsig.gui.beans.filterPanel.AbstractFilterQueryJPanel#initialize()
127
	 */
128
	protected void initialize() {
129
		setLabel(PluginServices.getText(this, "filter"));
130
		setLabelGroup(PluginServices.getText(this, "wfs"));
131
		super.initialize();
132
		this.resizeHeight(380);
129
        // At beginning, the JList is disabled (and its set a particular color for user could knew it)
130
        super.getValuesJList().setEnabled(false);
131
        //getValuesJList().setBackground(new Color(220, 220, 220));
132
    }
133 133

  
134
		defaultTreeModel = (DefaultTreeModel)fieldsJTree.getModel();
134
    /*
135
     *  (non-Javadoc)
136
     * @see org.gvsig.gui.beans.filterPanel.AbstractFilterQueryJPanel#initialize()
137
     */
138
    protected void initialize() {
139
        setLabel(PluginServices.getText(this, "filter"));
140
        setLabelGroup(PluginServices.getText(this, "wfs"));
141
        super.initialize();
142
        this.resizeHeight(380);
135 143

  
136
		this.addNewListeners();
137
		panelAsATabForWFSLayersLoad = true;
138
		getValidateFilterExpressionJCheckBox().setSelected(true);
144
        defaultTreeModel = (DefaultTreeModel)fieldsJTree.getModel();
139 145

  
140
		getValuesJLabel().setToolTipText(Messages.getText("values_of_the_selected_field_explanation"));
141
		getFieldsJLabel().setToolTipText(Messages.getText("fields_of_the_selected_feature_explanation"));
142
	}
146
        this.addNewListeners();
147
        panelAsATabForWFSLayersLoad = true;
148
        getValidateFilterExpressionJCheckBox().setSelected(true);
143 149

  
144
	/**
145
	 * Adds some more listener to the components of the panel
146
	 */
147
	private void addNewListeners() {
148
		// Enable "Apply" button when user changes the filter query
149
		txtExpression.getDocument().addDocumentListener(new DocumentListener() {
150
			/*
151
			 *  (non-Javadoc)
152
			 * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
153
			 */
154
			public void changedUpdate(DocumentEvent e) {
155
			}
150
        getValuesJLabel().setToolTipText(Messages.getText("values_of_the_selected_field_explanation"));
151
        getFieldsJLabel().setToolTipText(Messages.getText("fields_of_the_selected_feature_explanation"));
152
    }
156 153

  
157
			/*
158
			 *  (non-Javadoc)
159
			 * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
160
			 */
161
			public void insertUpdate(DocumentEvent e) {
162
				if (!panelAsATabForWFSLayersLoad) {
163
					IPanelGroup panelGroup = getPanelGroup();
164
					
165
					if (panelGroup == null)
166
						return;
167
					
168
					((WFSParamsPanel)panelGroup).setApplicable(true);
169
				}
170
			}
154
    /**
155
     * Adds some more listener to the components of the panel
156
     */
157
    private void addNewListeners() {
158
        // Enable "Apply" button when user changes the filter query
159
        txtExpression.getDocument().addDocumentListener(new DocumentListener() {
160
            /*
161
             *  (non-Javadoc)
162
             * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
163
             */
164
            public void changedUpdate(DocumentEvent e) {
165
            }
171 166

  
172
			/*
173
			 *  (non-Javadoc)
174
			 * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
175
			 */
176
			public void removeUpdate(DocumentEvent e) {
177
				if (!panelAsATabForWFSLayersLoad) {
178
					IPanelGroup panelGroup = getPanelGroup();
179
					
180
					if (panelGroup == null)
181
						return;
182
					
183
					((WFSParamsPanel)panelGroup).setApplicable(true);
184
				}
185
			}
186
		});
167
            /*
168
             *  (non-Javadoc)
169
             * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
170
             */
171
            public void insertUpdate(DocumentEvent e) {
172
                if (!panelAsATabForWFSLayersLoad) {
173
                    IPanelGroup panelGroup = getPanelGroup();
187 174

  
188
		// Listener for "fieldsJTree"
189
		getFieldsJTree().addMouseListener(new MouseAdapter() {
190
			/*
191
			 *  (non-Javadoc)
192
			 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
193
			 */
194
			public void mouseClicked(MouseEvent e) {
195
				int row = fieldsJTree.getRowForLocation(e.getX(), e.getY());
196
				TreePath treePath = fieldsJTree.getPathForLocation(e.getX(), e.getY());
175
                    if (panelGroup == null)
176
                        return;
197 177

  
198
				if (row > -1) {
199
					switch (e.getClickCount()) {
200
						case 2:
201
							putSymbolOfSelectedByMouseBranch(treePath);
202
							break;
203
					}
204
				}
205
			}
206
		});
178
                    ((WFSParamsPanel)panelGroup).setApplicable(true);
179
                }
180
            }
207 181

  
208
		// Listener for "valuesJList"
209
		getValuesJList().addMouseListener(new MouseAdapter() {
210
			/*
211
			 *  (non-Javadoc)
212
			 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
213
			 */
214
			public void mouseClicked(MouseEvent e) {
215
				int index = getValuesJList().getSelectedIndex();
182
            /*
183
             *  (non-Javadoc)
184
             * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
185
             */
186
            public void removeUpdate(DocumentEvent e) {
187
                if (!panelAsATabForWFSLayersLoad) {
188
                    IPanelGroup panelGroup = getPanelGroup();
216 189

  
217
				// Avoids exception when no value is in the list
218
				if (index == -1)
219
					return;
190
                    if (panelGroup == null)
191
                        return;
220 192

  
221
				if (e.getClickCount() == 2){
222
					String valor = ((JLabel) valuesListModel.getElementAt(index)).getText();
193
                    ((WFSParamsPanel)panelGroup).setApplicable(true);
194
                }
195
            }
196
        });
223 197

  
224
					// If value is an string -> set it between apostrophes
225
					if (getNodeOfCurrentPath().getEntityType().getName().compareTo("xs:string") == 0) {
226
						putSymbol("'" + valor + "'");
227
					}
228
					else {
229
						putSymbol(valor);
230
					}
231
				}
232
			}
233
		});
198
        // Listener for "fieldsJTree"
199
        getFieldsJTree().addMouseListener(new MouseAdapter() {
200
            /*
201
             *  (non-Javadoc)
202
             * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
203
             */
204
            public void mouseClicked(MouseEvent e) {
205
                int row = fieldsJTree.getRowForLocation(e.getX(), e.getY());
206
                TreePath treePath = fieldsJTree.getPathForLocation(e.getX(), e.getY());
234 207

  
235
		// Listener for a branch of the tree selection
236
		getFieldsJTree().addTreeSelectionListener(new TreeSelectionListener() {
237
			/*
238
			 *  (non-Javadoc)
239
			 * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent)
240
			 */
241
			public void valueChanged(TreeSelectionEvent e) {
242
				if (!panelAsATabForWFSLayersLoad) {
243
					DefaultExpression data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
208
                if (row > -1) {
209
                    switch (e.getClickCount()) {
210
                    case 2:
211
                        putSymbolOfSelectedByMouseBranch(treePath);
212
                        break;
213
                    }
214
                }
215
            }
216
        });
244 217

  
245
					if (data != null) {
246
						currentPath = e.getPath();
247
						fillValuesByPath(currentPath);
248
					}
249
				}
250
			}
251
		});
218
        // Listener for "valuesJList"
219
        getValuesJList().addMouseListener(new MouseAdapter() {
220
            /*
221
             *  (non-Javadoc)
222
             * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
223
             */
224
            public void mouseClicked(MouseEvent e) {
225
                int index = getValuesJList().getSelectedIndex();
252 226

  
253
		// Listener: when a user writes something on the textarea -> set it's foreground color to black
254
		getTxtExpression().getDocument().addDocumentListener(new DocumentListener() {
255
			/*
256
			 *  (non-Javadoc)
257
			 * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
258
			 */
259
			public void changedUpdate(DocumentEvent e) {
260
			}
227
                // Avoids exception when no value is in the list
228
                if (index == -1)
229
                    return;
261 230

  
262
			/*
263
			 *  (non-Javadoc)
264
			 * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
265
			 */
266
			public void insertUpdate(DocumentEvent e) {
267
				getTxtExpression().setForeground(Color.BLACK);
268
			}
231
                if (e.getClickCount() == 2){
232
                    String valor = valuesListModel.getElementAt(index).toString();
233
                    
234
                    // If value is an string -> set it between apostrophes
235
                    if (getNodeOfCurrentPath().getDataType().getType() == DataTypes.STRING) {
236
                        putSymbol("'" + valor + "'");
237
                    }
238
                    else {
239
                        putSymbol(valor);
240
                    }
241
                }
242
            }
243
        });
269 244

  
270
			/*
271
			 *  (non-Javadoc)
272
			 * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
273
			 */
274
			public void removeUpdate(DocumentEvent e) {
275
				getTxtExpression().setForeground(Color.BLACK);
276
			}
277
		});
278
	}
245
        // Listener for a branch of the tree selection
246
        getFieldsJTree().addTreeSelectionListener(new TreeSelectionListener() {
247
            /*
248
             *  (non-Javadoc)
249
             * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent)
250
             */
251
            public void valueChanged(TreeSelectionEvent e) {
252
                if (selectedLayer != null){
253
                    currentPath = e.getPath();
254
                    fillValuesByPath(currentPath);
255
                }
256
            }
257
        });
279 258

  
280
	/**
281
	 * Gets the element that the 'currentPath' field aims
282
	 *
283
	 * @return An XMLElement
284
	 */
285
	private XMLElement getNodeOfCurrentPath() {
259
        // Listener: when a user writes something on the textarea -> set it's foreground color to black
260
        getTxtExpression().getDocument().addDocumentListener(new DocumentListener() {
261
            /*
262
             *  (non-Javadoc)
263
             * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
264
             */
265
            public void changedUpdate(DocumentEvent e) {
266
            }
286 267

  
287
		if (currentPath != null) {
288
			Object node = currentPath.getLastPathComponent();
268
            /*
269
             *  (non-Javadoc)
270
             * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
271
             */
272
            public void insertUpdate(DocumentEvent e) {
273
                getTxtExpression().setForeground(Color.BLACK);
274
            }
289 275

  
290
			if ((node != null) && (node instanceof XMLElement)) {
291
				return (XMLElement) node;
292
			}
293
		}
276
            /*
277
             *  (non-Javadoc)
278
             * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
279
             */
280
            public void removeUpdate(DocumentEvent e) {
281
                getTxtExpression().setForeground(Color.BLACK);
282
            }
283
        });
284
    }
294 285

  
295
		return null;
296
	}
286
    /**
287
     * Gets the element that the 'currentPath' field aims
288
     *
289
     * @return An XMLElement
290
     */
291
    private WFSFeatureField getNodeOfCurrentPath() {
297 292

  
298
	/**
299
	 * Puts the symbol of selected branch
300
	 *
301
	 * @param mouseEvent A MouseEvent with information  of the selected branch
302
	 */
303
	public void putSymbolOfSelectedByMouseBranch(TreePath treePath) {
304
		// Sets the node selected
305
		if (treePath != null) {
306
			putSymbol("\"" + this.getPathOfLeafWithoutRoot(treePath.getLastPathComponent()) + "\"");
307
		}
308
	}
293
        if (currentPath != null) {
294
            Object node = currentPath.getLastPathComponent();
309 295

  
310
	/**
311
	 * This method returns the path without the root, of a node of a tree
312
	 * Each node is separated from its parent with the symbol "/"
313
	 *
314
	 * @param node A leaf node
315
	 * @return An string with the path
316
	 */
317
	private String getPathOfLeafWithoutRoot(Object node) {
318
		String path = "";
296
            if ((node != null) && (node instanceof WFSFeatureField)) {
297
                return (WFSFeatureField) node;
298
            }
299
        }
319 300

  
320
		if ((node != null) && (node instanceof XMLElement)) {
321
			XMLElement element = (XMLElement) node;
322
			XMLElement parent = element.getParentElement();
323
			path = element.getName();
301
        return null;
302
    }
324 303

  
325
			while (parent.getParentElement() != null){
326
				path = parent.getName() + "/" + path;
327
				parent = parent.getParentElement();
328
			}
329
		}
304
    /**
305
     * Puts the symbol of selected branch
306
     *
307
     * @param mouseEvent A MouseEvent with information  of the selected branch
308
     */
309
    public void putSymbolOfSelectedByMouseBranch(TreePath treePath) {
310
        // Sets the node selected
311
        if (treePath != null) {
312
            putSymbol("\"" + this.getPathOfLeafWithoutRoot(treePath.getLastPathComponent().toString()) + "\"");
313
        }
314
    }
330 315

  
331
		return path;
332
	}
316
    /**
317
     * This method returns the path without the root, of a node of a tree
318
     * Each node is separated from its parent with the symbol "/"
319
     *
320
     * @param node A leaf node
321
     * @return An string with the path
322
     */
323
    private String getPathOfLeafWithoutRoot(Object node) {
324
        String path = "";
333 325

  
334
	/**
335
	 * Gets the value of the inner attribute: 'panelAsATabForWFSLayersLoad'
336
	 *
337
	 * @return A boolean value
338
	 */
339
	public boolean getWFSFilterPanelIsAsTabForWFSLayersLoad() {
340
		return this.panelAsATabForWFSLayersLoad;
341
	}
326
        if ((node != null) && (node instanceof IXSElementDeclaration)) {
327
            IXSElementDeclaration element = (IXSElementDeclaration) node;
328
            IXSElementDeclaration parent = element.getParentElement();
329
            path = element.getNodeName();
342 330

  
343
	/**
344
	 * Sets the value of the inner attribute: 'panelAsATabForWFSLayersLoad'
345
	 *
346
	 * @param b A boolean value
347
	 */
348
	public void setWFSFilterPanelIsAsTabForWFSLayersLoad (boolean b) {
349
//		this.panelAsATabForWFSLayersLoad = b;
350
//
351
//		if (this.panelAsATabForWFSLayersLoad == true) {
352
//			// At beginning, the JList is disabled (and its set a particular color for user could knew it)
353
//			super.getValuesJList().setEnabled(false);
354
//			super.getValuesJList().setBackground(new Color(220, 220, 220)); // a grey color
355
//
356
//			this.allFieldsAndValuesKnownOfCurrentLayer.clear();
357
//			getValidateFilterExpressionJCheckBox().setSelected(true);
358
//		}
359
//		else {
360
//			// Unselect the selected path in the tree (if there was any selected)
361
//			if (this.currentPath != null) {
362
//				this.currentPath = null;
363
//				this.getFieldsJTree().removeSelectionPath(this.getFieldsJTree().getSelectionPath());
364
//			}
365
//
366
//			// Resets data loaded
367
//			super.getValuesJList().setEnabled(true);
368
//			super.getValuesJList().setBackground(Color.WHITE);
369
//
370
//			this.getFieldsJTree().removeAll();
371
//			this.getValuesJList().removeAll();
372
//
373
//			// Updates data associated to view with the new layer data
374
//			this.setNewDataToTable();
375
//
376
//			// Reads that new data
377
//			DefaultExpression data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
378
//
379
//			if (data != null) {
380
//				setModel(data);
381
//			}
382
//
383
//			// Loads values known of fields
384
//			this.setValuesKnownOfFields();
385
//		}
386
	}
331
            while (parent.getParentElement() != null){
332
                path = parent.getNodeName() + "/" + path;
333
                parent = parent.getParentElement();
334
            }
335
        }else if (node instanceof String){
336
            path = node.toString();
337
        }
387 338

  
388
	/**
389
	 * Refresh all information about fields
390
	 *
391
	 * @param feature a feature with fields
392
	 */
393
	public void refresh(WFSSelectedFeature feature) {
394
		featureName = feature.getTitle();
395
		setFields(feature);	
396
		setFilterExpressionIntoInterface(feature.getFilter());
397
	}
339
        return path;
340
    }
398 341

  
399
	///// END GUI METHODS /////
342
    /**
343
     * Gets the value of the inner attribute: 'panelAsATabForWFSLayersLoad'
344
     *
345
     * @return A boolean value
346
     */
347
    public boolean getWFSFilterPanelIsAsTabForWFSLayersLoad() {
348
        return this.panelAsATabForWFSLayersLoad;
349
    }
400 350

  
401
	///// METHODS FOR THE FILTER QUERY /////
351
    /**
352
     * Sets the value of the inner attribute: 'panelAsATabForWFSLayersLoad'
353
     *
354
     * @param b A boolean value
355
     */
356
    public void setWFSFilterPanelIsAsTabForWFSLayersLoad (boolean b) {
357
        //		this.panelAsATabForWFSLayersLoad = b;
358
        //
359
        //		if (this.panelAsATabForWFSLayersLoad == true) {
360
        //			// At beginning, the JList is disabled (and its set a particular color for user could knew it)
361
        //			super.getValuesJList().setEnabled(false);
362
        //			super.getValuesJList().setBackground(new Color(220, 220, 220)); // a grey color
363
        //
364
        //			this.allFieldsAndValuesKnownOfCurrentLayer.clear();
365
        //			getValidateFilterExpressionJCheckBox().setSelected(true);
366
        //		}
367
        //		else {
368
        //			// Unselect the selected path in the tree (if there was any selected)
369
        //			if (this.currentPath != null) {
370
        //				this.currentPath = null;
371
        //				this.getFieldsJTree().removeSelectionPath(this.getFieldsJTree().getSelectionPath());
372
        //			}
373
        //
374
        //			// Resets data loaded
375
        //			super.getValuesJList().setEnabled(true);
376
        //			super.getValuesJList().setBackground(Color.WHITE);
377
        //
378
        //			this.getFieldsJTree().removeAll();
379
        //			this.getValuesJList().removeAll();
380
        //
381
        //			// Updates data associated to view with the new layer data
382
        //			this.setNewDataToTable();
383
        //
384
        //			// Reads that new data
385
        //			DefaultExpression data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
386
        //
387
        //			if (data != null) {
388
        //				setModel(data);
389
        //			}
390
        //
391
        //			// Loads values known of fields
392
        //			this.setValuesKnownOfFields();
393
        //		}
394
    }
402 395

  
403
	/**
404
	 * Gets the query that will be send to the server
405
	 * @return SQL query (just the where part)
406
	 */
407
	public String getQuery(){
408
		String writtenQuery = txtExpression.getText().trim();
396
    /**
397
     * Refresh all information about fields
398
     *
399
     * @param feature a feature with fields
400
     */
401
    public void refresh(WFSSelectedFeature feature) {
402
        featureName = feature.getTitle();
403
        setFields(feature);	
404
        setFilterExpressionIntoInterface(feature.getFilter());
405
    }
409 406

  
410
		// Validate expression
411
		if (!this.validateExpression(writtenQuery)) {
412
			getTxtExpression().setForeground(Color.red);
413
			return null;
414
		}
415
		else {
416
			logger.debug("Codified WFS filter query: " + writtenQuery);
407
    ///// END GUI METHODS /////
417 408

  
418
			// Codify expression (only if the validation has been successful)
419
			return this.codifyExpression(writtenQuery); // Ignores the spaces at beginning and end of the chain of characters
420
		}
421
	}
409
    ///// METHODS FOR THE FILTER QUERY /////
422 410

  
423
	/**
424
	 * Gets the filter expression from the user interface
425
	 */
426
	public String getFilterExpressionFromInterface() {
427
		return getTxtExpression().getText();
428
	}
411
    /**
412
     * Gets the query that will be send to the server
413
     * @return SQL query (just the where part)
414
     */
415
    public String getQuery(){
416
        String writtenQuery = txtExpression.getText().trim();
429 417

  
430
	/**
431
	 * Writes the filter expression into the user interface
432
	 * @param filterExpression An string
433
	 */
434
	public void setFilterExpressionIntoInterface(String filterExpression){
435
		getTxtExpression().setText(filterExpression);
436
	}
418
        // Validate expression
419
        if (!this.validateExpression(writtenQuery)) {
420
            getTxtExpression().setForeground(Color.red);
421
            return null;
422
        }
423
        else {
424
            logger.debug("Codified WFS filter query: " + writtenQuery);
437 425

  
438
	/**
439
	 * Removes text in the JTextArea that has the filter subconsultation
440
	 */
441
	public void removeFilterExpression() {
442
		getTxtExpression().setText("");
443
	}
426
            // Codify expression (only if the validation has been successful)
427
            return this.codifyExpression(writtenQuery); // Ignores the spaces at beginning and end of the chain of characters
428
        }
429
    }
444 430

  
445
	/**
446
	 * Codifies the expression to ISO ISO-8859_1 and a format that the SQL parser could validate
447
	 *
448
	 * @param expression The expression to be codified
449
	 *
450
	 * @return The expression codified
451
	 */
452
	private String codifyExpression(String expression) {
453
		String result = new String("");
431
    /**
432
     * Gets the filter expression from the user interface
433
     */
434
    public String getFilterExpressionFromInterface() {
435
        return getTxtExpression().getText();
436
    }
454 437

  
455
		// Encode each string of the query
456
		int index = 0;
457
		int lastIndex = 0;
458
		boolean endInnerLoop;
438
    /**
439
     * Writes the filter expression into the user interface
440
     * @param filterExpression An string
441
     */
442
    public void setFilterExpressionIntoInterface(String filterExpression){
443
        getTxtExpression().setText(filterExpression);
444
    }
459 445

  
460
		// Encodes all inner strings to the equivalent codification in ISO-8859_1 with each ' symbol converted to ''
461
		while (index != -1) {
462
			index = expression.indexOf("'", index);
446
    /**
447
     * Removes text in the JTextArea that has the filter subconsultation
448
     */
449
    public void removeFilterExpression() {
450
        getTxtExpression().setText("");
451
    }
463 452

  
464
			// Add the parts of the chain of characters that not are string
465
			if (index == -1) {
466
				result += expression.substring(lastIndex, expression.length());
467
			}
468
			else {
469
				result += expression.substring(lastIndex, index).replaceAll(" [ ]+", " ");
470
			}
453
    /**
454
     * Codifies the expression to ISO ISO-8859_1 and a format that the SQL parser could validate
455
     *
456
     * @param expression The expression to be codified
457
     *
458
     * @return The expression codified
459
     */
460
    private String codifyExpression(String expression) {
461
        String result = new String("");
471 462

  
472
			lastIndex = index;
473
			endInnerLoop = false;
463
        // Encode each string of the query
464
        int index = 0;
465
        int lastIndex = 0;
466
        boolean endInnerLoop;
474 467

  
475
			// Tries to find each first apostrophe of each string of the query
476
			if ((index > 0) && (expression.charAt(index - 1) == ' ')) {
477
				index++;
468
        // Encodes all inner strings to the equivalent codification in ISO-8859_1 with each ' symbol converted to ''
469
        while (index != -1) {
470
            index = expression.indexOf("'", index);
478 471

  
479
				// Ignore all inner apostrophes and try to find the last of the string
480
				while (!endInnerLoop)  {
481
					index = expression.indexOf("'", index);
482
					index++;
472
            // Add the parts of the chain of characters that not are string
473
            if (index == -1) {
474
                result += expression.substring(lastIndex, expression.length());
475
            }
476
            else {
477
                result += expression.substring(lastIndex, index).replaceAll(" [ ]+", " ");
478
            }
483 479

  
484
					// If we haven't arrived to the finish of the string
485
					if (index != expression.length()) {
486
						if ((index == -1) || (expression.charAt(index) == ' ')) {
487
							result += translateString(expression.substring(lastIndex, index));
488
							endInnerLoop = true;
489
						}
490
					}
491
					else {
492
						result += translateString(expression.substring(lastIndex, index));
493
						endInnerLoop = true;
494
						index = -1; // Force to finish the external loop
495
					}
496
				}
497
				lastIndex = index;
498
			}
499
		}
480
            lastIndex = index;
481
            endInnerLoop = false;
500 482

  
501
		return result;
502
	}
483
            // Tries to find each first apostrophe of each string of the query
484
            if ((index > 0) && (expression.charAt(index - 1) == ' ')) {
485
                index++;
503 486

  
504
	/**
505
	 * Checks the filter expression if it's correct
506
	 *
507
	 * @param query The query expression to analyze
508
	 * @return True if it's valid or false if not
509
	 */
510
	private boolean validateExpression(String query) {
511
		try {
512
			// If it's needed to validate the query
513
			if (getValidateFilterExpressionJCheckBox().isSelected()) {
514
				// If it's an empty query -> ok
515
				if (query.trim().length() == 0)
516
					return true;
517
	
518
				// Replace all Date(dd-mmm-yyyy) format to ddd-mmm-yyyy (characters will replaced to spaces)
519
				int index = 0;
520
				String query_copy = new String(query);
521
				while ((index = query_copy.indexOf("Date(", index)) != -1) {
522
					if (index > 0) {
523
						if ((query_copy.charAt(index-1) != ' ') && (query_copy.charAt(index-1) != '('))
524
							break;
525
					}
526
	
527
					if (((index + 16) < query_copy.length()) && (query_copy.charAt(index + 16) == ')')) { // +17 is the length of Date(dd-mmm-yyyy)
528
						if ((index + 17) < query_copy.length()) {
529
							query_copy = query_copy.substring(0, index) + "     " + query_copy.substring(index+6, index+16) + " " + query_copy.substring(index+17);
530
						}
531
						else {
532
							query_copy = query_copy.substring(0, index) + "     " + query_copy.substring(index+6, index+16);
533
						}
534
					}
535
				}
536
	
537
				SQLQueryValidation sQLQueryValidation = new SQLQueryValidation(formatSQLQuery(query_copy), true);
538
	
539
				// Tries to validate the query, and if fails shows a message
540
				if (!sQLQueryValidation.validateQuery()) {
541
					JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "finded") + " " + sQLQueryValidation.getTokenThatProducedTheSyntacticError() + " " + PluginServices.getText(null, "in")  + " " + sQLQueryValidation.getErrorPositionAsMessage() + ".", PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
542
					return false;
543
				}
544
				else {
545
					// Analyzes tokens in query
546
					StringTokenizer tokens = new StringTokenizer(query, " ");
547
					String token, token_aux;
548
					boolean finish = false;
549
	
550
					// If there is a field or a value with spaces, (and then it's on differents tokens) -> unify them
551
					while (tokens.hasMoreTokens()) {
552
						token = tokens.nextToken().trim();
553
	
554
						if (token.charAt(0) == '\'') {
555
							if (token.charAt(token.length() -1) != '\'') {
556
								while (!finish) {
557
									if (!tokens.hasMoreTokens()) {
558
										JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "the_token") + " " + token + " " + PluginServices.getText(null, "has_bad_format"), PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
559
										return false;
560
									}
561
									else {
562
										token_aux = tokens.nextToken().trim();
563
										token += " " + token_aux;
564
	
565
										if (token_aux.charAt(token_aux.length() -1) == '\'')
566
											finish = true;
567
									}
568
								}
569
	
570
								finish = false;
571
							}
572
						}
573
	
574
						if (token.charAt(0) == '\"') {
575
							if (token.charAt(token.length() -1) != '\"') {
576
								while (!finish) {
577
									if (!tokens.hasMoreTokens()) {
578
										JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "the_token") + " " + token + " " + PluginServices.getText(null, "has_bad_format"), PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
579
										return false;
580
									}
581
									else {
582
										token_aux = tokens.nextToken().trim();
583
										token += " " + token_aux;
584
	
585
										if (token_aux.charAt(token_aux.length() -1) == '\"')
586
											finish = true;
587
									}
588
								}
589
	
590
								finish = false;
591
							}
592
						}
593
	
594
						// Tries to find an invalid token
595
						if (token.length() > 0) {
596
							// Validates if a supposed field exists
597
							if ( (token.length() > 2) && (token.charAt(0) == '\"') && (token.charAt(token.length()-1) == '\"') ) {
598
								if (! this.isAField(token.substring(1, token.length()-1))) {
599
									JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "the_token") + " " + token + " " + PluginServices.getText(null, "isnt_a_field_of_layer"), PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
600
									return false;
601
								}
602
							}
603
							else {
604
								// If it's an string -> ignore
605
								if (! ((token.charAt(0) == token.charAt(token.length() - 1)) && (token.charAt(0) == '\''))) {
606
	
607
									// If it's a date -> ignore
608
									int returnValue = validateDate(token);
609
	
610
									if (returnValue == 1) {
611
										JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "incorrect_format_on_date") + " " + token.substring(5, 16) + " .", PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
612
										return false;
613
									}
614
	
615
									if (returnValue == 2) {
616
										// Else -> Checks if the current token is a valid number or symbol
617
										if ((! StringNumberUtilities.isRealNumberWithIntegerExponent(token)) && (! this.isAnOperatorNameOrSymbol(token, getAllOperatorSymbols()))) {
618
											JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "not_valid_token") + ": " + token, PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
619
											return false;
620
										}
621
									}
622
								}
623
							}
624
						}
625
					}
626
	
627
					// If has validate all tokens -> query validated
628
					return true;
629
				}
630
			}
631
			else
632
				return true; // No validation done because user selected that option
633
		}
634
		catch (Exception e) {
635
			NotificationManager.showMessageError(PluginServices.getText(null, "filter_with_an_incorrect_format") + ".", e);
636
			return true; // No validation done because user selected that option
637
		}
638
	}
487
                // Ignore all inner apostrophes and try to find the last of the string
488
                while (!endInnerLoop)  {
489
                    index = expression.indexOf("'", index);
490
                    index++;
639 491

  
640
	/**
641
	 * <p>Formats a query removing non English symbols that can produce the SQL validator could invalidate it.</p>
642
	 * 
643
	 * @param an SQL query
644
	 * @return the SQL query without non English symbols
645
	 */
646
	private String formatSQLQuery(String token) {
647
		return token = token.replace("?", "n").replace("?", "c").replace("?", "a").
648
		replace("?", "e").replace("?", "i").replace("?", "o").replace("?", "u").replace("?", "a").
649
		replace("?", "e").replace("?", "i").replace("?", "o").replace("?", "u").replace("?", "a").
650
		replace("?", "e").replace("?", "i").replace("?", "o").replace("?", "u").replace("?", "a").
651
		replace("?", "e").replace("?", "i").replace("?", "o").replace("?", "u");
652
	}
492
                    // If we haven't arrived to the finish of the string
493
                    if (index != expression.length()) {
494
                        if ((index == -1) || (expression.charAt(index) == ' ')) {
495
                            result += translateString(expression.substring(lastIndex, index));
496
                            endInnerLoop = true;
497
                        }
498
                    }
499
                    else {
500
                        result += translateString(expression.substring(lastIndex, index));
501
                        endInnerLoop = true;
502
                        index = -1; // Force to finish the external loop
503
                    }
504
                }
505
                lastIndex = index;
506
            }
507
        }
653 508

  
654
	/**
655
	 * Returns true if there is a field with the same name as 'text'
656
	 *
657
	 * @param text An string
658
	 * @return A boolean value
659
	 */
660
	private boolean isAField(String text) {
661
		return this.allFieldsAndValuesKnownOfCurrentLayer.containsKey(text);
662
	}
509
        return result;
510
    }
663 511

  
664
	/**
665
	 * Validates if a text has a correct date format as Date(dd-mmm-yyyy)  (Ex. Date(03-feb-2004) )
666
	 *
667
	 * @param text date to validate
668
	 * @return 0 -> if has a date format; 1 -> if it's a date that has a but format; 2 -> if it isn't a date
669
	 */
670
	private int validateDate(String text) {
671
		// If it's a date -> check if format is correct (Ex.  Date(01-feb-2004) )
672
		if ( ((text.length() == 17) && (text.startsWith("Date(")) && (text.endsWith(")"))) && (text.charAt(7) == '-') && (text.charAt(11) == '-') ) {
673
			if ( (StringNumberUtilities.isNaturalNumber(text.substring(5, 7))) && (StringNumberUtilities.isNaturalNumber(text.substring(12, 16))) ) {
674
				try {
675
					// If can parse the date -> date with a correct format
676
					DateFormat.getDateInstance().parse(text.substring(5, 16));
677
					return 0;
678
				} catch (ParseException e) {
679
					// If can't parse the date -> date with an incorrect format
680
					NotificationManager.addError(e);
681
					return 1;
682
				}
683
			}
684
			else {
685
				return 1;
686
			}
687
		}
512
    /**
513
     * Checks the filter expression if it's correct
514
     *
515
     * @param query The query expression to analyze
516
     * @return True if it's valid or false if not
517
     */
518
    private boolean validateExpression(String query) {
519
        try {
520
            // If it's needed to validate the query
521
            if (getValidateFilterExpressionJCheckBox().isSelected()) {
522
                // If it's an empty query -> ok
523
                if (query.trim().length() == 0)
524
                    return true;
688 525

  
689
		return 2;
690
	}
526
                // Replace all Date(dd-mmm-yyyy) format to ddd-mmm-yyyy (characters will replaced to spaces)
527
                int index = 0;
528
                String query_copy = new String(query);
529
                while ((index = query_copy.indexOf("Date(", index)) != -1) {
530
                    if (index > 0) {
531
                        if ((query_copy.charAt(index-1) != ' ') && (query_copy.charAt(index-1) != '('))
532
                            break;
533
                    }
691 534

  
692
	/**
693
	 * Returns true if there is the 'text' is a symbol or a operator name
694
	 *
695
	 * @param text An string
696
	 * @return A boolean value
697
	 */
698
	private boolean isAnOperatorNameOrSymbol(String text, Set<String> operatorNamesAndSymbols) {
699
		return operatorNamesAndSymbols.contains(text);
700
	}
535
                    if (((index + 16) < query_copy.length()) && (query_copy.charAt(index + 16) == ')')) { // +17 is the length of Date(dd-mmm-yyyy)
536
                        if ((index + 17) < query_copy.length()) {
537
                            query_copy = query_copy.substring(0, index) + "     " + query_copy.substring(index+6, index+16) + " " + query_copy.substring(index+17);
538
                        }
539
                        else {
540
                            query_copy = query_copy.substring(0, index) + "     " + query_copy.substring(index+6, index+16);
541
                        }
542
                    }
543
                }
701 544

  
702
	///// END METHODS FOR THE FILTER QUERY /////
545
                SQLQueryValidation sQLQueryValidation = new SQLQueryValidation(formatSQLQuery(query_copy), true);
703 546

  
704
	///// METHODS FOR TRANSLATE DATA IN FILTER SENTENCES /////
547
                // Tries to validate the query, and if fails shows a message
548
                if (!sQLQueryValidation.validateQuery()) {
549
                    JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "finded") + " " + sQLQueryValidation.getTokenThatProducedTheSyntacticError() + " " + PluginServices.getText(null, "in")  + " " + sQLQueryValidation.getErrorPositionAsMessage() + ".", PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
550
                    return false;
551
                }
552
                else {
553
                    // Analyzes tokens in query
554
                    StringTokenizer tokens = new StringTokenizer(query, " ");
555
                    String token, token_aux;
556
                    boolean finish = false;
705 557

  
706
	/**
707
	 * Encodes an string to ISO 8859_1 with each ' symbol converted to ''
708
	 *
709
	 * @param text An string started and finished with simple apostrophes
710
	 *
711
	 * @return An string started and finished with simple apostrophes
712
	 */
713
	private String translateString(String text) {
714
		// Encode to the string to ISO 8859_1 (the URL codification)
715
		try {
558
                    // If there is a field or a value with spaces, (and then it's on differents tokens) -> unify them
559
                    while (tokens.hasMoreTokens()) {
560
                        token = tokens.nextToken().trim();
716 561

  
717
			// Ignore the first and last apostrophes
718
			if (text.length() > 2) {
719
				text = text.substring(1, text.length() -1);
562
                        if (token.charAt(0) == '\'') {
563
                            if (token.charAt(token.length() -1) != '\'') {
564
                                while (!finish) {
565
                                    if (!tokens.hasMoreTokens()) {
566
                                        JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "the_token") + " " + token + " " + PluginServices.getText(null, "has_bad_format"), PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
567
                                        return false;
568
                                    }
569
                                    else {
570
                                        token_aux = tokens.nextToken().trim();
571
                                        token += " " + token_aux;
720 572

  
721
				// Convert the string to ISO 8859_1 codification
722
				text = URLEncoder.encode(text, "8859_1");
573
                                        if (token_aux.charAt(token_aux.length() -1) == '\'')
574
                                            finish = true;
575
                                    }
576
                                }
723 577

  
724
				// Change ' (%27 code) to '' for the SQL parser (before send the query)
725
				text = text.replaceAll("\\%27", "\\'\\'");
726
			}
578
                                finish = false;
579
                            }
580
                        }
727 581

  
728
		} catch (UnsupportedEncodingException e1) {
729
			NotificationManager.addError(e1);
730
		}
582
                        if (token.charAt(0) == '\"') {
583
                            if (token.charAt(token.length() -1) != '\"') {
584
                                while (!finish) {
585
                                    if (!tokens.hasMoreTokens()) {
586
                                        JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "the_token") + " " + token + " " + PluginServices.getText(null, "has_bad_format"), PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
587
                                        return false;
588
                                    }
589
                                    else {
590
                                        token_aux = tokens.nextToken().trim();
591
                                        token += " " + token_aux;
731 592

  
732
		return "'" + text + "'";
733
	}
593
                                        if (token_aux.charAt(token_aux.length() -1) == '\"')
594
                                            finish = true;
595
                                    }
596
                                }
734 597

  
735
	///// END METHODS FOR TRANSLATE DATA IN FILTER SENTENCES /////
598
                                finish = false;
599
                            }
600
                        }
736 601

  
737
	///// METHODS FOR MANIPULATE 'fields' and 'values' /////
602
                        // Tries to find an invalid token
603
                        if (token.length() > 0) {
604
                            // Validates if a supposed field exists
605
                            if ( (token.length() > 2) && (token.charAt(0) == '\"') && (token.charAt(token.length()-1) == '\"') ) {
606
                                if (! this.isAField(token.substring(1, token.length()-1))) {
607
                                    JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "the_token") + " " + token + " " + PluginServices.getText(null, "isnt_a_field_of_layer"), PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
608
                                    return false;
609
                                }
610
                            }
611
                            else {
612
                                // If it's an string -> ignore
613
                                if (! ((token.charAt(0) == token.charAt(token.length() - 1)) && (token.charAt(0) == '\''))) {
738 614

  
739
	/**
740
	 * Sets the model with the fields and values of the feature selected.
741
	 *
742
	 * @param eds data source with the model of the feature selected
743
	 */
744
	public void setModel(ExpressionDataSource eds) {
745
//		try {
746
			model = eds;
747
//            model.start();
748
//        } catch (ReadDriverException e1) {
749
//        	NotificationManager.addError(e1);
750
//        }
615
                                    // If it's a date -> ignore
616
                                    int returnValue = validateDate(token);
751 617

  
618
                                    if (returnValue == 1) {
619
                                        JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "incorrect_format_on_date") + " " + token.substring(5, 16) + " .", PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
620
                                        return false;
621
                                    }
622

  
623
                                    if (returnValue == 2) {
624
                                        // Else -> Checks if the current token is a valid number or symbol
625
                                        if ((! StringNumberUtilities.isRealNumberWithIntegerExponent(token)) && (! this.isAnOperatorNameOrSymbol(token, getAllOperatorSymbols()))) {
626
                                            JOptionPane.showMessageDialog(null, PluginServices.getText(null, "filter_with_an_incorrect_format") + ": " + PluginServices.getText(null, "not_valid_token") + ": " + token, PluginServices.getText(null, "error_validating_filter_query"), JOptionPane.ERROR_MESSAGE);
627
                                            return false;
628
                                        }
629
                                    }
630
                                }
631
                            }
632
                        }
633
                    }
634

  
635
                    // If has validate all tokens -> query validated
636
                    return true;
637
                }
638
            }
639
            else
640
                return true; // No validation done because user selected that option
641
        }
642
        catch (Exception e) {
643
            NotificationManager.showMessageError(PluginServices.getText(null, "filter_with_an_incorrect_format") + ".", e);
644
            return true; // No validation done because user selected that option
645
        }
646
    }
647

  
648
    /**
649
     * <p>Formats a query removing non English symbols that can produce the SQL validator could invalidate it.</p>
650
     * 
651
     * @param an SQL query
652
     * @return the SQL query without non English symbols
653
     */
654
    private String formatSQLQuery(String token) {
655
        return token = token.replace("?", "n").replace("?", "c").replace("?", "a").
656
        replace("?", "e").replace("?", "i").replace("?", "o").replace("?", "u").replace("?", "a").
657
        replace("?", "e").replace("?", "i").replace("?", "o").replace("?", "u").replace("?", "a").
658
        replace("?", "e").replace("?", "i").replace("?", "o").replace("?", "u").replace("?", "a").
659
        replace("?", "e").replace("?", "i").replace("?", "o").replace("?", "u");
660
    }
661

  
662
    /**
663
     * Returns true if there is a field with the same name as 'text'
664
     *
665
     * @param text An string
666
     * @return A boolean value
667
     */
668
    private boolean isAField(String text) {
669
        return this.allFieldsAndValuesKnownOfCurrentLayer.containsKey(text);
670
    }
671

  
672
    /**
673
     * Validates if a text has a correct date format as Date(dd-mmm-yyyy)  (Ex. Date(03-feb-2004) )
674
     *
675
     * @param text date to validate
676
     * @return 0 -> if has a date format; 1 -> if it's a date that has a but format; 2 -> if it isn't a date
677
     */
678
    private int validateDate(String text) {
679
        // If it's a date -> check if format is correct (Ex.  Date(01-feb-2004) )
680
        if ( ((text.length() == 17) && (text.startsWith("Date(")) && (text.endsWith(")"))) && (text.charAt(7) == '-') && (text.charAt(11) == '-') ) {
681
            if ( (StringNumberUtilities.isNaturalNumber(text.substring(5, 7))) && (StringNumberUtilities.isNaturalNumber(text.substring(12, 16))) ) {
682
                try {
683
                    // If can parse the date -> date with a correct format
684
                    DateFormat.getDateInstance().parse(text.substring(5, 16));
685
                    return 0;
686
                } catch (ParseException e) {
687
                    // If can't parse the date -> date with an incorrect format
688
                    NotificationManager.addError(e);
689
                    return 1;
690
                }
691
            }
692
            else {
693
                return 1;
694
            }
695
        }
696

  
697
        return 2;
698
    }
699

  
700
    /**
701
     * Returns true if there is the 'text' is a symbol or a operator name
702
     *
703
     * @param text An string
704
     * @return A boolean value
705
     */
706
    private boolean isAnOperatorNameOrSymbol(String text, Set<String> operatorNamesAndSymbols) {
707
        return operatorNamesAndSymbols.contains(text);
708
    }
709

  
710
    ///// END METHODS FOR THE FILTER QUERY /////
711

  
712
    ///// METHODS FOR TRANSLATE DATA IN FILTER SENTENCES /////
713

  
714
    /**
715
     * Encodes an string to ISO 8859_1 with each ' symbol converted to ''
716
     *
717
     * @param text An string started and finished with simple apostrophes
718
     *
719
     * @return An string started and finished with simple apostrophes
720
     */
721
    private String translateString(String text) {
722
        // Encode to the string to ISO 8859_1 (the URL codification)
752 723
        try {
753
        	int numberOfFields = model.getFieldCount();
754 724

  
755
        	if (numberOfFields > 0) {
756
        		Vector<Object> fields = new Vector<Object>(0, 1);
757
        		int j = 0;
725
            // Ignore the first and last apostrophes
726
            if (text.length() > 2) {
727
                text = text.substring(1, text.length() -1);
758 728

  
759
				for (int i = 0; i < numberOfFields; i++) {
760
					 Object field = model.getFieldName(i);
729
                // Convert the string to ISO 8859_1 codification
730
                text = URLEncoder.encode(text, "8859_1");
761 731

  
762
					if (field != null) {
763
						fields.add(field);
732
                // Change ' (%27 code) to '' for the SQL parser (before send the query)
733
                text = text.replaceAll("\\%27", "\\'\\'");
734
            }
764 735

  
765
						String completeFieldPath = this.getPathOfLeafWithoutRoot(field);
736
        } catch (UnsupportedEncodingException e1) {
737
            NotificationManager.addError(e1);
738
        }
766 739

  
767
						if (! allFieldsAndValuesKnownOfCurrentLayer.containsKey(completeFieldPath) ) {
768
							allFieldsAndValuesKnownOfCurrentLayer.put(completeFieldPath, new HashMap<String, String>());
769
						}
740
        return "'" + text + "'";
741
    }
770 742

  
771
						j++;
772
					}
773
				}
743
    ///// END METHODS FOR TRANSLATE DATA IN FILTER SENTENCES /////
774 744

  
775
				fieldsTreeTableModel = new FieldsTreeTableModel(fields.toArray());
776
        	}
777
		} catch (FilterException e) {
778
			NotificationManager.addError(e);
779
		}
780
	}
745
    ///// METHODS FOR MANIPULATE 'fields' and 'values' /////
781 746

  
782
	/**
783
	 * If there is a field selected, show its new values
784
	 */
785
	public void updateFieldValues() {
786
//		if (currentPath != null) {
787
//			DefaultExpression data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
788
//
789
//			if (data != null) {
790
//				setModel(data);
791
//				fillValuesByPath(currentPath);
792
//
793
//				// Updates all tables that their data is about the changed view
794
//				this.updateTablesThatHasNewData();
795
//
796
//				// Adjust JScrollPanes to the the beginning
797
//				getFieldsJScrollPane().getHorizontalScrollBar().setValue(-1);
798
//				getFieldsJScrollPane().getVerticalScrollBar().setValue(-1);
799
//
800
//				// Adjust JScrollPanes to the the beginning
801
//				getValuesJScrollPane().getHorizontalScrollBar().setValue(-1);
802
//				getValuesJScrollPane().getVerticalScrollBar().setValue(-1);
803
//
804
//				// Adjusts valuesJList to the default position
805
//				getValuesJList().setSelectedIndex(-1); // No item selected
806
//			}
807
//		}
808
	}
747
    /**
748
     * Sets the model with the fields and values of the feature selected.
749
     *
750
     * @param eds data source with the model of the feature selected
751
     */
752
    public void setModel(ExpressionDataSource eds) {
753
        //		try {
754
        model = eds;
755
        //            model.start();
756
        //        } catch (ReadDriverException e1) {
757
        //        	NotificationManager.addError(e1);
758
        //        }
809 759

  
810
	/**
811
	 * Adds the fields of the feature.
812
	 *
813
	 * @param feature A Layer node with fields information
814
	 */
815
	private boolean setFields(WFSSelectedFeature feature) {
816
		Vector<Object> fields = feature.getFields();
760
        try {
761
            int numberOfFields = model.getFieldCount();
817 762

  
818
		this.resetFieldsAndValuesData();
763
            if (numberOfFields > 0) {
764
                Vector<Object> fields = new Vector<Object>(0, 1);
765
                int j = 0;
819 766

  
820
		int numberOfFields = fields.size();
767
                for (int i = 0; i < numberOfFields; i++) {
768
                    Object field = model.getFieldName(i);
821 769

  
822
		if (numberOfFields > 0) {
823
			Vector<XMLElement> fieldBranches = new Vector<XMLElement>(0, 1);
770
                    if (field != null) {
771
                        fields.add(field);
824 772

  
825
			for (Object o_field : fields) {
826
				XMLElement field = (XMLElement) o_field;
773
                        String completeFieldPath = this.getPathOfLeafWithoutRoot(field);
827 774

  
828
				IXMLType type = field.getEntityType();
775
                        if (! allFieldsAndValuesKnownOfCurrentLayer.containsKey(completeFieldPath) ) {
776
                            allFieldsAndValuesKnownOfCurrentLayer.put(completeFieldPath, new HashMap<String, String>());
777
                        }
829 778

  
830
				if (type != null) {
779
                        j++;
780
                    }
781
                }
831 782

  
832
					switch (type.getType()) {
833
						case IXMLType.GML_GEOMETRY: // Don't add branch / field
834
							break;
835
						case IXMLType.COMPLEX: case IXMLType.SIMPLE: // Add branch / field
836
							fieldBranches.add(field);
837
							break;
838
					}
839
				}
840
			}
783
                fieldsTreeTableModel = new FieldsTreeTableModel(fields.toArray());
784
            }
785
        } catch (FilterException e) {
786
            NotificationManager.addError(e);
787
        }
788
    }
841 789

  
842
			if (fieldBranches.size() > 0) {
843
				Object obj = fieldBranches.get(0);
790
    /**
791
     * If there is a field selected, show its new values
792
     */
793
    public void updateFieldValues() {
794
        //		if (currentPath != null) {
795
        //			DefaultExpression data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
796
        //
797
        //			if (data != null) {
798
        //				setModel(data);
799
        //				fillValuesByPath(currentPath);
800
        //
801
        //				// Updates all tables that their data is about the changed view
802
        //				this.updateTablesThatHasNewData();
803
        //
804
        //				// Adjust JScrollPanes to the the beginning
805
        //				getFieldsJScrollPane().getHorizontalScrollBar().setValue(-1);
806
        //				getFieldsJScrollPane().getVerticalScrollBar().setValue(-1);
807
        //
808
        //				// Adjust JScrollPanes to the the beginning
809
        //				getValuesJScrollPane().getHorizontalScrollBar().setValue(-1);
810
        //				getValuesJScrollPane().getVerticalScrollBar().setValue(-1);
811
        //
812
        //				// Adjusts valuesJList to the default position
813
        //				getValuesJList().setSelectedIndex(-1); // No item selected
814
        //			}
815
        //		}
816
    }
844 817

  
845
				fieldsTreeTableModel = new FieldsTreeTableModel(obj);
846
				fieldsJTree.setModel(new FieldsTreeTableModel(obj, false));
818
    /**
819
     * Adds the fields of the feature.
820
     *
821
     * @param feature A Layer node with fields information
822
     */
823
    private boolean setFields(WFSSelectedFeature feature) {		
847 824

  
848
				// Stores the name of all leafs (fields) of treeTableModel
849
				Object root = fieldsTreeTableModel.getRoot();
825
        this.resetFieldsAndValuesData();
850 826

  
851
				if (root != null) {
852
					Vector<Object> fieldsNames = fieldsTreeTableModel.getLeafsFromNodeBranch(root);
827
        int numberOfFields = feature.getWFSFeature().getFieldSize();
853 828

  
854
					for (Object field : fieldsNames) {
855
						// Avoid errors
856
						if ( (! (field instanceof XMLElement)) || (field == null) )	continue;
829
        if (numberOfFields > 0) {           
830
            Vector<WFSFeatureField> fieldBranches = new Vector<WFSFeatureField>(0, 1);
857 831

  
858
						// Don't load a geometry field
859
						if (((XMLElement)field).getEntityType() != null){
860
							if ( ((XMLElement)field).getEntityType().getType() == IXMLType.GML_GEOMETRY ){
861
								continue;
862
							}
863
						}
832
            for (int i=0 ; i<numberOfFields ; i++) {		
833
                WFSFeatureField featureField = feature.getWFSFeature().getFieldAt(i);
834
                if (!featureField.isGeometry()) {
835
                    fieldBranches.add(featureField);						
836
                }
837
            }
864 838

  
865
						String completeFieldPath = this.getPathOfLeafWithoutRoot(field);
866 839

  
867
						if (! allFieldsAndValuesKnownOfCurrentLayer.containsKey(completeFieldPath) ) {
868
							allFieldsAndValuesKnownOfCurrentLayer.put(completeFieldPath, new HashMap<String, String>());
869
						}
870
					}
871
				}
872
			}
873
		}
840
            if (fieldBranches.size() > 0) {
841
                Object obj = fieldBranches.get(0);
874 842

  
875
		return true;
876
	}
843
                fieldsTreeTableModel = new FieldsTreeTableModel(feature.getWFSFeature(), false);
844
                fieldsJTree.setModel(new FieldsTreeTableModel(feature.getWFSFeature(), false));
877 845

  
878
	/**
879
	 * This method load all values known of all fields known.
880
	 * (It's used when a new layer is loaded).
881
	 */
882
	private void setValuesKnownOfFields() {
883
		// Desde el modelo se deber?a acceder a los campos y sus valores cargados
884
//		try {
885
//			for (int i = 0; i < model.getFieldCount(); i++) {
886
//				String fieldName = model.getFieldName(i);
887
//				HashMap<String, String> fieldValues = (HashMap<String, String>) allFieldsAndValuesKnownOfCurrentLayer.get(fieldName);
888
//
889
//				if (fieldValues != null) {
890
//					for (int j = 0; j < model.getRowCount(); j++) {
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff