Statistics
| Revision:

gvsig-desktop-customize / trunk / org.gvsig.customize.app / org.gvsig.customize.app.mainplugin / src / main / java / org / gvsig / customize / DistributionParametersPanel.java @ 1

History | View | Annotate | Download (18.1 KB)

1

    
2
package org.gvsig.customize;
3

    
4
import java.awt.event.ActionEvent;
5
import java.awt.event.ActionListener;
6
import java.io.File;
7
import java.io.FileOutputStream;
8
import java.io.IOException;
9
import java.nio.file.DirectoryIteratorException;
10
import java.nio.file.DirectoryStream;
11
import java.nio.file.FileSystem;
12
import java.nio.file.FileSystems;
13
import java.nio.file.Files;
14
import java.nio.file.Path;
15
import java.nio.file.Paths;
16
import java.util.ArrayList;
17
import java.util.Arrays;
18
import java.util.Collections;
19
import java.util.HashMap;
20
import java.util.HashSet;
21
import java.util.List;
22
import java.util.Map;
23
import java.util.Set;
24
import javax.swing.DefaultListModel;
25
import javax.swing.JTextField;
26
import javax.swing.ListModel;
27
import javax.swing.ListSelectionModel;
28
import javax.swing.SwingUtilities;
29
import javax.swing.event.ListSelectionEvent;
30
import javax.swing.event.ListSelectionListener;
31
import org.apache.commons.io.FileUtils;
32
import org.apache.commons.io.IOUtils;
33
import org.apache.commons.lang3.BooleanUtils;
34
import org.apache.commons.lang3.StringUtils;
35
import org.gvsig.andami.PluginServices;
36
import org.gvsig.andami.PluginsLocator;
37
import org.gvsig.andami.PluginsManager;
38
import org.gvsig.app.ApplicationLocator;
39
import org.gvsig.app.ApplicationManager;
40
import org.gvsig.tools.dynobject.DynObject;
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43

    
44

    
45
public class DistributionParametersPanel extends DistributionParametersPanelLayout implements MessageBar {
46

    
47
    private static final Logger logger = LoggerFactory.getLogger(DistributionParametersPanel.class);
48

    
49
    private List<ActionListener> listeners = new ArrayList<ActionListener>();
50
    private final DynObject pluginProperties;
51
    private final PluginServices plugin;
52
    private JListWithCheckbox lchkPackages;
53
    private Set<String> defaultPackages = new HashSet<String>();
54

    
55
    public DistributionParametersPanel() {
56
        super();
57
        PluginsManager pluginManager = PluginsLocator.getManager();
58
        this.plugin = pluginManager.getPlugin(CustomizeExtension.class);
59
        this.pluginProperties = plugin.getPluginProperties();
60
        this.initComponents();
61
    }
62

    
63
    private String getPropertyPath(String name) {
64
        File f = (File) pluginProperties.getDynValue(name);
65
        if (f == null) {
66
            return "";
67
        }
68
        return f.getAbsolutePath();
69
    }
70

    
71
    private void initComponents() {
72
        this.lchkPackages = new JListWithCheckbox(this.lstPackages);
73

    
74
        this.setCloseAndCreateVisible(false);
75
        this.txtOnlineInstaller.setEditable(false);
76
        this.txtPackageSet.setEditable(false);
77
        this.txtWorkingFolder.setEditable(false);
78
        this.chkIncludeCustomizePlugin.setSelected(false);
79
        loadFormValues();
80

    
81
        this.butBrowseOnlineInstaller.addActionListener(new ActionListener() {
82
            @Override
83
            public void actionPerformed(ActionEvent ae) {
84
                doBrowseFile(getOnlineInstaller(), "Select the online installer", txtOnlineInstaller);
85
            }
86
        });
87
        this.butBrowsePackageSet.addActionListener(new ActionListener() {
88
            @Override
89
            public void actionPerformed(ActionEvent ae) {
90
                doBrowseFile(getPackageSetFolder(), "Select the package set", txtPackageSet);
91
                unzipPackagset();
92
            }
93
        });
94
        this.butBrowseWorkingFolder.addActionListener(new ActionListener() {
95
            @Override
96
            public void actionPerformed(ActionEvent ae) {
97
                doBrowseFolder(getWorkingFolder(), "Select the working folder", txtWorkingFolder);
98
            }
99
        });
100
        this.butClose.addActionListener(new ActionListener() {
101
            @Override
102
            public void actionPerformed(ActionEvent ae) {
103
                doClose();
104
            }
105
        });
106
        this.butCreate.addActionListener(new ActionListener() {
107
            @Override
108
            public void actionPerformed(ActionEvent ae) {
109
                doCreate();
110
            }
111
        });
112
        this.butAddPackage.addActionListener(new ActionListener() {
113
            @Override
114
            public void actionPerformed(ActionEvent ae) {
115
                doAddPackage();
116
            }
117
        });
118
        this.butRemovePackage.addActionListener(new ActionListener() {
119
            @Override
120
            public void actionPerformed(ActionEvent ae) {
121
                doRemovePackage();
122
            }
123
        });
124
        this.lchkPackages.addChecksListener(new ListSelectionListener() {
125
            @Override
126
            public void valueChanged(ListSelectionEvent lse) {
127
                doChecksValueChanged(lse);
128
            }
129
        });
130
        this.butCheckAll.addActionListener(new ActionListener() {
131
            @Override
132
            public void actionPerformed(ActionEvent ae) {
133
                doCheckAll();
134
            }
135
        });
136
        this.butUncheckAll.addActionListener(new ActionListener() {
137
            @Override
138
            public void actionPerformed(ActionEvent ae) {
139
                doUncheckAll();
140
            }
141
        });
142

    
143
    }
144

    
145
    private void doCheckAll() {
146
        ListModel model = this.lchkPackages.getModel();
147
        this.lchkPackages.getCheckedModel().addSelectionInterval(0, model.getSize()-1);
148
        for( int i=0; i<model.getSize(); i++) {
149
            String filename = (String) model.getElementAt(i);
150
            String code = getPackageCode(filename);
151
            this.defaultPackages.add(code);
152
        }        
153
    }
154
    
155
    private void doUncheckAll() {
156
        this.lchkPackages.getCheckedModel().clearSelection();
157
        this.defaultPackages.clear();
158
    }
159
    
160
    private void doChecksValueChanged(ListSelectionEvent lse) {
161
        ListSelectionModel checkedsModel = this.lchkPackages.getCheckedModel();
162
        ListModel model = this.lchkPackages.getModel();
163
        for (int i = lse.getFirstIndex(); i <= lse.getLastIndex(); i++) {
164
            String packageCode = getPackageCode((String) model.getElementAt(i));
165
            if (checkedsModel.isSelectedIndex(i)) {
166
                this.defaultPackages.add(packageCode);
167
            } else {
168
                this.defaultPackages.remove(packageCode);
169
            }
170
        }
171
    }
172

    
173
    private void loadFormValues() {
174
        this.txtDistributionId.setText((String) pluginProperties.getDynValue("distributionID"));
175
        this.txtOnlineInstaller.setText(getPropertyPath("onlineInstaller"));
176
        this.txtPackageSet.setText(getPropertyPath("packageSet"));
177
        this.txtWorkingFolder.setText(getPropertyPath("WorkingFolder"));
178
        this.chkIncludeCustomizePlugin.setSelected(BooleanUtils.isTrue((Boolean) pluginProperties.getDynValue("includeCustomizePlugin")));
179
        unzipPackagset();
180
        fillPackageList();
181
    }
182

    
183

    
184
    private void saveFormValues() {
185
        pluginProperties.setDynValue("onlineInstaller", getOnlineInstaller());
186
        pluginProperties.setDynValue("packageSet", getPackageSet());
187
        pluginProperties.setDynValue("WorkingFolder", getWorkingFolder());
188
        pluginProperties.setDynValue("distributionID", getDistributionId());
189
        pluginProperties.setDynValue("includeCustomizePlugin", getIncludeCustomizePlugin());
190
        plugin.savePluginProperties();
191
    }
192

    
193
    private void updateDefaultPackagesFile() {
194
        ArrayList lines = new ArrayList();
195
        lines.addAll(this.defaultPackages);
196
        if( this.getIncludeCustomizePlugin() ) {
197
            lines.add(this.plugin.getPluginName());
198
        }
199
        Collections.sort(lines);
200
        try {
201
            FileUtils.writeLines(
202
                    new File(this.getPackageSetFolder(), "defaultPackages"), 
203
                    lines
204
            );
205
        } catch (IOException ex) {
206
            this.message("Can't write defaultPackages. " + ex.getMessage());
207
            logger.warn("Can't write defaultPackages.", ex);
208
        }
209
    }
210

    
211
    private void doCreate() {
212
        saveFormValues();
213
        updateDefaultPackagesFile();
214
        this.fireActionPerformed();
215
    }
216

    
217
    private void doClose() {
218
        saveFormValues();
219
        this.setVisible(false);
220
    }
221

    
222
    private void doBrowseFile(File currentValue, String label, JTextField field) {
223
        ApplicationManager application = ApplicationLocator.getManager();
224
        File folder = currentValue;
225
        if (folder != null) {
226
            folder = folder.getParentFile();
227
        }
228
        File[] folders = application.showOpenFileDialog(label, folder);
229
        if (folders != null && folders.length == 1) {
230
            field.setText(folders[0].getAbsolutePath());
231
        }
232
    }
233

    
234
    private void doBrowseFolder(File currentValue, String label, JTextField field) {
235
        ApplicationManager application = ApplicationLocator.getManager();
236
        File folder = currentValue;
237
        if (folder != null) {
238
            folder = folder.getParentFile();
239
        }
240
        File[] folders = application.showOpenDirectoryDialog(label, folder);
241
        if (folders != null && folders.length == 1) {
242
            field.setText(folders[0].getAbsolutePath());
243
        }
244
    }
245

    
246
    public void message(final String msg) {
247
        if (!SwingUtilities.isEventDispatchThread()) {
248
            SwingUtilities.invokeLater(new Runnable() {
249
                @Override
250
                public void run() {
251
                    message(msg);
252
                }
253
            });
254
            return;
255
        }
256
        this.lblMessages.setText("<html>" + msg.replace("\n", "<br>\n") + "</html>");
257
    }
258

    
259
    public File getOnlineInstaller() {
260
        String path = this.txtOnlineInstaller.getText();
261
        if (StringUtils.isBlank(path)) {
262
            return null;
263
        }
264
        return new File(path);
265
    }
266

    
267
    private File getPackageSet() {
268
        String path = this.txtPackageSet.getText();
269
        if (StringUtils.isBlank(path)) {
270
            return null;
271
        }
272
        return new File(path);        
273
    }
274

    
275
    public File getPackageSetFolder() {
276
        File packagesetFolder = new File(getWorkingFolder(), "packages");
277
        return packagesetFolder;   
278
    }
279
    
280
    public File getWorkingFolder() {
281
        String path = this.txtWorkingFolder.getText();
282
        if (StringUtils.isBlank(path)) {
283
            return null;
284
        }
285
        return new File(path);
286
    }
287

    
288
    public String getDistributionId() {
289
        String id = this.txtDistributionId.getText();
290
        if (StringUtils.isBlank(id)) {
291
            return null;
292
        }
293
        return id.trim();
294
    }
295

    
296
    public boolean getIncludeCustomizePlugin() {
297
        return this.chkIncludeCustomizePlugin.isSelected();
298
    }
299

    
300
    public void setCloseAndCreateVisible(boolean visible) {
301
        this.butClose.setVisible(visible);
302
        this.butCreate.setVisible(visible);
303
    }
304

    
305
    public void setCloseAndCreateEnabled(final boolean enabled) {
306
        if (!SwingUtilities.isEventDispatchThread()) {
307
            SwingUtilities.invokeLater(new Runnable() {
308
                @Override
309
                public void run() {
310
                    setCloseAndCreateEnabled(enabled);
311
                }
312
            });
313
            return;
314
        }
315
        this.butClose.setEnabled(enabled);
316
        this.butCreate.setEnabled(enabled);
317
    }
318

    
319
    public void addActionListener(ActionListener l) {
320
        if (this.listeners.contains(l)) {
321
            return;
322
        }
323
        this.listeners.add(l);
324
    }
325

    
326
    protected void fireActionPerformed() {
327
        ActionEvent event = new ActionEvent(this, 0, "create_distribution");
328

    
329
        for (ActionListener listener : listeners) {
330
            try {
331
                listener.actionPerformed(event);
332
            } catch (Exception ex) {
333
                logger.warn("Error triggering event", ex);
334
            }
335
        }
336
    }
337

    
338
    private void loadDefaultPackages(File packages) {
339
        try {
340
            this.defaultPackages = new HashSet<String>();
341

    
342
            List<String> lines = FileUtils.readLines(packages);
343
            this.defaultPackages.clear();
344
            for (String line : lines) {
345
                line = line.trim();
346
                if (line.startsWith("#") || line.startsWith(";")) {
347
                    continue;
348
                }
349
                this.defaultPackages.add(line.toLowerCase());
350
            }
351
        } catch (IOException ex) {
352
            logger.warn("Can't load defaultPackages from '"+packages.getAbsolutePath()+"'.",ex);
353
        }
354
    }
355

    
356
    private String getPackageCode(String filename) {
357
        if( StringUtils.isEmpty(filename) ) {
358
            return filename;
359
        }
360
        String[] ss = filename.split("-");
361
        if (ss.length > 3) {
362
            return ss[3].toLowerCase();
363
        }
364
        return "";
365
    }
366

    
367
    private void fillPackageList() {
368
        File f = this.getWorkingFolder();
369
        if (f == null) {
370
            return;
371
        }
372
        DefaultListModel model = new DefaultListModel();
373
        int first = this.lchkPackages.getFirstVisibleIndex();
374
        File packagesetFolder = new File(f, "packages");
375
        if (packagesetFolder.exists()) {
376
            File[] packagesArray = packagesetFolder.listFiles();
377
            List<File>packages = Arrays.asList(packagesArray);
378
            Collections.sort(packages);
379
            for (File package1 : packages) {
380
                String filename = package1.getName();
381
                if ( ! "defaultPackages".equalsIgnoreCase(filename)) {
382
                    model.addElement(filename);
383
                }
384
            }
385
        }
386
        this.lchkPackages.setModel(model);
387
        updateCheckeds();
388
        this.lchkPackages.ensureIndexIsVisible(first);
389
    }
390
    
391
    private void updateCheckeds() {
392
        this.lchkPackages.getCheckedModel().clearSelection();
393
        ListModel model = this.lchkPackages.getModel();
394
        for( int i=0; i<model.getSize(); i++) {
395
            String filename = (String) model.getElementAt(i);
396
            String code = getPackageCode(filename);
397
            if (this.defaultPackages.contains(code)) {
398
                this.lchkPackages.getCheckedModel().addSelectionInterval(i, i);
399
            }
400
        }
401
    }
402

    
403
    private void unzipPackagset() {
404
        final Runnable updategui = new Runnable() {
405
            
406
            @Override
407
            public void run() {
408
                fillPackageList();
409
                updateCheckeds();
410
                lchkPackages.setEnabled(true);
411
                butBrowsePackageSet.setEnabled(true);
412
                butAddPackage.setEnabled(true);
413
                butRemovePackage.setEnabled(true);
414
            }
415
        };
416
        final Runnable task = new Runnable() {
417
            
418
            @Override
419
            public void run() {
420
                message("Updating package set");
421
                File packageSet = getPackageSet();
422
                if (packageSet == null) {
423
                    return;
424
                }
425
                if( getWorkingFolder() == null ) {
426
                    return;
427
                }
428
                
429
                File packagesetFolder = getPackageSetFolder();
430
                if (packagesetFolder.exists()) {
431
                    try {
432
                        FileUtils.deleteDirectory(packagesetFolder);
433
                    } catch (IOException ex) {
434
                        message("Can't delete 'packages' directory. " + ex.getMessage());
435
                    }
436
                }
437
                packagesetFolder.mkdir();
438
                
439
                Map<String, String> env = new HashMap<>();
440
                env.put("create", "true");
441
                
442
                FileSystem zipfs = null;
443
                try {
444
                    Path zippath = Paths.get(packageSet.getAbsolutePath());
445
                    zipfs = FileSystems.newFileSystem(zippath, null);
446
                    Iterable<Path> dirs = zipfs.getRootDirectories();
447
                    for (Path name : dirs) {
448
                        DirectoryStream<Path> stream = Files.newDirectoryStream(name);
449
                        for (Path file : stream) {
450
                            FileOutputStream fos = null;
451
                            try {
452
                                fos = new FileOutputStream(new File(packagesetFolder, file.getFileName().toString()));
453
                                Files.copy(file, fos);
454
                            } catch (IOException | DirectoryIteratorException x) {
455
                                // Do nothing
456
                            } finally {
457
                                if (fos != null) {
458
                                    IOUtils.closeQuietly(fos);
459
                                }
460
                            }
461
                        }
462
                    }
463
                    loadDefaultPackages(new File(packagesetFolder, "defaultPackages"));
464
                } catch (Exception ex) {
465
                    
466
                } finally {
467
                    message("");
468
                    if (zipfs != null) {
469
                        try {
470
                            zipfs.close();
471
                        } catch (IOException ex) {
472
                        }
473
                    }
474
                    SwingUtilities.invokeLater(updategui);
475
                }
476
            }
477
        };
478
        lchkPackages.setEnabled(false);
479
        butBrowsePackageSet.setEnabled(false);
480
        butAddPackage.setEnabled(false);
481
        butRemovePackage.setEnabled(false);
482
        Thread thread = new Thread(task);
483
        thread.start();
484
    }
485

    
486
    private void doRemovePackage() {
487
        List<String> filenames = this.lchkPackages.getSelectedValuesList();
488
        if (filenames == null || filenames.isEmpty()) {
489
            return;
490
        }
491
        File packagesetFolder = new File(getWorkingFolder(), "packages");
492
        for( String filename : filenames ) {
493
            File filetoremove = new File(packagesetFolder, filename);
494
            filetoremove.delete();
495
        }
496
        fillPackageList();
497
     }
498

    
499
    private void doAddPackage() {
500
        ApplicationManager application = ApplicationLocator.getManager();
501
        File[] files = application.showOpenFileDialog("Select package to add", this.getWorkingFolder());
502
        if (files == null) {
503
            return;
504
        }
505
        File packagesetFolder = new File(getWorkingFolder(), "packages");
506
        for (File file : files) {
507
            try {
508
                FileUtils.copyFileToDirectory(file, packagesetFolder);
509
            } catch (IOException ex) {
510
                this.message("Can't copy package to working folder. " + ex.getMessage());
511
            }
512
        }
513
        fillPackageList();
514
    }
515
}