Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app.document.table.app / org.gvsig.app.document.table.app.mainplugin / src / main / java / org / gvsig / app / project / documents / table / TableOperations.java @ 40558

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
package org.gvsig.app.project.documents.table;
25

    
26
import java.awt.Component;
27
import java.text.ParseException;
28
import java.util.ArrayList;
29
import java.util.Iterator;
30
import java.util.List;
31

    
32
import javax.swing.JOptionPane;
33
import javax.swing.event.TableModelListener;
34

    
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38
import org.gvsig.andami.PluginServices;
39
import org.gvsig.andami.messages.NotificationManager;
40
import org.gvsig.app.ApplicationLocator;
41
import org.gvsig.app.project.documents.table.gui.CreateNewAttributePanel;
42
import org.gvsig.app.project.documents.table.gui.FeatureTableDocumentPanel;
43
import org.gvsig.fmap.dal.DataTypes;
44
import org.gvsig.fmap.dal.exception.DataException;
45
import org.gvsig.fmap.dal.feature.EditableFeature;
46
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
47
import org.gvsig.fmap.dal.feature.EditableFeatureType;
48
import org.gvsig.fmap.dal.feature.Feature;
49
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
50
import org.gvsig.fmap.dal.feature.FeatureSelection;
51
import org.gvsig.fmap.dal.feature.FeatureSet;
52
import org.gvsig.fmap.dal.feature.FeatureStore;
53
import org.gvsig.fmap.dal.feature.FeatureType;
54
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureTypeException;
55
import org.gvsig.fmap.mapcontrol.dal.feature.swing.FeatureTable;
56
import org.gvsig.fmap.mapcontrol.dal.feature.swing.table.FeatureTableModel;
57
import org.gvsig.i18n.Messages;
58
import org.gvsig.tools.dispose.DisposableIterator;
59

    
60
/**
61
 * Feature Table Operations.
62
 * 
63
 * @author Vicente Caballero Navarro
64
 * 
65
 */
66
public class TableOperations {
67

    
68
    private static Logger logger = LoggerFactory.getLogger(TableOperations.class);
69
    
70
    public static final int MAX_FIELD_LENGTH = 254;
71
    private static TableOperations fto = null;
72
    private ArrayList<Feature> selectedFeatures = new ArrayList<Feature>();
73
    private boolean cutting = false;
74
    
75
    private FeatureTableDocumentPanel tablePanel = null;
76
    private FeatureStore featureStore;
77

    
78
    public static TableOperations getInstance() {
79
        if (fto == null) {
80
            fto = new TableOperations();
81
        }
82
        return fto;
83
    }
84

    
85
    public void setTablePanel(FeatureTableDocumentPanel tp) {
86
        tablePanel = tp;
87
        featureStore = tp.getModel().getStore();
88
    }
89

    
90
    public void copyFeatures() throws DataException {
91
        cutting = false;
92
        copy();
93
    }
94

    
95
    public boolean hasSelection() {
96
        return !selectedFeatures.isEmpty();
97
    }
98

    
99
    public void pasteFeatures() throws DataException {
100
        if (cutting) {
101
            delete();
102
            cutting = false;
103
        }
104
        Iterator<Feature> features = selectedFeatures.iterator();
105
        while (features.hasNext()) {
106
            Feature feature = features.next();
107
            featureStore.insert(feature.getEditable());
108
        }
109
    }
110

    
111
    public void cutFeatures() throws DataException {
112
        cutting = true;
113
        copy();
114
    }
115

    
116
    private void copy() throws DataException {
117
        DisposableIterator features = null;
118
        try {
119
            features =
120
                ((FeatureSelection) featureStore.getSelection()).fastIterator();
121
            selectedFeatures.clear();
122
            while (features.hasNext()) {
123
                Feature feature = (Feature) features.next();
124
                selectedFeatures.add(feature);
125
            }
126
        } finally {
127
            if (features != null) {
128
                features.dispose();
129
            }
130
        }
131
    }
132

    
133
    private void delete() throws DataException {
134
        Iterator<Feature> features = selectedFeatures.iterator();
135
        while (features.hasNext()) {
136
            Feature feature = features.next();
137
            featureStore.delete(feature);
138
        }
139
    }
140

    
141
    public void deleteFeatures() throws DataException {
142
        
143
        FeatureTableModel _ftm = this.tablePanel.getTablePanel().getTableModel();
144
        List<TableModelListener> tmll = removeTableModelListeners(_ftm);
145
        
146

    
147
        DisposableIterator features = null;
148
        try {
149
            /*
150
            features =
151
                ((FeatureSelection) featureStore.getSelection()).fastIterator();
152
                */
153
            
154
            FeatureSet all_fset = featureStore.getFeatureSet();
155
            FeatureSelection sele = (FeatureSelection) featureStore.getSelection();
156
            features = all_fset.fastIterator();
157
            Feature item = null;
158
            
159
            while (features.hasNext()) {
160
                item = (Feature) features.next();
161
                if (sele.isSelected(item)) {
162
                    all_fset.delete(item);
163
                }
164
            }
165

    
166
            /*
167
            while (features.hasNext()) {
168
                features.remove();
169
            }
170
            */
171
            
172
        } finally {
173
            if (features != null) {
174
                features.dispose();
175
            }
176
            
177
            addTableModelListeners(_ftm, tmll);
178
        }
179
    }
180

    
181
    /**
182
     * @param _ftm
183
     * @param tmll
184
     */
185
    private void addTableModelListeners(
186
        FeatureTableModel _model,
187
        List<TableModelListener> _list) {
188
        
189
        Iterator<TableModelListener> iter = _list.iterator();
190
        while (iter.hasNext()) {
191
            _model.addTableModelListener(iter.next());
192
        }
193
        _model.fireTableDataChanged();
194
    }
195

    
196
    /**
197
     * @param ftm
198
     * @param class1
199
     * @return
200
     */
201
    private List<TableModelListener> removeTableModelListeners(FeatureTableModel ftm) {
202
        
203
        TableModelListener[] ll = ftm.getListeners(TableModelListener.class);
204
        List<TableModelListener> resp = new ArrayList<TableModelListener>();
205
        
206
        int n = ll.length;
207
        for (int i=0; i<n; i++) {
208
            resp.add(ll[i]);
209
            ftm.removeTableModelListener(ll[i]);
210
        }
211

    
212
        return resp;
213
    }
214

    
215
    public void insertNewFeature() throws DataException {
216
        // if (getModel().getAssociatedTable()!=null){
217
        // JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),"No se puede a?adir una fila a una tabla asociada a una capa.");
218
        // return;
219
        // }
220
        EditableFeature feature = featureStore.createNewFeature();
221
        featureStore.insert(feature);
222
    }
223

    
224
    public void deleteAttributes(FeatureTable table) throws DataException {
225
        EditableFeatureType eft =
226
            featureStore.getDefaultFeatureType().getEditable();
227
        FeatureAttributeDescriptor[] selecteds =
228
            table.getSelectedColumnsAttributeDescriptor();
229
        for (int i = 0; i < selecteds.length; i++) {
230
            eft.remove(selecteds[i].getName());
231
        }
232
        featureStore.update(eft);
233
    }
234

    
235
    public void insertAttributes(FeatureTable table) throws DataException {
236
        EditableFeatureType eft =
237
            featureStore.getDefaultFeatureType().getEditable();
238

    
239
        try {
240
            CreateNewAttributePanel panelNewField =
241
                new CreateNewAttributePanel();
242

    
243
            EditableFeatureAttributeDescriptor ead =
244
                panelNewField.loadFieldDescription(eft);
245
            if (ead == null) {
246
                return;
247
            }
248
            if (ead.getType() == DataTypes.STRING
249
                && ead.getSize() > MAX_FIELD_LENGTH) {
250
                NotificationManager.showMessageInfo(
251
                    PluginServices.getText(this, "max_length_is") + ":"
252
                        + MAX_FIELD_LENGTH, null);
253
                ead.setSize(MAX_FIELD_LENGTH);
254
            }
255
            PluginServices.getMDIManager().closeWindow(panelNewField);
256
        } catch (ParseException e2) {
257
            NotificationManager.addError(e2);
258
        }
259
        featureStore.update(eft);
260

    
261
    }
262

    
263
    public void renameAttributes(FeatureTable table) throws DataException {
264
        
265
        FeatureType _ft = featureStore.getDefaultFeatureType();
266

    
267
        FeatureAttributeDescriptor[] selecteds =
268
            table.getSelectedColumnsAttributeDescriptor();
269

    
270
        for (int i = selecteds.length - 1; i >= 0; i--) {
271
            String newName =
272
                JOptionPane.showInputDialog((Component) PluginServices
273
                    .getMDIManager().getActiveWindow(),
274
                    PluginServices.getText(
275
                    this, "_Please_insert_new_field_name_Cannot_be_undone"),
276
                    selecteds[i]
277
                    .getName());
278
            if (newName == null) {
279
                return;
280
            }
281
            if (_ft.getIndex(newName) != -1) {
282
                NotificationManager.showMessageInfo(
283
                    PluginServices.getText(this, "field_already_exists"), null);
284
                return;
285
            }
286
            
287
            renameAttribute(featureStore, selecteds[i].getName(), newName);
288
        }
289
        
290
        // featureStore.finishEditing();
291
        // featureStore.edit(FeatureStore.MODE_FULLEDIT);
292
    }
293

    
294
    /**
295
     * This method renames a field in three steps:
296
     * 
297
     * (1) add new field using type and size of old field.
298
     * (2) copy value from old field to new field.
299
     * (3) remove old field.
300
     * 
301
     * @param fs
302
     * @param name
303
     * @param newName
304
     * @return true if the change took place
305
     */
306
    private static boolean renameAttribute(FeatureStore fs, String name, String newName) {
307

    
308
        EditableFeatureType eft = null;
309
        FeatureType dft = null;
310
        try {
311
            dft = fs.getDefaultFeatureType();
312
            
313
            if (dft instanceof EditableFeatureType) {
314
                eft = (EditableFeatureType) dft;
315
            } else {
316
                eft = dft.getEditable();
317
            }
318
            
319
            EditableFeatureAttributeDescriptor efad =
320
                (EditableFeatureAttributeDescriptor) eft.getAttributeDescriptor(name);
321
            efad.setName(newName);
322
            fs.update(eft);
323
            
324
        } catch (DataException de) {
325
            
326
            Component root_comp =
327
                ApplicationLocator.getManager().getRootComponent();
328

    
329
            JOptionPane.showMessageDialog(
330
                root_comp,
331
                Messages.getText("_Unable_to_rename_attribute") +
332
                ": " + de.getMessage(),
333
                Messages.getText("_Unable_to_rename_attribute"),
334
                JOptionPane.ERROR_MESSAGE);
335
            return false;
336
        }
337
        return true;
338

    
339
        /*
340
        try {
341
            // ========== add new field
342
            eft = fs.getDefaultFeatureType().getEditable();
343
            FeatureAttributeDescriptor fad = eft.getAttributeDescriptor(name);
344
            eft.add(newName, fad.getType(), fad.getSize());
345
            fs.update(eft);
346
        } catch (DataException ex) {
347
            logger.info("Unable to rename attribute (" + name + " --> " + newName + ")", ex);
348
            ApplicationLocator.getManager().message(
349
                Messages.getText("_Unable_to_rename_attribute"),
350
                JOptionPane.ERROR_MESSAGE);
351
            // did not even add new field
352
            return false;
353
        }
354
        
355
        boolean error_when_inserting = false;
356
        try {
357
            // ========== copy value old field -> new field
358
            FeatureSet fset = fs.getFeatureSet();
359
            DisposableIterator diter = fset.fastIterator();
360
            Feature feat = null;
361
            Object val = null;
362
            EditableFeature efeat = null;
363
            while (diter.hasNext()) {
364
                feat = (Feature) diter.next();
365
                val = feat.get(name);
366
                efeat = feat.getEditable();
367
                efeat.set(newName, val);
368
                fset.update(efeat);
369
            }
370
            diter.dispose();
371
            
372
            // Closing editing to check that store admits new field
373
            fs.finishEditing();
374
        } catch (DataException ex) {
375
            
376
            logger.info("Error while renaming att to: " + newName, ex);
377
            String final_msg = getLastMessage(ex);
378
            JOptionPane.showMessageDialog(
379
                root_comp,
380
                Messages.getText("_Unable_to_rename_attribute")
381
                + ": " + final_msg,
382
                Messages.getText("_Rename_column"),
383
                JOptionPane.ERROR_MESSAGE);
384
            error_when_inserting = true;
385
        }
386
        
387
        if (error_when_inserting) {
388
            try {
389
                // Trying to remove new field and leave table as it was
390
                eft.remove(newName);
391
                fs.update(eft);
392
            } catch (DataException ex) {
393
                // Unable to remove added field but user was
394
                // already notified that something went wrong
395
            }
396
            // Not changed
397
            return false;
398
        }
399
            
400

401
        try {
402
            // Finally reopen editing and delete old field
403
            fs.edit(FeatureStore.MODE_FULLEDIT);
404
            eft = fs.getDefaultFeatureType().getEditable();
405
            eft.remove(name);
406
            fs.update(eft);
407
            
408
        } catch (DataException ex) {
409
            logger.info("Unable to rename attribute (" + name + " --> " + newName + ")", ex);
410
            ApplicationLocator.getManager().message(
411
                Messages.getText("_Unable_to_rename_attribute"),
412
                JOptionPane.ERROR_MESSAGE);
413
            return false;
414
        }
415
        return true;
416
        */
417

    
418
    }
419
    
420
    /**
421
     * @param ex
422
     * @return
423
     */
424
    private static String getLastMessage(Throwable ex) {
425
        
426
        Throwable p = ex;
427
        while (p.getCause() != null && p.getCause() != p) {
428
            p = p.getCause();
429
        }
430
        return p.getMessage();
431
    }
432

    
433
    /**
434
     * Renames field in feature store
435
     * 
436
     * @param fs
437
     * @param oldname
438
     * @param newname
439
     * @return 
440
     * @throws DataException
441
     */
442
    public static void renameColumn(FeatureStore fs,
443
        String oldname, String newname) throws DataException {
444
        
445
        FeatureType _ft = fs.getDefaultFeatureType();
446
        if (_ft.getIndex(newname) != -1) {
447
            throw new StoreUpdateFeatureTypeException(
448
                new Exception("Attribute name already existed."),
449
                fs.getName());
450
        }
451
        renameAttribute(fs, oldname, newname);
452
        // fs.finishEditing();
453
    }
454

    
455
}