Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / org.gvsig.newlayer / org.gvsig.newlayer.lib / org.gvsig.newlayer.lib.impl / src / main / java / org / gvsig / newlayer / impl / FeatureTypePanel.java @ 38555

History | View | Annotate | Download (40 KB)

1
package org.gvsig.newlayer.impl;
2

    
3
import java.awt.BorderLayout;
4
import java.awt.Component;
5
import java.awt.GridBagConstraints;
6
import java.awt.GridBagLayout;
7
import java.awt.Insets;
8
import java.awt.event.ActionEvent;
9
import java.awt.event.ActionListener;
10
import java.awt.event.ItemEvent;
11
import java.awt.event.ItemListener;
12
import java.util.ArrayList;
13
import java.util.Iterator;
14
import java.util.List;
15

    
16
import javax.swing.ComboBoxModel;
17
import javax.swing.DefaultCellEditor;
18
import javax.swing.JButton;
19
import javax.swing.JCheckBox;
20
import javax.swing.JComboBox;
21
import javax.swing.JLabel;
22
import javax.swing.JOptionPane;
23
import javax.swing.JPanel;
24
import javax.swing.JScrollPane;
25
import javax.swing.JTable;
26
import javax.swing.JTextField;
27
import javax.swing.ListSelectionModel;
28
import javax.swing.UIManager;
29
import javax.swing.event.ListDataListener;
30
import javax.swing.event.ListSelectionEvent;
31
import javax.swing.event.ListSelectionListener;
32
import javax.swing.event.TableModelEvent;
33
import javax.swing.event.TableModelListener;
34
import javax.swing.table.DefaultTableCellRenderer;
35
import javax.swing.table.DefaultTableModel;
36
import javax.swing.table.TableCellRenderer;
37
import javax.swing.table.TableColumn;
38
import javax.swing.table.TableModel;
39

    
40
import org.cresques.cts.IProjection;
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43

    
44
import org.gvsig.app.gui.panels.CRSSelectPanel;
45
import org.gvsig.app.gui.panels.crs.ISelectCrsPanel;
46
import org.gvsig.fmap.dal.DALLocator;
47
import org.gvsig.fmap.dal.DataManager;
48
import org.gvsig.fmap.dal.DataStoreProviderFactory;
49
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
50
import org.gvsig.fmap.dal.feature.EditableFeatureType;
51
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
52
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
53
import org.gvsig.fmap.dal.feature.FeatureType;
54
import org.gvsig.fmap.geom.DataTypes;
55
import org.gvsig.fmap.geom.Geometry;
56
import org.gvsig.fmap.geom.GeometryLocator;
57
import org.gvsig.fmap.geom.GeometryManager;
58
import org.gvsig.fmap.geom.type.GeometryType;
59
import org.gvsig.gui.beans.wizard.panel.NotContinueWizardException;
60
import org.gvsig.gui.beans.wizard.panel.OptionPanel;
61
import org.gvsig.i18n.Messages;
62
import org.gvsig.newlayer.NewLayerService;
63
import org.gvsig.tools.dataTypes.DataType;
64
import org.gvsig.tools.swing.api.ToolsSwingLocator;
65
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
66

    
67
public class FeatureTypePanel extends JPanel implements OptionPanel {
68
    private static final int COLUMN_FIELD = 0;
69
    private static final int COLUMN_TYPE = 1;
70
    private static final int COLUMN_LENGTH = 2;
71
    private static final int COLUMN_GEOMETRYTYPE = 3;
72
    private static final int COLUMN_GEOMETRYSUBTYPE = 4;
73
    private static final int COLUMN_CRS = 5;
74
    private static final int COLUMN_PRIMARYKEY = 6;
75
    private static final int COLUMN_MANDATORY = 7;
76
 
77
        private static final long serialVersionUID = 263541873998597624L;
78
        
79
    private FeatureType defaultFeatType = null;
80
    
81
    private NewLayerService newLayer_Service = null;
82
    private int inDefaultFeatTypeFieldCount = 0;
83
        private String inStoreName = null;
84
        private IProjection inProjection = null;
85
        private FeatureStoreProviderFactory spFactory = null;
86
        private boolean defaultHasGeometry = false;
87
        
88
        private static final Logger logger = LoggerFactory
89
                        .getLogger(FeatureTypePanel.class);
90

    
91
        private JLabel jLabel = null;
92
        private JScrollPane jScrollPane = null;
93
        protected JTable jTable = null;
94
        private JPanel jPanelEast = null;
95
        private JButton addFieldButton = null;
96
        private JButton deleteFieldButton = null;
97
        protected int MAX_FIELD_LENGTH = 254;
98
        
99
        // we dont need this list
100
        // we'll clear and rebuild featureType each time
101
        // the user clicks next
102
        // private List removedFields;
103

    
104
        // private DataServerExplorer explorer = null;
105

    
106
        public FeatureTypePanel(NewLayerService new_layer_service) {
107
            
108
            /*
109
            service.getFeatureType(),
110
        service.getStoreName(),
111
        service.getMapContext().getProjection();
112
        */
113
            newLayer_Service = new_layer_service;
114
        }
115
        
116
        private boolean fieldsInited = false;
117
        
118
        private void initFields() {
119
            
120
            if (newLayer_Service == null) {
121
                return;
122
            }
123
            
124
            fieldsInited = true;
125
            
126
        inStoreName = newLayer_Service.getStoreName();
127
        inProjection = newLayer_Service.getMapContext().getProjection();
128
        
129
        DataStoreProviderFactory dspf =
130
                DALLocator.getDataManager().getStoreProviderFactory(inStoreName);
131
        spFactory = (FeatureStoreProviderFactory) dspf;
132
        defaultFeatType = spFactory.createDefaultFeatureType();
133
        if (defaultFeatType != null) {
134
            inDefaultFeatTypeFieldCount =
135
                defaultFeatType.getAttributeDescriptors().length; 
136
            int def_geom_fld_index = defaultFeatType.getDefaultGeometryAttributeIndex(); 
137
            if (def_geom_fld_index >= 0 &&
138
                def_geom_fld_index < inDefaultFeatTypeFieldCount &&
139
                defaultFeatType.
140
                getAttributeDescriptor(def_geom_fld_index).
141
                getDataType().getType() == DataTypes.GEOMETRY) {
142
                
143
                defaultHasGeometry = true;
144
            }
145
        }
146
        }
147

    
148
        private void initializeComponents() {
149
                jLabel = new JLabel();
150
                jLabel.setText(Messages.getText("define_fields"));
151
                this.setLayout(new BorderLayout(5, 5));
152
                this.setSize(new java.awt.Dimension(499, 232));
153
                this.add(jLabel, java.awt.BorderLayout.NORTH);
154
                this.add(getJScrollPane(), java.awt.BorderLayout.CENTER);
155
                this.add(getJPanelSouth(), java.awt.BorderLayout.SOUTH);
156

    
157
        }
158

    
159
        /**
160
         * This method initializes jScrollPane
161
         * 
162
         * @return javax.swing.JScrollPane
163
         */
164
        private JScrollPane getJScrollPane() {
165
                if (jScrollPane == null) {
166
                        jScrollPane = new JScrollPane();
167
                        jScrollPane.setViewportView(getJTable());
168
                }
169
                return jScrollPane;
170
        }
171

    
172
        /**
173
         * This method initializes jTable
174
         * 
175
         * @return javax.swing.JTable
176
         */
177
        private JTable getJTable() {
178
                if (jTable == null) {
179
                        jTable = new JTable(){
180
                            public boolean isCellEditable(int row,int column){
181
                                
182
                                
183
                                if (row < inDefaultFeatTypeFieldCount) {
184
                                    // default fields
185
                                    Object o = getValueAt(row,COLUMN_TYPE);  
186
                                    if (o instanceof ComboItemDataType) {
187
                                        
188
                                        ComboItemDataType ot = (ComboItemDataType) o;
189
                                        return (ot.dataType.getType() == DataTypes.GEOMETRY)
190
                                            &&
191
                                            (column == COLUMN_GEOMETRYTYPE ||
192
                                        column == COLUMN_GEOMETRYSUBTYPE);
193
                                        
194
                                    } else {
195
                                        return false;
196
                                    }
197
                                    
198
                                } else {
199
                                    // fields added by user
200
                                    if (column == COLUMN_PRIMARYKEY) {
201
                                        return spFactory.allowsPrimaryKeyAttributes();
202
                                    }
203

    
204
                                    if (column == COLUMN_MANDATORY) {
205
                                        return spFactory.allowsMandatoryAttributes();
206
                                    }
207
                                    
208
                                    if (column == COLUMN_LENGTH) {
209
                                        
210
                                        Object o = getValueAt(row,COLUMN_TYPE);  
211
                                if (o instanceof ComboItemDataType) {
212
                                    
213
                                    ComboItemDataType ot = (ComboItemDataType) o;
214
                                    return dataTypeNeedsSize(ot.dataType.getType());
215
                                    
216
                                } else {
217
                                    return false;
218
                                }
219
                                        
220
                                    }
221

    
222
                                    if (defaultHasGeometry &&
223
                                        (column == COLUMN_GEOMETRYTYPE
224
                            || column == COLUMN_GEOMETRYSUBTYPE
225
                            || column == COLUMN_CRS)) {
226
                                        // geom-related columns not editable
227
                                        return false;
228
                                    } else {
229
                                return true;
230
                                    }
231
                                }
232

    
233
                                /*
234
                                if ((column == COLUMN_GEOMETRYTYPE) ||
235
                                    (column == COLUMN_GEOMETRYSUBTYPE) ||
236
                                    (column == COLUMN_CRS)) {
237
                                    DataType dataType = 
238
                                        ((ComboItemDataType) getValueAt(row, COLUMN_TYPE)).dataType;                                   
239
                                    return dataType.getType() == DataTypes.GEOMETRY;
240
                                }
241
                                */
242
                            }  
243
                        };
244

    
245
                        DefaultTableModel tm = (DefaultTableModel) jTable.getModel();
246
                        tm.addColumn(Messages.getText("field"));
247

    
248
                        tm.addColumn(Messages.getText("type"));
249
                        tm.addColumn(Messages.getText("length"));
250
                        tm.addColumn(Messages.getText("geomType"));
251
                        tm.addColumn(Messages.getText("geomSubtype"));
252
                        tm.addColumn(Messages.getText("CRS"));
253
                        tm.addColumn(Messages.getText("primaryKey"));
254
                        tm.addColumn(Messages.getText("mandatory"));
255

    
256
                        // Ask to be notified of selection changes.
257
                        ListSelectionModel rowSM = jTable.getSelectionModel();
258
                        rowSM.addListSelectionListener(new ListSelectionListener() {
259
                                public void valueChanged(ListSelectionEvent e) {
260
                                        // Ignore extra messages.
261
                                        if (e.getValueIsAdjusting())
262
                                                return;
263

    
264
                                        ListSelectionModel lsm = (ListSelectionModel) e.getSource();
265
                                        if (lsm.isSelectionEmpty()) {
266
                                                // no rows are selected
267
                                                deleteFieldButton.setEnabled(false);
268
                                        } else {
269
                                            int min_sele = lsm.getMinSelectionIndex(); 
270
                            if (min_sele > -1 &&
271
                                min_sele < inDefaultFeatTypeFieldCount) {
272
                                deleteFieldButton.setEnabled(false);
273
                            } else {
274
                                deleteFieldButton.setEnabled(allowEditableFeatureType());
275
                            }
276
                                        }                
277
                                        
278
                                }
279
                        });
280
                        jTable.getColumn(Messages.getText("field")).setWidth(180);
281

    
282
                        jTable.getModel().addTableModelListener(new TableModelListener() {                
283
                public void tableChanged(TableModelEvent e) {
284
                    if (e.getColumn() == COLUMN_TYPE){
285
                        jTable.repaint();
286
                    }                    
287
                }
288
            });
289
                        
290

    
291
                        if (!fieldsInited) {
292
                            initFields();
293
                        }
294

    
295
                        // Rellenado de la tabla
296
                        if (defaultFeatType != null) {
297

    
298
                                Iterator it = defaultFeatType.iterator();
299
                                boolean some_error = false;
300
                                while (it.hasNext()) {
301
                                        FeatureAttributeDescriptor descriptor = (FeatureAttributeDescriptor) it
302
                                                        .next();
303

    
304
                    if (!addRowToFieldTable(
305
                        jTable,
306
                        null,
307
                        inProjection,
308
                        descriptor)) {
309
                        
310
                        some_error = true;
311
                    }
312
                    /*
313
                                        tm.setValueAt(descriptor.getName(), row, COLUMN_FIELD);
314
                                        tm.setValueAt(descriptor.getType(), row, COLUMN_TYPE);
315
                                        tm.setValueAt(descriptor.getSize(), row, COLUMN_LENGTH);
316
                                        tm.setValueAt(descriptor.getGeometryType(), row, COLUMN_GEOMETRYTYPE);
317
                                        tm.setValueAt(descriptor.getGeometrySubType(), row, COLUMN_GEOMETRYSUBTYPE);
318
                                        tm.setValueAt(descriptor.getSRS(), row, COLUMN_CRS);
319
                                        tm.setValueAt(descriptor.isPrimaryKey(), row, COLUMN_PRIMARYKEY);
320
                                        tm.setValueAt(descriptor.isMandatory(), row, COLUMN_MANDATORY);
321
                                        */
322
                                }
323
                                
324
                                if (some_error) {
325
                    String tit = Messages.getText("_Default_fields");
326
                    String msg = Messages.getText("_Unable_to_add_fields");
327
                    JOptionPane.showMessageDialog(
328
                        jTable, msg, tit,
329
                        JOptionPane.ERROR_MESSAGE);
330
                                }
331
                        }
332

    
333
                }
334
                jTable.setEnabled(allowEditableFeatureType());
335
                return jTable;
336
        }
337

    
338
        /**
339
         * This method initializes jPanelWest
340
         * 
341
         * @return javax.swing.JPanel
342
         */
343
        private JPanel getJPanelSouth() {
344
                if (jPanelEast == null) {
345
                        jPanelEast = new JPanel();
346
                        jPanelEast.setLayout(new BorderLayout());
347
                        
348
                        JPanel south_east = new JPanel(new GridBagLayout());
349
                        // south_east.setPreferredSize(new java.awt.Dimension(170, 50));
350
                        GridBagConstraints c = new GridBagConstraints();
351
                        c.fill = GridBagConstraints.HORIZONTAL;
352
                        c.insets = new Insets(8,10,8,0);  //top padding
353
                        c.gridx = 0;       
354
                        c.gridwidth = 1;   
355
                        c.gridy = 0;       
356
                        south_east.add(getJButtonAddField(), c);
357
            c.gridx = 1;       
358
                        south_east.add(getJButtonDeleteField(), c);
359
                        
360
                        jPanelEast.add(south_east, BorderLayout.EAST);
361
                }
362
                return jPanelEast;
363
        }
364

    
365
        /**
366
         * This method initializes jButtonAddField
367
         * 
368
         * @return javax.swing.JButton
369
         */
370
        private JButton getJButtonAddField() {
371
                if (addFieldButton == null) {
372
                    addFieldButton = new JButton();
373
                    addFieldButton.setText(Messages.getText("add_field"));
374
                    addFieldButton.setLocation(new java.awt.Point(7, 5));
375
                    addFieldButton.setSize(new java.awt.Dimension(145, 23));
376
                    addFieldButton.setPreferredSize(new java.awt.Dimension(100, 23));
377
                    addFieldButton
378
                                        .addActionListener(new java.awt.event.ActionListener() {
379
                                                public void actionPerformed(java.awt.event.ActionEvent e) {
380
                                                        DefaultTableModel tm = (DefaultTableModel) jTable
381
                                                                        .getModel();
382

    
383
                                                        // Figure out a suitable field name
384
                                                        ArrayList fieldNames = new ArrayList();
385
                                                        for (int i = 0; i < jTable.getRowCount(); i++) {
386
                                                                fieldNames.add(tm.getValueAt(i, COLUMN_FIELD));
387
                                                        }
388
                                                        String[] currentFieldNames = (String[]) fieldNames
389
                                                                        .toArray(new String[0]);
390
                                                        String newField = Messages.getText("field")
391
                                                                        .replaceAll(" +", "_");
392
                                                        int index = 0;
393
                                                        for (int i = 0; i < currentFieldNames.length; i++) {
394
                                                                if (currentFieldNames[i].startsWith(newField)) {
395
                                                                        try {
396
                                                                                index = Integer
397
                                                                                                .parseInt(currentFieldNames[i]
398
                                                                                                                .replaceAll(newField,
399
                                                                                                                                ""));
400
                                                                        } catch (Exception ex) { /* we don't care */
401
                                                                        }
402
                                                                }
403
                                                        }
404
                                                        String newFieldName = newField + (++index);
405

    
406
                                                        // Esto lo a?ado aqu? porque si no tiene registros,
407
                                                        // no hace caso. (Por eso no
408
                                                        // lo pongo en getJTable()
409
                                                        if (!addRowToFieldTable(
410
                                                            jTable,
411
                                                            newFieldName,
412
                                                            inProjection,
413
                                                            null)) {
414
                                                            
415
                                    String tit = Messages.getText("_Default_fields");
416
                                    String msg = Messages.getText("_Unable_to_add_fields");
417
                                    JOptionPane.showMessageDialog(
418
                                        jTable, msg, tit,
419
                                        JOptionPane.ERROR_MESSAGE);
420
                                                        }
421
                                                }
422
                                        });
423

    
424
                }
425
                addFieldButton.setEnabled(allowEditableFeatureType());
426
                return addFieldButton;
427
        }
428
        
429
        private boolean allowEditableFeatureType(){
430
            
431
            if (!fieldsInited) {
432
                initFields();
433
            }
434

    
435
                DataManager dataManager = DALLocator.getDataManager();
436
                FeatureStoreProviderFactory factory =
437
                    (FeatureStoreProviderFactory) dataManager.
438
                    getStoreProviderFactory(inStoreName);
439
                if (factory.allowEditableFeatureType()==FeatureStoreProviderFactory.NO) {
440
                        return false;
441
                }
442
                return true;
443
        }
444

    
445
        private class ComboItemDataType {
446
                private DataType dataType;
447

    
448
                public ComboItemDataType(DataType dataType) {
449
                        this.dataType = dataType;
450
                }
451

    
452
                @Override
453
                public String toString() {
454
                        return this.dataType.getName();
455
                }
456
        }
457

    
458
        private class ComboModelDataType implements ComboBoxModel {
459

    
460
                private List<ComboItemDataType> dataTypes;
461
                private ComboItemDataType selected;
462

    
463
                public ComboModelDataType(List<DataType> dataTypes, int sel_type) {
464
                    
465
                        this.dataTypes = new ArrayList<ComboItemDataType>();
466
                        ComboItemDataType item = null;
467
                        for (Iterator iterator = dataTypes.iterator(); iterator.hasNext();) {
468
                                DataType dataType = (DataType) iterator.next();
469
                                item = new ComboItemDataType(dataType);
470
                                this.dataTypes.add(item);
471
                                if (sel_type == dataType.getType()) {
472
                                    this.setSelectedItem(item);
473
                                }
474
                        }
475
                }
476

    
477
                public void addListDataListener(ListDataListener arg0) {
478
                        // DO NOTHING
479
                }
480

    
481
                public Object getElementAt(int arg0) {
482
                        return this.dataTypes.get(arg0);
483
                }
484

    
485
                public int getSize() {
486
                        return this.dataTypes.size();
487
                }
488

    
489
                public void removeListDataListener(ListDataListener arg0) {
490
                        // DO NOTHING
491
                }
492

    
493
                public Object getSelectedItem() {
494
                        return this.selected;
495
                }
496

    
497
                public void setSelectedItem(Object anItem) {
498
                        this.selected = (ComboItemDataType) anItem;
499
                }
500

    
501
        }
502

    
503
        class CrsRenderer extends JButton implements TableCellRenderer {
504
                private static final long serialVersionUID = -573793294070515376L;
505
                private JLabel label = null;
506
                
507
                public CrsRenderer() {
508
                        setOpaque(true);
509
                        label = new JLabel(Messages.getText("not_applicable"));
510
                }
511

    
512
                public Component getTableCellRendererComponent(JTable table,
513
                                Object value, boolean isSelected, boolean hasFocus, int row,
514
                                int column) {
515
                        
516
                    ComboItemDataType item =
517
                        (ComboItemDataType) table.getValueAt(row, COLUMN_TYPE);
518
                    
519
                    if (item == null) {
520
                        // happens sometimes. perhaps an early rendering?
521
                        return new JLabel();
522
                    }
523
                    
524
                    DataType dataType = item.dataType;                       
525
                        
526
            if (dataType.getType() != DataTypes.GEOMETRY) {                
527
                return label;
528
            }
529
                    
530
                    if (isSelected) {
531
                                setForeground(table.getSelectionForeground());
532
                                setBackground(table.getSelectionBackground());
533
                        } else {
534
                                setForeground(table.getForeground());
535
                                setBackground(UIManager.getColor("Button.background"));
536
                        }
537
                        setText((value == null) ? "" : ((IProjection) value).getFullCode());
538
                        return this;
539
                }
540
        }        
541
           
542
    private class GeometryComboCellRenderer extends JLabel implements TableCellRenderer{
543

    
544
        public Component getTableCellRendererComponent(JTable table,
545
            Object value, boolean isSelected, boolean hasFocus, int row,
546
            int column) {                     
547

    
548
            ComboItemDataType item = (ComboItemDataType) table.getValueAt(row, COLUMN_TYPE);
549
            DataType dataType = item.dataType;                       
550
                        
551
            if (dataType.getType() == DataTypes.GEOMETRY) {
552
                ComboItemGeomType geomType = (ComboItemGeomType)value;
553
                if (geomType != null) {            
554
                    this.setText(geomType.toString());
555
                }
556
            } else {
557
               this.setText(Messages.getText("not_applicable"));
558
            }
559
            
560
            return this;
561
        }
562
        
563
    }
564

    
565
        class ButtonEditor extends DefaultCellEditor {
566
                /**
567
                 * 
568
                 */
569
                private static final long serialVersionUID = -2820892672026188802L;
570

    
571
                protected JButton button;
572

    
573
                private String label;
574

    
575
                private boolean isPushed;
576

    
577
                private Object value;
578

    
579
                public ButtonEditor(JCheckBox checkBox) {
580
                        super(checkBox);
581
                        button = new JButton();
582
                        button.setOpaque(true);
583
                        button.addActionListener(new ActionListener() {
584
                                public void actionPerformed(ActionEvent e) {
585
                                        fireEditingStopped();
586
                                }
587
                        });
588
                }
589

    
590
                public Component getTableCellEditorComponent(JTable table,
591
                                Object value, boolean isSelected, int row, int column) {
592
                        if (isSelected) {
593
                                button.setForeground(table.getSelectionForeground());
594
                                button.setBackground(table.getSelectionBackground());
595
                        } else {
596
                                button.setForeground(table.getForeground());
597
                                button.setBackground(table.getBackground());
598
                        }
599
                        label = (value == null) ? "" : ((IProjection) value).getFullCode();// .toString();
600
                        button.setText(label);
601
                        isPushed = true;
602
                        this.value = value;
603
                        return button;
604
                }
605

    
606
                public Object getCellEditorValue() {
607
                        IProjection curProj = (IProjection) this.value;
608
                        if (isPushed) {
609
                                ISelectCrsPanel csSelect = CRSSelectPanel.getUIFactory()
610
                                                .getSelectCrsPanel(curProj, true);
611
                                WindowManager wm = ToolsSwingLocator.getWindowManager();
612
                                wm.showWindow((JPanel) csSelect, "Projection",
613
                                                WindowManager.MODE.DIALOG);
614
                                curProj = csSelect.getProjection();
615
                        }
616
                        isPushed = false;
617
                        return curProj;
618
                }
619

    
620
                public boolean stopCellEditing() {
621
                        isPushed = false;
622
                        return super.stopCellEditing();
623
                }
624

    
625
                protected void fireEditingStopped() {
626
                        super.fireEditingStopped();
627
                }
628
        }
629

    
630
        private class ComboItemGeomType {
631
                private int type;
632
                private String name;
633

    
634
                public ComboItemGeomType(String name, int type) {
635
                        this.type = type;
636
                        this.name = name;
637
                }
638

    
639
                @Override
640
                public String toString() {
641
                        return this.name;
642
                }
643
                
644
                public int getGeomType() {
645
                    return type;
646
                }
647
        }
648

    
649
        private class ComboModelGeomType implements ComboBoxModel {
650

    
651
                private List<ComboItemGeomType> geomTypes;
652
                private ComboItemGeomType selected;
653

    
654
                public ComboModelGeomType(
655
                    List<ComboItemGeomType> geomTypes, int sel_geom_type) {
656
                    
657
                        this.geomTypes = geomTypes;
658
                        int len = geomTypes.size();
659
                        ComboItemGeomType item = null;
660
                        for (int i=0; i<len; i++) {
661
                            item = geomTypes.get(i);
662
                            if (item.getGeomType() == sel_geom_type) {
663
                                setSelectedItem(item);
664
                            }
665
                        }
666
                }
667

    
668
                public void addListDataListener(ListDataListener arg0) {
669
                        // DO NOTHING
670
                }
671

    
672
                public Object getElementAt(int arg0) {
673
                        return this.geomTypes.get(arg0);
674
                }
675

    
676
                public int getSize() {
677
                        return this.geomTypes.size();
678
                }
679

    
680
                public void removeListDataListener(ListDataListener arg0) {
681
                        // DO NOTHING
682
                }
683

    
684
                public Object getSelectedItem() {
685
                        return this.selected;
686
                }
687

    
688
                public void setSelectedItem(Object anItem) {
689
                        this.selected = (ComboItemGeomType) anItem;
690
                }
691

    
692
        }
693

    
694
        private List<ComboItemGeomType> getGeomTypes() {
695
                List<ComboItemGeomType> geomTypes = new ArrayList<ComboItemGeomType>();
696
                geomTypes
697
                                .add(new ComboItemGeomType("GEOMETRY", Geometry.TYPES.GEOMETRY));
698
                geomTypes.add(new ComboItemGeomType("POINT", Geometry.TYPES.POINT));
699
                geomTypes.add(new ComboItemGeomType("CURVE", Geometry.TYPES.CURVE));
700
                geomTypes.add(new ComboItemGeomType("SURFACE", Geometry.TYPES.SURFACE));
701
                geomTypes.add(new ComboItemGeomType("SOLID", Geometry.TYPES.SOLID));
702
                geomTypes.add(new ComboItemGeomType("AGGREGATE",
703
                                Geometry.TYPES.AGGREGATE));
704
                geomTypes.add(new ComboItemGeomType("MULTIPOINT",
705
                                Geometry.TYPES.MULTIPOINT));
706
                geomTypes.add(new ComboItemGeomType("MULTICURVE",
707
                                Geometry.TYPES.MULTICURVE));
708
                geomTypes.add(new ComboItemGeomType("MULTISURFACE",
709
                                Geometry.TYPES.MULTISURFACE));
710
                geomTypes.add(new ComboItemGeomType("MULTISOLID",
711
                                Geometry.TYPES.MULTISOLID));
712

    
713
                return geomTypes;
714
        }
715

    
716
        private List<ComboItemGeomType> getGeomSubtypes() {
717
                List<ComboItemGeomType> geomSubtypes = new ArrayList<ComboItemGeomType>();
718
                geomSubtypes.add(new ComboItemGeomType("GEOM2D",
719
                                Geometry.SUBTYPES.GEOM2D));
720
                geomSubtypes.add(new ComboItemGeomType("GEOM2DM",
721
                                Geometry.SUBTYPES.GEOM2DM));
722
                geomSubtypes.add(new ComboItemGeomType("GEOM3D",
723
                                Geometry.SUBTYPES.GEOM3D));
724
                geomSubtypes.add(new ComboItemGeomType("GEOM3DM",
725
                                Geometry.SUBTYPES.GEOM3DM));
726
                geomSubtypes.add(new ComboItemGeomType("UNKNOWN",
727
                                Geometry.SUBTYPES.UNKNOWN));
728
                return geomSubtypes;
729
        }
730

    
731
        class CheckBoxRenderer extends JCheckBox implements TableCellRenderer {
732

    
733
                /**
734
                 * 
735
                 */
736
                private static final long serialVersionUID = 5093448776058027505L;
737

    
738
                public CheckBoxRenderer() {
739
                        setHorizontalAlignment(JLabel.CENTER);
740
                }
741

    
742
                public Component getTableCellRendererComponent(JTable table,
743
                                Object value, boolean isSelected, boolean hasFocus, int row,
744
                                int column) {
745
                        if (isSelected) {
746
                                setForeground(table.getSelectionForeground());
747
                                setBackground(table.getSelectionBackground());
748
                        } else {
749
                                setForeground(table.getForeground());
750
                                setBackground(table.getBackground());
751
                        }
752
                        setSelected((value != null && ((Boolean) value).booleanValue()));
753
                        return this;
754
                }
755
        }
756

    
757
        /**
758
         * This method initializes jButton
759
         * 
760
         * @return javax.swing.JButton
761
         */
762
        private JButton getJButtonDeleteField() {
763
                if (deleteFieldButton == null) {
764
                    deleteFieldButton = new JButton();
765
                    deleteFieldButton.setText(Messages.getText("delete_field"));
766
                    deleteFieldButton.setLocation(new java.awt.Point(7, 33));
767
                    deleteFieldButton.setSize(new java.awt.Dimension(145, 23));
768
                    deleteFieldButton.setEnabled(false);
769
                    deleteFieldButton
770
                                        .addActionListener(new java.awt.event.ActionListener() {
771
                                                public void actionPerformed(java.awt.event.ActionEvent e) {
772
                                                        int[] selecteds = jTable.getSelectedRows();
773
                                                        DefaultTableModel tm = (DefaultTableModel) jTable
774
                                                                        .getModel();
775

    
776
                                                        for (int i = selecteds.length - 1; i >= 0; i--) {
777
                                                            /*
778
                                                             * 
779
                                                                removedFields.add((String) tm.getValueAt(i, 0));
780
                                 */
781
                                                                tm.removeRow(selecteds[i]);
782
                                                        }
783
                                                }
784
                                        });
785
                }
786
                deleteFieldButton.setEnabled(false);
787
                return deleteFieldButton;
788
        }
789

    
790
        public String getPanelTitle() {
791
                return Messages.getText("fields_definitions");
792
        }
793

    
794
        public void nextPanel() throws NotContinueWizardException {
795
                if (allowEditableFeatureType()){
796
                        fillFeatureType();
797
                }
798
        }
799

    
800
        private void fillFeatureType() throws NotContinueWizardException {
801
            
802
            if (!fieldsInited) {
803
                initFields();
804
            }
805

    
806
                /*
807
                 * Coge los datos del formulario y los guarda en
808
                 * this.service.getFeatureType()
809
                 */
810

    
811
            EditableFeatureType edft = newLayer_Service.getFeatureType();
812

    
813
                // Clean and rebuild featureType everytime we click next
814
                removeAllFields(edft);
815
                edft.setDefaultGeometryAttributeName(null);
816

    
817
                GeometryManager gm = GeometryLocator.getGeometryManager();
818
                DefaultTableModel tm = (DefaultTableModel) jTable.getModel();
819
                
820
                for (int i = 0; i < tm.getRowCount(); i++) {
821
                        DataType dataType = ((ComboItemDataType) tm.getValueAt(i, COLUMN_TYPE)).dataType;
822

    
823
                        int fieldLength = 20;
824
                        if (dataTypeNeedsSize(dataType.getType())) {
825
                    fieldLength = 
826
                        Integer.parseInt((String) tm.getValueAt(i, COLUMN_LENGTH));
827
                        }
828

    
829
                        EditableFeatureAttributeDescriptor efad1 =
830
                            edft.add(
831
                                        (String) tm.getValueAt(i, COLUMN_FIELD), dataType.getType(),
832
                                        fieldLength);
833

    
834
                        if (dataType.getType() == DataTypes.DOUBLE ||
835
                            dataType.getType() == DataTypes.FLOAT) {
836
                            // TODO Improve this?
837
                            // Half of the size dedicated
838
                            // to precision (at least 1) 
839
                    efad1.setPrecision(Math.max(1, fieldLength/2));
840
                        }
841

    
842
                        if (dataType.getType() == DataTypes.GEOMETRY) {
843
                            
844
                int g_type = ((ComboItemGeomType) tm.getValueAt(i, COLUMN_GEOMETRYTYPE)).type;
845
                int g_subtype = ((ComboItemGeomType) tm.getValueAt(i, COLUMN_GEOMETRYSUBTYPE)).type;
846
                            
847
                            GeometryType gty = null;
848
                            
849
                            try {
850
                    gty = gm.getGeometryType(g_type, g_subtype);
851
                    efad1.setGeometryType(gty);
852
                    // efad1.setGeometryType(g_type);
853
                            } catch (Exception ex) {
854
                    String _msg = Messages.getText("_Invalid_geometry_type")
855
                        + " (" + g_type + ", " + g_subtype + ")";
856
                                throw new NotContinueWizardException(_msg, ex, this);
857
                            }
858
                                
859
                                efad1.setIsPrimaryKey(((Boolean) tm.getValueAt(i, COLUMN_PRIMARYKEY))
860
                                                .booleanValue());
861
                                efad1.setAllowNull(!((Boolean) tm.getValueAt(i, COLUMN_MANDATORY))
862
                                                .booleanValue());
863
                                efad1.setSRS((IProjection) tm.getValueAt(i, COLUMN_CRS));
864
                                
865
                                //If there is not a previous default geometry field, add it
866
                                // this will set the first geometry field
867
                                // as the default geometry field
868
                                if (edft.getDefaultGeometryAttribute() == null){
869
                                    edft.setDefaultGeometryAttributeName(efad1.getName());
870
                                }        
871
                        }
872
                }
873
        }
874

    
875
        /**
876
     * @param featureType
877
     */
878
    private void removeAllFields(EditableFeatureType ft) {
879
        
880
        FeatureAttributeDescriptor[] atts =  ft.getAttributeDescriptors();
881
        int len = atts.length;
882
        FeatureAttributeDescriptor item = null;
883
        for (int i=0; i<len; i++) {
884
            item = atts[i];
885
            ft.remove(item.getName());
886
        }
887
    }
888

    
889
    public void lastPanel() {
890
                // TODO Auto-generated method stub
891
                logger.info("FeatureTypePanel: lastPanel");
892
        }
893

    
894
        public void updatePanel() {
895
                initializeComponents();
896

    
897
        }
898

    
899
        public JPanel getJPanel() {
900
                return this;
901
        }
902
        
903
        /**
904
         * If fad is null, it's an addition after user has clicked on 'Add field'.
905
         * If fad is not null, it's the description of a default field and the
906
         * field name will also be taken from there.
907
         * 
908
         * @param the_table
909
         * @param new_fld_name
910
         * @param the_projection
911
         * @param fad
912
         * 
913
         * @return true if field was actually added, false otherwise
914
         */
915
    private boolean addRowToFieldTable(
916
        JTable the_table,
917
        String new_fld_name,
918
        IProjection the_projection,
919
        FeatureAttributeDescriptor fad) {
920
        
921
        if (fad == null && new_fld_name == null) {
922
            logger.info("Error: unable to add field to table (no description and no name)");
923
            return false;
924
        }
925
        
926
        DefaultTableModel the_tm = (DefaultTableModel) the_table.getModel();
927
        Object[] newRow = new Object[the_tm.getColumnCount()];
928
        
929
        /*
930
        tm.setValueAt(descriptor.getName(), row, COLUMN_FIELD);
931
        tm.setValueAt(descriptor.getType(), row, COLUMN_TYPE);
932
        tm.setValueAt(descriptor.getSize(), row, COLUMN_LENGTH);
933
        tm.setValueAt(descriptor.getGeometryType(), row, COLUMN_GEOMETRYTYPE);
934
        tm.setValueAt(descriptor.getGeometrySubType(), row, COLUMN_GEOMETRYSUBTYPE);
935
        tm.setValueAt(descriptor.getSRS(), row, COLUMN_CRS);
936
        tm.setValueAt(descriptor.isPrimaryKey(), row, COLUMN_PRIMARYKEY);
937
        tm.setValueAt(descriptor.isMandatory(), row, COLUMN_MANDATORY);
938
        */
939
        
940
        // =============================== name
941
        if (fad == null) {
942
            newRow[COLUMN_FIELD] = new_fld_name;
943
        } else {
944
            newRow[COLUMN_FIELD] = fad.getName();
945
        }
946
        // ===================================== field type
947
        TableColumn typeColumn = the_table.getColumnModel().getColumn(COLUMN_TYPE);
948
        List supp_types = spFactory.getSupportedDataTypes();
949
        
950
        DataManager daman = DALLocator.getDataManager();
951
        List all_types = daman.getDataTypes();
952
        
953
        
954
        ComboModelDataType model = null;
955
        if (fad == null) {
956

    
957
            // this is a user defined column, remove geometry if in default feattype 
958
            if (defaultHasGeometry) {
959
                supp_types = removeGeometryType(supp_types);
960
                all_types = removeGeometryType(all_types);
961
            }
962
            
963
            if (supp_types != null && supp_types.size() > 0) {
964
                model = new ComboModelDataType(
965
                    supp_types,
966
                    ((DataType) supp_types.get(0)).getType());
967
            } else {
968
                model = new ComboModelDataType(
969
                    all_types,
970
                    ((DataType) all_types.get(0)).getType());
971
            }
972
        } else {
973
            model = new ComboModelDataType(supp_types, fad.getType());
974
        }
975
        
976
        JComboBox comboBox = new JComboBox(model);
977
        typeColumn.setCellEditor(new DefaultCellEditor(comboBox));
978
        newRow[COLUMN_TYPE] = model.getSelectedItem();
979
        
980
        // ============================= width
981
        TableColumn widthColumn =
982
            the_table.getColumnModel().getColumn(COLUMN_LENGTH);
983
        if (fad == null) {
984
            newRow[COLUMN_LENGTH] = "20";
985
        } else {
986
            newRow[COLUMN_LENGTH] = "" + fad.getSize();
987
        }
988
        
989
        SimpleTextCellRenderer stcr = new SimpleTextCellRenderer();
990
        widthColumn.setCellEditor(new DefaultCellEditor(new JTextField()));
991
        widthColumn.setCellRenderer(stcr);
992
        
993
        
994
        // ============================= geom type
995
        TableColumn geomTypeColumn =
996
            the_table.getColumnModel().getColumn(COLUMN_GEOMETRYTYPE);
997
        ComboModelGeomType geomTypeModel = null;
998
        
999
        List<ComboItemGeomType> supptd =
1000
            leaveSupportedGeomTypes(getGeomTypes(),
1001
                spFactory.getSupportedGeometryTypesSubtypes(), 0);
1002
        
1003
        if (fad == null) {
1004
            geomTypeModel = new ComboModelGeomType(
1005
                supptd, supptd.size() > 0 ? supptd.get(0).getGeomType() : -1);
1006
        } else {
1007
            geomTypeModel = new ComboModelGeomType(
1008
                supptd, fad.getGeomType().getType());
1009
        }
1010
        
1011
        JComboBox geomTypeComboBox = new JComboBox(geomTypeModel);
1012
        geomTypeColumn.setCellEditor(new DefaultCellEditor(geomTypeComboBox));
1013
        
1014
        GeometryComboCellRenderer gccr = new GeometryComboCellRenderer();
1015
        geomTypeColumn.setCellRenderer(gccr);
1016
        newRow[COLUMN_GEOMETRYTYPE] = geomTypeModel.getSelectedItem();
1017
        
1018
        // ============================= geom sub type
1019

    
1020
        TableColumn geomSubTypeColumn =
1021
            the_table.getColumnModel().getColumn(COLUMN_GEOMETRYSUBTYPE);
1022
        ComboModelGeomType geomSubTypeModel = null;
1023

    
1024
        supptd =
1025
            leaveSupportedGeomTypes(getGeomSubtypes(),
1026
                spFactory.getSupportedGeometryTypesSubtypes(), 1);
1027
        
1028
        if (fad == null) {
1029
            geomSubTypeModel = new ComboModelGeomType(
1030
                supptd, supptd.size() > 0 ? supptd.get(0).getGeomType() : -1);
1031
        } else {
1032
            geomSubTypeModel = new ComboModelGeomType(
1033
                supptd, fad.getGeomType().getSubType());
1034
        }
1035
        
1036
        JComboBox geomSubTypeComboBox = new JComboBox(geomSubTypeModel);
1037
        geomSubTypeColumn.setCellEditor(new DefaultCellEditor(
1038
            geomSubTypeComboBox));
1039
        geomSubTypeColumn.setCellRenderer(new GeometryComboCellRenderer());
1040
        newRow[COLUMN_GEOMETRYSUBTYPE] = geomSubTypeModel.getSelectedItem();
1041

    
1042
        // ============================= CRS
1043

    
1044
        TableColumn crsColumn = the_table.getColumnModel().getColumn(COLUMN_CRS);
1045
        crsColumn.setCellEditor(new ButtonEditor(new JCheckBox()));
1046
        CrsRenderer crsButtonRenderer = new CrsRenderer();
1047
        crsColumn.setCellRenderer(crsButtonRenderer);
1048
        newRow[COLUMN_CRS] = the_projection;
1049

    
1050
        // ============================= PK
1051

    
1052
        TableColumn primaryKeyColumn =
1053
            the_table.getColumnModel().getColumn(COLUMN_PRIMARYKEY);
1054
        JCheckBox primaryKeyCheckBox = new JCheckBox();
1055
        
1056
        if (fad == null) {
1057
            primaryKeyCheckBox.setSelected(false);
1058
        } else {
1059
            primaryKeyCheckBox.setSelected(fad.isPrimaryKey());
1060
        }
1061

    
1062
        primaryKeyColumn.setCellEditor(
1063
            new DefaultCellEditor(primaryKeyCheckBox));
1064
        CheckBoxRenderer primaryKeyCheckBoxRenderer = new CheckBoxRenderer();
1065
        primaryKeyColumn.setCellRenderer(primaryKeyCheckBoxRenderer);
1066
        newRow[COLUMN_PRIMARYKEY] = primaryKeyCheckBox.isSelected();
1067
            
1068
        // ================================== mandatory
1069
        
1070
        TableColumn mandatoryColumn =
1071
            the_table.getColumnModel().getColumn(COLUMN_MANDATORY);
1072
        JCheckBox mandatoryCheckBox = new JCheckBox();
1073
        
1074
        if (fad == null) {
1075
            mandatoryCheckBox.setSelected(false);
1076
        } else {
1077
            mandatoryCheckBox.setSelected(fad.isMandatory());
1078
        }
1079
        
1080
        mandatoryColumn.setCellEditor(new DefaultCellEditor(mandatoryCheckBox));
1081
        CheckBoxRenderer mandatoryCheckBoxRenderer = new CheckBoxRenderer();
1082
        mandatoryColumn.setCellRenderer(mandatoryCheckBoxRenderer);
1083
        newRow[COLUMN_MANDATORY] = mandatoryCheckBox.isSelected();
1084

    
1085
        // ==================================
1086
        
1087
        // Add a new row
1088
        the_tm.addRow(newRow);
1089
        return true;
1090
    }
1091

    
1092
    /**
1093
     * @param supp_types
1094
     * @return
1095
     */
1096
    private List removeGeometryType(List dta_types) {
1097
        List resp = new ArrayList();
1098
        
1099
        int len = dta_types.size();
1100
        Object item_o = null;
1101
        DataType item_dt = null;
1102
        
1103
        for (int i=0; i<len; i++) {
1104
            item_o = dta_types.get(i);
1105
            if (item_o instanceof DataType) {
1106
                item_dt = (DataType) item_o;
1107
                if (item_dt.getType() != DataTypes.GEOMETRY) {
1108
                    resp.add(item_dt);
1109
                }
1110
            }
1111
        }
1112
        return resp;
1113
    }
1114

    
1115
    private List<ComboItemGeomType> leaveSupportedGeomTypes(
1116
        List<ComboItemGeomType> all_types,
1117
        List<int[]> supported,
1118
        int index /* 0 for geom types, 1 for geom subtypes */) {
1119
        
1120
        List<ComboItemGeomType> resp = new ArrayList<ComboItemGeomType>();
1121
        int len = all_types.size();
1122
        ComboItemGeomType item = null;
1123
        for (int i=0; i<len; i++) {
1124
            item = all_types.get(i);
1125
            if (isInNthElement(item.getGeomType(), supported, index)) {
1126
                resp.add(item);
1127
            }
1128
        }
1129
        return resp;
1130
    }
1131

    
1132

    
1133
    private boolean isInNthElement(int val, List<int[]> arr_list, int index) {
1134
        
1135
        int len = arr_list.size();
1136
        int[] item = null;
1137
        for (int i=0; i<len; i++) {
1138
            item = arr_list.get(i);
1139
            if (item != null && item.length > index && item[index] == val) {
1140
                return true;
1141
            }
1142
        }
1143
        return false;
1144
    }
1145
    
1146
    private boolean dataTypeNeedsSize(int data_type) {
1147
        
1148
        if (data_type == DataTypes.FLOAT
1149
            || data_type == DataTypes.INT
1150
            || data_type == DataTypes.STRING) {
1151
            return true;
1152
        } else {
1153
            return false;
1154
        }
1155
    }
1156
    
1157
    private class SimpleTextCellRenderer extends DefaultTableCellRenderer {
1158

    
1159
        public SimpleTextCellRenderer() {
1160
            super();
1161
        }
1162
        /* (non-Javadoc)
1163
         * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
1164
         */
1165
        public Component getTableCellRendererComponent(
1166
            JTable table,
1167
            Object value, boolean isSelected, boolean hasFocus, int row,
1168
            int column) {
1169
            
1170
            TableModel tm = table.getModel();
1171
            Object new_val = "";            
1172
            Object type_obj = tm.getValueAt(row, COLUMN_TYPE);
1173
            if (type_obj instanceof ComboItemDataType) {
1174
                ComboItemDataType type_item = (ComboItemDataType) type_obj;
1175
                if (dataTypeNeedsSize(type_item.dataType.getType())) {
1176
                    new_val = getCurrentOr(value, "");
1177
                } else {
1178
                    new_val = Messages.getText("not_applicable");
1179
                }
1180
                return super.getTableCellRendererComponent(
1181
                    table, new_val, isSelected, hasFocus, row, column);
1182
            } else {
1183
                return super.getTableCellRendererComponent(
1184
                    table, value, isSelected, hasFocus, row, column);
1185
            }
1186
        }
1187
        
1188
        private Object getCurrentOr(Object v, String d) {
1189
            
1190
            if (v instanceof String) {
1191
                String parse_str = (String) v;
1192
                try {
1193
                    Integer.parseInt(parse_str);
1194
                    return v;
1195
                } catch (Exception ex) {
1196
                    // not a valid integer
1197
                    return d;
1198
                }
1199
            } else {
1200
                return v;
1201
            }
1202
        }
1203

    
1204
    }
1205

    
1206
    private class EnableLengthItemListener implements ItemListener {
1207
        
1208
        private TableModel theTableModel = null;
1209
        private JTable theTable = null;
1210
        
1211
        public EnableLengthItemListener(JTable t, boolean b) {
1212
            theTable = t;
1213
            theTableModel = t.getModel();
1214
        }
1215
        
1216
        public void itemStateChanged(final ItemEvent e) {
1217
            doUpdate(e);
1218
        }
1219

    
1220
        public void doUpdate(ItemEvent e) {
1221
            
1222
            Object src_obj = e.getSource();
1223
            if (src_obj instanceof JComboBox) {
1224
                
1225
                // one of the field type combos has changed
1226
                int len = theTableModel.getRowCount();
1227
                Object type_obj = null;
1228
                ComboItemDataType type_item = null;
1229
                for (int i=0; i<len; i++) {
1230
                    type_obj = theTableModel.getValueAt(i, COLUMN_TYPE);
1231
                    if (type_obj instanceof ComboItemDataType) {
1232
                        type_item = (ComboItemDataType) type_obj;
1233
                        if (dataTypeNeedsSize(type_item.dataType.getType())) {
1234
                            theTableModel.setValueAt(
1235
                                "20",
1236
                                i, COLUMN_LENGTH);
1237
                        } else {
1238
                            theTableModel.setValueAt(
1239
                                Messages.getText("not_applicable"),
1240
                                i, COLUMN_LENGTH);
1241
                        }
1242
                    }
1243
                }
1244
                theTable.validate(); // .revalidate(); // .repaint();
1245
            }
1246
        }
1247

    
1248
    }
1249
    
1250
    
1251
    
1252
    
1253
    
1254
}