Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.xml2db / org.gvsig.xml2db.swing / org.gvsig.xml2db.swing.impl / src / main / java / org / gvsig / xml2db / swing / impl / createdbfromxml / CreatedbFromXmlPanel.java @ 47472

History | View | Annotate | Download (21.1 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright (c) 2007-2023 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.xml2db.swing.impl.createdbfromxml;
24

    
25
import org.gvsig.xml2db.swing.impl.Task;
26
import java.awt.Color;
27
import java.awt.Cursor;
28
import java.awt.GridBagConstraints;
29
import java.awt.event.ActionEvent;
30
import java.io.File;
31
import java.util.ArrayList;
32
import java.util.List;
33
import javax.swing.AbstractListModel;
34
import javax.swing.JComponent;
35
import org.cresques.cts.IProjection;
36
import java.nio.charset.Charset;
37
import java.util.Collections;
38
import java.util.Locale;
39
import javax.swing.JOptionPane;
40
import javax.swing.SwingUtilities;
41
import javax.swing.event.ChangeEvent;
42
import javax.swing.event.ChangeListener;
43
import org.apache.commons.io.FilenameUtils;
44
import org.apache.commons.lang3.StringUtils;
45
import org.gvsig.fmap.dal.DALLocator;
46
import org.gvsig.fmap.dal.DataManager;
47
import org.gvsig.fmap.dal.feature.EditableFeatureType;
48
import org.gvsig.fmap.dal.store.h2.H2SpatialUtils;
49
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
50
import org.gvsig.fmap.dal.swing.DALSwingLocator;
51
import org.gvsig.fmap.dal.swing.DataSwingManager;
52
import org.gvsig.fmap.dal.swing.ProjectionPickerController;
53
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel;
54
import org.gvsig.tools.ToolsLocator;
55
import org.gvsig.tools.i18n.I18nManager;
56
import org.gvsig.tools.swing.api.ToolsSwingLocator;
57
import org.gvsig.tools.swing.api.ToolsSwingManager;
58
import org.gvsig.tools.swing.api.ToolsSwingUtils;
59
import org.gvsig.tools.swing.api.pickercontroller.CharsetPickerController;
60
import org.gvsig.tools.swing.api.pickercontroller.FilePickerController;
61
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
62
import org.gvsig.tools.swing.api.task.TaskStatusController;
63
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
64
import org.gvsig.tools.swing.api.windowmanager.Dialog;
65
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
66
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
67
import org.gvsig.tools.task.SimpleTaskStatus;
68
import org.gvsig.tools.util.LabeledValue;
69
import org.gvsig.tools.util.LabeledValueImpl;
70
import org.gvsig.xml2db.lib.api.Xml2dbLocator;
71
import org.gvsig.xml2db.lib.api.Xml2dbManager;
72
import org.gvsig.xml2db.lib.api.xmlinfo.XMLInfo;
73
import org.gvsig.xml2db.lib.api.xmlinfo.XMLTableInfo;
74
import org.gvsig.xml2db.swing.Xml2dbPanel;
75
import org.gvsig.xml2db.swing.impl.Xml2dbSwingCommons;
76
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
78

    
79
/**
80
 *
81
 * @author jjdelcerro
82
 */
83
@SuppressWarnings("UseSpecificCatch")
84
public class CreatedbFromXmlPanel 
85
        extends CreatedbFromXmlPanelView 
86
        implements Xml2dbPanel
87
    {
88

    
89
    protected static final Logger LOGGER = LoggerFactory.getLogger(CreatedbFromXmlPanel.class);
90
    private PickerController<Locale> pickerLocale;
91

    
92
    private static class XMLInfoListModel extends AbstractListModel<LabeledValue<XMLTableInfo>> {
93
        
94
        private final XMLInfo xmlinfo;
95
        private final List<LabeledValue<XMLTableInfo>> tables;
96
        
97
        
98
        public XMLInfoListModel() {
99
            this(null);
100
        }
101
        
102
        public XMLInfoListModel(XMLInfo xmlinfo) {
103
            this.xmlinfo = xmlinfo;
104
            if( xmlinfo != null ) {
105
                this.tables = new ArrayList<>(xmlinfo.size());
106
                for (XMLTableInfo tableInfo : xmlinfo) {
107
                    this.tables.add(new LabeledValueImpl<>(tableInfo.getName(),tableInfo));
108
                }
109
            } else {
110
                this.tables = null;
111
            }
112
        }
113

    
114
        @Override
115
        public LabeledValue<XMLTableInfo> getElementAt(int index) {
116
            if( this.tables == null ) {
117
                return null;
118
            }
119
            return tables.get(index);
120
        }
121

    
122
        @Override
123
        public int getSize() {
124
            if( this.tables == null ) {
125
                return 0;
126
            }
127
            return this.tables.size();
128
        }
129
        
130
        
131
    }
132
            
133
    
134
    private Dialog dialog;
135
    private FilePickerController pickerXMLFile;
136
    private FilePickerController pickerDbfile;
137
    private ProjectionPickerController pickerProjection;
138
    private CharsetPickerController pickerCharset;
139
    private TaskStatusController taskStatusController;
140
    private Task lastTask;
141
    private XMLInfo xmlinfo;
142
    
143
    public CreatedbFromXmlPanel() {
144
        this.createComponents();
145
    }
146
    
147
    private void createComponents() {    
148
        this.lastTask = Task.FAKE_TASK;
149
        this.xmlinfo = null;
150
        this.initComponents();
151
    }
152
    
153
    private void initComponents() {
154
    
155
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
156
        DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager();
157
        
158
        this.taskStatusController = ToolsSwingLocator.getTaskStatusSwingManager().createTaskStatusController(
159
                lblStatusCaption, 
160
                lblStatusMsg,
161
                pbStatus
162
        );
163
        this.taskStatusController.setVisible(false);
164
        
165
        this.translate();
166
        
167
        this.setTablesModel(null);
168
        
169
        this.pickerXMLFile = toolsSwingManager.createFilePickerController(
170
                this.txtXMLFile, 
171
                this.btnXMLFile,
172
                null,
173
                "Xml2db_xmlFile",
174
                null,
175
                true
176

    
177
        );
178
        this.pickerXMLFile.addChangeListener((ChangeEvent e) -> {
179
            doChangeXMLfile();
180
        });
181

    
182
        this.pickerCharset = toolsSwingManager.createCharsetPickerController(
183
                null,
184
                this.cboCharset
185
        );
186
        
187
        this.pickerProjection = dataSwingManager.createProjectionPickerController(
188
                this.txtProjection, 
189
                this.btnProjection
190
        );
191
        this.pickerProjection.addChangeListener((ChangeEvent e) -> {
192
            setTablesModel(null);
193
        });
194
        
195
        this.pickerDbfile = toolsSwingManager.createFilePickerController(
196
                this.txtDatabaseFile, 
197
                this.btnDataBaseFile
198
        );
199
        this.pickerDbfile.addChangeListener((ChangeEvent e) -> {
200
            doChangeDBfile();
201
        });
202
        
203
        this.btnAnalizeXML.addActionListener((ActionEvent e) -> {
204
            doAnalizeXML();
205
        });
206
        this.btnAnalizeXML.setCursor(new Cursor(Cursor.HAND_CURSOR));
207
        
208
        this.btnViewTableStructure.addActionListener((ActionEvent e) -> {
209
            doViewTableStructure();
210
        });
211
        this.btnViewTableStructure.setCursor(new Cursor(Cursor.HAND_CURSOR));
212
        
213
        this.pickerCharset.set(Charset.defaultCharset());
214
        
215
        this.chkRegisterConnection.setSelected(true);
216
        
217
        this.chkOverwriteDatabase.addChangeListener((ChangeEvent e) -> {
218
            updateStateComponents();
219
        });
220
        
221
        this.cboCharset.setSelectedIndex(-1);
222
        
223
        this.pickerLocale = toolsSwingManager.createLocalePickerController(this.cboLocale);
224
        this.pickerLocale.set(Locale.getDefault());
225
        this.pickerLocale.addChangeListener((ChangeEvent e) -> {
226
            setTablesModel(null);
227
        });
228
        
229
        toolsSwingManager.addClearButton(this.txtPrefixesForTables);
230
        
231
        SwingUtilities.invokeLater(() -> { updateStateComponents(); });
232
        
233
        ToolsSwingUtils.ensureRowsCols(this, 5, 80, 6, 100);
234
    }
235

    
236
    private void translate() {
237
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
238
        
239
        toolsSwingManager.translate(this.lblCharset);
240
        toolsSwingManager.translate(this.lblRepositoryName);
241
        toolsSwingManager.translate(this.lblCreatedb);
242
        toolsSwingManager.translate(this.lblFileXML);
243
        toolsSwingManager.translate(this.lblDatabaseFile);
244
        toolsSwingManager.translate(this.lblProjection);
245
        toolsSwingManager.translate(this.lblTables);
246
        toolsSwingManager.translate(this.btnAnalizeXML);
247
        toolsSwingManager.translate(this.btnViewTableStructure);
248
        toolsSwingManager.translate(this.lblRegisterConnection);
249
        toolsSwingManager.translate(this.lblOverwriteDatabase);
250
        toolsSwingManager.translate(this.lblLocale);
251
        toolsSwingManager.translate(this.lblPrefixesForTables);
252
        
253
    }
254
    
255
    private boolean isProcessing() {
256
        return this.lastTask.isProcessing();
257
    }
258
    
259
    private void updateStateComponents() {
260
        if( !SwingUtilities.isEventDispatchThread() ) {
261
            SwingUtilities.invokeLater(this::updateStateComponents);
262
            return;
263
        }
264
        message(null);
265
        if( this.isProcessing() ) {
266
            this.pickerXMLFile.setEnabled(false);
267
            this.pickerCharset.setEnabled(false);
268
            this.pickerProjection.setEnabled(false);
269
            this.btnAnalizeXML.setEnabled(false);
270
            this.lstTables.setEnabled(false);
271
            this.btnViewTableStructure.setEnabled(false);
272
            if( this.dialog!=null ) {
273
                this.dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, false);
274
            }
275
            return;
276
        }
277
        this.pickerXMLFile.setEnabled(true);
278
        this.pickerCharset.setEnabled(true);
279
        this.pickerProjection.setEnabled(true);
280
        
281
        I18nManager i18n = ToolsLocator.getI18nManager();
282
        File xmlfile = this.pickerXMLFile.get();
283
        if( xmlfile == null || !xmlfile.exists() ) {
284
            if( xmlfile==null ) {
285
                this.message(i18n.getTranslation("_XML_file_is_required"), JOptionPane.WARNING_MESSAGE);
286
            } else {
287
                this.message(i18n.getTranslation("_XML_file_not_exists"), JOptionPane.WARNING_MESSAGE);
288
            }
289
            this.btnAnalizeXML.setEnabled(false);
290
            this.lstTables.setEnabled(false);
291
            this.btnViewTableStructure.setEnabled(false);
292
            if( this.dialog!=null ) {
293
                this.dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, false);
294
            }
295
            return;
296
        }
297
        this.btnAnalizeXML.setEnabled(true);
298
        if( this.lstTables.getModel().getSize()<1 ) {
299
            if( this.xmlinfo == null ) {
300
                this.message(i18n.getTranslation("_Analize_XML_required"), JOptionPane.WARNING_MESSAGE);
301
            } else {
302
                this.message(i18n.getTranslation("_No_tables_recognized_in_the_XML"), JOptionPane.WARNING_MESSAGE);
303
            }
304
            this.btnViewTableStructure.setEnabled(false);
305
            if( this.dialog!=null ) {
306
                this.dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, false);
307
            }
308
            return;
309
        }
310
        
311
        if( this.xmlinfo!=null && this.xmlinfo.hasGeometries() && this.pickerProjection.get()==null ) {
312
            this.message(i18n.getTranslation("_Projection_is_required"), JOptionPane.WARNING_MESSAGE);
313
            if( this.dialog!=null ) {
314
                this.dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, false);
315
            }
316
            return;
317
        }
318
        
319
        this.lstTables.setEnabled(true);
320
        this.btnViewTableStructure.setEnabled(true);
321
        File dbfile = this.pickerDbfile.get();
322
        if( dbfile == null ) {
323
            this.message(i18n.getTranslation("_Database_file_is_required"), JOptionPane.WARNING_MESSAGE);
324
            if( this.dialog!=null ) {
325
                this.dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, false);
326
            }
327
            return;
328
        }
329
        if( H2SpatialUtils.existsH2db(dbfile) && !this.chkOverwriteDatabase.isSelected() ) {
330
            this.message(i18n.getTranslation("_Database_file_already_exists"), JOptionPane.WARNING_MESSAGE);
331
            if( this.dialog!=null ) {
332
                this.dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, false);
333
            }
334
            return;
335
        }
336
        if( StringUtils.isBlank(this.txtRepositoryName.getText()) ) {
337
            this.message(i18n.getTranslation("_Repository_name_is_required"), JOptionPane.WARNING_MESSAGE);
338
            if( this.dialog!=null ) {
339
                this.dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, false);
340
            }
341
            return;
342
        }
343
        if( this.dialog!=null ) {
344
            this.dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, true);        
345
        }
346
        this.taskStatusController.setVisible(this.lastTask.needToShowTheStatus());        
347
    }
348

    
349
    @Override
350
    public void setDialog(Dialog dialog) {
351
        this.dialog = dialog;
352
    }
353

    
354
    @Override
355
    public JComponent asJComponent() {
356
        return this;
357
    }
358
    
359
    @Override
360
    public void performAction() {
361
        doCreatedb();
362
    }
363

    
364
    private void doCreatedb() {
365
        if( this.xmlinfo==null ) {
366
            return;
367
        }
368
        File dbfile = this.pickerDbfile.get();
369
        if( dbfile==null || dbfile.exists()) {
370
            return;
371
        }
372
        String s = this.txtRepositoryName.getText();
373
        if( StringUtils.isBlank(s) ) {
374
            s = FilenameUtils.getBaseName(dbfile.getName());
375
        } 
376
        String repoName = s;
377
        
378
        boolean registerConnection = this.chkRegisterConnection.isSelected();
379
        
380
        Xml2dbManager manager = Xml2dbLocator.getXml2dbManager();
381
        
382
        I18nManager i18n = ToolsLocator.getI18nManager();
383
        if( H2SpatialUtils.existsH2db(dbfile) ) {
384
            if( !this.chkOverwriteDatabase.isSelected() ) {
385
                message(i18n.getTranslation("Database already exists"), JOptionPane.WARNING_MESSAGE);
386
                return;
387
            }
388
        }        
389
        
390
        this.lastTask = new Task(                
391
                "Xml2db_Creating_database", 
392
                i18n.getTranslation("_Create_database"), 
393
                this::updateStateComponents, 
394
                taskStatusController
395
            ) {
396
            @Override
397
            protected void task(SimpleTaskStatus taskStatus) throws Throwable{
398
                try {
399
                    if( H2SpatialUtils.existsH2db(dbfile) ) {
400
                        taskStatus.message(i18n.getTranslation("_Removing_existing_database"));
401
                        H2SpatialUtils.server_stop();
402
                        H2SpatialUtils.removeH2db(dbfile);
403
                        H2SpatialUtils.server_start();
404
                    }        
405
                    JDBCServerExplorerParameters params = manager.createDatabase(dbfile, xmlinfo, taskStatus);
406
                    if( params == null ) {
407
                        throw new RuntimeException("Can't create database");
408
                    }
409
                    if( registerConnection ) {
410
                        addToConnectionPool(params,repoName);   
411
                    }
412
                } catch(Exception ex) {
413
                    LOGGER.warn("Can't create database",ex);
414
                    throw ex;
415
                }
416
            }
417

    
418
            @Override
419
            protected void postTask() {
420
                message(null);
421
            }
422
        };
423
        
424
        this.lastTask.start();
425
        
426
    }
427

    
428
    public void addToConnectionPool(JDBCServerExplorerParameters params, String id) {
429
        DataManager dataManager = DALLocator.getDataManager();
430
        dataManager.getDataServerExplorerPool().add(id, params);
431
    }
432
    
433
    private void doAnalizeXML() {
434
        Xml2dbManager manager = Xml2dbLocator.getXml2dbManager();
435
        File xmlfile = this.pickerXMLFile.get();
436
        if( xmlfile == null || !xmlfile.exists() ) {
437
            return;
438
        }
439
        IProjection proj = this.pickerProjection.get();
440
        Charset charset = this.pickerCharset.get();
441
        Locale locale = this.pickerLocale.get();
442
        
443
        String tablesPrefix = StringUtils.defaultIfBlank(this.txtPrefixesForTables.getText(), null);
444
        
445
        I18nManager i18n = ToolsLocator.getI18nManager();
446

    
447
        this.lastTask = new Task(                
448
                "Xml2db_AnalizeXML", 
449
                i18n.getTranslation("_Analize_xml"), 
450
                this::updateStateComponents, 
451
                taskStatusController
452
            ) {
453
            @Override
454
            protected void task(SimpleTaskStatus taskStatus) throws Throwable{
455
                try {
456
                    XMLInfo xmlinfo = manager.extractStructure(xmlfile, charset, proj, locale, tablesPrefix, taskStatus);
457
                    if( proj==null && xmlinfo.getSrid()!=null ) {
458
                        pickerProjection.set(xmlinfo.getSrid());
459
                    }
460
                    if( xmlinfo.getCharset()!=null && charset==null ) {
461
                        pickerCharset.set(xmlinfo.getCharset());
462
                    }
463
                    setTablesModel(xmlinfo);
464
                } catch(Throwable ex) {
465
                    LOGGER.warn("Can't analize xml",ex);
466
                    setTablesModel(null);
467
                    I18nManager i18n = ToolsLocator.getI18nManager();
468
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
469
                    dialogs.messageDialog(
470
                            i18n.getTranslation("_Problems_processing_XML_file")
471
                                    +"\n\n"
472
                                    + ex.getLocalizedMessage(), 
473
                            i18n.getTranslation("_Xml2db_Create_database_from_xml"), 
474
                            JOptionPane.WARNING_MESSAGE
475
                    );
476
                    throw ex;
477
                }
478
            }
479
        };
480
        this.lastTask.start();
481
    }
482
    
483
    private void setTablesModel(XMLInfo xmlinfo) {
484
        if( !SwingUtilities.isEventDispatchThread() ) {
485
            SwingUtilities.invokeLater(() -> {this.setTablesModel(xmlinfo);});
486
            return;
487
        }
488
        this.xmlinfo = xmlinfo;
489
        if( xmlinfo == null ) {
490
            lstTables.setModel(new XMLInfoListModel()); 
491
            return;
492
        }
493
        lstTables.setModel(new XMLInfoListModel(xmlinfo)); 
494
    }
495
    
496
    private void doViewTableStructure() {
497
        LabeledValue<XMLTableInfo> x = (LabeledValue<XMLTableInfo>)this.lstTables.getSelectedValue();
498
        if( x == null ) {
499
            return;
500
        }
501
//        I18nManager i18n = ToolsLocator.getI18nManager();
502
        DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager();
503
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
504
        
505
        XMLTableInfo tableInfo = x.getValue();
506
        EditableFeatureType featureType = tableInfo.getFeatureType();
507
        
508
        FeatureTypePanel panel = dataSwingManager.createFeatureTypePanel();
509
        panel.put(featureType);
510
        Dialog theDialog = windowManager.createDialog(
511
                panel.asJComponent(),
512
                ToolsSwingUtils.makeTitle("_Xml2db_Column_manager", tableInfo.getName(), featureType.getLabel()),
513
                null, 
514
                WindowManager_v2.BUTTONS_OK_CANCEL
515
        );
516
        theDialog.addActionListener((ActionEvent e) -> {
517
            if( theDialog.getAction()==WindowManager_v2.BUTTON_OK) {
518
                panel.fetch(x.getValue().getFeatureType());
519
            }
520
        });
521
        theDialog.show(
522
                WindowManager.MODE.WINDOW,
523
                Collections.singletonMap("align", GridBagConstraints.CENTER)
524
        );
525
    }
526
    
527
    private void doChangeXMLfile() {
528
        File xmlfile = this.pickerXMLFile.get();
529
        if( xmlfile != null ) {
530
            File dbfile = this.pickerDbfile.get();
531
            if( dbfile == null ) {
532
                dbfile = new File(FilenameUtils.removeExtension(xmlfile.getAbsolutePath()));
533
                this.pickerDbfile.set(dbfile);
534
                this.txtRepositoryName.setText(FilenameUtils.getBaseName(xmlfile.getName()));
535
            }
536
        }
537
        updateStateComponents();
538
    }
539
    
540
    private void doChangeDBfile() {
541
        File dbfile = this.pickerDbfile.get();
542
        if( dbfile != null ) {
543
            String repoName = this.txtRepositoryName.getText();
544
            if( StringUtils.isBlank(repoName) ) {
545
                this.txtRepositoryName.setText(FilenameUtils.getBaseName(dbfile.getName()));
546
            }
547
        }
548
        updateStateComponents();
549
    }
550
    
551
    private void message(String msg) {
552
        message(msg,JOptionPane.INFORMATION_MESSAGE);
553
    }
554
    
555
    private void message(String msg, int type) {
556
        if( StringUtils.isBlank(msg) ) {
557
            this.lblStatusMsg.setText("");
558
            return;
559
        }
560
        if( type == JOptionPane.WARNING_MESSAGE ) {
561
            msg = Xml2dbSwingCommons.getHTMLColorTag(Color.RED.darker(), msg);
562
        }        
563
        this.lblStatusMsg.setText(msg);
564
        this.lblStatusMsg.setVisible(true);
565
    }
566
    
567
}