Statistics
| Revision:

root / org.gvsig.educa.thematicmap.app / trunk / org.gvsig.educa.thematicmap.app / org.gvsig.educa.thematicmap.app.editor / src / main / java / org / gvsig / educa / thematicmap / app / editor / impl / DefaultThematicMapEditorManager.java @ 83

History | View | Annotate | Download (23.5 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.educa.thematicmap.app.editor.impl;
23

    
24
import java.io.File;
25
import java.io.IOException;
26
import java.util.List;
27

    
28
import javax.swing.JFileChooser;
29
import javax.swing.SwingUtilities;
30

    
31
import org.apache.commons.lang3.ObjectUtils;
32
import org.apache.commons.lang3.StringUtils;
33

    
34
import org.gvsig.andami.PluginServices;
35
import org.gvsig.andami.messages.NotificationManager;
36
import org.gvsig.andami.ui.mdiManager.IWindow;
37
import org.gvsig.app.project.Project;
38
import org.gvsig.app.project.ProjectManager;
39
import org.gvsig.app.project.documents.Document;
40
import org.gvsig.app.project.documents.view.ViewDocument;
41
import org.gvsig.app.project.documents.view.ViewManager;
42
import org.gvsig.educa.thematicmap.ThematicMapException;
43
import org.gvsig.educa.thematicmap.ThematicMapFileServices;
44
import org.gvsig.educa.thematicmap.ThematicMapLocator;
45
import org.gvsig.educa.thematicmap.ThematicMapManager;
46
import org.gvsig.educa.thematicmap.app.editor.CompilationListener;
47
import org.gvsig.educa.thematicmap.app.editor.ThematicMapEditorManager;
48
import org.gvsig.educa.thematicmap.app.viewer.ThematicMapDocument;
49
import org.gvsig.educa.thematicmap.app.viewer.ThematicMapDocumentManager;
50
import org.gvsig.educa.thematicmap.compilation.ThematicMapCompilation;
51
import org.gvsig.educa.thematicmap.compilation.ThematicMapCompilationInformation;
52
import org.gvsig.educa.thematicmap.compilation.ThematicMapCompiler;
53
import org.gvsig.educa.thematicmap.compilation.ThematicMapCompilerStatus;
54
import org.gvsig.educa.thematicmap.map.CantLoadContextException;
55
import org.gvsig.educa.thematicmap.map.InvalidThematicMapFormatException;
56
import org.gvsig.educa.thematicmap.map.ThematicMap;
57
import org.gvsig.educa.thematicmap.map.ThematicMapInformation;
58
import org.gvsig.educa.thematicmap.swing.ThematicMapSwingLocator;
59
import org.gvsig.educa.thematicmap.swing.ThematicMapSwingManager;
60
import org.gvsig.educa.thematicmap.swing.ThematicMapWindowManager;
61
import org.gvsig.educa.thematicmap.swing.ThematicMapWindowManager.MESSAGE_DIALOG_TYPE;
62
import org.gvsig.educa.thematicmap.swing.editor.ThematicMapCompilationEditor;
63
import org.gvsig.educa.thematicmap.swing.editor.ThematicMapCompilationEditorListener;
64
import org.gvsig.fmap.mapcontext.MapContext;
65
import org.gvsig.tools.persistence.exception.PersistenceException;
66
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
67

    
68
/**
69
 * <p>
70
 * Default implementation of {@link ThematicMapEditorManager}
71
 * </p>
72
 * 
73
 * @author gvSIG Team
74
 * @version $Id$
75
 * 
76
 */
77
public class DefaultThematicMapEditorManager implements
78
    ThematicMapEditorManager {
79

    
80
    private ThematicMapDocumentManager docManager;
81
    private final ThematicMapManager manager;
82
    private final ThematicMapSwingManager swingManager;
83
    private final ThematicMapWindowManager winManager;
84
    private final ThematicMapFileServices fileServices;
85
    private File workFolder;
86
    private final JFileChooser fileChooser;
87

    
88
    /**
89
     *
90
     */
91
    public DefaultThematicMapEditorManager() {
92
        swingManager = ThematicMapSwingLocator.getSwingManager();
93
        manager = swingManager.getManager();
94
        fileServices = ThematicMapLocator.getFileServices();
95
        winManager = swingManager.getWindowManager();
96
        fileChooser = new JFileChooser();
97
    }
98

    
99
    /**
100
     * <p>
101
     * {@link CompilationListener} instance which create a new
102
     * {@link ThematicMapDocument} from a {@link ViewDocument}
103
     * </p>
104
     * <p>
105
     * Delegates on previously received listener (if any)
106
     * </p>
107
     * 
108
     * @author gvSIG Team
109
     * @version $Id$
110
     * 
111
     */
112
    private class CreateDocumentListener implements CompilationListener {
113

    
114
        private final CompilationListener delegate;
115
        private final boolean openWindow;
116
        private final ViewDocument sourceView;
117

    
118
        /**
119
         * @param openWindow
120
         * 
121
         */
122
        public CreateDocumentListener(ViewDocument sourceView,
123
            CompilationListener delegate, boolean openWindow) {
124
            this.sourceView = sourceView;
125
            this.delegate = delegate;
126
            this.openWindow = openWindow;
127
        }
128

    
129
        /** {@inheridDoc} */
130
        public void finished(ThematicMapCompilerStatus status) {
131
            // Gets created map
132
            ThematicMap map =
133
                manager.getMapById(status.getResultCompilation()
134
                    .getInformation().getId());
135

    
136
            // Check if a document already exist for this map
137
            ThematicMapDocumentManager docManager = getDocManager();
138
            ThematicMapDocument doc = docManager.getDocumentForMap(map);
139
            if (doc == null) {
140
                doc = docManager.createDocument(map);
141
                getProject().add(doc);
142
            } else {
143
                // If exist reload
144
                try {
145
                    doc.reloadThematicMap();
146
                } catch (Exception ex) {
147
                    NotificationManager.addError(swingManager
148
                        .getTranslation("problems_reloading_thematic_map"), ex);
149
                }
150
            }
151
            // Link view to thematic map
152
            doc.setSourceView(sourceView);
153

    
154
            if (openWindow) {
155
                final IWindow window = docManager.getMainWindow(doc);
156
                SwingUtilities.invokeLater(new Runnable() {
157

    
158
                    public void run() {
159
                        PluginServices.getMDIManager().addWindow(window);
160
                    }
161
                });
162
            }
163

    
164
            if (delegate != null) {
165
                delegate.finished(status);
166
            }
167
        }
168

    
169
        /** {@inheridDoc} */
170
        public void canceledCompilation(ThematicMapCompilerStatus status) {
171
            if (delegate != null) {
172
                delegate.canceledCompilation(status);
173
            }
174
        }
175

    
176
        /** {@inheridDoc} */
177
        public void canceledEditing(ThematicMapCompilation compilation) {
178
            if (delegate != null) {
179
                delegate.canceledEditing(compilation);
180
            }
181
        }
182

    
183
        /** {@inheridDoc} */
184
        public void fail(ThematicMapCompilerStatus status) {
185
            if (delegate != null) {
186
                delegate.fail(status);
187
            } else {
188
                String msg =
189
                    swingManager
190
                        .getTranslation(
191
                            "problems_creating_thematic_map_from_a_view")
192
                        .concat(": ").concat(status.getFailMessage());
193
                if (status.getException() != null) {
194
                    NotificationManager.addWarning(msg, status.getException());
195
                } else {
196
                    NotificationManager.addWarning(msg);
197
                }
198
            }
199
        }
200

    
201
        public void exception(String message, Throwable exception) {
202
            if (delegate != null) {
203
                delegate.exception(message, exception);
204
            } else {
205
                String msg =
206
                    swingManager
207
                        .getTranslation(
208
                            "problems_creating_thematic_map_from_a_view")
209
                        .concat(": ").concat(message);
210
                NotificationManager.addError(msg, exception);
211
            }
212
        }
213

    
214
    }
215

    
216
    /**
217
     * <p>
218
     * {@link CompilationListener} instance which update the
219
     * {@link ThematicMapDocument} from its related {@link ViewDocument} (
220
     * {@link ThematicMapDocument#getSourceView()})
221
     * </p>
222
     * <p>
223
     * Delegates on previously received listener (if any)
224
     * </p>
225
     * 
226
     * @author gvSIG Team
227
     * @version $Id$
228
     * 
229
     */
230
    private class UpdateDocumentListener implements CompilationListener {
231

    
232
        private final CompilationListener delegate;
233
        private final boolean openWindow;
234
        private final ThematicMapDocument toUpdate;
235

    
236
        /**
237
         * @param openWindow
238
         * 
239
         */
240
        public UpdateDocumentListener(ThematicMapDocument toUpdate,
241
            CompilationListener delegate, boolean openWindow) {
242
            this.toUpdate = toUpdate;
243
            this.delegate = delegate;
244
            this.openWindow = openWindow;
245
        }
246

    
247
        /** {@inheridDoc} */
248
        public void finished(ThematicMapCompilerStatus status) {
249

    
250
            // close doc windows if it was opened
251
            PluginServices.getMDIManager().closeSingletonWindow(toUpdate);
252

    
253
            // Reload maps
254
            try {
255
                toUpdate.reloadThematicMap();
256
            } catch (Exception ex) {
257
                NotificationManager.addError(swingManager
258
                    .getTranslation("problems_reloading_thematic_map"), ex);
259
                return;
260
            }
261

    
262
            if (openWindow) {
263
                final IWindow window =
264
                    toUpdate.getFactory().getMainWindow(toUpdate);
265
                SwingUtilities.invokeLater(new Runnable() {
266

    
267
                    public void run() {
268
                        PluginServices.getMDIManager().addWindow(window);
269
                    }
270
                });
271
            }
272

    
273
            if (delegate != null) {
274
                delegate.finished(status);
275
            }
276
        }
277

    
278
        /** {@inheridDoc} */
279
        public void canceledCompilation(ThematicMapCompilerStatus status) {
280
            if (delegate != null) {
281
                delegate.canceledCompilation(status);
282
            }
283
        }
284

    
285
        /** {@inheridDoc} */
286
        public void canceledEditing(ThematicMapCompilation compilation) {
287
            if (delegate != null) {
288
                delegate.canceledEditing(compilation);
289
            }
290
        }
291

    
292
        /** {@inheridDoc} */
293
        public void fail(ThematicMapCompilerStatus status) {
294
            if (delegate != null) {
295
                delegate.fail(status);
296
            } else {
297
                String msg =
298
                    swingManager
299
                        .getTranslation("problems_regeneration_thematic_map")
300
                        .concat(": ").concat(status.getFailMessage());
301
                if (status.getException() != null) {
302
                    NotificationManager.addWarning(msg, status.getException());
303
                } else {
304
                    NotificationManager.addWarning(msg);
305
                }
306
            }
307
        }
308

    
309
        public void exception(String message, Throwable exception) {
310
            if (delegate != null) {
311
                delegate.exception(message, exception);
312
            } else {
313
                String msg =
314
                    swingManager
315
                        .getTranslation("problems_regeneration_thematic_map")
316
                        .concat(": ").concat(message);
317
                NotificationManager.addError(msg, exception);
318
            }
319
        }
320

    
321
    }
322

    
323
    /** {@inheridDoc} */
324
    public void createThematicMapFromView(ViewDocument view,
325
        CompilationListener listener, boolean openWindow) {
326

    
327
        if (view == null) {
328
            throw new IllegalArgumentException("View document required");
329
        }
330

    
331
        ThematicMapCompilation compilation =
332
            manager.createCompilationInstance();
333

    
334
        ThematicMapCompilationInformation info = compilation.getInformation();
335
        info.setName(view.getName());
336
        info.setId(generateIdForViewName(view.getName()));
337
        info.setVersion(1);
338

    
339
        compilation.setMapContext(view.getMapContext().cloneFMap());
340

    
341
        ThematicMapCompilationEditor editor =
342
            swingManager.getCopilationEditor(compilation, false);
343

    
344
        final CreateDocumentListener myListener =
345
            new CreateDocumentListener(view, listener, openWindow);
346

    
347
        editor.setListener(new ThematicMapCompilationEditorListener() {
348

    
349
            public void finished(final ThematicMapCompilationEditor editor) {
350
                editor.getSwingComponent().setVisible(false);
351
                SwingUtilities.invokeLater(new Runnable() {
352

    
353
                    public void run() {
354
                        try {
355
                            compileInInstallFolder(editor.getCompilation(),
356
                                myListener);
357
                        } catch (Exception ex) {
358
                            myListener.exception("Exception compiling", ex);
359
                        }
360
                    }
361
                });
362
            }
363

    
364
            public void canceled(final ThematicMapCompilationEditor editor) {
365
                editor.getSwingComponent().setVisible(false);
366
                SwingUtilities.invokeLater(new Runnable() {
367

    
368
                    public void run() {
369
                        myListener.canceledEditing(editor.getCompilation());
370
                    }
371
                });
372
            }
373

    
374
        });
375

    
376
        winManager.showCompilationEditor(editor, MODE.WINDOW);
377
    }
378

    
379
    /** {@inheridDoc} */
380
    public void compileInInstallFolder(ThematicMapCompilation compilation,
381
        CompilationListener listener) {
382

    
383
        if (compilation == null) {
384
            throw new IllegalArgumentException("Compilation required");
385
        }
386

    
387
        ThematicMapCompiler compiler = manager.createCompilerInstance();
388

    
389
        compiler.setTargetFolder(manager.getInstallationMapFolder());
390

    
391
        // prepare a temp folder
392
        compiler.setWorkFolder(getWorkFolder());
393

    
394
        ThematicMapCompilerStatus result = compiler.compile(compilation);
395
        if (listener != null) {
396
            if (result.getStatus() == ThematicMapCompilerStatus.Status.finished_ok) {
397
                listener.finished(result);
398
                return;
399
            }
400
            if (result.getStatus() == ThematicMapCompilerStatus.Status.canceled) {
401
                listener.canceledCompilation(result);
402
                return;
403
            }
404
            listener.fail(result);
405
        }
406
    }
407

    
408
    /**
409
     * Generates a ThematicMap id from a View Document name
410
     * 
411
     * @param viewName
412
     * @return
413
     */
414
    private String generateIdForViewName(String viewName) {
415
        String name = StringUtils.replace(viewName.trim(), " ", "_");
416
        return name;
417
    }
418

    
419
    /**
420
     * Prepare a work folder for compiler base on
421
     * {@link ThematicMapManager#getTemporalFolder()}
422
     * 
423
     * @return
424
     */
425
    private String getWorkFolder() {
426
        if (workFolder == null) {
427
            workFolder =
428
                fileServices.getNewWritableFolder(
429
                    new File(manager.getTemporalFolder()), "_compiler_");
430
            workFolder.deleteOnExit();
431
        }
432
        return workFolder.getAbsolutePath();
433
    }
434

    
435
    /** {@inheridDoc} */
436
    public ThematicMapDocumentManager getDocManager() {
437
        if (docManager == null) {
438
            docManager =
439
                (ThematicMapDocumentManager) ProjectManager.getInstance()
440
                    .getDocumentManager(ThematicMapDocumentManager.TYPENAME);
441
        }
442
        return docManager;
443
    }
444

    
445
    /** {@inheridDoc} */
446
    public File generatePackage(ThematicMapDocument thematicMap,
447
        File targetFolder) throws ThematicMapException, IOException {
448

    
449
        if (thematicMap == null) {
450
            throw new IllegalArgumentException("Thematic Map document required");
451
        }
452

    
453
        return manager.generatePackageFile(thematicMap.getThematicMap()
454
            .getInformation().getId(), targetFolder);
455

    
456
    }
457

    
458
    /** {@inheridDoc} */
459
    public File generatePackage(ThematicMapDocument thematicMap)
460
        throws ThematicMapException, IOException {
461
        File target =
462
            askForAOutputFolder(swingManager
463
                .getTranslation("Select_folder_to_store_package"));
464
        return generatePackage(thematicMap, target);
465
    }
466

    
467
    /** {@inheridDoc} */
468
    public ThematicMapDocument getThematicMapDocumentByView(ViewDocument view) {
469

    
470
        if (view == null) {
471
            throw new IllegalArgumentException("View document required");
472
        }
473

    
474
        List<Document> documents =
475
            getProject().getDocuments(ThematicMapDocumentManager.TYPENAME);
476
        ThematicMapDocument map;
477
        for (Document doc : documents) {
478
            map = (ThematicMapDocument) doc;
479
            if (ObjectUtils.equals(map.getSourceView(), view)) {
480
                return map;
481
            }
482
        }
483
        return null;
484
    }
485

    
486
    /**
487
     * Gets current gvSIG project
488
     * 
489
     * @return
490
     */
491
    public Project getProject() {
492
        return ProjectManager.getInstance().getCurrentProject();
493
    }
494

    
495
    /**
496
     * Shows a dialog to ask a output folder
497
     * 
498
     * @param description
499
     *            of the file is for
500
     * @return
501
     */
502
    public File askForAOutputFolder(String description) {
503
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
504
        int targetFolderAnswere = fileChooser.showDialog(null, description);
505
        if (targetFolderAnswere != JFileChooser.APPROVE_OPTION) {
506
            return null;
507
        }
508
        return fileChooser.getSelectedFile();
509
    }
510

    
511
    /** {@inheridDoc} */
512
    public ViewDocument exportThematicMapToView(ThematicMapDocument map,
513
        boolean openViewWindow) throws IOException,
514
        InvalidThematicMapFormatException, PersistenceException {
515
        File target;
516
        while (true) {
517
            target =
518
                askForAOutputFolder(swingManager
519
                    .getTranslation("Select_folder_to_extract_data"));
520
            if (target == null) {
521
                return null;
522
            }
523
            if (!target.exists()) {
524
                continue;
525
            }
526
            if (target.list().length == 0) {
527
                break;
528
            } else {
529
                winManager.showMessageDialog(swingManager
530
                    .getTranslation("Select_folder_to_extract_data"),
531
                    swingManager.getTranslation("folder_must_be_empty"),
532
                    MESSAGE_DIALOG_TYPE.WARNING);
533
            }
534
        }
535
        return exportThematicMapToView(map, target, openViewWindow);
536
    }
537

    
538
    /** {@inheridDoc} */
539
    public ViewDocument exportThematicMapToView(ThematicMapDocument map,
540
        File exportFolder, boolean openViewWindow) throws IOException,
541
        InvalidThematicMapFormatException, PersistenceException {
542

    
543
        if (map == null) {
544
            throw new IllegalArgumentException("Thematic Map document required");
545
        }
546

    
547
        if (!fileServices.isWritableFolder(exportFolder)) {
548
            throw new IllegalArgumentException(
549
                "Not a writable folder: ".concat(exportFolder.getAbsolutePath()));
550
        }
551
        if (exportFolder.list().length > 0) {
552
            throw new IllegalArgumentException(
553
                "Not a empty folder: ".concat(exportFolder.getAbsolutePath()));
554
        }
555

    
556
        File mapFile = new File(map.getThematicMap().getSourceFilePath());
557
        fileServices.unzipFile(mapFile, exportFolder);
558

    
559
        // Prepares mapContext file path
560
        File mapContextFile =
561
            new File(exportFolder, "mapContext/mapContext.xml");
562

    
563
        // Check if mapContext file exists
564
        if (!mapContextFile.exists()) {
565
            throw new InvalidThematicMapFormatException(mapFile,
566
                "Missing mapContext/mapContext.xml file in deployed map: "
567
                    .concat(mapContextFile.getAbsolutePath()));
568
        }
569
        if (!mapContextFile.isFile()) {
570
            throw new InvalidThematicMapFormatException(mapFile,
571
                "mapContext/mapContext.xml file in deployed map is not a file: "
572
                    .concat(mapContextFile.getAbsolutePath()));
573
        }
574

    
575
        // Load map context
576
        MapContext mapContext =
577
            fileServices.loadMapContext(mapContextFile, exportFolder);
578

    
579
        // Create view document
580
        ProjectManager projectManager = ProjectManager.getInstance();
581
        final ViewDocument view =
582
            (ViewDocument) projectManager.createDocument(ViewManager.TYPENAME);
583

    
584
        ThematicMapInformation info = map.getThematicMap().getInformation();
585

    
586
        // Fill view values
587
        view.setName(map.getName());
588
        view.setComment(String.format(
589
            swingManager.getTranslation("generated_from_thematic_map"),
590
            info.getId(), info.getName(), info.getVersion(),
591
            info.getBuildNumber()));
592
        view.setMapContext(mapContext);
593

    
594
        // Add view document to project
595
        getProject().add(view);
596

    
597
        if (openViewWindow) {
598
            // Open view window
599
            SwingUtilities.invokeLater(new Runnable() {
600

    
601
                public void run() {
602
                    IWindow viewWindow = view.getFactory().getMainWindow(view);
603
                    PluginServices.getMDIManager().addWindow(viewWindow);
604

    
605
                }
606
            });
607
        }
608

    
609
        // If map has no source view link it to the new one
610
        if (map.getSourceView() == null) {
611
            map.setSourceView(view);
612
        }
613

    
614
        return view;
615
    }
616

    
617
    /** {@inheridDoc} */
618
    public void regenerateThematicMap(ThematicMapDocument map,
619
        CompilationListener listener, boolean openWindow)
620
        throws InvalidThematicMapFormatException, CantLoadContextException,
621
        IOException {
622
        if (map == null) {
623
            throw new IllegalArgumentException(
624
                "Thematic Map document is required");
625
        }
626
        if (map.getSourceView() == null) {
627
            // No source view it can't regenerate it
628
            return;
629
        }
630
        ViewDocument document = map.getSourceView();
631

    
632
        // Get a compilation instance from map
633
        ThematicMapCompilation compilation =
634
            manager.createCompilationInstanceFromMap(map.getThematicMap());
635

    
636
        // Update map context from view
637
        compilation.setMapContext(document.getMapContext());
638

    
639
        // Create a editor and disable id change
640
        ThematicMapCompilationEditor editor =
641
            swingManager.getCopilationEditor(compilation, false);
642
        editor.allowChangeId(false);
643

    
644
        // Add update listener
645
        final UpdateDocumentListener myListener =
646
            new UpdateDocumentListener(map, listener, openWindow);
647

    
648
        // Add editor listener which call to compiler or notify cancel to
649
        // listener
650
        editor.setListener(new ThematicMapCompilationEditorListener() {
651

    
652
            public void finished(final ThematicMapCompilationEditor editor) {
653
                editor.getSwingComponent().setVisible(false);
654
                SwingUtilities.invokeLater(new Runnable() {
655

    
656
                    public void run() {
657
                        try {
658
                            compileInInstallFolder(editor.getCompilation(),
659
                                myListener);
660
                        } catch (Exception ex) {
661
                            myListener.exception("Exception compiling", ex);
662
                        }
663

    
664
                    }
665
                });
666
            }
667

    
668
            public void canceled(final ThematicMapCompilationEditor editor) {
669
                editor.getSwingComponent().setVisible(false);
670
                SwingUtilities.invokeLater(new Runnable() {
671

    
672
                    public void run() {
673
                        myListener.canceledEditing(editor.getCompilation());
674
                    }
675
                });
676
            }
677

    
678
        });
679

    
680
        // Show editor
681
        winManager.showCompilationEditor(editor, MODE.WINDOW);
682

    
683
    }
684
}