Statistics
| Revision:

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

History | View | Annotate | Download (22.1 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.slf4j.Logger;
60
import org.slf4j.LoggerFactory;
61

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

    
81
/**
82
 * This class substitutes the old "FilterDialog" class made by
83
 * "Fernando Gonz?lez Cort?s"
84
 * The functionality is the same, but now the class is made from separately (and
85
 * reusable) components
86
 * 
87
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
88
 */
89
public class FilterDialog extends TableFilterQueryJPanel implements IWindow,
90
    IWindowListener {
91

    
92
    /**
93
     * 
94
     */
95
    private static final long serialVersionUID = -149317534873551735L;
96
    private static final Logger logger =
97
        LoggerFactory.getLogger(FilterDialog.class);
98
    private FeatureStore model = null;
99
    private ArrayList expressionListeners = new ArrayList();
100
    private ExceptionHandlingSupport exceptionHandlingSupport =
101
        new ExceptionHandlingSupport();
102
    private NumberFormat nf = NumberFormat.getNumberInstance();
103

    
104
    private String title;
105

    
106
    private final int filterDialog_Width = 500;
107
    private final int filterDialog_Height = 362;
108
    private final int widthIncrementForAndami = 20; // This is necessary because
109
                                                    // when the panel is sent to
110
                                                    // Andami, that needs a bit
111
                                                    // more width-space to show
112
                                                    // that panel.
113

    
114
    /**
115
     * This is the default constructor
116
     */
117
    public FilterDialog(String _title) {
118
        super();
119
        title = _title;
120
        defaultTreeModel = (DefaultTreeModel) fieldsJTree.getModel();
121
    }
122

    
123
    /**
124
     * This is the default constructor
125
     */
126
    public FilterDialog() {
127
        super();
128
        defaultTreeModel = (DefaultTreeModel) fieldsJTree.getModel();
129
    }
130

    
131
    /*
132
     * (non-Javadoc)
133
     * 
134
     * @see
135
     * org.gvsig.gui.beans.filterPanel.AbstractFilterQueryJPanel#initialize()
136
     */
137
    @Override
138
    protected void initialize() {
139
        super.initialize();
140

    
141
        super.resizeHeight(filterDialog_Height);
142
        super.resizeWidth(filterDialog_Width - widthIncrementForAndami);
143

    
144
        this.addNewListeners();
145
    }
146

    
147
    /**
148
     * Adds some listeners
149
     */
150
    private void addNewListeners() {
151
        // Listener for "btnAdd"
152
        // Adds more elements to the current set
153
        getBtnAddToCurrentSet().addActionListener(
154
            new java.awt.event.ActionListener() {
155

    
156
                /*
157
                 * (non-Javadoc)
158
                 * 
159
                 * @see
160
                 * java.awt.event.ActionListener#actionPerformed(java.awt.event
161
                 * .ActionEvent)
162
                 */
163
                public void actionPerformed(java.awt.event.ActionEvent e) {
164
                    // final String expr = "select * from '" +
165
                    // model.getName() + "' where " +
166
                    // getTxtExpression().getText() + ";";
167
                    final String expr = getTxtExpression().getText();
168
                    logger.debug(expr);
169

    
170
                    PluginServices.backgroundExecution(new Runnable() {
171

    
172
                        public void run() {
173
                            for (int i = 0; i < expressionListeners.size(); i++) {
174
                                ExpressionListener l =
175
                                    (ExpressionListener) expressionListeners
176
                                        .get(i);
177
                                try {
178
                                    l.addToSet(expr);
179
                                } catch (DataException e) {
180
                                    e.printStackTrace();
181
                                }
182
                            }
183
                        }
184
                    });
185
                }
186
            });
187

    
188
        // Listener for "btnNuevo"
189
        // Adds a new set
190
        getBtnNewSet().addActionListener(new java.awt.event.ActionListener() {
191

    
192
            public void actionPerformed(java.awt.event.ActionEvent e) {
193
                // final String expr = "select * from '" +
194
                // model.getName() + "' where " +
195
                // getTxtExpression().getText() + ";";
196
                final String expr = getTxtExpression().getText();
197

    
198
                logger.debug(expr);
199

    
200
                PluginServices.backgroundExecution(new Runnable() {
201

    
202
                    public void run() {
203
                        for (int i = 0; i < expressionListeners.size(); i++) {
204
                            ExpressionListener l =
205
                                (ExpressionListener) expressionListeners.get(i);
206
                            try {
207
                                l.newSet(expr);
208
                            } catch (DataException e) {
209
                                // TODO Auto-generated catch block
210
                                NotificationManager.addError(e);
211
                            }
212
                        }
213
                    }
214
                });
215
            }
216
        });
217

    
218
        // Listener for "btnFromSet"
219
        // Selects elements from the current filtered selection
220
        getBtnFromSet().addActionListener(new java.awt.event.ActionListener() {
221

    
222
            public void actionPerformed(java.awt.event.ActionEvent e) {
223
                // final String expr = "select * from '" +
224
                // model.getName() + "' where " +
225
                // getTxtExpression().getText() + ";";
226
                final String expr = getTxtExpression().getText();
227
                logger.debug(expr);
228

    
229
                PluginServices.backgroundExecution(new Runnable() {
230

    
231
                    public void run() {
232
                        for (int i = 0; i < expressionListeners.size(); i++) {
233
                            ExpressionListener l =
234
                                (ExpressionListener) expressionListeners.get(i);
235
                            try {
236
                                l.fromSet(expr);
237
                            } catch (DataException e) {
238
                                NotificationManager.addError(e);
239
                            }
240
                        }
241
                    }
242
                });
243
            }
244
        });
245

    
246
        // Listener for "fieldsJTree"
247
        getFieldsJTree().addMouseListener(new MouseAdapter() {
248

    
249
            /*
250
             * (non-Javadoc)
251
             * 
252
             * @see
253
             * java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent
254
             * )
255
             */
256
            @Override
257
            public void mouseClicked(MouseEvent e) {
258
                int row = fieldsJTree.getRowForLocation(e.getX(), e.getY());
259

    
260
                if (row > -1) {
261
                    switch (e.getClickCount()) {
262
                    case 1:
263
                        fillValues(row);
264
                        break;
265
                    case 2:
266
                        putSymbol(jtreeRoot.getChildAt(row).toString());
267
                        break;
268
                    }
269
                }
270
            }
271
        });
272

    
273
        // Listener for "valuesJList"
274
        getValuesJList().addMouseListener(new MouseAdapter() {
275

    
276
            /*
277
             * (non-Javadoc)
278
             * 
279
             * @see
280
             * java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent
281
             * )
282
             */
283
            @Override
284
            public void mouseClicked(MouseEvent e) {
285
                if (e.getClickCount() == 2) {
286
                    Object valor =
287
                        valuesListModel.getElementAt(getValuesJList()
288
                            .getSelectedIndex());
289

    
290
                    if (valor instanceof Date) {
291
                        putSymbol("date('" + valor + "')");
292
                    } else
293
                        if (valor instanceof Boolean) {
294
                            putSymbol("boolean('" + valor.toString() + "')");
295
                        } else
296
                            if (valor instanceof String) {
297
                                putSymbol("'" + valor + "'");
298
                            } else {
299
                                putSymbol(valor.toString());
300
                            }
301
                }
302
            }
303
        });
304
    }
305

    
306
    /**
307
     * Rellena la lista con los valores del campo seleccionado
308
     */
309
    private void fillValues(int row) {
310
        // int index = lstCampos.getSelectedIndex();
311

    
312
        // Index es ahora el ?ndice del campo seleccionado
313
        // Se eliminan los duplicados
314
        Collection conjunto = new TreeSet(new Comparator() {
315

    
316
            public int compare(Object o1, Object o2) {
317
                return ((Comparable) o1).compareTo(o2);
318
            }
319
        }); // Para poder ordenar
320

    
321
        valuesListModel.clear();
322
        FeatureSet fs = null;
323
        DisposableIterator iterator = null;
324
        try {
325
            String[] fieldName =
326
                new String[] { ((FeatureAttributeDescriptor) model
327
                    .getDefaultFeatureType().get(row)).getName() };
328

    
329
            FeatureQuery query = model.createFeatureQuery();
330
            query.setAttributeNames(fieldName);
331
            fs = model.getFeatureSet(query);
332
            iterator = fs.iterator();
333
            while (iterator.hasNext()) {
334
                Feature feature = (Feature) iterator.next();
335
                Object value = feature.get(fieldName[0]);
336
                if (value == null) {
337
                    continue;
338
                }
339

    
340
                conjunto.add(value);
341
            }
342

    
343
            Iterator it = conjunto.iterator();
344

    
345
            while (it.hasNext()) {
346
                valuesListModel.addElement(it.next());
347
            }
348
        } catch (DataException e) {
349
            throwException(e);
350
        } finally {
351
            DisposeUtils.dispose(iterator);
352
            DisposeUtils.dispose(fs);
353
        }
354
    }
355

    
356
    /**
357
     * DOCUMENT ME!
358
     * 
359
     * @param t
360
     *            DOCUMENT ME!
361
     */
362
    public void setModel(FeatureStore t) {
363
        // try {
364
        model = t;
365
        // model.start();
366
        // } catch (ReadException e1) {
367
        // NotificationManager.addError(e1.getMessage(), e1);
368
        // }
369

    
370
        jtreeRoot.removeAllChildren();
371

    
372
        try {
373
            Iterator attributes = model.getDefaultFeatureType().iterator();
374
            while (attributes.hasNext()) {
375
                FeatureAttributeDescriptor descriptor =
376
                    (FeatureAttributeDescriptor) attributes.next();
377
                Object field = descriptor.getName();
378

    
379
                if (field != null) {
380
                    jtreeRoot.add(new DefaultMutableTreeNode(field.toString()));
381
                }
382
            }
383
            // for (int i = 0; i < model.getFieldCount(); i++) {
384
            // Object field = model.getFieldName(i);
385
            //
386
            // if (field != null) {
387
            // jtreeRoot.add(new DefaultMutableTreeNode(field.toString()));
388
            // }
389
            // }
390

    
391
            defaultTreeModel.setRoot(jtreeRoot);
392
        } catch (DataException e) {
393
            throwException(e);
394
        }
395
    }
396

    
397
    /**
398
     * DOCUMENT ME!
399
     * 
400
     * @return DOCUMENT ME!
401
     * 
402
     * @throws ParseException
403
     *             DOCUMENT ME!
404
     */
405
    private String validateExpression() throws ParseException {
406
        String expression = txtExpression.getText();
407
        // HashSet variablesIndexes = new HashSet();
408
        //
409
        // StringBuffer traducida = new StringBuffer();
410

    
411
        // Se transforman los nombres de los campos en las variables xix que
412
        // analizar?n
413
        // Se quitan los Date(fecha) y se mete la fecha correspondiente
414
        expression = translateDates(expression);
415
        expression = translateNumber(expression);
416
        expression = translateWord(expression, "true", "1");
417
        expression = translateWord(expression, "false", "0");
418

    
419
        String replacement;
420
        Pattern patron = Pattern.compile("[^<>!]=");
421
        Matcher m = patron.matcher(expression);
422
        int index = 0;
423

    
424
        while (m.find(index)) {
425
            index = m.start();
426
            replacement = expression.charAt(index) + "==";
427
            m.replaceFirst(replacement);
428
            index++;
429
        }
430

    
431
        expression = expression.replaceAll("[^<>!]=", "==");
432

    
433
        logger.debug(expression);
434

    
435
        return expression;
436
    }
437

    
438
    /**
439
     * Redefinition of the 'putSymbol' method of AbstractFilterQueryJPanel
440
     * (I've made this redefinition for write the same code as the 'putSymbol'
441
     * code of the original class (FilterDialog) that was in this project
442
     * (appgvSIG) and didn't has path troubles to find 'StringUtilities').
443
     * 
444
     * Sets a symbol on the filter expression (JTextArea that stores and shows
445
     * the current filter expression)
446
     * 
447
     * @param symbol
448
     *            A symbol: character, characters, number, ...
449
     */
450
    @Override
451
    protected void putSymbol(String symbol) {
452
        int position = txtExpression.getCaretPosition();
453
        txtExpression.setText(StringUtilities.insert(txtExpression.getText(),
454
            position, symbol));
455

    
456
        if (symbol.equals(" () ")) {
457
            position = position + 2;
458
        } else {
459
            position = position + symbol.length();
460
        }
461

    
462
        txtExpression.setCaretPosition(position);
463
    }
464

    
465
    /**
466
     * DOCUMENT ME!
467
     * 
468
     * @param expresion
469
     *            DOCUMENT ME!
470
     * @param substring
471
     *            DOCUMENT ME!
472
     * @param startingPos
473
     *            DOCUMENT ME!
474
     * 
475
     * @return DOCUMENT ME!
476
     */
477
    private int getIndex(String expresion, String substring, int startingPos) {
478
        int index = startingPos;
479

    
480
        do {
481
            index = expresion.indexOf(substring, index);
482
        } while ((StringUtilities.isBetweenSymbols(expresion, index, "\""))
483
            && (index != -1));
484

    
485
        return index;
486
    }
487

    
488
    /**
489
     * DOCUMENT ME!
490
     * 
491
     * @param expresion
492
     *            DOCUMENT ME!
493
     * @param word
494
     *            DOCUMENT ME!
495
     * @param translation
496
     *            DOCUMENT ME!
497
     * 
498
     * @return DOCUMENT ME!
499
     * 
500
     * @throws ParseException
501
     *             DOCUMENT ME!
502
     */
503
    private String translateWord(String expresion, String word,
504
        String translation) throws ParseException {
505
        int booleanIndex = 0;
506
        int endIndex = 0;
507
        StringBuffer res = new StringBuffer();
508

    
509
        while ((booleanIndex = getIndex(expresion, word, booleanIndex)) != -1) {
510
            res.append(expresion.substring(endIndex, booleanIndex));
511
            endIndex = booleanIndex + word.length();
512
            booleanIndex++;
513
            res.append(translation);
514
        }
515

    
516
        if (endIndex < expresion.length()) {
517
            res.append(expresion.substring(endIndex));
518
        }
519

    
520
        return res.toString();
521
    }
522

    
523
    /**
524
     * DOCUMENT ME!
525
     * 
526
     * @param expresion
527
     *            DOCUMENT ME!
528
     * 
529
     * @return DOCUMENT ME!
530
     * 
531
     * @throws ParseException
532
     *             DOCUMENT ME!
533
     */
534
    private String translateDates(String expresion) throws ParseException {
535
        // Se obtiene el valor de la fecha
536
        String date =
537
            StringUtilities.substringDelimited(expresion, "Date(", ")", 0);
538

    
539
        if (date == null) {
540
            return expresion;
541
        }
542

    
543
        // Se comprueba que no est? entre comillas
544
        int startIndex = expresion.indexOf(date);
545

    
546
        while (startIndex != -1) {
547
            if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
548
                // Se sustituye por el valor ordinal de la fecha
549
                expresion =
550
                    expresion.substring(0, startIndex - 5)
551
                        + expresion.substring(startIndex).replaceFirst(
552
                            date + "\\)",
553
                            new Long((filterButtonsJPanel.getDateFormat()
554
                                .parse(date)).getTime()).toString());
555
                ;
556
            } else {
557
                startIndex += date.length();
558
            }
559

    
560
            // Se obtiene el valor de la fecha
561

    
562
            /*
563
             * date = StringUtilities.substringDelimited(expresion, "Date(",
564
             * ")",
565
             * startIndex);
566
             */
567
            if (date == null) {
568
                return expresion;
569
            }
570

    
571
            startIndex = expresion.indexOf(date, startIndex);
572
        }
573

    
574
        return expresion;
575
    }
576

    
577
    /**
578
     * DOCUMENT ME!
579
     * 
580
     * @param expresion
581
     *            DOCUMENT ME!
582
     * 
583
     * @return DOCUMENT ME!
584
     * 
585
     * @throws ParseException
586
     *             DOCUMENT ME!
587
     */
588
    public String translateNumber(String expresion) throws ParseException {
589
        DefaultCharSet ss = new DefaultCharSet();
590
        ss.addInterval('0', '9');
591
        ss.addCharacter(',');
592
        ss.addCharacter('.');
593

    
594
        String number = StringUtilities.substringWithSymbols(expresion, ss, 0);
595

    
596
        if (number == null) {
597
            return expresion;
598
        }
599

    
600
        int startIndex = expresion.indexOf(number);
601

    
602
        while (startIndex != -1) {
603
            Number n = nf.parse(number);
604

    
605
            if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
606
                // Se sustituye por el valor ordinal de la fecha
607
                expresion =
608
                    expresion.substring(0, startIndex)
609
                        + expresion.substring(startIndex).replaceFirst(number,
610
                            n.toString());
611
            } else {
612
                startIndex += n.toString().length();
613
            }
614

    
615
            number =
616
                StringUtilities.substringWithSymbols(expresion, ss, startIndex);
617

    
618
            if (number == null) {
619
                return expresion;
620
            }
621

    
622
            startIndex = expresion.indexOf(number, startIndex);
623
        }
624

    
625
        return expresion;
626
    }
627

    
628
    /**
629
     * DOCUMENT ME!
630
     * 
631
     * @param arg0
632
     * 
633
     * @return
634
     */
635
    public boolean addExpressionListener(ExpressionListener arg0) {
636
        return expressionListeners.add(arg0);
637
    }
638

    
639
    /**
640
     * DOCUMENT ME!
641
     * 
642
     * @param arg0
643
     * 
644
     * @return
645
     */
646
    public boolean removeExpressionListener(ExpressionListener arg0) {
647
        return expressionListeners.remove(arg0);
648
    }
649

    
650
    /**
651
     * @see com.iver.mdiApp.ui.MDIManager.IWindow#getWindowInfo()
652
     */
653
    public WindowInfo getWindowInfo() {
654
        WindowInfo vi = new WindowInfo(WindowInfo.ICONIFIABLE);
655

    
656
        // if (System.getProperty("os.name")co.compareTo(arg0))
657
        vi.setHeight(this.filterDialog_Height);
658
        vi.setWidth(this.filterDialog_Width);
659

    
660
        // Old instructions
661
        // vi.setWidth(480);
662
        // vi.setHeight(362);
663
        vi
664
            .setTitle(PluginServices.getText(this, "filtro") + " (" + title
665
                + ")");
666
        return vi;
667
    }
668

    
669
    /**
670
     * DOCUMENT ME!
671
     * 
672
     * @param o
673
     *            DOCUMENT ME!
674
     */
675
    public void addExceptionListener(ExceptionListener o) {
676
        exceptionHandlingSupport.addExceptionListener(o);
677
    }
678

    
679
    /**
680
     * DOCUMENT ME!
681
     * 
682
     * @param o
683
     *            DOCUMENT ME!
684
     * 
685
     * @return DOCUMENT ME!
686
     */
687
    public boolean removeExceptionListener(ExceptionListener o) {
688
        return exceptionHandlingSupport.removeExceptionListener(o);
689
    }
690

    
691
    /**
692
     * DOCUMENT ME!
693
     * 
694
     * @param t
695
     *            DOCUMENT ME!
696
     */
697
    private void throwException(Throwable t) {
698
        exceptionHandlingSupport.throwException(t);
699
    }
700

    
701
    /*
702
     * (non-Javadoc)
703
     * 
704
     * @see com.iver.andami.ui.mdiManager.ViewListener#viewActivated()
705
     */
706
    public void windowActivated() {
707
    }
708

    
709
    /*
710
     * (non-Javadoc)
711
     * 
712
     * @see com.iver.andami.ui.mdiManager.ViewListener#viewClosed()
713
     */
714
    public void windowClosed() {
715
        // try {
716
        // model.stop();
717
        // } catch (ReadDriverException e) {
718
        // NotificationManager.addError(e.getMessage(), e);
719
        // }
720
    }
721

    
722
    public Object getWindowProfile() {
723
        return WindowInfo.TOOL_PROFILE;
724
    }
725
}