Statistics
| Revision:

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

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

    
77

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

    
119
/**
120
 * This will be the tab for add a filter to a WFS query.
121
 * This class gets the graphical interface from FilterQueryJPanel and add logic.
122
 *
123
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
124
 */
125
public class WFSFilterPanel extends FilterQueryJPanel {
126
        private static Logger logger = Logger.getLogger(Table.class.getName());
127
        private WFSParamsPanel parent = null;
128
        private ArrayList expressionListeners = new ArrayList();
129
        private ExpressionDataSource model = null;
130
        private NumberFormat nf = NumberFormat.getNumberInstance();
131
        private ExceptionHandlingSupport exceptionHandlingSupport = new ExceptionHandlingSupport();
132
        private FieldsTreeTableModel fieldsTreeTableModel;
133
        private boolean panelAsATabForWFSLayersLoad;
134
        private TreePath currentPath;
135
        private String featureName;
136
        private Map allFieldsAndValuesKnownOfCurrentLayer; // This will have all values (not repeated) known of all fields (not repeated)
137
        private short eventsReceived; // This attribute is necessary to avoid a bug produced by the reception duplicated of an event when a layer of a WFS service is selected.
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
                        /*
419
                         * This attribute is necessary to avoid a bug produced by the reception duplicated of an event
420
                         *  when a layer of a WFS service is selected.
421
                         */ 
422
                        if ((eventsReceived % 2) == 0)
423
                                this.allFieldsAndValuesKnownOfCurrentLayer.clear();
424
                        
425
                        eventsReceived ++;
426

    
427
                        this.allFieldsAndValuesKnownOfCurrentLayer.clear();
428
                        getValidateFilterExpressionJCheckBox().setSelected(true);
429
                }
430
                else {
431
                        // Unselect the selected path in the tree (if there was any selected)
432
                        if (this.currentPath != null) {
433
                                this.currentPath = null;
434
                                this.getFieldsJTree().removeSelectionPath(this.getFieldsJTree().getSelectionPath());
435
                        }
436

    
437
                        // Resets data loaded
438
                        super.getValuesJList().setEnabled(true);
439
                        super.getValuesJList().setBackground(Color.WHITE);
440

    
441
                        this.getFieldsJTree().removeAll();
442
                        this.getValuesJList().removeAll();
443
                        
444
                        /*
445
                         * This attribute is necessary to avoid a bug produced by the reception duplicated of an event
446
                         *  when a layer of a WFS service is selected.
447
                         */ 
448
                        eventsReceived = 0;
449

    
450
                        // Updates data associated to view with the new layer data
451
                        this.setNewDataToTable();
452

    
453
                        // If theres is any table associated to the current view -> update that table/s
454
//                        this.updateTablesThatHasNewData();
455

    
456
                        // Reads that new data
457
                        DataReturnedOfDataLoadingFromActiveView data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
458

    
459
                        if ((data != null) && (data.getData() != null)) {
460
                                setModel(data.getData());
461
//                                currentPath = e.getPath();
462
//                                fillValuesByPath(currentPath);
463
                        }
464

    
465
                        // Loads values known of fields
466
                        this.setValuesKnownOfFields();
467
                }
468
        }
469

    
470
        /**
471
         * Refresh all information about fields
472
         *
473
         * @param feature
474
         */
475
        public boolean refresh(WFSLayerNode feature) {
476
                featureName = feature.getTitle();
477
                return setFields(feature);
478
        }
479

    
480
        ///// END GUI METHODS /////
481

    
482
        ///// METHODS FOR THE FILTER QUERY /////
483

    
484
        /**
485
         * Gets the query that will be send to the server
486
         * @return SQL query (just the where part)
487
         */
488
        public String getQuery(){
489
                String writtenQuery = txtExpression.getText().trim();
490

    
491
                // Validate expression
492
                if (!this.validateExpression(writtenQuery)) {
493
                        getTxtExpression().setForeground(Color.red);
494
                        return null;
495
                }
496
                else
497
                        // Codify expression (only if the validation has been successful)
498
                        return this.codifyExpression(writtenQuery); // Ignores the spaces at beginning and end of the chain of characters
499
        }
500

    
501
        /**
502
         * Gets the filter expression from the user interface
503
         */
504
        public String getFilterExpressionFromInterface() {
505
                return getTxtExpression().getText();
506
        }
507

    
508
        /**
509
         * Writes the filter expression into the user interface
510
         * @param filterExpression An string
511
         */
512
        public void setFilterExpressionIntoInterface(String filterExpression){
513
                getTxtExpression().setText(filterExpression);
514
        }
515

    
516
        /**
517
         * Removes text in the JTextArea that has the filter subconsultation
518
         */
519
        public void removeFilterExpression() {
520
                getTxtExpression().setText("");
521
        }
522

    
523
        /**
524
         * Codifies the expression to ISO ISO-8859_1 and a format that the SQL parser could validate
525
         *
526
         * @param expression The expression to be codified
527
         *
528
         * @return The expression codified
529
         */
530
        private String codifyExpression(String expression) {
531
                String result = new String("");
532

    
533
                // Encode each string of the query
534
                int index = 0;
535
                int lastIndex = 0;
536
                boolean endInnerLoop;
537
                // Encodes all inner strings to the equivalent codification in ISO-8859_1 with each ' symbol converted to ''
538
                while (index != -1) {
539
                        index = expression.indexOf("'", index);
540

    
541
                        // Add the parts of the chain of characters that not are string
542
                        if (index == -1) {
543
                                result += expression.substring(lastIndex, expression.length());
544
                        }
545
                        else {
546
                                result += expression.substring(lastIndex, index).replaceAll(" [ ]+", " ");
547
                        }
548

    
549
                        lastIndex = index;
550
                        endInnerLoop = false;
551

    
552
                        // Tries to find each first apostrophe of each string of the query
553
                        if ((index > 0) && (expression.charAt(index - 1) == ' ')) {
554
                                index++;
555

    
556
                                // Ignore all inner apostrophes and try to find the last of the string
557
                                while (!endInnerLoop)  {
558
                                        index = expression.indexOf("'", index);
559
                                        index++;
560

    
561
                                        // If we haven't arrived to the finish of the string
562
                                        if (index != expression.length()) {
563
                                                if ((index == -1) || (expression.charAt(index) == ' ')) {
564
                                                        result += translateString(expression.substring(lastIndex, index));
565
                                                        endInnerLoop = true;
566
                                                }
567
                                        }
568
                                        else {
569
                                                result += translateString(expression.substring(lastIndex, index));
570
                                                endInnerLoop = true;
571
                                                index = -1; // Force to finish the external loop
572
                                        }
573
                                }
574
                                lastIndex = index;
575
                        }
576
                }
577

    
578
                // Field names are transformated in xix variables that will be analyzed
579
                // Date(date) is substituted by the correct date format
580
                try {
581
                        result = translateDates(result);
582
                }
583
                catch(ParseException e) {
584
                        JOptionPane.showMessageDialog(this, PluginServices.getText(null, "error_codifying_dates"), PluginServices.getText(null, "error_coding_filter_query"), JOptionPane.ERROR_MESSAGE);
585
                        return null;
586
                }
587

    
588
                try {
589
                        result = translateNumber(result);
590
                }
591
                catch(ParseException e) {
592
                        JOptionPane.showMessageDialog(this, PluginServices.getText(null, "error_codifying_numbers"), PluginServices.getText(null, "error_coding_filter_query"), JOptionPane.ERROR_MESSAGE);
593
                        return null;
594
                }
595

    
596
                try {
597
                        result = translateWord(result, "true", "1");
598
                }
599
                catch(ParseException e) {
600
                        JOptionPane.showMessageDialog(this, PluginServices.getText(null, "error_codifying_words"), PluginServices.getText(null, "error_coding_filter_query"), JOptionPane.ERROR_MESSAGE);
601
                        return null;
602
                }
603

    
604
                try {
605
                        result = translateWord(result, "false", "0");
606
                }
607
                catch(ParseException e) {
608
                        JOptionPane.showMessageDialog(this, PluginServices.getText(null, "error_codifying_words"), PluginServices.getText(null, "error_coding_filter_query"), JOptionPane.ERROR_MESSAGE);
609
                        return null;
610
                }
611

    
612
                logger.debug(result);
613

    
614
                return result;
615
        }
616

    
617
        /**
618
         * Checks the filter expression if it's correct
619
         *
620
         * @param query The query expression to analyze
621
         * @return True if it's valid or false if not
622
         */
623
        private boolean validateExpression(String query) {
624
                // If it's needed to validate the query
625
                if (getValidateFilterExpressionJCheckBox().isSelected()) {
626
                        // If it's an empty query -> ok
627
                        if (query.trim().length() == 0)
628
                                return true;
629

    
630
                        // Replace all Date(dd-mmm-yyyy) format to ddd-mmm-yyyy (characters will replaced to spaces)
631
                        int index = 0;
632
                        String query_copy = new String(query);
633
                        while ((index = query_copy.indexOf("Date(", index)) != -1) {
634
                                if (index > 0) {
635
                                        if ((query_copy.charAt(index-1) != ' ') && (query_copy.charAt(index-1) != '('))
636
                                                break;
637
                                }
638

    
639
                                if (((index + 16) < query_copy.length()) && (query_copy.charAt(index + 16) == ')')) { // +17 is the length of Date(dd-mmm-yyyy)
640
                                        if ((index + 17) < query_copy.length()) {
641
                                                query_copy = query_copy.substring(0, index) + "     " + query_copy.substring(index+6, index+16) + " " + query_copy.substring(index+17);
642
                                        }
643
                                        else {
644
                                                query_copy = query_copy.substring(0, index) + "     " + query_copy.substring(index+6, index+16);
645
                                        }
646
                                }
647
                        }
648

    
649
                        SQLQueryValidation sQLQueryValidation = new SQLQueryValidation(query_copy, true);
650

    
651
                        // Tries to validate the query, and if fails shows a message
652
                        if (!sQLQueryValidation.validateQuery()) {
653
                                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);
654
                                return false;
655
                        }
656
                        else {
657
                                // Analyzes tokens in query
658
                                StringTokenizer tokens = new StringTokenizer(query, " ");
659
                                String token, token_aux;
660
                                boolean finish = false;
661

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

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

    
677
                                                                        if (token_aux.charAt(token_aux.length() -1) == '\'')
678
                                                                                finish = true;
679
                                                                }
680
                                                        }
681

    
682
                                                        finish = false;
683
                                                }
684
                                        }
685

    
686
                                        if (token.charAt(0) == '\"') {
687
                                                if (token.charAt(token.length() -1) != '\"') {
688
                                                        while (!finish) {
689
                                                                if (!tokens.hasMoreTokens()) {
690
                                                                        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);
691
                                                                        return false;
692
                                                                }
693
                                                                else {
694
                                                                        token_aux = tokens.nextToken().trim();
695
                                                                        token += " " + token_aux;
696

    
697
                                                                        if (token_aux.charAt(token_aux.length() -1) == '\"')
698
                                                                                finish = true;
699
                                                                }
700
                                                        }
701

    
702
                                                        finish = false;
703
                                                }
704
                                        }
705

    
706
                                        // Tries to find an invalid token
707
                                        if (token.length() > 0) {
708
                                                // Validates if a supposed field exists
709
                                                if ( (token.length() > 2) && (token.charAt(0) == '\"') && (token.charAt(token.length()-1) == '\"') ) {
710
                                                        if (! this.isAField(token.substring(1, token.length()-1))) {
711
                                                                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);
712
                                                                return false;
713
                                                        }
714
                                                }
715
                                                else {
716
                                                        // If it's an string -> ignore
717
                                                        if (! ((token.charAt(0) == token.charAt(token.length() - 1)) && (token.charAt(0) == '\''))) {
718

    
719
                                                                // If it's a date -> ignore
720
                                                                int returnValue = validateDate(token);
721

    
722
                                                                if (returnValue == 1) {
723
                                                                        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);
724
                                                                        return false;
725
                                                                }
726

    
727
                                                                if (returnValue == 2) {
728
                                                                        // Else -> Checks if the current token is a valid number or symbol
729
                                                                        if ((! StringNumberUtilities.isRealNumberWithIntegerExponent(token)) && (! this.isAnOperatorNameOrSymbol(token, getAllOperatorSymbols()))) {
730
                                                                                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);
731
                                                                                return false;
732
                                                                        }
733
                                                                }
734
                                                        }
735
                                                }
736
                                        }
737
                                }
738

    
739
                                // If has validate all tokens -> query validated
740
                                return true;
741
                        }
742
                }
743
                else
744
                        return true; // No validation done because user selected that option
745
        }
746
        
747
        /**
748
         * Returns true if there is a field with the same name as 'text'
749
         *
750
         * @param text An string
751
         * @return A boolean value
752
         */
753
        private boolean isAField(String text) {
754
                return this.allFieldsAndValuesKnownOfCurrentLayer.containsKey(text);
755
        }
756

    
757
        /**
758
         * Validates if a text has a correct date format as Date(dd-mmm-yyyy)  (Ex. Date(03-feb-2004) )
759
         *
760
         * @param text
761
         * @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
762
         */
763
        private int validateDate(String text) {
764
                // If it's a date -> check if format is correct (Ex.  Date(01-feb-2004) )
765
                if ( ((text.length() == 17) && (text.startsWith("Date(")) && (text.endsWith(")"))) && (text.charAt(7) == '-') && (text.charAt(11) == '-') ) {
766
                        if ( (StringNumberUtilities.isNaturalNumber(text.substring(5, 7))) && (StringNumberUtilities.isNaturalNumber(text.substring(12, 16))) ) {
767
                                try {
768
                                        // If can parse the date -> date with a correct format
769
                                        DateFormat.getDateInstance().parse(text.substring(5, 16));
770
                                        return 0;
771
                                } catch (ParseException e) {
772
                                        // If can't parse the date -> date with an incorrect format
773
                                        return 1;
774
                                }
775
                        }
776
                        else {
777
                                return 1;
778
                        }
779
                }
780

    
781
                return 2;
782

    
783
        }
784

    
785
        /**
786
         * Returns true if there is the 'text' is a symbol or a operator name
787
         *
788
         * @param text An string
789
         * @return A boolean value
790
         */
791
        private boolean isAnOperatorNameOrSymbol(String text, Set operatorNamesAndSymbols) {
792
                return operatorNamesAndSymbols.contains(text);
793
        }
794

    
795
        /**
796
         * DOCUMENT ME!
797
         *
798
         * @return DOCUMENT ME!
799
         *
800
         * @throws ParseException DOCUMENT ME!
801
         * @deprecated In this moments its a reference of the old Validate Expression method
802
         */
803
        private String oldValidateExpressionMethod() throws ParseException {
804
                String expression = txtExpression.getText();
805
//                HashSet variablesIndexes = new HashSet();
806
//
807
//                StringBuffer traducida = new StringBuffer();
808

    
809
                //Se transforman los nombres de los campos en las variables xix que analizar?n
810
                //Se quitan los Date(fecha) y se mete la fecha correspondiente
811
                expression = translateDates(expression);
812
                expression = translateNumber(expression);
813
                expression = translateWord(expression, "true", "1");
814
                expression = translateWord(expression, "false", "0");
815

    
816
                String replacement;
817
                Pattern patron = Pattern.compile("[^<>!]=");
818
                Matcher m = patron.matcher(expression);
819
                int index = 0;
820

    
821
                while (m.find(index)) {
822
                        index = m.start();
823
                        replacement = expression.charAt(index) + "==";
824
                        m.replaceFirst(replacement);
825
                        index++;
826
                }
827

    
828
                expression = expression.replaceAll("[^<>!]=", "==");
829

    
830
                logger.debug(expression);
831

    
832
                return expression;
833
        }
834

    
835
        ///// END METHODS FOR THE FILTER QUERY /////
836

    
837
        ///// METHODS FOR TRANSLATE DATA IN FILTER SENTENCES /////
838

    
839
        /**
840
         * DOCUMENT ME!
841
         *
842
         * @param expresion DOCUMENT ME!
843
         * @param word DOCUMENT ME!
844
         * @param translation DOCUMENT ME!
845
         *
846
         * @return DOCUMENT ME!
847
         *
848
         * @throws ParseException DOCUMENT ME!
849
         */
850
        private String translateWord(String expresion, String word,        String translation) throws ParseException {
851
                int booleanIndex = 0;
852
                int endIndex = 0;
853
                StringBuffer res = new StringBuffer();
854

    
855
                while ((booleanIndex = getIndex(expresion, word, booleanIndex)) != -1) {
856
                        res.append(expresion.substring(endIndex, booleanIndex));
857
                        endIndex = booleanIndex + word.length();
858
                        booleanIndex++;
859
                        res.append(translation);
860
                }
861

    
862
                if (endIndex < expresion.length()) {
863
                        res.append(expresion.substring(endIndex));
864
                }
865

    
866
                return res.toString();
867
        }
868

    
869
        /**
870
         * DOCUMENT ME!
871
         *
872
         * @param expresion DOCUMENT ME!
873
         *
874
         * @return DOCUMENT ME!
875
         *
876
         * @throws ParseException DOCUMENT ME!
877
         */
878
        private String translateDates(String expresion) throws ParseException {
879
                //Se obtiene el valor de la fecha
880
                String date = StringUtilities.substringDelimited(expresion, "Date(", ")", 0);
881

    
882
                if (date == null) {
883
                        return expresion;
884
                }
885

    
886
                //Se comprueba que no est? entre comillas
887
                int startIndex = expresion.indexOf(date);
888

    
889
                while (startIndex != -1) {
890
                        if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
891

    
892
                                //Se sustituye por el valor ordinal de la fecha
893
                                expresion = expresion.substring(0, startIndex - 5) +
894
                                        expresion.substring(startIndex).replaceFirst(date + "\\)",
895
                                                new Long((filterButtonsJPanel.getDateFormat().parse(date)).getTime()).toString());
896

    
897
                        } else {
898
                                startIndex += date.length();
899
                        }
900

    
901
                        if (date == null) {
902
                                return expresion;
903
                        }
904

    
905
                        startIndex = expresion.indexOf(date, startIndex);
906
                }
907

    
908
                return expresion;
909
        }
910

    
911
        /**
912
         * DOCUMENT ME!
913
         *
914
         * @param expresion DOCUMENT ME!
915
         *
916
         * @return DOCUMENT ME!
917
         *
918
         * @throws ParseException DOCUMENT ME!
919
         */
920
        private String translateNumber(String expresion) throws ParseException {
921
                DefaultCharSet ss = new DefaultCharSet();
922
                ss.addInterval('0', '9');
923
                ss.addCharacter(',');
924
                ss.addCharacter('.');
925

    
926
                String number = StringUtilities.substringWithSymbols(expresion, ss, 0);
927

    
928
                if (number == null) {
929
                        return expresion;
930
                }
931

    
932
                int startIndex = expresion.indexOf(number);
933

    
934
                while (startIndex != -1) {
935
                        Number n = nf.parse(number);
936

    
937
                        if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
938

    
939
                                //Se sustituye por el valor ordinal de la fecha
940
                                expresion = expresion.substring(0, startIndex) +
941
                                        expresion.substring(startIndex).replaceFirst(number,
942
                                                n.toString());
943
                        } else {
944
                                startIndex += n.toString().length();
945
                        }
946

    
947
                        number = StringUtilities.substringWithSymbols(expresion, ss,
948
                                        startIndex);
949

    
950
                        if (number == null) {
951
                                return expresion;
952
                        }
953

    
954
                        startIndex = expresion.indexOf(number, startIndex);
955
                }
956

    
957
                return expresion;
958
        }
959

    
960
        /**
961
         * Encodes an string to ISO 8859_1 with each ' symbol converted to ''
962
         *
963
         * @param text An string started and finished with simple apostrophes
964
         *
965
         * @return An string started and finished with simple apostrophes
966
         */
967
        private String translateString(String text) {
968
                // Encode to the string to ISO 8859_1 (the URL codification)
969
                try {
970

    
971
                        // Ignore the first and last apostrophes
972
                        if (text.length() > 2) {
973
                                text = text.substring(1, text.length() -1);
974

    
975
                                // Convert the string to ISO 8859_1 codification
976
                                text = URLEncoder.encode(text, "8859_1");
977

    
978
                                // Change '  (%27 code) to '' for the SQL parser (bebore sent the query)
979
                                text = text.replaceAll("\\%27", "\\'\\'");
980
                        }
981

    
982
                } catch (UnsupportedEncodingException e1) {
983
                        e1.printStackTrace();
984
                }
985

    
986
                return "'" + text + "'";
987
        }
988

    
989
        ///// END METHODS FOR TRANSLATE DATA IN FILTER SENTENCES /////
990

    
991
        ///// METHODS FOR MANIPULATE 'fields' and 'values' /////
992

    
993
        /**
994
         * DOCUMENT ME!
995
         *
996
         * @param t DOCUMENT ME!
997
         */
998
        public void setModel(ExpressionDataSource t) {
999
                try {
1000
                        model = t;
1001
            model.start();
1002
        } catch (ReadDriverException e1) {
1003
            NotificationManager.addError(e1.getMessage(), e1);
1004
        }
1005

    
1006
        try {
1007
                int numberOfFields = model.getFieldCount();
1008

    
1009
                if (numberOfFields > 0) {
1010
                        Vector fields = new Vector(0, 1);
1011
                        int j = 0;
1012

    
1013
                                for (int i = 0; i < numberOfFields; i++) {
1014
                                         Object field = model.getFieldName(i);
1015

    
1016
                                        if (field != null) {
1017
                                                fields.add(field);
1018

    
1019
                                                String completeFieldPath = this.getPathOfLeafWithoutRoot(field);
1020

    
1021
                                                if (! allFieldsAndValuesKnownOfCurrentLayer.containsKey(completeFieldPath) ) {
1022
                                                        allFieldsAndValuesKnownOfCurrentLayer.put(completeFieldPath, new HashMap());
1023
                                                }
1024

    
1025
                                                j++;
1026
                                        }
1027
                                }
1028

    
1029
                                fieldsTreeTableModel = new FieldsTreeTableModel(fields.toArray());
1030
                }
1031
                } catch (FilterException e) {
1032
                        throwException(e);
1033
                }
1034
        }
1035

    
1036
        /**
1037
         * If there is a field selected, show its new values
1038
         */
1039
        public void updateFieldValues() {
1040
                if (currentPath != null) {
1041

    
1042
                        DataReturnedOfDataLoadingFromActiveView data = DataLoadingFromActiveView.getDefaultExpressionDataSource();
1043

    
1044
                        if ((data != null) && (data.getData() != null)) {
1045
                                setModel(data.getData());
1046
                                fillValuesByPath(currentPath);
1047

    
1048
//                                valuesListModel.clear();
1049

    
1050
                                // Updates all tables that their data is about the changed view
1051
                                this.updateTablesThatHasNewData();
1052

    
1053
                                // Adjust JScrollPanes to the the beginning
1054
                                getFieldsJScrollPane().getHorizontalScrollBar().setValue(-1);
1055
                                getFieldsJScrollPane().getVerticalScrollBar().setValue(-1);
1056

    
1057
                                // Adjust JScrollPanes to the the beginning
1058
                                getValuesJScrollPane().getHorizontalScrollBar().setValue(-1);
1059
                                getValuesJScrollPane().getVerticalScrollBar().setValue(-1);
1060

    
1061
                                // Adjusts valuesJList to the default position
1062
                                getValuesJList().setSelectedIndex(-1); // No item selected
1063
                        }
1064
                }
1065
        }
1066

    
1067
        /**
1068
         * Sets Fields
1069
         *
1070
         * @param feature A Layer node with fields information
1071
         */
1072
        private boolean setFields(WFSLayerNode feature) {
1073
                Vector fields = feature.getFields();
1074

    
1075
                this.resetFieldsAndValuesData();
1076

    
1077
                int numberOfFields = fields.size();
1078

    
1079
                if (numberOfFields > 0) {
1080
                        Vector fieldBranches = new Vector(0, 1);
1081

    
1082
                        for (int i=0; i<fields.size(); i++) {
1083
                                XMLElement field = (XMLElement)fields.get(i);
1084

    
1085
                                IXMLType type = field.getEntityType();
1086

    
1087
                                if (type != null) {
1088

    
1089
                                        switch (type.getType()) {
1090
                                                case IXMLType.GML_GEOMETRY: // Don't add branch / field
1091
                                                        break;
1092
                                                case IXMLType.COMPLEX: case IXMLType.SIMPLE: // Add branch / field
1093
                                                        fieldBranches.add(field);
1094
                                                        break;
1095
                                        }
1096
                                }
1097
                        }
1098

    
1099
                        if (fieldBranches.size() > 0) {
1100
                                Object obj = fieldBranches.get(0);
1101

    
1102
                                fieldsTreeTableModel = new FieldsTreeTableModel(obj);
1103
                                fieldsJTree.setModel(new FieldsTreeTableModel(obj, false));
1104

    
1105
                                // Stores the name of all leafs (fields) of treeTableModel
1106
                                Object root = fieldsTreeTableModel.getRoot();
1107

    
1108
                                if (root != null) {
1109
                                        Vector fieldsNames = fieldsTreeTableModel.getLeafsFromNodeBranch(root);
1110

    
1111
                                        for (int j = 0; j < fieldsNames.size(); j++) {
1112
                                                Object field = fieldsNames.get(j);
1113

    
1114
                                                // Avoid errors
1115
                                                if ( (! (field instanceof XMLElement)) || (field == null) )        continue;
1116

    
1117
                                                // Don't load a geometry field
1118
                                                if (((XMLElement)field).getEntityType() != null){
1119
                                                        if ( ((XMLElement)field).getEntityType().getType() == IXMLType.GML_GEOMETRY ){
1120
                                                                continue;
1121
                                                        }
1122
                                                }
1123

    
1124
                                                String completeFieldPath = this.getPathOfLeafWithoutRoot(field);
1125

    
1126
                                                if (! allFieldsAndValuesKnownOfCurrentLayer.containsKey(completeFieldPath) ) {
1127
                                                        allFieldsAndValuesKnownOfCurrentLayer.put(completeFieldPath, new HashMap());
1128
                                                }
1129
                                        }
1130
                                }
1131
                        }
1132
                }
1133
                return true;
1134
        }
1135

    
1136
        /**
1137
         * This method load all values known of all fields known
1138
         * (It's used when a new layer is load)
1139
         */
1140
        private void setValuesKnownOfFields() {
1141
                // Desde el modelo se deber?a acceder a los campos y sus valores cargados
1142
                try {
1143
                        for (int i = 0; i < model.getFieldCount(); i++) {
1144
                                String fieldName = model.getFieldName(i);
1145
                                HashMap fieldValues = (HashMap) allFieldsAndValuesKnownOfCurrentLayer.get(fieldName);
1146

    
1147
                                if (fieldValues != null) {
1148
                                        for (int j = 0; j < model.getRowCount(); j++) {
1149
                                                Value value = model.getFieldValue(j, i);
1150

    
1151
                                                if (value instanceof NullValue)
1152
                                                    continue;
1153

    
1154
                                                Object obj = (Object)value;
1155

    
1156
                                                if (obj == null)
1157
                                                        continue;
1158

    
1159
                                                fieldValues.put(obj.toString(), obj.toString());
1160

    
1161
                                        }
1162
                                }
1163
                        }
1164
                }
1165
                catch (Exception e) {
1166
                        e.printStackTrace();
1167
                }
1168
        }
1169

    
1170
        /**
1171
         * Resets the data of fields and their values of the current layer feature, and removes the branches of JTree
1172
         */
1173
        private void resetFieldsAndValuesData() {
1174
                fieldsJTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
1175
                txtExpression.setText("");
1176
                ((DefaultListModel)valuesJList.getModel()).removeAllElements();
1177
        }
1178

    
1179
        /**
1180
         * FIlls list with the values of selected field
1181
         *
1182
         * @param treePath A path in the tree
1183
         */
1184
        private void fillValuesByPath(TreePath treePath) {
1185
                // Duplicates are removed
1186
                TreeSet conjunto = new TreeSet(new Comparator() {
1187
                        public int compare(Object o1, Object o2) {
1188
                                if ((o1 != null) && (o2 != null)) {
1189
                                        Value v2 = (Value) o2;
1190
                                        Value v1 = (Value) o1;
1191
                                        BooleanValue boolVal;
1192

    
1193
                                        try {
1194
                                                boolVal = (BooleanValue) (v1.greater(v2));
1195

    
1196
                                                if (boolVal.getValue()) {
1197
                                                        return 1;
1198
                                                }
1199

    
1200
                                                boolVal = (BooleanValue) (v1.less(v2));
1201

    
1202
                                                if (boolVal.getValue()) {
1203
                                                        return -1;
1204
                                                }
1205
                                        } catch (IncompatibleTypesException e) {
1206
                                                throw new RuntimeException(e);
1207
                                        }
1208
                                }
1209

    
1210
                                return 0;
1211
                        }
1212
                }); // For ordernation
1213

    
1214
                // Remove the previous items
1215
                valuesListModel.clear();
1216

    
1217
                try {
1218
                        //Object root = treePath.getPath()[0];
1219
                        XMLElement element = ((XMLElement)treePath.getLastPathComponent());
1220

    
1221
                        // Gets the values associated to the selected branch
1222
                        switch (element.getEntityType().getType()) {
1223
                                case IXMLType.SIMPLE:
1224

    
1225
                                        if(element.getParentElement().getParentElement() == null) {
1226
                                                // Find the selected field and try to obtein values related
1227
                                                for (int i = 0; i < model.getFieldCount(); i++) {
1228
                                                        String name = model.getFieldName(i);
1229

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

    
1235
                                                                        if (value instanceof NullValue)
1236
                                                                            continue;
1237

    
1238
                                                                        if (!conjunto.contains(value)) {
1239
                                                                                conjunto.add(value);
1240
                                                                        }
1241
                                                                }
1242

    
1243
                                                                break;
1244
                                                        }
1245
                                                }
1246
                                        }else{
1247
                                                //create a vector with the parent names from the leaf until the root
1248
                                                XMLElement parent = element.getParentElement();
1249
                                                Vector parentNames = new Vector();
1250
                                                parentNames.add(element.getName());
1251
                                                while (parent != null){
1252
                                                        parentNames.add(parent.getName());
1253
                                                        parent = parent.getParentElement();
1254
                                                }
1255

    
1256
                                                //The field name (in the gvSIG table) is the second field name
1257
                                                String fieldName = (String)parentNames.get(parentNames.size()-2);
1258

    
1259
                                                for (int i = 0; i < model.getFieldCount(); i++) {
1260
                                                        String name = model.getFieldName(i);
1261

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

    
1267
                                                                        if (value instanceof NullValue)
1268
                                                                            continue;
1269

    
1270
                                                                        if (value instanceof ComplexValue){
1271
                                                                                for (int k=parentNames.size()-3 ; k>=0 ; k--){
1272
                                                                                        ComplexValue complex = (ComplexValue)value;
1273
                                                                                        Value childValue = (Value)complex.get(parentNames.get(k));
1274
                                                                                        if (k==0){
1275
                                                                                                if (!conjunto.contains(childValue)) {
1276
                                                                                                        conjunto.add(childValue);
1277
                                                                                                }
1278
                                                                                        }else{
1279
                                                                                                value = childValue;
1280
                                                                                        }
1281
                                                                                }
1282
                                                                        }
1283
                                                                }
1284

    
1285
                                                                break;
1286
                                                        }
1287
                                                }
1288
                                        }
1289
                                        break;
1290
                                case IXMLType.COMPLEX:
1291
                                        break;
1292
                                default:
1293
                                        // Do Nothing
1294
                        }
1295

    
1296
                        // Add the values to the model of the graphic list
1297
                        Iterator it = conjunto.iterator();
1298
                        Object[] objects = currentPath.getPath();
1299

    
1300
                        if (objects.length == 0)
1301
                                return;
1302

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

    
1305
                        if (selectedField != null) { // If there is a selected field
1306
                                Map fieldValues = (HashMap)allFieldsAndValuesKnownOfCurrentLayer.get(selectedField); // Gets valus stored associated to this field
1307
                                JLabel currentValueLabel = null;
1308

    
1309
                                // If the field doesn't exits -> create a new Map with its values
1310
                                if (fieldValues == null) {
1311
                                        fieldValues = new HashMap();
1312
                                        allFieldsAndValuesKnownOfCurrentLayer.put(selectedField, fieldValues);
1313

    
1314
                                        while (it.hasNext()) {
1315
                                                // A label with text with yelow background color for values that are loaded in the layer
1316
                                                currentValueLabel = new JLabelAsCellValueLoaded();
1317

    
1318
                                                currentValueLabel.setText(it.next().toString());
1319

    
1320
                                                if (currentValueLabel.getText().compareTo("") != 0) {
1321
                                                        fieldValues.put(currentValueLabel.getText(), currentValueLabel.getText());
1322

    
1323
                                                        // All values loaded in this loop must be at beginning of the list (and in a differenciated color)
1324
                                                        if ( ! valuesListModel.contains(currentValueLabel) )
1325
                                                                valuesListModel.addElement(currentValueLabel);
1326
                                                }
1327
                                        }
1328
                                }
1329
                                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)
1330

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

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

    
1339
                                                if (elementPosition == -1) // If it must be added
1340
                                                        valuesListModel.addElement(new JLabelAsCellValueLoaded(text));
1341
                                                else
1342
                                                        ((DefaultListModelForJLabelAsCell)valuesListModel).changeElementThatHasTextToJLabelLoadedValue(text); // Change to 'JLabelLoadedValue'
1343
                                        }
1344
                                }
1345

    
1346
                                // Load the rest of the values associated to the current selected field
1347
                                if (fieldValues != null) {
1348
                                        // A label with text with yelow background color for values that are loaded in the layer
1349
                                        currentValueLabel = new JLabelAsCellValueNotLoaded();
1350

    
1351
                                        Set values = fieldValues.keySet();
1352

    
1353
                                        it = values.iterator();
1354

    
1355
                                        while (it.hasNext()) {
1356
                                                String name = it.next().toString();
1357

    
1358
                                                if ( ! ((DefaultListModelForJLabelAsCell)valuesListModel).containsJLabelText(name) )
1359
                                                        valuesListModel.addElement(new JLabelAsCellValueNotLoaded(name));
1360
                                        }
1361
                                }
1362
                        }
1363

    
1364
                } catch (Exception e) {
1365
                        throwException(e);
1366
                }
1367
        }
1368

    
1369
        ///// END METHODS FOR MANIPULATE 'fields' and 'values' /////
1370

    
1371
        ///// METHODS FOR PARENT NOTIFICATIONS /////
1372

    
1373
        //
1374
//        /**
1375
//         * @see WFSParamsPanel#isApplicable(boolean)
1376
//         *
1377
//         * This also loads values of fields
1378
//         *
1379
//         * @param b A boolean value
1380
//         */
1381
//        private void setApplicate(boolean b) {
1382
//                parent.isApplicable(b);
1383
//        }
1384

    
1385
        ///// END METHODS FOR PARENT NOTIFICATIONS /////
1386

    
1387
        ///// METHOS FOR 'allFieldsAndValuesKnownOfCurrentLayer' /////
1388

    
1389
        /**
1390
         * Sets all fields and values known about the current layer
1391
         *
1392
         * @param _allFieldsAndValuesKnownOfCurrentLayer A Map object
1393
         */
1394
        public void setAllFieldsAndValuesKnownOfCurrentLayer(Map _allFieldsAndValuesKnownOfCurrentLayer) {
1395
                if (_allFieldsAndValuesKnownOfCurrentLayer == null)
1396
                        this.allFieldsAndValuesKnownOfCurrentLayer = new HashMap();
1397
                else
1398
                        this.allFieldsAndValuesKnownOfCurrentLayer = _allFieldsAndValuesKnownOfCurrentLayer;
1399
        }
1400

    
1401
        /**
1402
         * Gets all fields and values known about the current layer
1403
         *
1404
         * @return _allFieldsAndValuesKnownOfCurrentLayer A Map object
1405
         */
1406
        public Map getAllFieldsAndValuesKnownOfCurrentLayer() {
1407
                return allFieldsAndValuesKnownOfCurrentLayer;
1408
        }
1409

    
1410
        ///// METHOS FOR 'allFieldsAndValuesKnownOfCurrentLayer' /////
1411

    
1412
        ///// UPDATE TABLES DATA /////
1413

    
1414
        /**
1415
         * Updates all tables that their data is about the changed view
1416
         */
1417
        private void updateTablesThatHasNewData() {
1418
                boolean oneTimeNewDataToTableAdded = false;
1419

    
1420
                IWindow[] activeNoModalWindows = PluginServices.getMDIManager().getAllWindows();
1421

    
1422
                for (int i = 0; i < activeNoModalWindows.length; i++) {
1423
                        IWindow window = activeNoModalWindows[i];
1424
                        if (window instanceof Table) {
1425
                                Table table = (Table) window;
1426

    
1427
                                int pos1 = featureName.indexOf(':');
1428

    
1429
                                if ((pos1 >= 0) && (pos1 < featureName.length()))
1430
                                        featureName = featureName.substring(pos1 +1, featureName.length());
1431

    
1432
//                                        String featureOfTable = ((XMLElement)currentPath.getParentPath().getLastPathComponent()).getName();
1433
                                        String featureOfTable = table.getModel().getName();
1434
                                        int pos2 = featureOfTable.indexOf(':');
1435

    
1436
                                        if ((pos2 >= 0) && (pos2 < featureName.length()))
1437
                                                featureOfTable = featureOfTable.substring(pos2 +1, featureOfTable.length());
1438

    
1439
                                if (featureName.trim().compareTo(featureOfTable.trim()) == 0) {
1440
                                        // Only add the new data associated to the table one time
1441
                                        if (oneTimeNewDataToTableAdded == false) {
1442
                                                setNewDataToTable();
1443
                                                oneTimeNewDataToTableAdded = true;
1444
                                        }
1445

    
1446
                                        // Refresh the table with the new data
1447
                                        table.refresh();
1448
                                }
1449
                        }
1450
                }
1451
        }
1452

    
1453
        /**
1454
         * This method is a modification of the "execute" method from the "ShowTable" class
1455
         *
1456
         * @see com.iver.cit.gvsig.ShowTable#execute(String)
1457
         */
1458
        private void setNewDataToTable() {
1459
                BaseView vista = (BaseView) PluginServices.getMDIManager().getActiveWindow();
1460
                FLayer[] actives = vista.getModel().getMapContext().getLayers().getActives();
1461

    
1462
                try {
1463
                        for (int i = 0; i < actives.length; i++) {
1464
                                if (actives[i] instanceof AlphanumericData) {
1465
                                        AlphanumericData co = (AlphanumericData) actives[i];
1466

    
1467
                                        //SelectableDataSource dataSource;
1468
                                        //dataSource = co.getRecordset();
1469

    
1470
                                        ProjectExtension ext = (ProjectExtension) PluginServices.getExtension(ProjectExtension.class);
1471

    
1472
                                        ProjectTable projectTable = ext.getProject().getTable(co);
1473
                                        EditableAdapter ea=null;
1474
                                        ReadableVectorial rv=((FLyrVect)actives[i]).getSource();
1475
                                        if (rv instanceof VectorialEditableAdapter){
1476
                                                ea=(EditableAdapter)((FLyrVect)actives[i]).getSource();
1477
                                        }else{
1478
                                                ea=new EditableAdapter();
1479
                                                SelectableDataSource sds=((FLyrVect)actives[i]).getRecordset();
1480
                                                ea.setOriginalDataSource(sds);
1481
                                        }
1482

    
1483
                                        if (projectTable == null) {
1484
                                                projectTable = ProjectFactory.createTable(PluginServices.getText(this, "Tabla_de_Atributos") + ": " + actives[i].getName(),
1485
                                                                ea);
1486
                                                projectTable.setProjectDocumentFactory(new ProjectTableFactory());
1487
                                                projectTable.setAssociatedTable(co);
1488
                                                ext.getProject().addDocument(projectTable);
1489
                                        }
1490
                                        projectTable.setModel(ea);
1491

    
1492
                                        // Removed part of code that created another (visual) table
1493
//                                        Table t = new Table();
1494
//                                        t.setModel(projectTable);
1495
//                                        PluginServices.getMDIManager().addWindow(t);
1496
                                }
1497
                        }
1498
                }catch (ReadDriverException e) {
1499
                        NotificationManager.addError(PluginServices.getText(this,"No_se_pudo_obtener_la_tabla_de_la_capa"), e);
1500
        }
1501
        }
1502

    
1503
        ///// END UPDATE TABLES DATA /////
1504

    
1505
        ///// OTHER METHODS /////
1506

    
1507
        /**
1508
         * DOCUMENT ME!
1509
         *
1510
         * @param expresion DOCUMENT ME!
1511
         * @param substring DOCUMENT ME!
1512
         * @param startingPos DOCUMENT ME!
1513
         *
1514
         * @return DOCUMENT ME!
1515
         */
1516
        private int getIndex(String expresion, String substring, int startingPos) {
1517
                int index = startingPos;
1518

    
1519
                do {
1520
                        index = expresion.indexOf(substring, index);
1521
                } while ((StringUtilities.isBetweenSymbols(expresion, index, "\"")) &&
1522
                                (index != -1));
1523

    
1524
                return index;
1525
        }
1526

    
1527
        /**
1528
         * DOCUMENT ME!
1529
         *
1530
         * @param arg0
1531
         *
1532
         * @return
1533
         */
1534
        public boolean addExpressionListener(ExpressionListener arg0) {
1535
                return expressionListeners.add(arg0);
1536
        }
1537

    
1538
        /**
1539
         * DOCUMENT ME!
1540
         *
1541
         * @param arg0
1542
         *
1543
         * @return
1544
         */
1545
        public boolean removeExpressionListener(ExpressionListener arg0) {
1546
                return expressionListeners.remove(arg0);
1547
        }
1548
        /**
1549
         * DOCUMENT ME!
1550
         *
1551
         * @param o DOCUMENT ME!
1552
         *
1553
         * @return DOCUMENT ME!
1554
         */
1555
        public boolean removeExceptionListener(ExceptionListener o) {
1556
                return exceptionHandlingSupport.removeExceptionListener(o);
1557
        }
1558

    
1559
        /**
1560
         * DOCUMENT ME!
1561
         *
1562
         * @param t DOCUMENT ME!
1563
         */
1564
        private void throwException(Throwable t) {
1565
                exceptionHandlingSupport.throwException(t);
1566
        }
1567

    
1568
        ///// END OTHER METHODS /////
1569
}