Statistics
| Revision:

svn-gvsig-desktop / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / gui / filter / FilterDialog.java @ 37965

History | View | Annotate | Download (16.7 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 com.iver.cit.gvsig.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.Comparator;
49
import java.util.Iterator;
50
import java.util.TreeSet;
51
import java.util.regex.Matcher;
52
import java.util.regex.Pattern;
53

    
54
import javax.swing.tree.DefaultMutableTreeNode;
55
import javax.swing.tree.DefaultTreeModel;
56

    
57
import org.apache.log4j.Logger;
58
import org.gvsig.gui.beans.filterPanel.tableFilterQueryPanel.TableFilterQueryJPanel;
59

    
60
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
61
import com.hardcode.gdbms.engine.instruction.IncompatibleTypesException;
62
import com.hardcode.gdbms.engine.values.BooleanValue;
63
import com.hardcode.gdbms.engine.values.DateValue;
64
import com.hardcode.gdbms.engine.values.NullValue;
65
import com.hardcode.gdbms.engine.values.StringValue;
66
import com.hardcode.gdbms.engine.values.Value;
67
import com.iver.andami.PluginServices;
68
import com.iver.andami.messages.NotificationManager;
69
import com.iver.andami.ui.mdiManager.IWindow;
70
import com.iver.andami.ui.mdiManager.IWindowListener;
71
import com.iver.andami.ui.mdiManager.WindowInfo;
72
import com.iver.cit.gvsig.project.documents.table.gui.Table;
73
import com.iver.utiles.DefaultCharSet;
74
import com.iver.utiles.StringUtilities;
75
import com.iver.utiles.exceptionHandling.ExceptionHandlingSupport;
76
import com.iver.utiles.exceptionHandling.ExceptionListener;
77

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

    
91
        private String title;
92

    
93
        private final int filterDialog_Width = 500;
94
        private final int filterDialog_Height = 362;
95
        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.
96

    
97

    
98
        /**
99
         * This is the default constructor
100
         */
101
        public FilterDialog(String _title) {
102
                super();
103
                title = _title;
104
                defaultTreeModel = (DefaultTreeModel)fieldsJTree.getModel();
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
         * @see org.gvsig.gui.beans.filterPanel.AbstractFilterQueryJPanel#initialize()
117
         */
118
        protected void initialize() {
119
                super.initialize();
120

    
121
                super.resizeHeight(filterDialog_Height);
122
                super.resizeWidth(filterDialog_Width - widthIncrementForAndami);
123

    
124
                this.addNewListeners();
125
        }
126

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

    
143
                                logger.debug(expr);
144

    
145
                                PluginServices.backgroundExecution(new Runnable() {
146
                                                public void run() {
147
                                                        for (int i = 0;
148
                                                                        i < expressionListeners.size();
149
                                                                        i++) {
150
                                                                ExpressionListener l = (ExpressionListener) expressionListeners.get(i);
151
                                                                l.addToSet(expr);
152
                                                        }
153
                                                }
154
                                        });
155
                        }
156
                });
157

    
158
                // Listener for "btnNuevo"
159
                // Adds a new set
160
                getBtnNewSet().addActionListener(new java.awt.event.ActionListener() {
161
                        public void actionPerformed(java.awt.event.ActionEvent e) {
162
                                final String expr = "select * from '" +
163
                                        model.getDataSourceName() + "' where " +
164
                                        getTxtExpression().getText() + ";";
165

    
166
                                logger.debug(expr);
167

    
168
                                PluginServices.backgroundExecution(new Runnable() {
169
                                        public void run() {
170
                                                for (int i = 0; i < expressionListeners.size(); i++) {
171
                                                        ExpressionListener l = (ExpressionListener) expressionListeners.get(i);
172
                                                        l.newSet(expr);
173
                                                }
174
                                        }
175
                                });
176
                        }
177
                });
178

    
179
                // Listener for "btnFromSet"
180
                // Selects elements in the table that are according the current filter condition
181
                getBtnFromSet().addActionListener(new java.awt.event.ActionListener() {
182
                        public void actionPerformed(java.awt.event.ActionEvent e) {
183
                                final String expr = "select * from '" +
184
                                        model.getDataSourceName() + "' where " +
185
                                        getTxtExpression().getText() + ";";
186

    
187
                                logger.debug(expr);
188

    
189
                                PluginServices.backgroundExecution(new Runnable() {
190
                                        public void run() {
191
                                                for (int i = 0; i < expressionListeners.size(); i++) {
192
                                                        ExpressionListener l = (ExpressionListener) expressionListeners.get(i);
193
                                                        l.fromSet(expr);
194
                                                }
195
                                        }
196
                                });
197
                        }
198
                });
199

    
200
                // Listener for "fieldsJTree"
201
                getFieldsJTree().addMouseListener(new MouseAdapter() {
202
                        /*
203
                         *  (non-Javadoc)
204
                         * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
205
                         */
206
                        public void mouseClicked(MouseEvent e) {
207
                                int row = fieldsJTree.getRowForLocation(e.getX(), e.getY());
208

    
209
                                if (row > -1) {
210
                                        switch (e.getClickCount()) {
211
                                                case 1:
212
                                                        fillValues(row);
213
                                                        break;
214
                                                case 2:
215
                                                        String alias = jtreeRoot.getChildAt(row).toString();
216
                                                        String name;
217
                                                        try {
218
                                                                name = model.getFieldName(row);
219
                                                                putSymbol(name);
220
                                                        } catch (FilterException e1) {
221
                                                                e1.printStackTrace();
222
                                                        }
223
                                                        
224
                                                        break;
225
                                        }
226
                                }
227
                        }
228
                });
229

    
230
                // Listener for "valuesJList"
231
                getValuesJList().addMouseListener(new MouseAdapter() {
232
                        /*
233
                         *  (non-Javadoc)
234
                         * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
235
                         */
236
                        public void mouseClicked(MouseEvent e) {
237
                                if (e.getClickCount() == 2) {
238
                                        Value valor = (Value) valuesListModel.getElementAt(getValuesJList().getSelectedIndex());
239

    
240
                                        if (valor instanceof DateValue) {
241
                                                putSymbol("date('" + valor + "')");
242
                                        } else if (valor instanceof BooleanValue) {
243
                                                putSymbol("boolean('" + valor.toString() + "')");
244
                                        } else if (valor instanceof StringValue) {
245
                                                putSymbol("'" + valor.toString().replaceAll("'","''") + "'");
246
                                        } else {
247
                                                putSymbol(valor.toString());
248
                                        }
249
                                }
250
                        }
251
                });
252
        }
253

    
254
        /**
255
         * Rellena la lista con los valores del campo seleccionado
256
         */
257
        private void fillValues(int row) {
258
                //int index = lstCampos.getSelectedIndex();
259

    
260
                //Index es ahora el ?ndice del campo seleccionado
261
                //Se eliminan los duplicados
262
                TreeSet conjunto = new TreeSet(new Comparator() {
263
                        public int compare(Object o1, Object o2) {
264
                                if ((o1 != null) && (o2 != null)) {
265
                                        Value v2 = (Value) o2;
266
                                        Value v1 = (Value) o1;
267
                                        BooleanValue boolVal;
268

    
269
                                        try {
270
                                                boolVal = (BooleanValue) (v1.greater(v2));
271

    
272
                                                if (boolVal.getValue()) {
273
                                                        return 1;
274
                                                }
275

    
276
                                                boolVal = (BooleanValue) (v1.less(v2));
277

    
278
                                                if (boolVal.getValue()) {
279
                                                        return -1;
280
                                                }
281
                                        } catch (IncompatibleTypesException e) {
282
                                                throw new RuntimeException(e);
283
                                        }
284
                                }
285

    
286
                                return 0;
287
                        }
288
                }); // Para poder ordenar
289

    
290

    
291
                valuesListModel.clear();
292
                try {
293
                        for (int i = 0; i < model.getRowCount(); i++) {
294
                                Value value = model.getFieldValue(i, row);
295

    
296
                                if (value instanceof NullValue)
297
                                    continue;
298

    
299
                                if (!conjunto.contains(value)) {
300
                                    conjunto.add(value);
301
                                }
302
                        }
303

    
304
                        Iterator it = conjunto.iterator();
305

    
306
                        while (it.hasNext())
307
                                valuesListModel.addElement(it.next());
308
                } catch (FilterException e) {
309
                        throwException(e);
310
                }
311
        }
312

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

    
326
        jtreeRoot.removeAllChildren();
327

    
328
        try {
329
                        for (int i = 0; i < model.getFieldCount(); i++) {
330
                                Object field = model.getFieldAlias(i);
331

    
332
                                if (field != null) {
333
                                        jtreeRoot.add(new DefaultMutableTreeNode(field.toString()));
334
                                }
335
                        }
336

    
337
                        defaultTreeModel.setRoot(jtreeRoot);
338
                } catch (FilterException e) {
339
                        throwException(e);
340
                }
341
        }
342

    
343
                /**
344
                 * DOCUMENT ME!
345
                 *
346
                 * @return DOCUMENT ME!
347
                 *
348
                 * @throws ParseException DOCUMENT ME!
349
                 */
350
                private String validateExpression() throws ParseException {
351
                        String expression = txtExpression.getText();
352
        //                HashSet variablesIndexes = new HashSet();
353
        //
354
        //                StringBuffer traducida = new StringBuffer();
355

    
356
                        //Se transforman los nombres de los campos en las variables xix que analizar?n
357
                        //Se quitan los Date(fecha) y se mete la fecha correspondiente
358
                        expression = translateDates(expression);
359
                        expression = translateNumber(expression);
360
                        expression = translateWord(expression, "true", "1");
361
                        expression = translateWord(expression, "false", "0");
362

    
363
                        String replacement;
364
                        Pattern patron = Pattern.compile("[^<>!]=");
365
                        Matcher m = patron.matcher(expression);
366
                        int index = 0;
367

    
368
                        while (m.find(index)) {
369
                                index = m.start();
370
                                replacement = expression.charAt(index) + "==";
371
                                m.replaceFirst(replacement);
372
                                index++;
373
                        }
374

    
375
                        expression = expression.replaceAll("[^<>!]=", "==");
376

    
377
                        logger.debug(expression);
378

    
379
                        return expression;
380
                }
381
        /**
382
         * Redefinition of the 'putSymbol' method of AbstractFilterQueryJPanel
383
         *   (I've made this redefinition for write the same code as the 'putSymbol'
384
         *    code of the original class (FilterDialog) that was in this project
385
         *    (appgvSIG) and didn't has path troubles to find 'StringUtilities').
386
         *
387
         * Sets a symbol on the filter expression (JTextArea that stores and shows
388
         *   the current filter expression)
389
         *
390
         * @param symbol A symbol: character, characters, number, ...
391
         */
392
        protected void putSymbol(String symbol) {
393
                int position = txtExpression.getCaretPosition();
394
                txtExpression.setText(StringUtilities.insert(txtExpression.getText(),
395
                                position, symbol));
396

    
397
                if (symbol.equals(" () ")) {
398
                        position = position + 2;
399
                } else {
400
                        position = position + symbol.length();
401
                }
402

    
403
                txtExpression.setCaretPosition(position);
404
        }
405

    
406
        /**
407
         * DOCUMENT ME!
408
         *
409
         * @param expresion DOCUMENT ME!
410
         * @param substring DOCUMENT ME!
411
         * @param startingPos DOCUMENT ME!
412
         *
413
         * @return DOCUMENT ME!
414
         */
415
        private int getIndex(String expresion, String substring, int startingPos) {
416
                int index = startingPos;
417

    
418
                do {
419
                        index = expresion.indexOf(substring, index);
420
                } while ((StringUtilities.isBetweenSymbols(expresion, index, "\"")) &&
421
                                (index != -1));
422

    
423
                return index;
424
        }
425

    
426
        /**
427
         * DOCUMENT ME!
428
         *
429
         * @param expresion DOCUMENT ME!
430
         * @param word DOCUMENT ME!
431
         * @param translation DOCUMENT ME!
432
         *
433
         * @return DOCUMENT ME!
434
         *
435
         * @throws ParseException DOCUMENT ME!
436
         */
437
        private String translateWord(String expresion, String word,
438
                String translation) throws ParseException {
439
                int booleanIndex = 0;
440
                int endIndex = 0;
441
                StringBuffer res = new StringBuffer();
442

    
443
                while ((booleanIndex = getIndex(expresion, word, booleanIndex)) != -1) {
444
                        res.append(expresion.substring(endIndex, booleanIndex));
445
                        endIndex = booleanIndex + word.length();
446
                        booleanIndex++;
447
                        res.append(translation);
448
                }
449

    
450
                if (endIndex < expresion.length()) {
451
                        res.append(expresion.substring(endIndex));
452
                }
453

    
454
                return res.toString();
455
        }
456

    
457
        /**
458
         * DOCUMENT ME!
459
         *
460
         * @param expresion DOCUMENT ME!
461
         *
462
         * @return DOCUMENT ME!
463
         *
464
         * @throws ParseException DOCUMENT ME!
465
         */
466
        private String translateDates(String expresion) throws ParseException {
467
                //Se obtiene el valor de la fecha
468
                String date = StringUtilities.substringDelimited(expresion, "Date(",
469
                                ")", 0);
470

    
471
                if (date == null) {
472
                        return expresion;
473
                }
474

    
475
                //Se comprueba que no est? entre comillas
476
                int startIndex = expresion.indexOf(date);
477

    
478
                while (startIndex != -1) {
479
                        if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
480
                                //Se sustituye por el valor ordinal de la fecha
481
                                expresion = expresion.substring(0, startIndex - 5) +
482
                                        expresion.substring(startIndex).replaceFirst(date + "\\)",
483
                                                new Long((filterButtonsJPanel.getDateFormat().parse(date)).getTime()).toString());
484
                                ;
485
                        } else {
486
                                startIndex += date.length();
487
                        }
488

    
489
                        //Se obtiene el valor de la fecha
490

    
491
                        /*            date = StringUtilities.substringDelimited(expresion, "Date(", ")",
492
                           startIndex);
493
                         */
494
                        if (date == null) {
495
                                return expresion;
496
                        }
497

    
498
                        startIndex = expresion.indexOf(date, startIndex);
499
                }
500

    
501
                return expresion;
502
        }
503

    
504
        /**
505
         * DOCUMENT ME!
506
         *
507
         * @param expresion DOCUMENT ME!
508
         *
509
         * @return DOCUMENT ME!
510
         *
511
         * @throws ParseException DOCUMENT ME!
512
         */
513
        public String translateNumber(String expresion) throws ParseException {
514
                DefaultCharSet ss = new DefaultCharSet();
515
                ss.addInterval('0', '9');
516
                ss.addCharacter(',');
517
                ss.addCharacter('.');
518

    
519
                String number = StringUtilities.substringWithSymbols(expresion, ss, 0);
520

    
521
                if (number == null) {
522
                        return expresion;
523
                }
524

    
525
                int startIndex = expresion.indexOf(number);
526

    
527
                while (startIndex != -1) {
528
                        Number n = nf.parse(number);
529

    
530
                        if (!StringUtilities.isBetweenSymbols(expresion, startIndex, "\"")) {
531
                                //Se sustituye por el valor ordinal de la fecha
532
                                expresion = expresion.substring(0, startIndex) +
533
                                        expresion.substring(startIndex).replaceFirst(number,
534
                                                n.toString());
535
                        } else {
536
                                startIndex += n.toString().length();
537
                        }
538

    
539
                        number = StringUtilities.substringWithSymbols(expresion, ss,
540
                                        startIndex);
541

    
542
                        if (number == null) {
543
                                return expresion;
544
                        }
545

    
546
                        startIndex = expresion.indexOf(number, startIndex);
547
                }
548

    
549
                return expresion;
550
        }
551

    
552
        /**
553
         * DOCUMENT ME!
554
         *
555
         * @param arg0
556
         *
557
         * @return
558
         */
559
        public boolean addExpressionListener(ExpressionListener arg0) {
560
                return expressionListeners.add(arg0);
561
        }
562

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

    
574
        /**
575
         * @see com.iver.mdiApp.ui.MDIManager.IWindow#getWindowInfo()
576
         */
577
        public WindowInfo getWindowInfo() {
578
                WindowInfo vi = new WindowInfo(WindowInfo.ICONIFIABLE | WindowInfo.PALETTE);
579

    
580
                //if (System.getProperty("os.name")co.compareTo(arg0))
581
                vi.setHeight(this.filterDialog_Height);
582
                vi.setWidth(this.filterDialog_Width);
583

    
584
                // Old instructions
585
//                vi.setWidth(480);
586
//                vi.setHeight(362);
587
                vi.setTitle(PluginServices.getText( this, "filtro") + " (" + title + ")");
588
                return vi;
589
        }
590

    
591
        /**
592
         * DOCUMENT ME!
593
         *
594
         * @param o DOCUMENT ME!
595
         */
596
        public void addExceptionListener(ExceptionListener o) {
597
                exceptionHandlingSupport.addExceptionListener(o);
598
        }
599

    
600
        /**
601
         * DOCUMENT ME!
602
         *
603
         * @param o DOCUMENT ME!
604
         *
605
         * @return DOCUMENT ME!
606
         */
607
        public boolean removeExceptionListener(ExceptionListener o) {
608
                return exceptionHandlingSupport.removeExceptionListener(o);
609
        }
610

    
611
        /**
612
         * DOCUMENT ME!
613
         *
614
         * @param t DOCUMENT ME!
615
         */
616
        private void throwException(Throwable t) {
617
                exceptionHandlingSupport.throwException(t);
618
        }
619

    
620
    /* (non-Javadoc)
621
     * @see com.iver.andami.ui.mdiManager.ViewListener#viewActivated()
622
     */
623
    public void windowActivated() {
624
    }
625

    
626
    /* (non-Javadoc)
627
     * @see com.iver.andami.ui.mdiManager.ViewListener#viewClosed()
628
     */
629
    public void windowClosed() {
630
        try {
631
            model.stop();
632
        } catch (ReadDriverException e) {
633
            NotificationManager.addError(e.getMessage(), e);
634
        }
635
    }
636
    public Object getWindowProfile() {
637
                return WindowInfo.TOOL_PROFILE;
638
        }
639
}