Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / gui / filter / FilterDialog.java @ 42488

History | View | Annotate | Download (21.9 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.gui.filter;
25

    
26
import java.awt.event.MouseAdapter;
27
import java.awt.event.MouseEvent;
28
import java.text.NumberFormat;
29
import java.text.ParseException;
30
import java.util.ArrayList;
31
import java.util.Collection;
32
import java.util.Comparator;
33
import java.util.Date;
34
import java.util.Iterator;
35
import java.util.TreeSet;
36
import java.util.regex.Matcher;
37
import java.util.regex.Pattern;
38

    
39
import javax.swing.tree.DefaultMutableTreeNode;
40
import javax.swing.tree.DefaultTreeModel;
41

    
42
import org.slf4j.Logger;
43
import org.slf4j.LoggerFactory;
44

    
45
import org.gvsig.andami.PluginServices;
46
import org.gvsig.andami.messages.NotificationManager;
47
import org.gvsig.andami.ui.mdiManager.IWindow;
48
import org.gvsig.andami.ui.mdiManager.IWindowListener;
49
import org.gvsig.andami.ui.mdiManager.WindowInfo;
50
import org.gvsig.fmap.dal.exception.DataException;
51
import org.gvsig.fmap.dal.feature.Feature;
52
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
53
import org.gvsig.fmap.dal.feature.FeatureQuery;
54
import org.gvsig.fmap.dal.feature.FeatureSet;
55
import org.gvsig.fmap.dal.feature.FeatureStore;
56
import org.gvsig.gui.beans.filterPanel.tableFilterQueryPanel.TableFilterQueryJPanel;
57
import org.gvsig.tools.dispose.DisposableIterator;
58
import org.gvsig.tools.dispose.DisposeUtils;
59
import org.gvsig.utils.DefaultCharSet;
60
import org.gvsig.utils.StringUtilities;
61
import org.gvsig.utils.exceptionHandling.ExceptionHandlingSupport;
62
import org.gvsig.utils.exceptionHandling.ExceptionListener;
63

    
64
/**
65
 * This class substitutes the old "FilterDialog" class made by
66
 * "Fernando Gonz?lez Cort?s"
67
 * The functionality is the same, but now the class is made from separately (and
68
 * reusable) components
69
 * 
70
 * @author Pablo Piqueras Bartolom? (p_queras@hotmail.com)
71
 */
72
public class FilterDialog extends TableFilterQueryJPanel implements IWindow,
73
    IWindowListener {
74

    
75
    /**
76
     * 
77
     */
78
    private static final long serialVersionUID = -149317534873551735L;
79
    private static final Logger logger =
80
        LoggerFactory.getLogger(FilterDialog.class);
81
    private FeatureStore model = null;
82
    private ArrayList expressionListeners = new ArrayList();
83
    private ExceptionHandlingSupport exceptionHandlingSupport =
84
        new ExceptionHandlingSupport();
85
    private NumberFormat nf = NumberFormat.getNumberInstance();
86

    
87
    private String title;
88

    
89
    private final int filterDialog_Width = 500;
90
    private final int filterDialog_Height = 362;
91
    private final int widthIncrementForAndami = 20; // This is necessary because
92
                                                    // when the panel is sent to
93
                                                    // Andami, that needs a bit
94
                                                    // more width-space to show
95
                                                    // that panel.
96

    
97
    /**
98
     * This is the default constructor
99
     */
100
    public FilterDialog(String _title) {
101
        super();
102
        title = _title;
103
        defaultTreeModel = (DefaultTreeModel) fieldsJTree.getModel();
104
    }
105

    
106
    /**
107
     * This is the default constructor
108
     */
109
    public FilterDialog() {
110
        super();
111
        defaultTreeModel = (DefaultTreeModel) fieldsJTree.getModel();
112
    }
113

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

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

    
127
        this.addNewListeners();
128
    }
129

    
130
    /**
131
     * Adds some listeners
132
     */
133
    private void addNewListeners() {
134
        // Listener for "btnAdd"
135
        // Adds more elements to the current set
136
        getBtnAddToCurrentSet().addActionListener(
137
            new java.awt.event.ActionListener() {
138

    
139
                /*
140
                 * (non-Javadoc)
141
                 * 
142
                 * @see
143
                 * java.awt.event.ActionListener#actionPerformed(java.awt.event
144
                 * .ActionEvent)
145
                 */
146
                public void actionPerformed(java.awt.event.ActionEvent e) {
147
                    // final String expr = "select * from '" +
148
                    // model.getName() + "' where " +
149
                    // getTxtExpression().getText() + ";";
150
                    final String expr = getTxtExpression().getText();
151
                    logger.debug(expr);
152

    
153
                    PluginServices.backgroundExecution(new Runnable() {
154

    
155
                        public void run() {
156
                            for (int i = 0; i < expressionListeners.size(); i++) {
157
                                ExpressionListener l =
158
                                    (ExpressionListener) expressionListeners
159
                                        .get(i);
160
                                try {
161
                                    l.addToSet(expr);
162
                                } catch (DataException e) {
163
                                    e.printStackTrace();
164
                                }
165
                            }
166
                        }
167
                    });
168
                }
169
            });
170

    
171
        // Listener for "btnNuevo"
172
        // Adds a new set
173
        getBtnNewSet().addActionListener(new java.awt.event.ActionListener() {
174

    
175
            public void actionPerformed(java.awt.event.ActionEvent e) {
176
                // final String expr = "select * from '" +
177
                // model.getName() + "' where " +
178
                // getTxtExpression().getText() + ";";
179
                final String expr = getTxtExpression().getText();
180

    
181
                logger.debug(expr);
182

    
183
                PluginServices.backgroundExecution(new Runnable() {
184

    
185
                    public void run() {
186
                        for (int i = 0; i < expressionListeners.size(); i++) {
187
                            ExpressionListener l =
188
                                (ExpressionListener) expressionListeners.get(i);
189
                            try {
190
                                l.newSet(expr);
191
                            } catch (DataException e) {
192
                                // TODO Auto-generated catch block
193
                                NotificationManager.addError(e);
194
                            }
195
                        }
196
                    }
197
                });
198
            }
199
        });
200

    
201
        // Listener for "btnFromSet"
202
        // Selects elements from the current filtered selection
203
        getBtnFromSet().addActionListener(new java.awt.event.ActionListener() {
204

    
205
            public void actionPerformed(java.awt.event.ActionEvent e) {
206
                // final String expr = "select * from '" +
207
                // model.getName() + "' where " +
208
                // getTxtExpression().getText() + ";";
209
                final String expr = getTxtExpression().getText();
210
                logger.debug(expr);
211

    
212
                PluginServices.backgroundExecution(new Runnable() {
213

    
214
                    public void run() {
215
                        for (int i = 0; i < expressionListeners.size(); i++) {
216
                            ExpressionListener l =
217
                                (ExpressionListener) expressionListeners.get(i);
218
                            try {
219
                                l.fromSet(expr);
220
                            } catch (DataException e) {
221
                                NotificationManager.addError(e);
222
                            }
223
                        }
224
                    }
225
                });
226
            }
227
        });
228

    
229
        // Listener for "fieldsJTree"
230
        getFieldsJTree().addMouseListener(new MouseAdapter() {
231

    
232
            /*
233
             * (non-Javadoc)
234
             * 
235
             * @see
236
             * java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent
237
             * )
238
             */
239
            @Override
240
            public void mouseClicked(MouseEvent e) {
241
                int row = fieldsJTree.getRowForLocation(e.getX(), e.getY());
242

    
243
                if (row > -1) {
244
                    switch (e.getClickCount()) {
245
                    case 1:
246
                        fillValues(row);
247
                        break;
248
                    case 2:
249
                        putSymbol(jtreeRoot.getChildAt(row).toString());
250
                        break;
251
                    }
252
                }
253
            }
254
        });
255

    
256
        // Listener for "valuesJList"
257
        getValuesJList().addMouseListener(new MouseAdapter() {
258

    
259
            /*
260
             * (non-Javadoc)
261
             * 
262
             * @see
263
             * java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent
264
             * )
265
             */
266
            @Override
267
            public void mouseClicked(MouseEvent e) {
268
                if (e.getClickCount() == 2) {
269
                    Object valor =
270
                        valuesListModel.getElementAt(getValuesJList()
271
                            .getSelectedIndex());
272

    
273
                    if (valor instanceof Date) {
274
                        putSymbol("date('" + valor + "')");
275
                    } else
276
                        if (valor instanceof Boolean) {
277
                          putSymbol(valor.toString());
278
                        } else
279
                            if (valor instanceof String) {
280
                                putSymbol("'" + valor + "'");
281
                            } else {
282
                                putSymbol(valor.toString());
283
                            }
284
                }
285
            }
286
        });
287
    }
288

    
289
    /**
290
     * Rellena la lista con los valores del campo seleccionado
291
     */
292
    private void fillValues(int row) {
293
        // int index = lstCampos.getSelectedIndex();
294

    
295
        // Index es ahora el ?ndice del campo seleccionado
296
        // Se eliminan los duplicados
297
        Collection conjunto = new TreeSet(new Comparator() {
298

    
299
            public int compare(Object o1, Object o2) {
300
                return ((Comparable) o1).compareTo(o2);
301
            }
302
        }); // Para poder ordenar
303

    
304
        valuesListModel.clear();
305
        FeatureSet fs = null;
306
        DisposableIterator iterator = null;
307
        try {
308
            String[] fieldName =
309
                new String[] { ((FeatureAttributeDescriptor) model
310
                    .getDefaultFeatureType().get(row)).getName() };
311

    
312
            FeatureQuery query = model.createFeatureQuery();
313
            query.setAttributeNames(fieldName);
314
            fs = model.getFeatureSet(query);
315
            iterator = fs.fastIterator();
316
            while (iterator.hasNext()) {
317
                Feature feature = (Feature) iterator.next();
318
                Object value = feature.get(fieldName[0]);
319
                if (value == null) {
320
                    continue;
321
                }
322

    
323
                conjunto.add(value);
324
            }
325

    
326
            Iterator it = conjunto.iterator();
327

    
328
            while (it.hasNext()) {
329
                valuesListModel.addElement(it.next());
330
            }
331
        } catch (DataException e) {
332
            throwException(e);
333
        } finally {
334
            DisposeUtils.dispose(iterator);
335
            DisposeUtils.dispose(fs);
336
        }
337
    }
338

    
339
    /**
340
     * DOCUMENT ME!
341
     * 
342
     * @param t
343
     *            DOCUMENT ME!
344
     */
345
    public void setModel(FeatureStore t) {
346
        // try {
347
        model = t;
348
        // model.start();
349
        // } catch (ReadException e1) {
350
        // NotificationManager.addError(e1.getMessage(), e1);
351
        // }
352

    
353
        jtreeRoot.removeAllChildren();
354

    
355
        try {
356
            Iterator attributes = model.getDefaultFeatureType().iterator();
357
            while (attributes.hasNext()) {
358
                FeatureAttributeDescriptor descriptor =
359
                    (FeatureAttributeDescriptor) attributes.next();
360
                Object field = descriptor.getName();
361

    
362
                if (field != null) {
363
                    jtreeRoot.add(new DefaultMutableTreeNode(field.toString()));
364
                }
365
            }
366
            // for (int i = 0; i < model.getFieldCount(); i++) {
367
            // Object field = model.getFieldName(i);
368
            //
369
            // if (field != null) {
370
            // jtreeRoot.add(new DefaultMutableTreeNode(field.toString()));
371
            // }
372
            // }
373

    
374
            defaultTreeModel.setRoot(jtreeRoot);
375
        } catch (DataException e) {
376
            throwException(e);
377
        }
378
    }
379

    
380
    /**
381
     * DOCUMENT ME!
382
     * 
383
     * @return DOCUMENT ME!
384
     * 
385
     * @throws ParseException
386
     *             DOCUMENT ME!
387
     */
388
    private String validateExpression() throws ParseException {
389
        String expression = txtExpression.getText();
390
        // HashSet variablesIndexes = new HashSet();
391
        //
392
        // StringBuffer traducida = new StringBuffer();
393

    
394
        // Se transforman los nombres de los campos en las variables xix que
395
        // analizar?n
396
        // Se quitan los Date(fecha) y se mete la fecha correspondiente
397
        expression = translateDates(expression);
398
        expression = translateNumber(expression);
399
        expression = translateWord(expression, "true", "1");
400
        expression = translateWord(expression, "false", "0");
401

    
402
        String replacement;
403
        Pattern patron = Pattern.compile("[^<>!]=");
404
        Matcher m = patron.matcher(expression);
405
        int index = 0;
406

    
407
        while (m.find(index)) {
408
            index = m.start();
409
            replacement = expression.charAt(index) + "==";
410
            m.replaceFirst(replacement);
411
            index++;
412
        }
413

    
414
        expression = expression.replaceAll("[^<>!]=", "==");
415

    
416
        logger.debug(expression);
417

    
418
        return expression;
419
    }
420

    
421
    /**
422
     * Redefinition of the 'putSymbol' method of AbstractFilterQueryJPanel
423
     * (I've made this redefinition for write the same code as the 'putSymbol'
424
     * code of the original class (FilterDialog) that was in this project
425
     * (appgvSIG) and didn't has path troubles to find 'StringUtilities').
426
     * 
427
     * Sets a symbol on the filter expression (JTextArea that stores and shows
428
     * the current filter expression)
429
     * 
430
     * @param symbol
431
     *            A symbol: character, characters, number, ...
432
     */
433
    @Override
434
    protected void putSymbol(String symbol) {
435
        int position = txtExpression.getCaretPosition();
436
        txtExpression.setText(StringUtilities.insert(txtExpression.getText(),
437
            position, symbol));
438

    
439
        if (symbol.equals(" () ")) {
440
            position = position + 2;
441
        } else {
442
            position = position + symbol.length();
443
        }
444

    
445
        txtExpression.setCaretPosition(position);
446
    }
447

    
448
    /**
449
     * DOCUMENT ME!
450
     * 
451
     * @param expresion
452
     *            DOCUMENT ME!
453
     * @param substring
454
     *            DOCUMENT ME!
455
     * @param startingPos
456
     *            DOCUMENT ME!
457
     * 
458
     * @return DOCUMENT ME!
459
     */
460
    private int getIndex(String expresion, String substring, int startingPos) {
461
        int index = startingPos;
462

    
463
        do {
464
            index = expresion.indexOf(substring, index);
465
        } while ((StringUtilities.isBetweenSymbols(expresion, index, "\""))
466
            && (index != -1));
467

    
468
        return index;
469
    }
470

    
471
    /**
472
     * DOCUMENT ME!
473
     * 
474
     * @param expresion
475
     *            DOCUMENT ME!
476
     * @param word
477
     *            DOCUMENT ME!
478
     * @param translation
479
     *            DOCUMENT ME!
480
     * 
481
     * @return DOCUMENT ME!
482
     * 
483
     * @throws ParseException
484
     *             DOCUMENT ME!
485
     */
486
    private String translateWord(String expresion, String word,
487
        String translation) throws ParseException {
488
        int booleanIndex = 0;
489
        int endIndex = 0;
490
        StringBuffer res = new StringBuffer();
491

    
492
        while ((booleanIndex = getIndex(expresion, word, booleanIndex)) != -1) {
493
            res.append(expresion.substring(endIndex, booleanIndex));
494
            endIndex = booleanIndex + word.length();
495
            booleanIndex++;
496
            res.append(translation);
497
        }
498

    
499
        if (endIndex < expresion.length()) {
500
            res.append(expresion.substring(endIndex));
501
        }
502

    
503
        return res.toString();
504
    }
505

    
506
    /**
507
     * DOCUMENT ME!
508
     * 
509
     * @param expresion
510
     *            DOCUMENT ME!
511
     * 
512
     * @return DOCUMENT ME!
513
     * 
514
     * @throws ParseException
515
     *             DOCUMENT ME!
516
     */
517
    private String translateDates(String expresion) throws ParseException {
518
        // Se obtiene el valor de la fecha
519
        String date =
520
            StringUtilities.substringDelimited(expresion, "Date(", ")", 0);
521

    
522
        if (date == null) {
523
            return expresion;
524
        }
525

    
526
        // Se comprueba que no est? entre comillas
527
        int startIndex = expresion.indexOf(date);
528

    
529
        while (startIndex != -1) {
530
            if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
531
                // Se sustituye por el valor ordinal de la fecha
532
                expresion =
533
                    expresion.substring(0, startIndex - 5)
534
                        + expresion.substring(startIndex).replaceFirst(
535
                            date + "\\)",
536
                            new Long((filterButtonsJPanel.getDateFormat()
537
                                .parse(date)).getTime()).toString());
538
                ;
539
            } else {
540
                startIndex += date.length();
541
            }
542

    
543
            // Se obtiene el valor de la fecha
544

    
545
            /*
546
             * date = StringUtilities.substringDelimited(expresion, "Date(",
547
             * ")",
548
             * startIndex);
549
             */
550
            if (date == null) {
551
                return expresion;
552
            }
553

    
554
            startIndex = expresion.indexOf(date, startIndex);
555
        }
556

    
557
        return expresion;
558
    }
559

    
560
    /**
561
     * DOCUMENT ME!
562
     * 
563
     * @param expresion
564
     *            DOCUMENT ME!
565
     * 
566
     * @return DOCUMENT ME!
567
     * 
568
     * @throws ParseException
569
     *             DOCUMENT ME!
570
     */
571
    public String translateNumber(String expresion) throws ParseException {
572
        DefaultCharSet ss = new DefaultCharSet();
573
        ss.addInterval('0', '9');
574
        ss.addCharacter(',');
575
        ss.addCharacter('.');
576

    
577
        String number = StringUtilities.substringWithSymbols(expresion, ss, 0);
578

    
579
        if (number == null) {
580
            return expresion;
581
        }
582

    
583
        int startIndex = expresion.indexOf(number);
584

    
585
        while (startIndex != -1) {
586
            Number n = nf.parse(number);
587

    
588
            if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
589
                // Se sustituye por el valor ordinal de la fecha
590
                expresion =
591
                    expresion.substring(0, startIndex)
592
                        + expresion.substring(startIndex).replaceFirst(number,
593
                            n.toString());
594
            } else {
595
                startIndex += n.toString().length();
596
            }
597

    
598
            number =
599
                StringUtilities.substringWithSymbols(expresion, ss, startIndex);
600

    
601
            if (number == null) {
602
                return expresion;
603
            }
604

    
605
            startIndex = expresion.indexOf(number, startIndex);
606
        }
607

    
608
        return expresion;
609
    }
610

    
611
    /**
612
     * DOCUMENT ME!
613
     * 
614
     * @param arg0
615
     * 
616
     * @return
617
     */
618
    public boolean addExpressionListener(ExpressionListener arg0) {
619
        return expressionListeners.add(arg0);
620
    }
621

    
622
    /**
623
     * DOCUMENT ME!
624
     * 
625
     * @param arg0
626
     * 
627
     * @return
628
     */
629
    public boolean removeExpressionListener(ExpressionListener arg0) {
630
        return expressionListeners.remove(arg0);
631
    }
632

    
633
    /**
634
     * @see com.iver.mdiApp.ui.MDIManager.IWindow#getWindowInfo()
635
     */
636
    public WindowInfo getWindowInfo() {
637
        WindowInfo vi = new WindowInfo(WindowInfo.ICONIFIABLE);
638

    
639
        // if (System.getProperty("os.name")co.compareTo(arg0))
640
        vi.setHeight(this.filterDialog_Height);
641
        vi.setWidth(this.filterDialog_Width);
642

    
643
        // Old instructions
644
        // vi.setWidth(480);
645
        // vi.setHeight(362);
646
        vi
647
            .setTitle(PluginServices.getText(this, "_Selection_by_attributes") + " (" + title
648
                + ")");
649
        return vi;
650
    }
651

    
652
    /**
653
     * DOCUMENT ME!
654
     * 
655
     * @param o
656
     *            DOCUMENT ME!
657
     */
658
    public void addExceptionListener(ExceptionListener o) {
659
        exceptionHandlingSupport.addExceptionListener(o);
660
    }
661

    
662
    /**
663
     * DOCUMENT ME!
664
     * 
665
     * @param o
666
     *            DOCUMENT ME!
667
     * 
668
     * @return DOCUMENT ME!
669
     */
670
    public boolean removeExceptionListener(ExceptionListener o) {
671
        return exceptionHandlingSupport.removeExceptionListener(o);
672
    }
673

    
674
    /**
675
     * DOCUMENT ME!
676
     * 
677
     * @param t
678
     *            DOCUMENT ME!
679
     */
680
    private void throwException(Throwable t) {
681
        exceptionHandlingSupport.throwException(t);
682
    }
683

    
684
    /*
685
     * (non-Javadoc)
686
     * 
687
     * @see com.iver.andami.ui.mdiManager.ViewListener#viewActivated()
688
     */
689
    public void windowActivated() {
690
    }
691

    
692
    /*
693
     * (non-Javadoc)
694
     * 
695
     * @see com.iver.andami.ui.mdiManager.ViewListener#viewClosed()
696
     */
697
    public void windowClosed() {
698
        // try {
699
        // model.stop();
700
        // } catch (ReadDriverException e) {
701
        // NotificationManager.addError(e.getMessage(), e);
702
        // }
703
    }
704

    
705
    public Object getWindowProfile() {
706
        return WindowInfo.TOOL_PROFILE;
707
    }
708
}