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

History | View | Annotate | Download (20.9 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
        SwingUtilities.invokeLater(() -> { updateStateComponents(); });
230
        
231
        ToolsSwingUtils.ensureRowsCols(this, 5, 80, 6, 100);
232
    }
233

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

    
346
    @Override
347
    public void setDialog(Dialog dialog) {
348
        this.dialog = dialog;
349
    }
350

    
351
    @Override
352
    public JComponent asJComponent() {
353
        return this;
354
    }
355
    
356
    @Override
357
    public void performAction() {
358
        doCreatedb();
359
    }
360

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

    
415
            @Override
416
            protected void postTask() {
417
                message(null);
418
            }
419
        };
420
        
421
        this.lastTask.start();
422
        
423
    }
424

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

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