Statistics
| Revision:

root / trunk / extensions / extWFS2 / src / com / iver / cit / gvsig / gui / panels / WFSFilterPanel.java @ 11131

History | View | Annotate | Download (47.1 KB)

1
package com.iver.cit.gvsig.gui.panels;
2

    
3
import java.awt.Color;
4
import java.awt.event.MouseAdapter;
5
import java.awt.event.MouseEvent;
6
import java.io.UnsupportedEncodingException;
7
import java.net.URLEncoder;
8
import java.text.DateFormat;
9
import java.text.NumberFormat;
10
import java.text.ParseException;
11
import java.util.ArrayList;
12
import java.util.Comparator;
13
import java.util.HashMap;
14
import java.util.Iterator;
15
import java.util.Map;
16
import java.util.Set;
17
import java.util.StringTokenizer;
18
import java.util.TreeSet;
19
import java.util.Vector;
20
import java.util.regex.Matcher;
21
import java.util.regex.Pattern;
22

    
23
import javax.swing.DefaultListModel;
24
import javax.swing.JLabel;
25
import javax.swing.JOptionPane;
26
import javax.swing.event.DocumentEvent;
27
import javax.swing.event.DocumentListener;
28
import javax.swing.event.TreeSelectionEvent;
29
import javax.swing.event.TreeSelectionListener;
30
import javax.swing.tree.DefaultMutableTreeNode;
31
import javax.swing.tree.DefaultTreeModel;
32
import javax.swing.tree.TreePath;
33

    
34
import org.apache.log4j.Logger;
35
import org.gvsig.gui.beans.Messages;
36
import org.gvsig.gui.beans.filterPanel.filterQueryPanel.FilterQueryJPanel;
37
import org.gvsig.gui.beans.filterPanel.filterQueryPanel.jLabelAsCell.DefaultListModelForJLabelAsCell;
38
import org.gvsig.gui.beans.filterPanel.filterQueryPanel.jLabelAsCell.JLabelAsCellValueLoaded;
39
import org.gvsig.gui.beans.filterPanel.filterQueryPanel.jLabelAsCell.JLabelAsCellValueNotLoaded;
40
import org.gvsig.remoteClient.gml.schemas.XMLElement;
41
import org.gvsig.remoteClient.gml.types.IXMLType;
42

    
43
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
44
import com.hardcode.gdbms.engine.data.driver.DriverException;
45
import com.hardcode.gdbms.engine.instruction.IncompatibleTypesException;
46
import com.hardcode.gdbms.engine.values.BooleanValue;
47
import com.hardcode.gdbms.engine.values.ComplexValue;
48
import com.hardcode.gdbms.engine.values.NullValue;
49
import com.hardcode.gdbms.engine.values.Value;
50
import com.iver.andami.PluginServices;
51
import com.iver.andami.messages.NotificationManager;
52
import com.iver.andami.ui.mdiManager.IWindow;
53
import com.iver.cit.gvsig.ProjectExtension;
54
import com.iver.cit.gvsig.fmap.edition.EditableAdapter;
55
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
56
import com.iver.cit.gvsig.fmap.layers.FLayer;
57
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
58
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
59
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
60
import com.iver.cit.gvsig.fmap.layers.WFSLayerNode;
61
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
62
import com.iver.cit.gvsig.gui.filter.ExpressionDataSource;
63
import com.iver.cit.gvsig.gui.filter.ExpressionListener;
64
import com.iver.cit.gvsig.gui.filter.FilterException;
65
import com.iver.cit.gvsig.gui.panels.fieldsTree.FieldsTreeTableModel;
66
import com.iver.cit.gvsig.project.ProjectFactory;
67
import com.iver.cit.gvsig.project.documents.table.ProjectTable;
68
import com.iver.cit.gvsig.project.documents.table.ProjectTableFactory;
69
import com.iver.cit.gvsig.project.documents.table.gui.Table;
70
import com.iver.cit.gvsig.project.documents.view.gui.View;
71
import com.iver.cit.gvsig.sqlQueryValidation.SQLQueryValidation;
72
import com.iver.utiles.DefaultCharSet;
73
import com.iver.utiles.StringUtilities;
74
import com.iver.utiles.exceptionHandling.ExceptionHandlingSupport;
75
import com.iver.utiles.exceptionHandling.ExceptionListener;
76
import com.iver.utiles.stringNumberUtilities.StringNumberUtilities;
77

    
78

    
79
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
80
 *
81
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
82
 *
83
 * This program is free software; you can redistribute it and/or
84
 * modify it under the terms of the GNU General Public License
85
 * as published by the Free Software Foundation; either version 2
86
 * of the License, or (at your option) any later version.
87
 *
88
 * This program is distributed in the hope that it will be useful,
89
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
90
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
91
 * GNU General Public License for more details.
92
 *
93
 * You should have received a copy of the GNU General Public License
94
 * along with this program; if not, write to the Free Software
95
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
96
 *
97
 * For more information, contact:
98
 *
99
 *  Generalitat Valenciana
100
 *   Conselleria d'Infraestructures i Transport
101
 *   Av. Blasco Ib??ez, 50
102
 *   46010 VALENCIA
103
 *   SPAIN
104
 *
105
 *      +34 963862235
106
 *   gvsig@gva.es
107
 *      www.gvsig.gva.es
108
 *
109
 *    or
110
 *
111
 *   IVER T.I. S.A
112
 *   Salamanca 50
113
 *   46005 Valencia
114
 *   Spain
115
 *
116
 *   +34 963163400
117
 *   dac@iver.es
118
 */
119

    
120
/**
121
 * This will be the tab for add a filter to a WFS query.
122
 * This class gets the graphical interface from FilterQueryJPanel and add logic.
123
 *
124
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
125
 */
126
public class WFSFilterPanel extends FilterQueryJPanel {
127
        private static Logger logger = Logger.getLogger(Table.class.getName());
128
        private WFSParamsPanel parent = null;
129
        private ArrayList expressionListeners = new ArrayList();
130
        private ExpressionDataSource model = null;
131
        private NumberFormat nf = NumberFormat.getNumberInstance();
132
        private ExceptionHandlingSupport exceptionHandlingSupport = new ExceptionHandlingSupport();
133
        private FieldsTreeTableModel fieldsTreeTableModel;
134
        private boolean panelAsATabForWFSLayersLoad;
135
        private TreePath currentPath;
136
        private String featureName;
137
        private Map allFieldsAndValuesKnownOfCurrentLayer; // This will have all values (not repeated) known of all fields (not repeated)
138

    
139
        ///// GUI METHODS ////
140

    
141
        /**
142
         * This method initializes
143
         *
144
         * @param parent A reference to the parent container component of this component
145
         */
146
        public WFSFilterPanel(WFSParamsPanel parent) {
147
                super();
148
                this.parent = parent;
149
                currentPath = null;
150
                featureName = null;
151
                allFieldsAndValuesKnownOfCurrentLayer = new HashMap(); // Initial capacity = 0
152

    
153
                // At beginning, the JList is disabled (and its set a particular color for user could knew it)
154
                super.getValuesJList().setEnabled(false);
155
                getValuesJList().setBackground(new Color(220, 220, 220));
156
        }
157

    
158
        /*
159
         *  (non-Javadoc)
160
         * @see org.gvsig.gui.beans.filterPanel.AbstractFilterQueryJPanel#initialize()
161
         */
162
        protected void initialize() {
163
                super.initialize();
164
                this.resizeHeight(380);
165

    
166
                defaultTreeModel = (DefaultTreeModel)fieldsJTree.getModel();
167

    
168
                this.addNewListeners();
169
                panelAsATabForWFSLayersLoad = true;
170
                getValidateFilterExpressionJCheckBox().setSelected(true);
171

    
172
                getValuesJLabel().setToolTipText(Messages.getText("values_of_the_selected_field_explanation"));
173
                getFieldsJLabel().setToolTipText(Messages.getText("fields_of_the_selected_feature_explanation"));
174
        }
175

    
176
        /**
177
         * Adds some more listener to the components of the panel
178
         */
179
        private void addNewListeners() {
180

    
181
                // Enable "Apply" button when user changes the filter query
182
                txtExpression.getDocument().addDocumentListener(new DocumentListener() {
183
                        /*
184
                         *  (non-Javadoc)
185
                         * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
186
                         */
187
                        public void changedUpdate(DocumentEvent e) {
188
                        }
189

    
190
                        /*
191
                         *  (non-Javadoc)
192
                         * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
193
                         */
194
                        public void insertUpdate(DocumentEvent e) {
195
                                if (!panelAsATabForWFSLayersLoad)
196
                                        parent.isApplicable(true);
197
                        }
198

    
199
                        /*
200
                         *  (non-Javadoc)
201
                         * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
202
                         */
203
                        public void removeUpdate(DocumentEvent e) {
204
                                if (!panelAsATabForWFSLayersLoad)
205
                                        parent.isApplicable(true);
206
                        }
207
                });
208

    
209
                // Listener for "fieldsJTree"
210
                getFieldsJTree().addMouseListener(new MouseAdapter() {
211
                        /*
212
                         *  (non-Javadoc)
213
                         * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
214
                         */
215
                        public void mouseClicked(MouseEvent e) {
216
                                int row = fieldsJTree.getRowForLocation(e.getX(), e.getY());
217
                                TreePath treePath = fieldsJTree.getPathForLocation(e.getX(), e.getY());
218

    
219
                                if (row > -1) {
220
                                        switch (e.getClickCount()) {
221
                                                case 2:
222
                                                        putSymbolOfSelectedByMouseBranch(treePath);
223
                                                        break;
224
                                        }
225
                                }
226
                        }
227
                });
228

    
229
                // Listener for "valuesJList"
230
                getValuesJList().addMouseListener(new MouseAdapter() {
231
                        /*
232
                         *  (non-Javadoc)
233
                         * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
234
                         */
235
                        public void mouseClicked(MouseEvent e) {
236
                                int index = getValuesJList().getSelectedIndex();
237

    
238
                                // Avoids exception when no value is in the list
239
                                if (index == -1)
240
                                        return;
241

    
242
                                if (e.getClickCount() == 2){
243
                                        String valor = ((JLabel) valuesListModel.getElementAt(index)).getText();
244

    
245
                                        // If value is an string -> set it between apostrophes
246
                                        if (getNodeOfCurrentPath().getEntityType().getName().compareTo("xs:string") == 0) {
247
                                                putSymbol("'" + valor + "'");
248
                                        }
249
                                        else {
250
                                                putSymbol(valor);
251
                                        }
252
                                }
253
                        }
254
                });
255

    
256
                // Listener for a branch of the tree selection
257
                getFieldsJTree().addTreeSelectionListener(new TreeSelectionListener() {
258
                        /*
259
                         *  (non-Javadoc)
260
                         * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent)
261
                         */
262
                        public void valueChanged(TreeSelectionEvent e) {
263
                                if (!panelAsATabForWFSLayersLoad) {
264
                                        DataReturnedOfDataLoadingFromActiveView data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
265

    
266
                                        if ((data != null) && (data.getData() != null)) {
267
//                                                setModel(data.getData());
268
                                                currentPath = e.getPath();
269
                                                fillValuesByPath(currentPath);
270
                                        }
271
                                }
272
                        }
273
                });
274

    
275
                // Listener: when a user writes something on the textarea -> set it's foreground color to black
276
                getTxtExpression().getDocument().addDocumentListener(new DocumentListener() {
277
                        /*
278
                         *  (non-Javadoc)
279
                         * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
280
                         */
281
                        public void changedUpdate(DocumentEvent e) {
282
                        }
283

    
284
                        /*
285
                         *  (non-Javadoc)
286
                         * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
287
                         */
288
                        public void insertUpdate(DocumentEvent e) {
289
                                getTxtExpression().setForeground(Color.BLACK);
290
                        }
291

    
292
                        /*
293
                         *  (non-Javadoc)
294
                         * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
295
                         */
296
                        public void removeUpdate(DocumentEvent e) {
297
                                getTxtExpression().setForeground(Color.BLACK);
298
                        }
299
                });
300

    
301
//                // Listener: if user wants or not that the filter expression would be validated
302
//                getValidateFilterExpressionJCheckBox().addItemListener(new ItemListener() {
303
//                        /*
304
//                         * (non-Javadoc)
305
//                         * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
306
//                         */
307
//                        public void itemStateChanged(ItemEvent e) {
308
//                                if (e.getStateChange() == ItemEvent.SELECTED)
309
//                                        System.out.println("Seleccionada");
310
//                                else {
311
//                                        if (e.getStateChange() == ItemEvent.DESELECTED)
312
//                                                System.out.println("Deseleccionada");
313
//                                }
314
//                        }
315
//                });
316
        }
317

    
318
        /**
319
         * Gets the element that the 'currentPath' field aims
320
         *
321
         * @return An XMLElement
322
         */
323
        private XMLElement getNodeOfCurrentPath() {
324

    
325
                if (currentPath != null) {
326
                        Object node = currentPath.getLastPathComponent();
327

    
328
                        if ((node != null) && (node instanceof XMLElement)) {
329
                                return (XMLElement) node;
330
                        }
331
                }
332

    
333
                return null;
334
        }
335

    
336
        /**
337
         * Puts the symbol of selected brach
338
         *
339
         * @param mouseEvent A MouseEvent with information  of the selected branch
340
         */
341
        public void putSymbolOfSelectedByMouseBranch(TreePath treePath) {
342
                // Sets the node selected
343
                if (treePath != null) {
344
                        putSymbol("\"" + this.getPathOfLeafWithoutRoot(treePath.getLastPathComponent()) + "\"");
345
                }
346
        }
347

    
348
        /**
349
         * This method returns the path of a node of a tree
350
         * Each node is separated from its parent with the symbol "/"
351
         *
352
         * @param node A node of a
353
         * @return An string with the path
354
         */
355
        private String getPathOfLeaf(Object node) {
356
                String path = "";
357

    
358
                if ((node != null) && (node instanceof XMLElement)) {
359
                        XMLElement element = (XMLElement) node;
360
                        XMLElement parent = element.getParentElement();
361
                        path = element.getName();
362

    
363
                        while (parent != null){
364
                                path = parent.getName() + "/" + path;
365
                                parent = parent.getParentElement();
366
                        }
367
                }
368

    
369
                return path;
370
        }
371

    
372
        /**
373
         * This method returns the path without the root, of a node of a tree
374
         * Each node is separated from its parent with the symbol "/"
375
         *
376
         * @param node A node of a
377
         * @return An string with the path
378
         */
379
        private String getPathOfLeafWithoutRoot(Object node) {
380
                String path = "";
381

    
382
                if ((node != null) && (node instanceof XMLElement)) {
383
                        XMLElement element = (XMLElement) node;
384
                        XMLElement parent = element.getParentElement();
385
                        path = element.getName();
386

    
387
                        while (parent.getParentElement() != null){
388
                                path = parent.getName() + "/" + path;
389
                                parent = parent.getParentElement();
390
                        }
391
                }
392

    
393
                return path;
394
        }
395

    
396
        /**
397
         * Gets the value of the inner attribute: 'panelAsATabForWFSLayersLoad'
398
         *
399
         * @return A boolean value
400
         */
401
        public boolean getWFSFilterPanelIsAsTabForWFSLayersLoad() {
402
                return this.panelAsATabForWFSLayersLoad;
403
        }
404

    
405
        /**
406
         * Sets the value of the inner attribute: 'panelAsATabForWFSLayersLoad'
407
         *
408
         * @param b A boolean value
409
         */
410
        public void setWFSFilterPanelIsAsTabForWFSLayersLoad (boolean b) {
411
                this.panelAsATabForWFSLayersLoad = b;
412

    
413
                if (this.panelAsATabForWFSLayersLoad == true) {
414
                        // At beginning, the JList is disabled (and its set a particular color for user could knew it)
415
                        super.getValuesJList().setEnabled(false);
416
                        super.getValuesJList().setBackground(new Color(220, 220, 220)); // a grey color
417

    
418
                        this.allFieldsAndValuesKnownOfCurrentLayer.clear();
419
                        getValidateFilterExpressionJCheckBox().setSelected(true);
420
                }
421
                else {
422
                        // Unselect the selected path in the tree (if there was any selected)
423
                        if (this.currentPath != null) {
424
                                this.currentPath = null;
425
                                this.getFieldsJTree().removeSelectionPath(this.getFieldsJTree().getSelectionPath());
426
                        }
427

    
428
                        // Resets data loaded
429
                        super.getValuesJList().setEnabled(true);
430
                        super.getValuesJList().setBackground(Color.WHITE);
431

    
432
                        this.getFieldsJTree().removeAll();
433
                        this.getValuesJList().removeAll();
434

    
435
                        // Updates data associated to view with the new layer data
436
                        this.setNewDataToTable();
437

    
438
                        // If theres is any table associated to the current view -> update that table/s
439
//                        this.updateTablesThatHasNewData();
440

    
441
                        // Reads that new data
442
                        DataReturnedOfDataLoadingFromActiveView data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
443

    
444
                        if ((data != null) && (data.getData() != null)) {
445
                                setModel(data.getData());
446
//                                currentPath = e.getPath();
447
//                                fillValuesByPath(currentPath);
448
                        }
449

    
450
                        // Loads values known of fields
451
                        this.setValuesKnownOfFields();
452
                }
453
        }
454

    
455
        /**
456
         * Refresh all information about fields
457
         *
458
         * @param feature
459
         */
460
        public boolean refresh(WFSLayerNode feature) {
461
                featureName = feature.getTitle();
462
                return setFields(feature);
463
        }
464

    
465
        ///// END GUI METHODS /////
466

    
467
        ///// METHODS FOR THE FILTER QUERY /////
468

    
469
        /**
470
         * Gets the query that will be send to the server
471
         * @return SQL query (just the where part)
472
         */
473
        public String getQuery(){
474
                String writtenQuery = txtExpression.getText().trim();
475

    
476
                // Validate expression
477
                if (!this.validateExpression(writtenQuery)) {
478
                        getTxtExpression().setForeground(Color.red);
479
                        return null;
480
                }
481
                else
482
                        // Codify expression (only if the validation has been successful)
483
                        return this.codifyExpression(writtenQuery); // Ignores the spaces at beginning and end of the chain of characters
484
        }
485

    
486
        /**
487
         * Gets the filter expression from the user interface
488
         */
489
        public String getFilterExpressionFromInterface() {
490
                return getTxtExpression().getText();
491
        }
492

    
493
        /**
494
         * Writes the filter expression into the user interface
495
         * @param filterExpression An string
496
         */
497
        public void setFilterExpressionIntoInterface(String filterExpression){
498
                getTxtExpression().setText(filterExpression);
499
        }
500

    
501
        /**
502
         * Removes text in the JTextArea that has the filter subconsultation
503
         */
504
        public void removeFilterExpression() {
505
                getTxtExpression().setText("");
506
        }
507

    
508
        /**
509
         * Codifies the expression to ISO ISO-8859_1 and a format that the SQL parser could validate
510
         *
511
         * @param expression The expression to be codified
512
         *
513
         * @return The expression codified
514
         */
515
        private String codifyExpression(String expression) {
516
                String result = new String("");
517

    
518
                // Encode each string of the query
519
                int index = 0;
520
                int lastIndex = 0;
521
                boolean endInnerLoop;
522
                // Encodes all inner strings to the equivalent codification in ISO-8859_1 with each ' symbol converted to ''
523
                while (index != -1) {
524
                        index = expression.indexOf("'", index);
525

    
526
                        // Add the parts of the chain of characters that not are string
527
                        if (index == -1) {
528
                                result += expression.substring(lastIndex, expression.length());
529
                        }
530
                        else {
531
                                result += expression.substring(lastIndex, index).replaceAll(" [ ]+", " ");
532
                        }
533

    
534
                        lastIndex = index;
535
                        endInnerLoop = false;
536

    
537
                        // Tries to find each first apostrophe of each string of the query
538
                        if ((index > 0) && (expression.charAt(index - 1) == ' ')) {
539
                                index++;
540

    
541
                                // Ignore all inner apostrophes and try to find the last of the string
542
                                while (!endInnerLoop)  {
543
                                        index = expression.indexOf("'", index);
544
                                        index++;
545

    
546
                                        // If we haven't arrived to the finish of the string
547
                                        if (index != expression.length()) {
548
                                                if ((index == -1) || (expression.charAt(index) == ' ')) {
549
                                                        result += translateString(expression.substring(lastIndex, index));
550
                                                        endInnerLoop = true;
551
                                                }
552
                                        }
553
                                        else {
554
                                                result += translateString(expression.substring(lastIndex, index));
555
                                                endInnerLoop = true;
556
                                                index = -1; // Force to finish the external loop
557
                                        }
558
                                }
559
                                lastIndex = index;
560
                        }
561
                }
562

    
563
                // Field names are transformated in xix variables that will be analyzed
564
                // Date(date) is substituted by the correct date format
565
                try {
566
                        result = translateDates(result);
567
                }
568
                catch(ParseException e) {
569
                        JOptionPane.showMessageDialog(this, PluginServices.getText(null, "error_codifying_dates"), PluginServices.getText(null, "error_coding_filter_query"), JOptionPane.ERROR_MESSAGE);
570
                        return null;
571
                }
572

    
573
                try {
574
                        result = translateNumber(result);
575
                }
576
                catch(ParseException e) {
577
                        JOptionPane.showMessageDialog(this, PluginServices.getText(null, "error_codifying_numbers"), PluginServices.getText(null, "error_coding_filter_query"), JOptionPane.ERROR_MESSAGE);
578
                        return null;
579
                }
580

    
581
                try {
582
                        result = translateWord(result, "true", "1");
583
                }
584
                catch(ParseException e) {
585
                        JOptionPane.showMessageDialog(this, PluginServices.getText(null, "error_codifying_words"), PluginServices.getText(null, "error_coding_filter_query"), JOptionPane.ERROR_MESSAGE);
586
                        return null;
587
                }
588

    
589
                try {
590
                        result = translateWord(result, "false", "0");
591
                }
592
                catch(ParseException e) {
593
                        JOptionPane.showMessageDialog(this, PluginServices.getText(null, "error_codifying_words"), PluginServices.getText(null, "error_coding_filter_query"), JOptionPane.ERROR_MESSAGE);
594
                        return null;
595
                }
596

    
597
                logger.debug(result);
598

    
599
                return result;
600
        }
601

    
602
        /**
603
         * Checks the filter expression if it's correct
604
         *
605
         * @param query The query expression to analyze
606
         * @return True if it's valid or false if not
607
         */
608
        private boolean validateExpression(String query) {
609
                // If it's needed to validate the query
610
                if (getValidateFilterExpressionJCheckBox().isSelected()) {
611
                        // If it's an empty query -> ok
612
                        if (query.trim().length() == 0)
613
                                return true;
614

    
615
                        // Replace all Date(dd-mmm-yyyy) format to ddd-mmm-yyyy (characters will replaced to spaces)
616
                        int index = 0;
617
                        String query_copy = new String(query);
618
                        while ((index = query_copy.indexOf("Date(", index)) != -1) {
619
                                if (index > 0) {
620
                                        if ((query_copy.charAt(index-1) != ' ') && (query_copy.charAt(index-1) != '('))
621
                                                break;
622
                                }
623

    
624
                                if (((index + 16) < query_copy.length()) && (query_copy.charAt(index + 16) == ')')) { // +17 is the length of Date(dd-mmm-yyyy)
625
                                        if ((index + 17) < query_copy.length()) {
626
                                                query_copy = query_copy.substring(0, index) + "     " + query_copy.substring(index+6, index+16) + " " + query_copy.substring(index+17);
627
                                        }
628
                                        else {
629
                                                query_copy = query_copy.substring(0, index) + "     " + query_copy.substring(index+6, index+16);
630
                                        }
631
                                }
632
                        }
633

    
634
                        SQLQueryValidation sQLQueryValidation = new SQLQueryValidation(query_copy, true);
635

    
636
                        // Tries to validate the query, and if fails shows a message
637
                        if (!sQLQueryValidation.validateQuery()) {
638
                                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);
639
                                return false;
640
                        }
641
                        else {
642
                                // Analyzes tokens in query
643
                                StringTokenizer tokens = new StringTokenizer(query, " ");
644
                                String token, token_aux;
645
                                boolean finish = false;
646

    
647
                                // If there is a field or a value with spaces, (and then it's on differents tokens) -> unify them
648
                                while (tokens.hasMoreTokens()) {
649
                                        token = tokens.nextToken().trim();
650

    
651
                                        if (token.charAt(0) == '\'') {
652
                                                if (token.charAt(token.length() -1) != '\'') {
653
                                                        while (!finish) {
654
                                                                if (!tokens.hasMoreTokens()) {
655
                                                                        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);
656
                                                                        return false;
657
                                                                }
658
                                                                else {
659
                                                                        token_aux = tokens.nextToken().trim();
660
                                                                        token += " " + token_aux;
661

    
662
                                                                        if (token_aux.charAt(token_aux.length() -1) == '\'')
663
                                                                                finish = true;
664
                                                                }
665
                                                        }
666

    
667
                                                        finish = false;
668
                                                }
669
                                        }
670

    
671
                                        if (token.charAt(0) == '\"') {
672
                                                if (token.charAt(token.length() -1) != '\"') {
673
                                                        while (!finish) {
674
                                                                if (!tokens.hasMoreTokens()) {
675
                                                                        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);
676
                                                                        return false;
677
                                                                }
678
                                                                else {
679
                                                                        token_aux = tokens.nextToken().trim();
680
                                                                        token += " " + token_aux;
681

    
682
                                                                        if (token_aux.charAt(token_aux.length() -1) == '\"')
683
                                                                                finish = true;
684
                                                                }
685
                                                        }
686

    
687
                                                        finish = false;
688
                                                }
689
                                        }
690

    
691
                                        // Tries to find an invalid token
692
                                        if (token.length() > 0) {
693
                                                // Validates if a supposed field exists
694
                                                if ( (token.length() > 2) && (token.charAt(0) == '\"') && (token.charAt(token.length()-1) == '\"') ) {
695
                                                        if (! this.isAField(token.substring(1, token.length()-1))) {
696
                                                                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);
697
                                                                return false;
698
                                                        }
699
                                                }
700
                                                else {
701
                                                        // If it's an string -> ignore
702
                                                        if (! ((token.charAt(0) == token.charAt(token.length() - 1)) && (token.charAt(0) == '\''))) {
703

    
704
                                                                // If it's a date -> ignore
705
                                                                int returnValue = validateDate(token);
706

    
707
                                                                if (returnValue == 1) {
708
                                                                        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);
709
                                                                        return false;
710
                                                                }
711

    
712
                                                                if (returnValue == 2) {
713
                                                                        // Else -> Checks if the current token is a valid number or symbol
714
                                                                        if ((! StringNumberUtilities.isRealNumberWithIntegerExponent(token)) && (! this.isAnOperatorNameOrSymbol(token, getAllOperatorSymbols()))) {
715
                                                                                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);
716
                                                                                return false;
717
                                                                        }
718
                                                                }
719
                                                        }
720
                                                }
721
                                        }
722
                                }
723

    
724
                                // If has validate all tokens -> query validated
725
                                return true;
726
                        }
727
                }
728
                else
729
                        return true; // No validation done because user selected that option
730
        }
731

    
732
        /**
733
         * Returns true if there is a field with the same name as 'text'
734
         *
735
         * @param text An string
736
         * @return A boolean value
737
         */
738
        private boolean isAField(String text) {
739
                return this.allFieldsAndValuesKnownOfCurrentLayer.containsKey(text);
740
        }
741

    
742
        /**
743
         * Validates if a text has a correct date format as Date(dd-mmm-yyyy)  (Ex. Date(03-feb-2004) )
744
         *
745
         * @param text
746
         * @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
747
         */
748
        private int validateDate(String text) {
749
                // If it's a date -> check if format is correct (Ex.  Date(01-feb-2004) )
750
                if ( ((text.length() == 17) && (text.startsWith("Date(")) && (text.endsWith(")"))) && (text.charAt(7) == '-') && (text.charAt(11) == '-') ) {
751
                        if ( (StringNumberUtilities.isNaturalNumber(text.substring(5, 7))) && (StringNumberUtilities.isNaturalNumber(text.substring(12, 16))) ) {
752
                                try {
753
                                        // If can parse the date -> date with a correct format
754
                                        DateFormat.getDateInstance().parse(text.substring(5, 16));
755
                                        return 0;
756
                                } catch (ParseException e) {
757
                                        // If can't parse the date -> date with an incorrect format
758
                                        return 1;
759
                                }
760
                        }
761
                        else {
762
                                return 1;
763
                        }
764
                }
765

    
766
                return 2;
767

    
768
        }
769

    
770
        /**
771
         * Returns true if there is the 'text' is a symbol or a operator name
772
         *
773
         * @param text An string
774
         * @return A boolean value
775
         */
776
        private boolean isAnOperatorNameOrSymbol(String text, Set operatorNamesAndSymbols) {
777
                return operatorNamesAndSymbols.contains(text);
778
        }
779

    
780
        /**
781
         * DOCUMENT ME!
782
         *
783
         * @return DOCUMENT ME!
784
         *
785
         * @throws ParseException DOCUMENT ME!
786
         * @deprecated In this moments its a reference of the old Validate Expression method
787
         */
788
        private String oldValidateExpressionMethod() throws ParseException {
789
                String expression = txtExpression.getText();
790
//                HashSet variablesIndexes = new HashSet();
791
//
792
//                StringBuffer traducida = new StringBuffer();
793

    
794
                //Se transforman los nombres de los campos en las variables xix que analizar?n
795
                //Se quitan los Date(fecha) y se mete la fecha correspondiente
796
                expression = translateDates(expression);
797
                expression = translateNumber(expression);
798
                expression = translateWord(expression, "true", "1");
799
                expression = translateWord(expression, "false", "0");
800

    
801
                String replacement;
802
                Pattern patron = Pattern.compile("[^<>!]=");
803
                Matcher m = patron.matcher(expression);
804
                int index = 0;
805

    
806
                while (m.find(index)) {
807
                        index = m.start();
808
                        replacement = expression.charAt(index) + "==";
809
                        m.replaceFirst(replacement);
810
                        index++;
811
                }
812

    
813
                expression = expression.replaceAll("[^<>!]=", "==");
814

    
815
                logger.debug(expression);
816

    
817
                return expression;
818
        }
819

    
820
        ///// END METHODS FOR THE FILTER QUERY /////
821

    
822
        ///// METHODS FOR TRANSLATE DATA IN FILTER SENTENCES /////
823

    
824
        /**
825
         * DOCUMENT ME!
826
         *
827
         * @param expresion DOCUMENT ME!
828
         * @param word DOCUMENT ME!
829
         * @param translation DOCUMENT ME!
830
         *
831
         * @return DOCUMENT ME!
832
         *
833
         * @throws ParseException DOCUMENT ME!
834
         */
835
        private String translateWord(String expresion, String word,        String translation) throws ParseException {
836
                int booleanIndex = 0;
837
                int endIndex = 0;
838
                StringBuffer res = new StringBuffer();
839

    
840
                while ((booleanIndex = getIndex(expresion, word, booleanIndex)) != -1) {
841
                        res.append(expresion.substring(endIndex, booleanIndex));
842
                        endIndex = booleanIndex + word.length();
843
                        booleanIndex++;
844
                        res.append(translation);
845
                }
846

    
847
                if (endIndex < expresion.length()) {
848
                        res.append(expresion.substring(endIndex));
849
                }
850

    
851
                return res.toString();
852
        }
853

    
854
        /**
855
         * DOCUMENT ME!
856
         *
857
         * @param expresion DOCUMENT ME!
858
         *
859
         * @return DOCUMENT ME!
860
         *
861
         * @throws ParseException DOCUMENT ME!
862
         */
863
        private String translateDates(String expresion) throws ParseException {
864
                //Se obtiene el valor de la fecha
865
                String date = StringUtilities.substringDelimited(expresion, "Date(", ")", 0);
866

    
867
                if (date == null) {
868
                        return expresion;
869
                }
870

    
871
                //Se comprueba que no est? entre comillas
872
                int startIndex = expresion.indexOf(date);
873

    
874
                while (startIndex != -1) {
875
                        if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
876

    
877
                                //Se sustituye por el valor ordinal de la fecha
878
                                expresion = expresion.substring(0, startIndex - 5) +
879
                                        expresion.substring(startIndex).replaceFirst(date + "\\)",
880
                                                new Long((filterButtonsJPanel.getDateFormat().parse(date)).getTime()).toString());
881

    
882
                        } else {
883
                                startIndex += date.length();
884
                        }
885

    
886
                        if (date == null) {
887
                                return expresion;
888
                        }
889

    
890
                        startIndex = expresion.indexOf(date, startIndex);
891
                }
892

    
893
                return expresion;
894
        }
895

    
896
        /**
897
         * DOCUMENT ME!
898
         *
899
         * @param expresion DOCUMENT ME!
900
         *
901
         * @return DOCUMENT ME!
902
         *
903
         * @throws ParseException DOCUMENT ME!
904
         */
905
        private String translateNumber(String expresion) throws ParseException {
906
                DefaultCharSet ss = new DefaultCharSet();
907
                ss.addInterval('0', '9');
908
                ss.addCharacter(',');
909
                ss.addCharacter('.');
910

    
911
                String number = StringUtilities.substringWithSymbols(expresion, ss, 0);
912

    
913
                if (number == null) {
914
                        return expresion;
915
                }
916

    
917
                int startIndex = expresion.indexOf(number);
918

    
919
                while (startIndex != -1) {
920
                        Number n = nf.parse(number);
921

    
922
                        if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
923

    
924
                                //Se sustituye por el valor ordinal de la fecha
925
                                expresion = expresion.substring(0, startIndex) +
926
                                        expresion.substring(startIndex).replaceFirst(number,
927
                                                n.toString());
928
                        } else {
929
                                startIndex += n.toString().length();
930
                        }
931

    
932
                        number = StringUtilities.substringWithSymbols(expresion, ss,
933
                                        startIndex);
934

    
935
                        if (number == null) {
936
                                return expresion;
937
                        }
938

    
939
                        startIndex = expresion.indexOf(number, startIndex);
940
                }
941

    
942
                return expresion;
943
        }
944

    
945
        /**
946
         * Encodes an string to ISO 8859_1 with each ' symbol converted to ''
947
         *
948
         * @param text An string started and finished with simple apostrophes
949
         *
950
         * @return An string started and finished with simple apostrophes
951
         */
952
        private String translateString(String text) {
953
                // Encode to the string to ISO 8859_1 (the URL codification)
954
                try {
955

    
956
                        // Ignore the first and last apostrophes
957
                        if (text.length() > 2) {
958
                                text = text.substring(1, text.length() -1);
959

    
960
                                // Convert the string to ISO 8859_1 codification
961
                                text = URLEncoder.encode(text, "8859_1");
962

    
963
                                // Change '  (%27 code) to '' for the SQL parser (bebore sent the query)
964
                                text = text.replaceAll("\\%27", "\\'\\'");
965
                        }
966

    
967
                } catch (UnsupportedEncodingException e1) {
968
                        e1.printStackTrace();
969
                }
970

    
971
                return "'" + text + "'";
972
        }
973

    
974
        ///// END METHODS FOR TRANSLATE DATA IN FILTER SENTENCES /////
975

    
976
        ///// METHODS FOR MANIPULATE 'fields' and 'values' /////
977

    
978
        /**
979
         * DOCUMENT ME!
980
         *
981
         * @param t DOCUMENT ME!
982
         */
983
        public void setModel(ExpressionDataSource t) {
984
                try {
985
                        model = t;
986
            model.start();
987
        } catch (ReadDriverException e1) {
988
            NotificationManager.addError(e1.getMessage(), e1);
989
        }
990

    
991
        try {
992
                int numberOfFields = model.getFieldCount();
993

    
994
                if (numberOfFields > 0) {
995
                        Vector fields = new Vector(0, 1);
996
                        int j = 0;
997

    
998
                                for (int i = 0; i < numberOfFields; i++) {
999
                                         Object field = model.getFieldName(i);
1000

    
1001
                                        if (field != null) {
1002
                                                fields.add(field);
1003

    
1004
                                                String completeFieldPath = this.getPathOfLeafWithoutRoot(field);
1005

    
1006
                                                if (! allFieldsAndValuesKnownOfCurrentLayer.containsKey(completeFieldPath) ) {
1007
                                                        allFieldsAndValuesKnownOfCurrentLayer.put(completeFieldPath, new HashMap());
1008
                                                }
1009

    
1010
                                                j++;
1011
                                        }
1012
                                }
1013

    
1014
                                fieldsTreeTableModel = new FieldsTreeTableModel(fields.toArray());
1015
                }
1016
                } catch (FilterException e) {
1017
                        throwException(e);
1018
                }
1019
        }
1020

    
1021
        /**
1022
         * If there is a field selected, show its new values
1023
         */
1024
        public void updateFieldValues() {
1025
                if (currentPath != null) {
1026

    
1027
                        DataReturnedOfDataLoadingFromActiveView data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
1028

    
1029
                        if ((data != null) && (data.getData() != null)) {
1030
                                setModel(data.getData());
1031
                                fillValuesByPath(currentPath);
1032

    
1033
//                                valuesListModel.clear();
1034

    
1035
                                // Updates all tables that their data is about the changed view
1036
                                this.updateTablesThatHasNewData();
1037

    
1038
                                // Adjust JScrollPanes to the the beginning
1039
                                getFieldsJScrollPane().getHorizontalScrollBar().setValue(-1);
1040
                                getFieldsJScrollPane().getVerticalScrollBar().setValue(-1);
1041

    
1042
                                // Adjust JScrollPanes to the the beginning
1043
                                getValuesJScrollPane().getHorizontalScrollBar().setValue(-1);
1044
                                getValuesJScrollPane().getVerticalScrollBar().setValue(-1);
1045

    
1046
                                // Adjusts valuesJList to the default position
1047
                                getValuesJList().setSelectedIndex(-1); // No item selected
1048
                        }
1049
                }
1050
        }
1051

    
1052
        /**
1053
         * Sets Fields
1054
         *
1055
         * @param feature A Layer node with fields information
1056
         */
1057
        private boolean setFields(WFSLayerNode feature) {
1058
                Vector fields = feature.getFields();
1059

    
1060
                this.resetFieldsAndValuesData();
1061

    
1062
                int numberOfFields = fields.size();
1063

    
1064
                if (numberOfFields > 0) {
1065
                        Vector fieldBranches = new Vector(0, 1);
1066

    
1067
                        for (int i=0; i<fields.size(); i++) {
1068
                                XMLElement field = (XMLElement)fields.get(i);
1069

    
1070
                                IXMLType type = field.getEntityType();
1071

    
1072
                                if (type != null) {
1073

    
1074
                                        switch (type.getType()) {
1075
                                                case IXMLType.GML_GEOMETRY: // Don't add branch / field
1076
                                                        break;
1077
                                                case IXMLType.COMPLEX: case IXMLType.SIMPLE: // Add branch / field
1078
                                                        fieldBranches.add(field);
1079
                                                        break;
1080
                                        }
1081
                                }
1082
                        }
1083

    
1084
                        if (fieldBranches.size() > 0) {
1085
                                Object obj = fieldBranches.get(0);
1086

    
1087
                                fieldsTreeTableModel = new FieldsTreeTableModel(obj);
1088
                                fieldsJTree.setModel(new FieldsTreeTableModel(obj, false));
1089

    
1090
                                // Stores the name of all leafs (fields) of treeTableModel
1091
                                Object root = fieldsTreeTableModel.getRoot();
1092

    
1093
                                if (root != null) {
1094
                                        Vector fieldsNames = fieldsTreeTableModel.getLeafsFromNodeBranch(root);
1095

    
1096
                                        for (int j = 0; j < fieldsNames.size(); j++) {
1097
                                                Object field = fieldsNames.get(j);
1098

    
1099
                                                // Avoid errors
1100
                                                if ( (! (field instanceof XMLElement)) || (field == null) )        continue;
1101

    
1102
                                                // Don't load a geometry field
1103
                                                if (((XMLElement)field).getEntityType() != null){
1104
                                                        if ( ((XMLElement)field).getEntityType().getType() == IXMLType.GML_GEOMETRY ){
1105
                                                                continue;
1106
                                                        }
1107
                                                }
1108

    
1109
                                                String completeFieldPath = this.getPathOfLeafWithoutRoot(field);
1110

    
1111
                                                if (! allFieldsAndValuesKnownOfCurrentLayer.containsKey(completeFieldPath) ) {
1112
                                                        allFieldsAndValuesKnownOfCurrentLayer.put(completeFieldPath, new HashMap());
1113
                                                }
1114
                                        }
1115
                                }
1116
                        }
1117
                }
1118
                return true;
1119
        }
1120

    
1121
        /**
1122
         * This method load all values known of all fields known
1123
         * (It's used when a new layer is load)
1124
         */
1125
        private void setValuesKnownOfFields() {
1126
                // Desde el modelo se deber?a acceder a los campos y sus valores cargados
1127
                try {
1128
                        for (int i = 0; i < model.getFieldCount(); i++) {
1129
                                String fieldName = model.getFieldName(i);
1130
                                HashMap fieldValues = (HashMap) allFieldsAndValuesKnownOfCurrentLayer.get(fieldName);
1131

    
1132
                                if (fieldValues != null) {
1133
                                        for (int j = 0; j < model.getRowCount(); j++) {
1134
                                                Value value = model.getFieldValue(j, i);
1135

    
1136
                                                if (value instanceof NullValue)
1137
                                                    continue;
1138

    
1139
                                                Object obj = (Object)value;
1140

    
1141
                                                if (obj == null)
1142
                                                        continue;
1143

    
1144
                                                fieldValues.put(obj.toString(), obj.toString());
1145

    
1146
                                        }
1147
                                }
1148
                        }
1149
                }
1150
                catch (Exception e) {
1151
                        e.printStackTrace();
1152
                }
1153
        }
1154

    
1155
        /**
1156
         * Resets the data of fields and their values of the current layer feature, and removes the branches of JTree
1157
         */
1158
        private void resetFieldsAndValuesData() {
1159
                fieldsJTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
1160
                txtExpression.setText("");
1161
                ((DefaultListModel)valuesJList.getModel()).removeAllElements();
1162
        }
1163

    
1164
        /**
1165
         * FIlls list with the values of selected field
1166
         *
1167
         * @param treePath A path in the tree
1168
         */
1169
        private void fillValuesByPath(TreePath treePath) {
1170
                // Duplicates are removed
1171
                TreeSet conjunto = new TreeSet(new Comparator() {
1172
                        public int compare(Object o1, Object o2) {
1173
                                if ((o1 != null) && (o2 != null)) {
1174
                                        Value v2 = (Value) o2;
1175
                                        Value v1 = (Value) o1;
1176
                                        BooleanValue boolVal;
1177

    
1178
                                        try {
1179
                                                boolVal = (BooleanValue) (v1.greater(v2));
1180

    
1181
                                                if (boolVal.getValue()) {
1182
                                                        return 1;
1183
                                                }
1184

    
1185
                                                boolVal = (BooleanValue) (v1.less(v2));
1186

    
1187
                                                if (boolVal.getValue()) {
1188
                                                        return -1;
1189
                                                }
1190
                                        } catch (IncompatibleTypesException e) {
1191
                                                throw new RuntimeException(e);
1192
                                        }
1193
                                }
1194

    
1195
                                return 0;
1196
                        }
1197
                }); // For ordernation
1198

    
1199
                // Remove the previous items
1200
                valuesListModel.clear();
1201

    
1202
                try {
1203
                        //Object root = treePath.getPath()[0];
1204
                        XMLElement element = ((XMLElement)treePath.getLastPathComponent());
1205

    
1206
                        // Gets the values associated to the selected branch
1207
                        switch (element.getEntityType().getType()) {
1208
                                case IXMLType.SIMPLE:
1209

    
1210
                                        if(element.getParentElement().getParentElement() == null) {
1211
                                                // Find the selected field and try to obtein values related
1212
                                                for (int i = 0; i < model.getFieldCount(); i++) {
1213
                                                        String name = model.getFieldName(i);
1214

    
1215
                                                        // If we find the field (this means that are loaded its values and we can obtein them)
1216
                                                        if (name.equals(element.getName())) {
1217
                                                                for (int j = 0; j < model.getRowCount(); j++) {
1218
                                                                        Value value = model.getFieldValue(j, i);
1219

    
1220
                                                                        if (value instanceof NullValue)
1221
                                                                            continue;
1222

    
1223
                                                                        if (!conjunto.contains(value)) {
1224
                                                                                conjunto.add(value);
1225
                                                                        }
1226
                                                                }
1227

    
1228
                                                                break;
1229
                                                        }
1230
                                                }
1231
                                        }else{
1232
                                                //create a vector with the parent names from the leaf until the root
1233
                                                XMLElement parent = element.getParentElement();
1234
                                                Vector parentNames = new Vector();
1235
                                                parentNames.add(element.getName());
1236
                                                while (parent != null){
1237
                                                        parentNames.add(parent.getName());
1238
                                                        parent = parent.getParentElement();
1239
                                                }
1240

    
1241
                                                //The field name (in the gvSIG table) is the second field name
1242
                                                String fieldName = (String)parentNames.get(parentNames.size()-2);
1243

    
1244
                                                for (int i = 0; i < model.getFieldCount(); i++) {
1245
                                                        String name = model.getFieldName(i);
1246

    
1247
                                                        // If we find the field (this means that are loaded its values and we can obtein them)
1248
                                                        if (name.equals(fieldName)) {
1249
                                                                for (int j = 0; j < model.getRowCount(); j++) {
1250
                                                                        Value value = model.getFieldValue(j, i);
1251

    
1252
                                                                        if (value instanceof NullValue)
1253
                                                                            continue;
1254

    
1255
                                                                        if (value instanceof ComplexValue){
1256
                                                                                for (int k=parentNames.size()-3 ; k>=0 ; k--){
1257
                                                                                        ComplexValue complex = (ComplexValue)value;
1258
                                                                                        Value childValue = (Value)complex.get(parentNames.get(k));
1259
                                                                                        if (k==0){
1260
                                                                                                if (!conjunto.contains(childValue)) {
1261
                                                                                                        conjunto.add(childValue);
1262
                                                                                                }
1263
                                                                                        }else{
1264
                                                                                                value = childValue;
1265
                                                                                        }
1266
                                                                                }
1267
                                                                        }
1268
                                                                }
1269

    
1270
                                                                break;
1271
                                                        }
1272
                                                }
1273
                                        }
1274
                                        break;
1275
                                case IXMLType.COMPLEX:
1276
                                        break;
1277
                                default:
1278
                                        // Do Nothing
1279
                        }
1280

    
1281
                        // Add the values to the model of the graphic list
1282
                        Iterator it = conjunto.iterator();
1283
                        Object[] objects = currentPath.getPath();
1284

    
1285
                        if (objects.length == 0)
1286
                                return;
1287

    
1288
                        String selectedField = ((XMLElement)objects[objects.length-1]).getName(); // Gets the selected field
1289

    
1290
                        if (selectedField != null) { // If there is a selected field
1291
                                Map fieldValues = (HashMap)allFieldsAndValuesKnownOfCurrentLayer.get(selectedField); // Gets valus stored associated to this field
1292
                                JLabel currentValueLabel = null;
1293

    
1294
                                // If the field doesn't exits -> create a new Map with its values
1295
                                if (fieldValues == null) {
1296
                                        fieldValues = new HashMap();
1297
                                        allFieldsAndValuesKnownOfCurrentLayer.put(selectedField, fieldValues);
1298

    
1299
                                        while (it.hasNext()) {
1300
                                                // A label with text with yelow background color for values that are loaded in the layer
1301
                                                currentValueLabel = new JLabelAsCellValueLoaded();
1302

    
1303
                                                currentValueLabel.setText(it.next().toString());
1304

    
1305
                                                if (currentValueLabel.getText().compareTo("") != 0) {
1306
                                                        fieldValues.put(currentValueLabel.getText(), currentValueLabel.getText());
1307

    
1308
                                                        // All values loaded in this loop must be at beginning of the list (and in a differenciated color)
1309
                                                        if ( ! valuesListModel.contains(currentValueLabel) )
1310
                                                                valuesListModel.addElement(currentValueLabel);
1311
                                                }
1312
                                        }
1313
                                }
1314
                                else { // Else -> Adds the new ones, and changes element labels that have changed  (before were loaded and now not, or before weren't loaded but now yes)
1315

    
1316
                                        // Changes element labels that have changed  (before were loaded and now not, or before weren't loaded but now yes)
1317
                                        ((DefaultListModelForJLabelAsCell)valuesListModel).setAllElementsToNotLoaded();
1318

    
1319
                                        // For each current value associated to de current selected field -> if its loaded -> put it at beginning of the list and change to 'JLabelLoadedValue'
1320
                                        while (it.hasNext()) {
1321
                                                String text = it.next().toString();
1322
                                                int elementPosition = ((DefaultListModelForJLabelAsCell)valuesListModel).getIndexOfJLabelText(text);
1323

    
1324
                                                if (elementPosition == -1) // If it must be added
1325
                                                        valuesListModel.addElement(new JLabelAsCellValueLoaded(text));
1326
                                                else
1327
                                                        ((DefaultListModelForJLabelAsCell)valuesListModel).changeElementThatHasTextToJLabelLoadedValue(text); // Change to 'JLabelLoadedValue'
1328
                                        }
1329
                                }
1330

    
1331
                                // Load the rest of the values associated to the current selected field
1332
                                if (fieldValues != null) {
1333
                                        // A label with text with yelow background color for values that are loaded in the layer
1334
                                        currentValueLabel = new JLabelAsCellValueNotLoaded();
1335

    
1336
                                        Set values = fieldValues.keySet();
1337

    
1338
                                        it = values.iterator();
1339

    
1340
                                        while (it.hasNext()) {
1341
                                                String name = it.next().toString();
1342

    
1343
                                                if ( ! ((DefaultListModelForJLabelAsCell)valuesListModel).containsJLabelText(name) )
1344
                                                        valuesListModel.addElement(new JLabelAsCellValueNotLoaded(name));
1345
                                        }
1346
                                }
1347
                        }
1348

    
1349
                } catch (Exception e) {
1350
                        throwException(e);
1351
                }
1352
        }
1353

    
1354
        ///// END METHODS FOR MANIPULATE 'fields' and 'values' /////
1355

    
1356
        ///// METHODS FOR PARENT NOTIFICATIONS /////
1357

    
1358
        //
1359
//        /**
1360
//         * @see WFSParamsPanel#isApplicable(boolean)
1361
//         *
1362
//         * This also loads values of fields
1363
//         *
1364
//         * @param b A boolean value
1365
//         */
1366
//        private void setApplicate(boolean b) {
1367
//                parent.isApplicable(b);
1368
//        }
1369

    
1370
        ///// END METHODS FOR PARENT NOTIFICATIONS /////
1371

    
1372
        ///// METHOS FOR 'allFieldsAndValuesKnownOfCurrentLayer' /////
1373

    
1374
        /**
1375
         * Sets all fields and values known about the current layer
1376
         *
1377
         * @param _allFieldsAndValuesKnownOfCurrentLayer A Map object
1378
         */
1379
        public void setAllFieldsAndValuesKnownOfCurrentLayer(Map _allFieldsAndValuesKnownOfCurrentLayer) {
1380
                if (_allFieldsAndValuesKnownOfCurrentLayer == null)
1381
                        this.allFieldsAndValuesKnownOfCurrentLayer = new HashMap();
1382
                else
1383
                        this.allFieldsAndValuesKnownOfCurrentLayer = _allFieldsAndValuesKnownOfCurrentLayer;
1384
        }
1385

    
1386
        /**
1387
         * Gets all fields and values known about the current layer
1388
         *
1389
         * @return _allFieldsAndValuesKnownOfCurrentLayer A Map object
1390
         */
1391
        public Map getAllFieldsAndValuesKnownOfCurrentLayer() {
1392
                return allFieldsAndValuesKnownOfCurrentLayer;
1393
        }
1394

    
1395
        ///// METHOS FOR 'allFieldsAndValuesKnownOfCurrentLayer' /////
1396

    
1397
        ///// UPDATE TABLES DATA /////
1398

    
1399
        /**
1400
         * Updates all tables that their data is about the changed view
1401
         */
1402
        private void updateTablesThatHasNewData() {
1403
                boolean oneTimeNewDataToTableAdded = false;
1404

    
1405
                IWindow[] activeNoModalWindows = PluginServices.getMDIManager().getAllWindows();
1406

    
1407
                for (int i = 0; i < activeNoModalWindows.length; i++) {
1408
                        IWindow window = activeNoModalWindows[i];
1409
                        if (window instanceof Table) {
1410
                                Table table = (Table) window;
1411

    
1412
                                int pos1 = featureName.indexOf(':');
1413

    
1414
                                if ((pos1 >= 0) && (pos1 < featureName.length()))
1415
                                        featureName = featureName.substring(pos1 +1, featureName.length());
1416

    
1417
//                                        String featureOfTable = ((XMLElement)currentPath.getParentPath().getLastPathComponent()).getName();
1418
                                        String featureOfTable = table.getModel().getName();
1419
                                        int pos2 = featureOfTable.indexOf(':');
1420

    
1421
                                        if ((pos2 >= 0) && (pos2 < featureName.length()))
1422
                                                featureOfTable = featureOfTable.substring(pos2 +1, featureOfTable.length());
1423

    
1424
                                if (featureName.trim().compareTo(featureOfTable.trim()) == 0) {
1425
                                        // Only add the new data associated to the table one time
1426
                                        if (oneTimeNewDataToTableAdded == false) {
1427
                                                setNewDataToTable();
1428
                                                oneTimeNewDataToTableAdded = true;
1429
                                        }
1430

    
1431
                                        // Refresh the table with the new data
1432
                                        table.refresh();
1433
                                }
1434
                        }
1435
                }
1436
        }
1437

    
1438
        /**
1439
         * This method is a modification of the "execute" method from the "ShowTable" class
1440
         *
1441
         * @see com.iver.cit.gvsig.ShowTable#execute(String)
1442
         */
1443
        private void setNewDataToTable() {
1444
                View vista = (View) PluginServices.getMDIManager().getActiveWindow();
1445
                FLayer[] actives = vista.getModel().getMapContext().getLayers().getActives();
1446

    
1447
                try {
1448
                        for (int i = 0; i < actives.length; i++) {
1449
                                if (actives[i] instanceof AlphanumericData) {
1450
                                        AlphanumericData co = (AlphanumericData) actives[i];
1451

    
1452
                                        //SelectableDataSource dataSource;
1453
                                        //dataSource = co.getRecordset();
1454

    
1455
                                        ProjectExtension ext = (ProjectExtension) PluginServices.getExtension(ProjectExtension.class);
1456

    
1457
                                        ProjectTable projectTable = ext.getProject().getTable(co);
1458
                                        EditableAdapter ea=null;
1459
                                        ReadableVectorial rv=((FLyrVect)actives[i]).getSource();
1460
                                        if (rv instanceof VectorialEditableAdapter){
1461
                                                ea=(EditableAdapter)((FLyrVect)actives[i]).getSource();
1462
                                        }else{
1463
                                                ea=new EditableAdapter();
1464
                                                SelectableDataSource sds=((FLyrVect)actives[i]).getRecordset();
1465
                                                ea.setOriginalDataSource(sds);
1466
                                        }
1467

    
1468
                                        if (projectTable == null) {
1469
                                                projectTable = ProjectFactory.createTable(PluginServices.getText(this, "Tabla_de_Atributos") + ": " + actives[i].getName(),
1470
                                                                ea);
1471
                                                projectTable.setProjectDocumentFactory(new ProjectTableFactory());
1472
                                                projectTable.setAssociatedTable(co);
1473
                                                ext.getProject().addDocument(projectTable);
1474
                                        }
1475
                                        projectTable.setModel(ea);
1476

    
1477
                                        // Removed part of code that created another (visual) table
1478
//                                        Table t = new Table();
1479
//                                        t.setModel(projectTable);
1480
//                                        PluginServices.getMDIManager().addWindow(t);
1481
                                }
1482
                        }
1483
                }catch (ReadDriverException e) {
1484
                        NotificationManager.addError(PluginServices.getText(this,"No_se_pudo_obtener_la_tabla_de_la_capa"), e);
1485
        }
1486
        }
1487

    
1488
        ///// END UPDATE TABLES DATA /////
1489

    
1490
        ///// OTHER METHODS /////
1491

    
1492
        /**
1493
         * DOCUMENT ME!
1494
         *
1495
         * @param expresion DOCUMENT ME!
1496
         * @param substring DOCUMENT ME!
1497
         * @param startingPos DOCUMENT ME!
1498
         *
1499
         * @return DOCUMENT ME!
1500
         */
1501
        private int getIndex(String expresion, String substring, int startingPos) {
1502
                int index = startingPos;
1503

    
1504
                do {
1505
                        index = expresion.indexOf(substring, index);
1506
                } while ((StringUtilities.isBetweenSymbols(expresion, index, "\"")) &&
1507
                                (index != -1));
1508

    
1509
                return index;
1510
        }
1511

    
1512
        /**
1513
         * DOCUMENT ME!
1514
         *
1515
         * @param arg0
1516
         *
1517
         * @return
1518
         */
1519
        public boolean addExpressionListener(ExpressionListener arg0) {
1520
                return expressionListeners.add(arg0);
1521
        }
1522

    
1523
        /**
1524
         * DOCUMENT ME!
1525
         *
1526
         * @param arg0
1527
         *
1528
         * @return
1529
         */
1530
        public boolean removeExpressionListener(ExpressionListener arg0) {
1531
                return expressionListeners.remove(arg0);
1532
        }
1533
        /**
1534
         * DOCUMENT ME!
1535
         *
1536
         * @param o DOCUMENT ME!
1537
         *
1538
         * @return DOCUMENT ME!
1539
         */
1540
        public boolean removeExceptionListener(ExceptionListener o) {
1541
                return exceptionHandlingSupport.removeExceptionListener(o);
1542
        }
1543

    
1544
        /**
1545
         * DOCUMENT ME!
1546
         *
1547
         * @param t DOCUMENT ME!
1548
         */
1549
        private void throwException(Throwable t) {
1550
                exceptionHandlingSupport.throwException(t);
1551
        }
1552

    
1553
        ///// END OTHER METHODS /////
1554
}