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 @ 41212

History | View | Annotate | Download (15.3 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.util.ArrayList;
32
import java.util.HashMap;
33
import java.util.Iterator;
34
import java.util.List;
35
import java.util.Map;
36
import java.util.logging.Level;
37

    
38
import javax.swing.event.TableModelEvent;
39

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

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

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

    
67
    private List<String> columnNames;
68

    
69
    private List<String> visibleColumnNames;
70

    
71
    private List<String> visibleColumnNamesOriginal;
72

    
73
    private Map<String, String> name2Alias;
74

    
75
    private Map<String, String> name2AliasOriginal;
76

    
77
    /**
78
     * @see FeatureTableModel#FeatureTableModel(FeatureStore, FeatureQuery)
79
     */
80
    public ConfigurableFeatureTableModel(FeatureStore featureStore,
81
        FeatureQuery featureQuery) throws BaseException {
82
        super(featureStore, featureQuery);
83
    }
84

    
85
    /**
86
     * @see FeatureTableModel#FeatureTableModel(FeatureStore, FeatureQuery, int)
87
     */
88
    public ConfigurableFeatureTableModel(FeatureStore featureStore,
89
        FeatureQuery featureQuery, int pageSize) throws BaseException {
90
        super(featureStore, featureQuery, pageSize);
91
    }
92

    
93
    @Override
94
    public int getColumnCount() {
95
        return visibleColumnNames.size();
96
    }
97

    
98
    public int getOriginalColumnCount() {
99
        return super.getColumnCount();
100
    }
101

    
102
    @Override
103
    public String getColumnName(int column) {
104
        int originalIndex = getOriginalColumnIndex(column);
105
        return getAliasForColumn(getOriginalColumnName(originalIndex));
106
    }
107

    
108
    @Override
109
    public Class<?> getColumnClass(int columnIndex) {
110
        int originalIndex = getOriginalColumnIndex(columnIndex);
111
        return super.getColumnClass(originalIndex);
112
    }
113

    
114
    @Override
115
    public FeatureAttributeDescriptor getDescriptorForColumn(int columnIndex) {
116
        int originalIndex = getOriginalColumnIndex(columnIndex);
117
        return super.getDescriptorForColumn(originalIndex);
118
    }
119

    
120
    /**
121
     * Returns the original name of the column, ignoring the alias.
122
     * 
123
     * @param column
124
     *            the original index of the column
125
     * @return the original column name
126
     */
127
    public String getOriginalColumnName(int column) {
128
        return super.getColumnName(column);
129
    }
130

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

    
155
    }
156

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

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

    
212
                if (((newColumns.contains(colName)
213
                    || renamedColumnsNewName.contains(colName)))
214
                    &&
215
                    fad.getType() != DataTypes.GEOMETRY) {
216
                    // Add new columns and renamed
217
                    visibleColumnNames.add(colName);
218
                    visibleColumnNamesOriginal.add(colName);
219
                }
220
                /*
221
                if (renamedColumnsNewName.contains(colName)) {
222
                    // Add renamed
223
                    insertWhereOldName(visibleColumnNames, colName, fad);
224
                    insertWhereOldName(visibleColumnNamesOriginal, colName, fad);
225
                }
226
                */
227
            }
228
        }
229

    
230
        // remove from visible columns removed columns
231
        visibleColumnNames = intersectKeepOrder(columnNames, visibleColumnNames);
232
        // instead of: visibleColumnNames.retainAll(columnNames);
233

    
234
        visibleColumnNamesOriginal = intersectKeepOrder(columnNames, visibleColumnNamesOriginal);
235
        // instead of: visibleColumnNamesOriginal.retainAll(columnNames);
236

    
237
        // remove from alias map removed columns
238
        name2Alias.keySet().retainAll(columnNames);
239
        name2AliasOriginal.keySet().retainAll(columnNames);
240

    
241
        super.setFeatureType(featureType);
242

    
243
    }
244

    
245
    /**
246
     * keeps order of first parameter
247
     * 
248
     * @param lista
249
     * @param listb
250
     * @return
251
     */
252
    private List<String> intersectKeepOrder(List<String> lista, List<String> listb) {
253
        
254
        List<String> resp = new ArrayList<String>();
255
        resp.addAll(lista);
256
        resp.retainAll(listb);
257
        return resp;
258
    }
259

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

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

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

    
330
    /**
331
     * Sets the alias for a column.
332
     * 
333
     * @param name
334
     *            the name of the column
335
     * @param alias
336
     *            the alias for the column
337
     */
338
    public void setAlias(String name, String alias) {
339
        name2Alias.put(name, alias);
340
        fireTableStructureChanged();
341
    }
342

    
343
    public void orderByColumn(String name, boolean ascending)
344
        throws BaseException {
345
        FeatureQueryOrder order = getHelper().getFeatureQuery().getOrder();
346
        if (order == null) {
347
            order = new FeatureQueryOrder();
348
            getHelper().getFeatureQuery().setOrder(order);
349
        }
350
        order.clear();
351
        order.add(name, ascending);
352
        getHelper().reload();
353
        fireTableChanged(new TableModelEvent(this, 0, getRowCount() - 1));
354
    }
355

    
356
    @Override
357
    protected void initialize() {
358
        super.initialize();
359

    
360
        initializeVisibleColumns();
361
        initializeAliases();
362
        updatePaginHelperWithHiddenColums();
363
    }
364

    
365
    /**
366
     * Returns if a column is visible.
367
     * 
368
     * @param name
369
     *            the name of the column
370
     * @return if the column is visible
371
     */
372
    public boolean isVisible(String name) {
373
        return visibleColumnNames.contains(name);
374
    }
375

    
376
    /**
377
     * Initializes the table name aliases.
378
     */
379
    private void initializeAliases() {
380
        int columns = super.getColumnCount();
381
        name2Alias = new HashMap<String, String>(columns);
382
        name2AliasOriginal = new HashMap<String, String>(columns);
383
    }
384

    
385
    /**
386
     * Initializes the table visible columns.
387
     */
388
    protected void initializeVisibleColumns() {
389
        int columns = super.getColumnCount();
390
        columnNames = new ArrayList<String>(columns);
391
        visibleColumnNames = new ArrayList<String>(columns);
392

    
393
        for (int i = 0; i < columns; i++) {
394
            String columnName = super.getColumnName(i);
395
            columnNames.add(columnName);
396

    
397
            // By default, geometry columns will not be visible
398
            FeatureAttributeDescriptor descriptor =
399
                super.getDescriptorForColumn(i);
400
            if (descriptor.getType() != DataTypes.GEOMETRY) {
401
                visibleColumnNames.add(columnName);
402
            }
403
        }
404
        
405
        visibleColumnNamesOriginal = new ArrayList<String>(visibleColumnNames);
406
    }
407

    
408
    /**
409
     * Returns the alias for the name of a column.
410
     * 
411
     * @param name
412
     *            of the column
413
     * @return the alias
414
     */
415
    protected String getAliasForColumn(String name) {
416
        String alias = name2Alias.get(name);
417
        return alias == null ? name : alias;
418
    }
419

    
420
    /**
421
     * Returns the original position of a column.
422
     * 
423
     * @param columnIndex
424
     *            the current visible column index
425
     * @return the original column index
426
     */
427
    protected int getOriginalColumnIndex(int columnIndex) {
428
        String columnName = visibleColumnNames.get(columnIndex);
429
        return columnNames.indexOf(columnName);
430
    }
431

    
432
    @Override
433
    protected Object getFeatureValue(Feature feature, int columnIndex) {
434
        int realColumnIndex = getOriginalColumnIndex(columnIndex);
435
        return super.getFeatureValue(feature, realColumnIndex);
436
    }
437

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