Statistics
| Revision:

root / branches / v2_0_0_prep / applications / appgvSIG / src / org / gvsig / app / gui / filter / FilterDialog.java @ 33205

History | View | Annotate | Download (17.3 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.app.gui.filter;
42

    
43
import java.awt.event.MouseAdapter;
44
import java.awt.event.MouseEvent;
45
import java.text.NumberFormat;
46
import java.text.ParseException;
47
import java.util.ArrayList;
48
import java.util.Collection;
49
import java.util.Comparator;
50
import java.util.Date;
51
import java.util.Iterator;
52
import java.util.TreeSet;
53
import java.util.regex.Matcher;
54
import java.util.regex.Pattern;
55

    
56
import javax.swing.tree.DefaultMutableTreeNode;
57
import javax.swing.tree.DefaultTreeModel;
58

    
59
import org.gvsig.andami.PluginServices;
60
import org.gvsig.andami.messages.NotificationManager;
61
import org.gvsig.andami.ui.mdiManager.IWindow;
62
import org.gvsig.andami.ui.mdiManager.IWindowListener;
63
import org.gvsig.andami.ui.mdiManager.WindowInfo;
64
import org.gvsig.fmap.dal.exception.DataException;
65
import org.gvsig.tools.dispose.DisposableIterator;
66
import org.gvsig.fmap.dal.feature.Feature;
67
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
68
import org.gvsig.fmap.dal.feature.FeatureQuery;
69
import org.gvsig.fmap.dal.feature.FeatureSet;
70
import org.gvsig.fmap.dal.feature.FeatureStore;
71
import org.gvsig.gui.beans.filterPanel.tableFilterQueryPanel.TableFilterQueryJPanel;
72
import org.gvsig.tools.dispose.DisposeUtils;
73
import org.gvsig.utils.DefaultCharSet;
74
import org.gvsig.utils.StringUtilities;
75
import org.gvsig.utils.exceptionHandling.ExceptionHandlingSupport;
76
import org.gvsig.utils.exceptionHandling.ExceptionListener;
77
import org.slf4j.Logger;
78
import org.slf4j.LoggerFactory;
79

    
80

    
81
/**
82
 * This class substitutes the old "FilterDialog" class made by "Fernando Gonz?lez Cort?s"
83
 * The functionality is the same, but now the class is made from separately (and reusable) components
84
 *
85
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
86
 */
87
public class FilterDialog extends TableFilterQueryJPanel implements IWindow, IWindowListener {
88
    private static final Logger logger = LoggerFactory
89
            .getLogger(FilterDialog.class);
90
        private FeatureStore model = null;
91
        private ArrayList expressionListeners = new ArrayList();
92
        private ExceptionHandlingSupport exceptionHandlingSupport = new ExceptionHandlingSupport();
93
        private NumberFormat nf = NumberFormat.getNumberInstance();
94

    
95
        private String title;
96

    
97
        private final int filterDialog_Width = 500;
98
        private final int filterDialog_Height = 362;
99
        private final int widthIncrementForAndami = 20; // This is necessary because when the panel is sent to Andami, that needs a bit more width-space to show that panel.
100

    
101

    
102
        /**
103
         * This is the default constructor
104
         */
105
        public FilterDialog(String _title) {
106
                super();
107
                title = _title;
108
                defaultTreeModel = (DefaultTreeModel)fieldsJTree.getModel();
109
        }
110
        /**
111
         * This is the default constructor
112
         */
113
        public FilterDialog() {
114
                super();
115
                defaultTreeModel = (DefaultTreeModel)fieldsJTree.getModel();
116
        }
117

    
118
        /*
119
         *  (non-Javadoc)
120
         * @see org.gvsig.gui.beans.filterPanel.AbstractFilterQueryJPanel#initialize()
121
         */
122
        protected void initialize() {
123
                super.initialize();
124

    
125
                super.resizeHeight(filterDialog_Height);
126
                super.resizeWidth(filterDialog_Width - widthIncrementForAndami);
127

    
128
                this.addNewListeners();
129
        }
130

    
131
        /**
132
         * Adds some listeners
133
         */
134
        private void addNewListeners() {
135
                // Listener for "btnAdd"
136
                // Adds more elements to the current set
137
                getBtnAddToCurrentSet().addActionListener(new java.awt.event.ActionListener() {
138
                        /*
139
                         *  (non-Javadoc)
140
                         * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
141
                         */
142
                        public void actionPerformed(java.awt.event.ActionEvent e) {
143
//                                final String expr = "select * from '" +
144
//                                        model.getName() + "' where " +
145
//                                        getTxtExpression().getText() + ";";
146
                                final String expr = getTxtExpression().getText();
147
                                logger.debug(expr);
148

    
149
                                PluginServices.backgroundExecution(new Runnable() {
150
                                                public void run() {
151
                                                        for (int i = 0;
152
                                                                        i < expressionListeners.size();
153
                                                                        i++) {
154
                                                                ExpressionListener l = (ExpressionListener) expressionListeners.get(i);
155
                                                                try {
156
                                                                                l.addToSet(expr);
157
                                                                        } catch (DataException e) {
158
                                                                                e.printStackTrace();
159
                                                                        }
160
                                                        }
161
                                                }
162
                                        });
163
                        }
164
                });
165

    
166
                // Listener for "btnNuevo"
167
                // Adds a new set
168
                getBtnNewSet().addActionListener(new java.awt.event.ActionListener() {
169
                        public void actionPerformed(java.awt.event.ActionEvent e) {
170
//                                final String expr = "select * from '" +
171
//                                        model.getName() + "' where " +
172
//                                        getTxtExpression().getText() + ";";
173
                                final String expr = getTxtExpression().getText();
174

    
175
                                logger.debug(expr);
176

    
177
                                PluginServices.backgroundExecution(new Runnable() {
178
                                        public void run() {
179
                                                for (int i = 0; i < expressionListeners.size(); i++) {
180
                                                        ExpressionListener l = (ExpressionListener) expressionListeners.get(i);
181
                                                        try {
182
                                                                l.newSet(expr);
183
                                                        } catch (DataException e) {
184
                                                                // TODO Auto-generated catch block
185
                                                                NotificationManager.addError(e);
186
                                                        }
187
                                                }
188
                                        }
189
                                });
190
                        }
191
                });
192

    
193
                // Listener for "btnFromSet"
194
                // Selects elements in the table that are according the current filter condition
195
                getBtnFromSet().addActionListener(new java.awt.event.ActionListener() {
196
                        public void actionPerformed(java.awt.event.ActionEvent e) {
197
//                                final String expr = "select * from '" +
198
//                                        model.getName() + "' where " +
199
//                                        getTxtExpression().getText() + ";";
200
                                final String expr = getTxtExpression().getText();
201
                                logger.debug(expr);
202

    
203
                                PluginServices.backgroundExecution(new Runnable() {
204
                                        public void run() {
205
                                                for (int i = 0; i < expressionListeners.size(); i++) {
206
                                                        ExpressionListener l = (ExpressionListener) expressionListeners.get(i);
207
                                                        try {
208
                                                                l.fromSet(expr);
209
                                                        } catch (DataException e) {
210
                                                                NotificationManager.addError(e);
211
                                                        }
212
                                                }
213
                                        }
214
                                });
215
                        }
216
                });
217

    
218
                // Listener for "fieldsJTree"
219
                getFieldsJTree().addMouseListener(new MouseAdapter() {
220
                        /*
221
                         *  (non-Javadoc)
222
                         * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
223
                         */
224
                        public void mouseClicked(MouseEvent e) {
225
                                int row = fieldsJTree.getRowForLocation(e.getX(), e.getY());
226

    
227
                                if (row > -1) {
228
                                        switch (e.getClickCount()) {
229
                                                case 1:
230
                                                        fillValues(row);
231
                                                        break;
232
                                                case 2:
233
                                                        putSymbol(jtreeRoot.getChildAt(row).toString());
234
                                                        break;
235
                                        }
236
                                }
237
                        }
238
                });
239

    
240
                // Listener for "valuesJList"
241
                getValuesJList().addMouseListener(new MouseAdapter() {
242
                        /*
243
                         *  (non-Javadoc)
244
                         * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
245
                         */
246
                        public void mouseClicked(MouseEvent e) {
247
                                if (e.getClickCount() == 2) {
248
                                        Object valor = valuesListModel.getElementAt(getValuesJList().getSelectedIndex());
249

    
250
                                        if (valor instanceof Date) {
251
                                                putSymbol("date('" + valor + "')");
252
                                        } else if (valor instanceof Boolean) {
253
                                                putSymbol("boolean('" + valor.toString() + "')");
254
                                        } else if (valor instanceof String) {
255
                                                putSymbol("'" + valor + "'");
256
                                        } else {
257
                                                putSymbol(valor.toString());
258
                                        }
259
                                }
260
                        }
261
                });
262
        }
263

    
264
        /**
265
         * Rellena la lista con los valores del campo seleccionado
266
         */
267
        private void fillValues(int row) {
268
                //int index = lstCampos.getSelectedIndex();
269

    
270
                //Index es ahora el ?ndice del campo seleccionado
271
                //Se eliminan los duplicados
272
                Collection conjunto = new TreeSet(new Comparator() {
273
                        public int compare(Object o1, Object o2) {
274
                                return ((Comparable)o1).compareTo(o2);
275
                        }
276
                }); // Para poder ordenar
277

    
278

    
279
                valuesListModel.clear();
280
                FeatureSet fs = null;
281
                DisposableIterator iterator = null;
282
                try {
283
                        String[] fieldName = new String[] {
284
                                ((FeatureAttributeDescriptor)model.getDefaultFeatureType().get(row)).getName()
285
                                };
286

    
287

    
288
                        FeatureQuery query = model.createFeatureQuery();
289
                        query.setAttributeNames(fieldName);
290
                        fs = model.getFeatureSet(query);
291
                        iterator = fs.iterator();
292
                        while (iterator.hasNext()) {
293
                                Feature feature = (Feature) iterator.next();
294
                                Object value = feature.get(fieldName[0]);
295
                                if (value == null) {
296
                                        continue;
297
                                }
298

    
299
                                conjunto.add(value);
300
                        }
301

    
302
                        Iterator it = conjunto.iterator();
303

    
304
                        while (it.hasNext()) {
305
                                valuesListModel.addElement(it.next());
306
                        }
307
                } catch (DataException e) {
308
                        throwException(e);
309
                } finally {
310
                        DisposeUtils.dispose(iterator);
311
                        DisposeUtils.dispose(fs);
312
                }
313
        }
314

    
315
        /**
316
         * DOCUMENT ME!
317
         *
318
         * @param t DOCUMENT ME!
319
         */
320
        public void setModel(FeatureStore t) {
321
//                try {
322
                        model = t;
323
//            model.start();
324
//        } catch (ReadException e1) {
325
//            NotificationManager.addError(e1.getMessage(), e1);
326
//        }
327

    
328
        jtreeRoot.removeAllChildren();
329

    
330
        try {
331
                Iterator attributes=model.getDefaultFeatureType().iterator();
332
                while (attributes.hasNext()) {
333
                                FeatureAttributeDescriptor descriptor = (FeatureAttributeDescriptor) attributes.next();
334
                                Object field = descriptor.getName();
335

    
336
                                if (field != null) {
337
                                        jtreeRoot.add(new DefaultMutableTreeNode(field.toString()));
338
                                }
339
                        }
340
//                for (int i = 0; i < model.getFieldCount(); i++) {
341
//                                Object field = model.getFieldName(i);
342
//
343
//                                if (field != null) {
344
//                                        jtreeRoot.add(new DefaultMutableTreeNode(field.toString()));
345
//                                }
346
//                        }
347

    
348
                        defaultTreeModel.setRoot(jtreeRoot);
349
                } catch (DataException e) {
350
                        throwException(e);
351
                }
352
        }
353

    
354
                /**
355
                 * DOCUMENT ME!
356
                 *
357
                 * @return DOCUMENT ME!
358
                 *
359
                 * @throws ParseException DOCUMENT ME!
360
                 */
361
                private String validateExpression() throws ParseException {
362
                        String expression = txtExpression.getText();
363
        //                HashSet variablesIndexes = new HashSet();
364
        //
365
        //                StringBuffer traducida = new StringBuffer();
366

    
367
                        //Se transforman los nombres de los campos en las variables xix que analizar?n
368
                        //Se quitan los Date(fecha) y se mete la fecha correspondiente
369
                        expression = translateDates(expression);
370
                        expression = translateNumber(expression);
371
                        expression = translateWord(expression, "true", "1");
372
                        expression = translateWord(expression, "false", "0");
373

    
374
                        String replacement;
375
                        Pattern patron = Pattern.compile("[^<>!]=");
376
                        Matcher m = patron.matcher(expression);
377
                        int index = 0;
378

    
379
                        while (m.find(index)) {
380
                                index = m.start();
381
                                replacement = expression.charAt(index) + "==";
382
                                m.replaceFirst(replacement);
383
                                index++;
384
                        }
385

    
386
                        expression = expression.replaceAll("[^<>!]=", "==");
387

    
388
                        logger.debug(expression);
389

    
390
                        return expression;
391
                }
392
        /**
393
         * Redefinition of the 'putSymbol' method of AbstractFilterQueryJPanel
394
         *   (I've made this redefinition for write the same code as the 'putSymbol'
395
         *    code of the original class (FilterDialog) that was in this project
396
         *    (appgvSIG) and didn't has path troubles to find 'StringUtilities').
397
         *
398
         * Sets a symbol on the filter expression (JTextArea that stores and shows
399
         *   the current filter expression)
400
         *
401
         * @param symbol A symbol: character, characters, number, ...
402
         */
403
        protected void putSymbol(String symbol) {
404
                int position = txtExpression.getCaretPosition();
405
                txtExpression.setText(StringUtilities.insert(txtExpression.getText(),
406
                                position, symbol));
407

    
408
                if (symbol.equals(" () ")) {
409
                        position = position + 2;
410
                } else {
411
                        position = position + symbol.length();
412
                }
413

    
414
                txtExpression.setCaretPosition(position);
415
        }
416

    
417
        /**
418
         * DOCUMENT ME!
419
         *
420
         * @param expresion DOCUMENT ME!
421
         * @param substring DOCUMENT ME!
422
         * @param startingPos DOCUMENT ME!
423
         *
424
         * @return DOCUMENT ME!
425
         */
426
        private int getIndex(String expresion, String substring, int startingPos) {
427
                int index = startingPos;
428

    
429
                do {
430
                        index = expresion.indexOf(substring, index);
431
                } while ((StringUtilities.isBetweenSymbols(expresion, index, "\"")) &&
432
                                (index != -1));
433

    
434
                return index;
435
        }
436

    
437
        /**
438
         * DOCUMENT ME!
439
         *
440
         * @param expresion DOCUMENT ME!
441
         * @param word DOCUMENT ME!
442
         * @param translation DOCUMENT ME!
443
         *
444
         * @return DOCUMENT ME!
445
         *
446
         * @throws ParseException DOCUMENT ME!
447
         */
448
        private String translateWord(String expresion, String word,
449
                String translation) throws ParseException {
450
                int booleanIndex = 0;
451
                int endIndex = 0;
452
                StringBuffer res = new StringBuffer();
453

    
454
                while ((booleanIndex = getIndex(expresion, word, booleanIndex)) != -1) {
455
                        res.append(expresion.substring(endIndex, booleanIndex));
456
                        endIndex = booleanIndex + word.length();
457
                        booleanIndex++;
458
                        res.append(translation);
459
                }
460

    
461
                if (endIndex < expresion.length()) {
462
                        res.append(expresion.substring(endIndex));
463
                }
464

    
465
                return res.toString();
466
        }
467

    
468
        /**
469
         * DOCUMENT ME!
470
         *
471
         * @param expresion DOCUMENT ME!
472
         *
473
         * @return DOCUMENT ME!
474
         *
475
         * @throws ParseException DOCUMENT ME!
476
         */
477
        private String translateDates(String expresion) throws ParseException {
478
                //Se obtiene el valor de la fecha
479
                String date = StringUtilities.substringDelimited(expresion, "Date(",
480
                                ")", 0);
481

    
482
                if (date == null) {
483
                        return expresion;
484
                }
485

    
486
                //Se comprueba que no est? entre comillas
487
                int startIndex = expresion.indexOf(date);
488

    
489
                while (startIndex != -1) {
490
                        if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
491
                                //Se sustituye por el valor ordinal de la fecha
492
                                expresion = expresion.substring(0, startIndex - 5) +
493
                                        expresion.substring(startIndex).replaceFirst(date + "\\)",
494
                                                new Long((filterButtonsJPanel.getDateFormat().parse(date)).getTime()).toString());
495
                                ;
496
                        } else {
497
                                startIndex += date.length();
498
                        }
499

    
500
                        //Se obtiene el valor de la fecha
501

    
502
                        /*            date = StringUtilities.substringDelimited(expresion, "Date(", ")",
503
                           startIndex);
504
                         */
505
                        if (date == null) {
506
                                return expresion;
507
                        }
508

    
509
                        startIndex = expresion.indexOf(date, startIndex);
510
                }
511

    
512
                return expresion;
513
        }
514

    
515
        /**
516
         * DOCUMENT ME!
517
         *
518
         * @param expresion DOCUMENT ME!
519
         *
520
         * @return DOCUMENT ME!
521
         *
522
         * @throws ParseException DOCUMENT ME!
523
         */
524
        public String translateNumber(String expresion) throws ParseException {
525
                DefaultCharSet ss = new DefaultCharSet();
526
                ss.addInterval('0', '9');
527
                ss.addCharacter(',');
528
                ss.addCharacter('.');
529

    
530
                String number = StringUtilities.substringWithSymbols(expresion, ss, 0);
531

    
532
                if (number == null) {
533
                        return expresion;
534
                }
535

    
536
                int startIndex = expresion.indexOf(number);
537

    
538
                while (startIndex != -1) {
539
                        Number n = nf.parse(number);
540

    
541
                        if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
542
                                //Se sustituye por el valor ordinal de la fecha
543
                                expresion = expresion.substring(0, startIndex) +
544
                                        expresion.substring(startIndex).replaceFirst(number,
545
                                                n.toString());
546
                        } else {
547
                                startIndex += n.toString().length();
548
                        }
549

    
550
                        number = StringUtilities.substringWithSymbols(expresion, ss,
551
                                        startIndex);
552

    
553
                        if (number == null) {
554
                                return expresion;
555
                        }
556

    
557
                        startIndex = expresion.indexOf(number, startIndex);
558
                }
559

    
560
                return expresion;
561
        }
562

    
563
        /**
564
         * DOCUMENT ME!
565
         *
566
         * @param arg0
567
         *
568
         * @return
569
         */
570
        public boolean addExpressionListener(ExpressionListener arg0) {
571
                return expressionListeners.add(arg0);
572
        }
573

    
574
        /**
575
         * DOCUMENT ME!
576
         *
577
         * @param arg0
578
         *
579
         * @return
580
         */
581
        public boolean removeExpressionListener(ExpressionListener arg0) {
582
                return expressionListeners.remove(arg0);
583
        }
584

    
585
        /**
586
         * @see com.iver.mdiApp.ui.MDIManager.IWindow#getWindowInfo()
587
         */
588
        public WindowInfo getWindowInfo() {
589
                WindowInfo vi = new WindowInfo(WindowInfo.ICONIFIABLE);
590

    
591
                //if (System.getProperty("os.name")co.compareTo(arg0))
592
                vi.setHeight(this.filterDialog_Height);
593
                vi.setWidth(this.filterDialog_Width);
594

    
595
                // Old instructions
596
//                vi.setWidth(480);
597
//                vi.setHeight(362);
598
                vi.setTitle(PluginServices.getText( this, "filtro") + " (" + title + ")");
599
                return vi;
600
        }
601

    
602
        /**
603
         * DOCUMENT ME!
604
         *
605
         * @param o DOCUMENT ME!
606
         */
607
        public void addExceptionListener(ExceptionListener o) {
608
                exceptionHandlingSupport.addExceptionListener(o);
609
        }
610

    
611
        /**
612
         * DOCUMENT ME!
613
         *
614
         * @param o DOCUMENT ME!
615
         *
616
         * @return DOCUMENT ME!
617
         */
618
        public boolean removeExceptionListener(ExceptionListener o) {
619
                return exceptionHandlingSupport.removeExceptionListener(o);
620
        }
621

    
622
        /**
623
         * DOCUMENT ME!
624
         *
625
         * @param t DOCUMENT ME!
626
         */
627
        private void throwException(Throwable t) {
628
                exceptionHandlingSupport.throwException(t);
629
        }
630

    
631
    /* (non-Javadoc)
632
     * @see com.iver.andami.ui.mdiManager.ViewListener#viewActivated()
633
     */
634
    public void windowActivated() {
635
    }
636

    
637
    /* (non-Javadoc)
638
     * @see com.iver.andami.ui.mdiManager.ViewListener#viewClosed()
639
     */
640
    public void windowClosed() {
641
//        try {
642
//            model.stop();
643
//        } catch (ReadDriverException e) {
644
//            NotificationManager.addError(e.getMessage(), e);
645
//        }
646
    }
647

    
648
    public Object getWindowProfile() {
649
                return WindowInfo.TOOL_PROFILE;
650
        }
651
}