Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.fmap.control / src / main / java / org / gvsig / fmap / mapcontrol / dal / feature / swing / table / ConfigurableFeatureTableModel.java @ 42775

History | View | Annotate | Download (17.8 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
/*
25
 * AUTHORS (In addition to CIT):
26
 * 2008 {DiSiD Technologies}  {Create a JTable TableModel for a FeatureQuery}
27
 */
28
package org.gvsig.fmap.mapcontrol.dal.feature.swing.table;
29

    
30
import java.security.InvalidParameterException;
31
import java.text.SimpleDateFormat;
32
import java.util.ArrayList;
33
import java.util.HashMap;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Locale;
37
import java.util.Map;
38

    
39
import javax.swing.event.TableModelEvent;
40
import org.apache.commons.lang3.StringUtils;
41

    
42
import org.gvsig.fmap.dal.DataTypes;
43
import org.gvsig.fmap.dal.feature.EditableFeature;
44
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
45
import org.gvsig.fmap.dal.feature.Feature;
46
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
47
import org.gvsig.fmap.dal.feature.FeatureQuery;
48
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
49
import org.gvsig.fmap.dal.feature.FeatureStore;
50
import org.gvsig.fmap.dal.feature.FeatureType;
51
import org.gvsig.tools.exception.BaseException;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

    
55
/**
56
 * Extends the FeatureTableModel to add more configurable options, like the
57
 * visible columns, column name aliases and row order.
58
 * 
59
 * TODO: a?adir la persistencia.
60
 * 
61
 * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
62
 */
63
public class ConfigurableFeatureTableModel extends FeatureTableModel {
64

    
65
    private static final long serialVersionUID = -8223987814719746492L;
66
    
67
    private static final Logger logger = LoggerFactory.getLogger(ConfigurableFeatureTableModel.class);
68

    
69
    private List<String> columnNames;
70

    
71
    private List<String> visibleColumnNames;
72

    
73
    private List<String> visibleColumnNamesOriginal;
74

    
75
    private Map<String, String> name2Alias;
76

    
77
    private Map<String, String> name2AliasOriginal;
78

    
79
    private Map<String,String> patterns = null;
80

    
81
    private Locale localeOfData;    
82
    /**
83
     * @see FeatureTableModel#FeatureTableModel(FeatureStore, FeatureQuery)
84
     */
85
    public ConfigurableFeatureTableModel(FeatureStore featureStore,
86
        FeatureQuery featureQuery) throws BaseException {
87
        super(featureStore, featureQuery);
88
        this.localeOfData = Locale.getDefault();
89
    }
90

    
91
    /**
92
     * @see FeatureTableModel#FeatureTableModel(FeatureStore, FeatureQuery, int)
93
     */
94
    public ConfigurableFeatureTableModel(FeatureStore featureStore,
95
        FeatureQuery featureQuery, int pageSize) throws BaseException {
96
        super(featureStore, featureQuery, pageSize);
97
    }
98

    
99
    @Override
100
    public int getColumnCount() {
101
        return visibleColumnNames.size();
102
    }
103

    
104
    public int getOriginalColumnCount() {
105
        return super.getColumnCount();
106
    }
107

    
108
    @Override
109
    public String getColumnName(int column) {
110
        int originalIndex = getOriginalColumnIndex(column);
111
        return getAliasForColumn(getOriginalColumnName(originalIndex));
112
    }
113

    
114
    @Override
115
    public Class<?> getColumnClass(int columnIndex) {
116
        int originalIndex = getOriginalColumnIndex(columnIndex);
117
        return super.getColumnClass(originalIndex);
118
    }
119

    
120
    @Override
121
    public FeatureAttributeDescriptor getDescriptorForColumn(int columnIndex) {
122
        int originalIndex = getOriginalColumnIndex(columnIndex);
123
        return super.getDescriptorForColumn(originalIndex);
124
    }
125

    
126
    /**
127
     * Returns the original name of the column, ignoring the alias.
128
     * 
129
     * @param column
130
     *            the original index of the column
131
     * @return the original column name
132
     */
133
    public String getOriginalColumnName(int column) {
134
        return super.getColumnName(column);
135
    }
136

    
137
    /**
138
     * Sets the visibility of a table column.
139
     * 
140
     * @param columnIndex
141
     *            the index of the column to update
142
     * @param visible
143
     *            if the column will be visible or not
144
     */
145
    public void setVisible(String name, boolean visible) {
146
        // If we don't have already the column as visible,
147
        // add to the list, without order, and recreate
148
        // the visible columns list in the original order
149
        if (!columnNames.contains(name)) {
150
            throw new InvalidParameterException(name); // FIXME
151
        }
152
        if (visible && !visibleColumnNames.contains(name)) {
153
            visibleColumnNames.add(name);
154
            setVisibleColumns(visibleColumnNames);
155
        } else {
156
            visibleColumnNames.remove(name);
157
            setVisibleColumns(visibleColumnNames);
158
            fireTableStructureChanged();
159
        }
160

    
161
    }
162

    
163
    @Override
164
    public void setFeatureType(FeatureType featureType) {
165
        // Check if there is a new column name
166
        List<String> newColumns = new ArrayList<String>();
167
        List<String> renamedColumnsNewName = new ArrayList<String>();
168
        
169
        @SuppressWarnings("unchecked")
170
        Iterator<FeatureAttributeDescriptor> attrIter = featureType.iterator();
171
        FeatureAttributeDescriptor fad = null;
172
        EditableFeatureAttributeDescriptor efad = null;
173
        
174
        String colName;
175
        while (attrIter.hasNext()) {
176
            fad = attrIter.next();
177
            colName = fad.getName();
178
            if (!columnNames.contains(colName)) {
179
                if (fad instanceof EditableFeatureAttributeDescriptor) {
180
                    efad = (EditableFeatureAttributeDescriptor) fad; 
181
                    /*
182
                     * If editable att descriptor,
183
                     * check original name
184
                     */
185
                    if (efad.getOriginalName() != null) {
186
                        if (!columnNames.contains(efad.getOriginalName())) {
187
                            /*
188
                             * Check with original name but add current name
189
                             */
190
                            newColumns.add(colName);
191
                        } else {
192
                            /*
193
                             * List of new names of renamed columns
194
                             */
195
                            renamedColumnsNewName.add(colName);
196
                        }
197
                    } else {
198
                        newColumns.add(colName);
199
                    }
200
                } else {
201
                    newColumns.add(colName);
202
                }
203
            }
204
        }
205

    
206
        // Update column names
207
        columnNames.clear();
208
        @SuppressWarnings("unchecked")
209
        Iterator<FeatureAttributeDescriptor> visibleAttrIter =
210
            featureType.iterator();
211
        while (visibleAttrIter.hasNext()) {
212
            fad = visibleAttrIter.next();
213
            colName = fad.getName();
214
            columnNames.add(colName);
215
            //If the column is added has to be visible
216
            if (!visibleColumnNames.contains(colName)) {
217

    
218
                if (((newColumns.contains(colName)
219
                    || renamedColumnsNewName.contains(colName)))
220
                    &&
221
                    fad.getType() != DataTypes.GEOMETRY) {
222
                    // Add new columns and renamed
223
                    visibleColumnNames.add(colName);
224
                    visibleColumnNamesOriginal.add(colName);
225
                }
226
                /*
227
                if (renamedColumnsNewName.contains(colName)) {
228
                    // Add renamed
229
                    insertWhereOldName(visibleColumnNames, colName, fad);
230
                    insertWhereOldName(visibleColumnNamesOriginal, colName, fad);
231
                }
232
                */
233
            }
234
        }
235

    
236
        // remove from visible columns removed columns
237
        visibleColumnNames = intersectKeepOrder(columnNames, visibleColumnNames);
238
        // instead of: visibleColumnNames.retainAll(columnNames);
239

    
240
        visibleColumnNamesOriginal = intersectKeepOrder(columnNames, visibleColumnNamesOriginal);
241
        // instead of: visibleColumnNamesOriginal.retainAll(columnNames);
242

    
243
        // remove from alias map removed columns
244
        name2Alias.keySet().retainAll(columnNames);
245
        name2AliasOriginal.keySet().retainAll(columnNames);
246

    
247
        super.setFeatureType(featureType);
248

    
249
    }
250

    
251
    /**
252
     * keeps order of first parameter
253
     * 
254
     * @param lista
255
     * @param listb
256
     * @return
257
     */
258
    private List<String> intersectKeepOrder(List<String> lista, List<String> listb) {
259
        
260
        List<String> resp = new ArrayList<String>();
261
        resp.addAll(lista);
262
        resp.retainAll(listb);
263
        return resp;
264
    }
265

    
266
    private void insertWhereOldNamee(
267
        List<String> str_list,
268
        String str,
269
        FeatureAttributeDescriptor fad) {
270
        
271
        if (fad instanceof EditableFeatureAttributeDescriptor) {
272
            EditableFeatureAttributeDescriptor efad =
273
                (EditableFeatureAttributeDescriptor) fad;
274
            if (efad.getOriginalName() != null) {
275
                int old_ind = str_list.indexOf(efad.getOriginalName());
276
                if (old_ind != -1) {
277
                    // Insert before old name
278
                    str_list.add(old_ind, str);
279
                } else {
280
                    // Insert anyway (add)
281
                    str_list.add(str);
282
                }
283
            } else {
284
                // Insert anyway (add)
285
                str_list.add(str);
286
            }
287
        } else {
288
            // Insert anyway (add)
289
            str_list.add(str);
290
        }
291
    }
292

    
293
    /**
294
     * Sets the current visible columns list, in the original order.
295
     * 
296
     * @param names
297
     *            the names of the columns to set as visible
298
     */
299
    public void setVisibleColumns(List<String> names) {
300
        // Recreate the visible column names list
301
        // to maintain the original order        
302
        visibleColumnNames = new ArrayList<String>(names.size());
303
        for (int i = 0; i < columnNames.size(); i++) {
304
            String columnName = columnNames.get(i);
305
            if (names.contains(columnName)) {
306
                visibleColumnNames.add(columnName);
307
            }
308
        }
309
        updatePaginHelperWithHiddenColums();
310
        fireTableStructureChanged();
311
    }
312

    
313
    protected String[] getHiddenColumnNames() {
314
        List<String> hiddenColumns = new ArrayList<String>();
315
        hiddenColumns.addAll(columnNames);
316
        
317
        for (int i = 0; i < visibleColumnNames.size(); i++) {
318
            String columnName = visibleColumnNames.get(i);
319
            hiddenColumns.remove(columnName);
320
        }
321
        if( hiddenColumns.size()<1 ) {
322
            return null;
323
        }
324
        return (String[]) hiddenColumns.toArray(new String[hiddenColumns.size()]);
325
    }
326
        
327
    /**
328
     * Changes all columns to be visible.
329
     */
330
    public void setAllVisible() {
331
        visibleColumnNames.clear();
332
        visibleColumnNames.addAll(columnNames);
333
        fireTableStructureChanged();
334
    }
335

    
336
    /**
337
     * Sets the alias for a column.
338
     * 
339
     * @param name
340
     *            the name of the column
341
     * @param alias
342
     *            the alias for the column
343
     */
344
    public void setAlias(String name, String alias) {
345
        name2Alias.put(name, alias);
346
        fireTableStructureChanged();
347
    }
348

    
349
    public void orderByColumn(String name, boolean ascending)
350
        throws BaseException {
351
        FeatureQueryOrder order = getHelper().getFeatureQuery().getOrder();
352
        if (order == null) {
353
            order = new FeatureQueryOrder();
354
            getHelper().getFeatureQuery().setOrder(order);
355
        }
356
        order.clear();
357
        order.add(name, ascending);
358
        getHelper().reload();
359
        fireTableChanged(new TableModelEvent(this, 0, getRowCount() - 1));
360
    }
361

    
362
    @Override
363
    protected void initialize() {
364
        super.initialize();
365

    
366
        initializeVisibleColumns();
367
        initializeAliases();
368
        updatePaginHelperWithHiddenColums();
369
    }
370

    
371
    /**
372
     * Returns if a column is visible.
373
     * 
374
     * @param name
375
     *            the name of the column
376
     * @return if the column is visible
377
     */
378
    public boolean isVisible(String name) {
379
        return visibleColumnNames.contains(name);
380
    }
381

    
382
    /**
383
     * Initializes the table name aliases.
384
     */
385
    private void initializeAliases() {
386
        int columns = super.getColumnCount();
387
        name2Alias = new HashMap<String, String>(columns);
388
        name2AliasOriginal = new HashMap<String, String>(columns);
389
    }
390

    
391
    /**
392
     * Initializes the table visible columns.
393
     */
394
    protected void initializeVisibleColumns() {
395
        int columns = super.getColumnCount();
396
        columnNames = new ArrayList<String>(columns);
397
        visibleColumnNames = new ArrayList<String>(columns);
398

    
399
        for (int i = 0; i < columns; i++) {
400
            String columnName = super.getColumnName(i);
401
            columnNames.add(columnName);
402

    
403
            // By default, geometry columns will not be visible
404
            FeatureAttributeDescriptor descriptor =
405
                super.getDescriptorForColumn(i);
406
            if (descriptor.getType() != DataTypes.GEOMETRY) {
407
                visibleColumnNames.add(columnName);
408
            }
409
        }
410
        
411
        visibleColumnNamesOriginal = new ArrayList<String>(visibleColumnNames);
412
    }
413

    
414
    /**
415
     * Returns the alias for the name of a column.
416
     * 
417
     * @param name
418
     *            of the column
419
     * @return the alias
420
     */
421
    protected String getAliasForColumn(String name) {
422
        String alias = name2Alias.get(name);
423
        return alias == null ? name : alias;
424
    }
425

    
426
    /**
427
     * Returns the original position of a column.
428
     * 
429
     * @param columnIndex
430
     *            the current visible column index
431
     * @return the original column index
432
     */
433
    public int getOriginalColumnIndex(int columnIndex) {
434
        String columnName = visibleColumnNames.get(columnIndex);
435
        return columnNames.indexOf(columnName);
436
    }
437

    
438
    @Override
439
    protected Object getFeatureValue(Feature feature, int columnIndex) {
440
        int realColumnIndex = getOriginalColumnIndex(columnIndex);
441
        return super.getFeatureValue(feature, realColumnIndex);
442
    }
443

    
444
    @Override
445
    protected EditableFeature setFeatureValue(Feature feature, int columnIndex,
446
        Object value) {
447
        int realColumnIndex = getOriginalColumnIndex(columnIndex);
448
        return super.setFeatureValue(feature, realColumnIndex, value);
449
    }
450
    
451
    /**
452
     * Make current changes in configuration (visible columns and aliases)
453
     * as definitive.
454
     */
455
    public void acceptChanges() {
456
            visibleColumnNamesOriginal = new ArrayList<String>(visibleColumnNames);
457
            name2AliasOriginal = new HashMap<String, String>(name2Alias);
458
    }
459
    
460
    /**
461
     * Cancel current changes in configuration (visible columns and aliases)
462
     * and return to previous status.
463
     */
464
    public void cancelChanges() {
465
            visibleColumnNames = new ArrayList<String>(visibleColumnNamesOriginal);
466
            name2Alias = new HashMap<String, String>(name2AliasOriginal);
467
            fireTableStructureChanged();
468
    }
469

    
470
    protected void initializeFormattingPatterns() {
471
        this.patterns = new HashMap<String, String>();
472

    
473
        int columns = super.getColumnCount();
474

    
475
        for (int i = 0; i < columns; i++) {
476
            String columnName = super.getColumnName(i);
477
            initializeFormattingPattern(columnName);
478
        }
479
    } 
480
    
481
    protected void initializeFormattingPattern(String columnName) {
482
        FeatureAttributeDescriptor descriptor = 
483
                this.getFeatureType().getAttributeDescriptor(columnName);
484

    
485
        switch(descriptor.getDataType().getType()) {
486
        case DataTypes.BYTE:
487
        case DataTypes.INT:
488
        case DataTypes.LONG:
489
            String defaultIntegerPattern = "#,##0";
490
            this.patterns.put(columnName,defaultIntegerPattern);
491
            break;
492
        case DataTypes.DOUBLE:
493
            String defaultDoublePattern = "#,##0.0000000000";
494
            this.patterns.put(columnName,defaultDoublePattern);
495
            break;
496
        case DataTypes.FLOAT:
497
            String defaultFloatPattern = "#,##0.0000";
498
            this.patterns.put(columnName,defaultFloatPattern);
499
            break;
500
        case DataTypes.DATE:
501
            String defaultDatePattern = new SimpleDateFormat().toPattern();
502
            this.patterns.put(columnName,defaultDatePattern);
503
            break;
504
        default:
505
            this.patterns.put(columnName,null);
506
        }
507
    }
508
    
509
    public String getFormattingPattern(int column) {
510
        String columnName = this.visibleColumnNames.get(column);
511
        return this.getFormattingPattern(columnName);
512
    }
513
    
514
    public String getFormattingPattern(String columnName) {
515
        if( this.patterns==null ) {
516
            initializeFormattingPatterns();
517
        }
518
        String pattern = this.patterns.get(columnName);
519
        if( StringUtils.isBlank(pattern) ) {
520
            initializeFormattingPattern(columnName);
521
        }
522
        return pattern;
523
    }
524
    
525
    public void setFormattingPattern(String columnName, String pattern) {
526
        if( this.patterns==null ) {
527
            initializeFormattingPatterns();
528
        }
529
        this.patterns.put(columnName,pattern);
530
    }
531
    
532
    public Locale getLocaleOfData() {
533
        return this.localeOfData;
534
    }
535
    
536
    public void setLocaleOfData(Locale locale) {
537
        this.localeOfData = locale;
538
    }
539
    
540

    
541
}