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

History | View | Annotate | Download (16.1 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.awt.event.ActionEvent;
28
import java.awt.event.ActionListener;
29
import java.text.ParseException;
30
import java.util.ArrayList;
31
import java.util.Iterator;
32
import java.util.List;
33

    
34
import javax.swing.JOptionPane;
35
import javax.swing.event.TableModelListener;
36

    
37
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39

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

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

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

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

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

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

    
97
    public boolean hasSelection() {
98
        return !selectedFeatures.isEmpty();
99
    }
100

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

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

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

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

    
143
    public void deleteFeatures() throws DataException {
144
        
145
        FeatureTableModel _ftm = this.tablePanel.getTablePanel().getTableModel();
146
        List<TableModelListener> tmll = removeTableModelListeners(_ftm);
147
        DisposableIterator feat_iter = null;
148
        Feature feat = null;
149
        try {
150
                
151
                
152
            FeatureSelection selection = featureStore.createFeatureSelection();
153
            selection.select((FeatureSet) featureStore.getSelection());
154
            feat_iter = selection.fastIterator();
155
            while (feat_iter.hasNext()) {
156
                feat = (Feature) feat_iter.next();
157
                featureStore.delete(feat);
158
            }
159

    
160
            /*
161
            FeatureSet all_fset = featureStore.getFeatureSet();
162
            FeatureSelection sele = (FeatureSelection) featureStore.getSelection();
163
            features = all_fset.fastIterator();
164
            Feature item = null;
165
            while (features.hasNext()) {
166
                item = (Feature) features.next();
167
                if (sele.isSelected(item)) {
168
                    all_fset.delete(item);
169
                }
170
            }
171
            */
172

    
173
        } finally {
174
            if (feat_iter != null) {
175
                    feat_iter.dispose();
176
            }
177
            
178
            addTableModelListeners(_ftm, tmll);
179
        }
180
    }
181

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

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

    
213
        return resp;
214
    }
215

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

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

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

    
240
                List<String> tmpfnames = new ArrayList<String>();
241
                int size = eft.size();
242
                for (int i = 0; i < size; i++) {
243
                        FeatureAttributeDescriptor ad = (FeatureAttributeDescriptor) eft.get(i);
244
                        tmpfnames.add(ad.getName());
245
                }
246

    
247
                CreateNewAttributePanel panelNewField = new CreateNewAttributePanel();
248
                panelNewField.setCurrentFieldNames(tmpfnames.toArray(new String[0]));
249
                panelNewField.setOkAction(new NewFieldActionListener(panelNewField, eft));
250
                ApplicationLocator.getManager().getUIManager().addWindow(panelNewField);
251
                featureStore.update(eft);
252
    }
253

    
254
    public void renameAttributes(FeatureTable table) throws DataException {
255
        
256
        FeatureType _ft = featureStore.getDefaultFeatureType();
257

    
258
        FeatureAttributeDescriptor[] selecteds =
259
            table.getSelectedColumnsAttributeDescriptor();
260

    
261
        for (int i = selecteds.length - 1; i >= 0; i--) {
262
            String newName =
263
                JOptionPane.showInputDialog((Component) PluginServices
264
                    .getMDIManager().getActiveWindow(),
265
                    PluginServices.getText(
266
                    this, "_Please_insert_new_field_name"),
267
                    selecteds[i]
268
                    .getName());
269
            if (newName == null || newName.length() == 0) {
270
                continue;
271
            }
272
            if (_ft.getIndex(newName) != -1) {
273
                NotificationManager.showMessageInfo(
274
                                Messages.getText("field_already_exists"), null);
275
                return;
276
            }
277
            
278
            renameAttribute(featureStore, selecteds[i].getName(), newName);
279
        }
280
        
281
        // featureStore.finishEditing();
282
        // featureStore.edit(FeatureStore.MODE_FULLEDIT);
283
    }
284

    
285
    /**
286
     * This method renames a field in three steps:
287
     * 
288
     * (1) add new field using type and size of old field.
289
     * (2) copy value from old field to new field.
290
     * (3) remove old field.
291
     * 
292
     * @param fs
293
     * @param name
294
     * @param newName
295
     * @return true if the change took place
296
     */
297
    private static boolean renameAttribute(FeatureStore fs, String name, String newName) {
298

    
299
        EditableFeatureType eft = null;
300
        FeatureType dft = null;
301
        try {
302
            dft = fs.getDefaultFeatureType();
303
            
304
            if (dft instanceof EditableFeatureType) {
305
                eft = (EditableFeatureType) dft;
306
            } else {
307
                eft = dft.getEditable();
308
            }
309
            
310
            EditableFeatureAttributeDescriptor efad =
311
                (EditableFeatureAttributeDescriptor) eft.getAttributeDescriptor(name);
312
            efad.setName(newName);
313
            fs.update(eft);
314
            
315
        } catch (DataException de) {
316
            
317
            Component root_comp =
318
                ApplicationLocator.getManager().getRootComponent();
319

    
320
            JOptionPane.showMessageDialog(
321
                root_comp,
322
                Messages.getText("_Unable_to_rename_attribute") +
323
                ": " + de.getMessage(),
324
                Messages.getText("_Unable_to_rename_attribute"),
325
                JOptionPane.ERROR_MESSAGE);
326
            return false;
327
        }
328
        return true;
329

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

392
        try {
393
            // Finally reopen editing and delete old field
394
            fs.edit(FeatureStore.MODE_FULLEDIT);
395
            eft = fs.getDefaultFeatureType().getEditable();
396
            eft.remove(name);
397
            fs.update(eft);
398
            
399
        } catch (DataException ex) {
400
            logger.info("Unable to rename attribute (" + name + " --> " + newName + ")", ex);
401
            ApplicationLocator.getManager().message(
402
                Messages.getText("_Unable_to_rename_attribute"),
403
                JOptionPane.ERROR_MESSAGE);
404
            return false;
405
        }
406
        return true;
407
        */
408

    
409
    }
410
    
411

    
412

    
413
    /**
414
     * Renames field in feature store
415
     * 
416
     * @param fs
417
     * @param oldname
418
     * @param newname
419
     * @return 
420
     * @throws DataException
421
     */
422
    public static void renameColumn(FeatureStore fs,
423
        String oldname, String newname) throws DataException {
424
        
425
        FeatureType _ft = fs.getDefaultFeatureType();
426
        if (_ft.getIndex(newname) != -1) {
427
            throw new StoreUpdateFeatureTypeException(
428
                new Exception("Attribute name already existed."),
429
                fs.getName());
430
        }
431
        renameAttribute(fs, oldname, newname);
432
        // fs.finishEditing();
433
    }
434
    
435
    public class NewFieldActionListener implements ActionListener {
436

    
437
            private CreateNewAttributePanel panel = null;
438
            private EditableFeatureType eft = null;
439
            
440
            public NewFieldActionListener(CreateNewAttributePanel p, EditableFeatureType t) {
441
                    eft = t;
442
                    panel = p;
443
            }
444
            
445
                public void actionPerformed(ActionEvent e) {
446
            try {
447
                EditableFeatureAttributeDescriptor ead = panel.loadFieldDescription(eft);
448
                if (ead == null) {
449
                    return;
450
                }
451
                if (ead.getType() == DataTypes.STRING
452
                    && ead.getSize() > TableOperations.MAX_FIELD_LENGTH) {
453
                    NotificationManager.showMessageInfo(
454
                        PluginServices.getText(this,
455
                            "max_length_is")
456
                            + ":"
457
                            + TableOperations.MAX_FIELD_LENGTH,
458
                        null);
459
                    ead.setSize(TableOperations.MAX_FIELD_LENGTH);
460
                }
461
                PluginServices.getMDIManager().closeWindow(panel);
462
            } catch (ParseException e2) {
463
                NotificationManager.addError(e2);
464
            }
465
                        
466
                }
467
            
468
    }
469

    
470
}