Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / extension / ProjectExtension.java @ 41217

History | View | Annotate | Download (21.7 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.extension;
25

    
26
import java.awt.Component;
27
import java.io.File;
28
import java.lang.reflect.InvocationTargetException;
29
import java.text.MessageFormat;
30
import java.util.ArrayList;
31
import java.util.Iterator;
32
import java.util.List;
33
import java.util.prefs.Preferences;
34

    
35
import javax.swing.JOptionPane;
36
import javax.swing.SwingUtilities;
37

    
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40
import org.apache.commons.io.FilenameUtils;
41
import org.gvsig.andami.IconThemeHelper;
42
import org.gvsig.andami.Launcher;
43
import org.gvsig.andami.Launcher.TerminationProcess;
44
import org.gvsig.andami.PluginServices;
45
import org.gvsig.andami.messages.NotificationManager;
46
import org.gvsig.andami.plugins.Extension;
47
import org.gvsig.andami.plugins.IExtension;
48
import org.gvsig.andami.plugins.status.IExtensionStatus;
49
import org.gvsig.andami.plugins.status.IUnsavedData;
50
import org.gvsig.andami.plugins.status.UnsavedData;
51
import org.gvsig.andami.ui.mdiManager.IWindow;
52
import org.gvsig.andami.ui.mdiManager.WindowInfo;
53
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
54
import org.gvsig.app.ApplicationLocator;
55
import org.gvsig.app.ApplicationManager;
56
import org.gvsig.app.project.Project;
57
import org.gvsig.app.project.ProjectManager;
58
import org.gvsig.app.project.documents.gui.ProjectWindow;
59
import org.gvsig.app.project.documents.view.ViewManager;
60
import org.gvsig.gui.beans.swing.JFileChooser;
61
import org.gvsig.tools.ToolsLocator;
62
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
63
import org.gvsig.tools.persistence.exception.PersistenceException;
64
import org.gvsig.utils.GenericFileFilter;
65
import org.gvsig.utils.save.AfterSavingListener;
66
import org.gvsig.utils.save.BeforeSavingListener;
67
import org.gvsig.utils.save.SaveEvent;
68
import org.gvsig.utils.swing.threads.IMonitorableTask;
69

    
70
/**
71
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
72
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos en
73
 * esta clase.
74
 * 
75
 * @author Fernando Gonz?lez Cort?s
76
 */
77
public class ProjectExtension extends Extension implements IExtensionStatus {
78
        private static final Logger LOG = LoggerFactory
79
                        .getLogger(ProjectExtension.class);
80

    
81
        private static String projectPath = null;
82
        private ProjectWindow projectFrame;
83
        private Project p;
84
        private String lastSavePath;
85
        private WindowInfo seedProjectWindow;
86
        public static final String PROJECT_FILE_CHOOSER_ID = "PROJECT_FILECHOOSER_ID";
87
        /**
88
         * Use UTF-8 for encoding, as it can represent characters from any language.
89
         * 
90
         * Another sensible option would be encoding =
91
         * System.getProperty("file.encoding"); but this would need some extra
92
         * testing.
93
         * 
94
         * @deprecated see PersistentManager
95
         */
96
        public static String PROJECTENCODING = "UTF-8";
97

    
98
        private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
99

    
100
        private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
101

    
102
        /**
103
         * @see com.iver.mdiApp.plugins.IExtension#initialize()
104
         */
105
        public void initialize() {
106
                // try {
107
                // Class.forName("javax.media.jai.EnumeratedParameter");
108
                // } catch (ClassNotFoundException e) {
109
                // NotificationManager
110
                // .addError(
111
                // "La m?quina virtual con la que se ejecuta gvSIG no tiene JAI instalado",
112
                // e);
113
                // }
114

    
115
                initializeDocumentActionsExtensionPoint();
116
                registerDocuments();
117
                registerIcons();
118
        }
119

    
120
        private void registerIcons() {
121
                IconThemeHelper.registerIcon("action", "application-project-new", this);
122
                IconThemeHelper
123
                                .registerIcon("action", "application-project-open", this);
124
                IconThemeHelper
125
                                .registerIcon("action", "application-project-save", this);
126
                IconThemeHelper.registerIcon("action", "application-project-save-as",
127
                                this);
128

    
129
                IconThemeHelper.registerIcon("project", "project-icon", this);
130
        }
131

    
132

    
133

    
134

    
135

    
136
        public ProjectWindow getProjectFrame() {
137
                if (projectFrame == null) {
138
                        projectFrame = new ProjectWindow();
139
                }
140
                return projectFrame;
141
        }
142

    
143
        /**
144
         * Muestra la ventana con el gestor de proyectos.
145
         */
146
        public void showProjectWindow() {
147
                if (seedProjectWindow != null) {
148
                        if (seedProjectWindow.isClosed()) {
149
                                // if it was closed, we just don't open the window now
150
                                seedProjectWindow.setClosed(false);
151
                                return;
152
                        }
153
                        WindowInfo winProps = seedProjectWindow;
154
                        seedProjectWindow = null;
155
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
156
                        PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
157
                                        winProps);
158
                } else {
159
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
160
                }
161
        }
162

    
163
        /**
164
         * Muestra la ventana con el gestor de proyectos, con las propiedades de
165
         * ventana especificadas.
166
         */
167
        public void showProjectWindow(WindowInfo wi) {
168
                seedProjectWindow = wi;
169
                showProjectWindow();
170
        }
171

    
172
        /**
173
         * Guarda el proyecto actual en disco.
174
         */
175
        private boolean saveProject() {
176
                boolean saved = false;
177
                // if (p.getPath() == null) {
178
                if (projectPath == null) {
179
                        saved = saveAsProject(null);
180
                } else {
181
                        long t1, t2;
182
                        t1 = System.currentTimeMillis();
183
                        saved = writeProject(new File(projectPath), p, false);
184
                        t2 = System.currentTimeMillis();
185
                        PluginServices.getLogger().info(
186
                                        "Project saved. " + (t2 - t1) + " miliseconds");
187
                        getProjectFrame().refreshControls();
188
                }
189
                return saved;
190
        }
191

    
192
        private boolean saveAsProject(File file) {
193
                boolean saved = false;
194

    
195
                if (lastSavePath == null) {
196
                        lastSavePath = projectPath;
197
                }
198

    
199
                if (file == null) {
200
                        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
201
                        JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
202
                                        prefs.get("ProjectsFolder", null));
203

    
204
                        jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
205
                        jfc.addChoosableFileFilter(new GenericFileFilter(
206
                                        Project.FILE_EXTENSION, MessageFormat.format(PluginServices
207
                                                        .getText(this, "tipo_fichero_proyecto"),
208
                                                        Project.FILE_EXTENSION)));
209

    
210
                        if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
211
                                return saved;
212
                        }
213
                        file = jfc.getSelectedFile();
214
                }
215

    
216
                if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
217
                                .toLowerCase()))) {
218
                        file = new File(file.getPath() + Project.FILE_EXTENSION);
219
                }
220
                saved = writeProject(file, p);
221
                String filePath = file.getAbsolutePath();
222
                lastSavePath = filePath.substring(0,
223
                                filePath.lastIndexOf(File.separatorChar));
224

    
225
                getProjectFrame().refreshControls();
226
                return saved;
227
        }
228

    
229
        /**
230
         * Checks whether the project and related unsaved data is modified, and
231
         * allows the user to save it.
232
         * 
233
         * @return true if the data has been correctly saved, false otherwise
234
         */
235
        private boolean askSave() {
236
                if (p != null && p.hasChanged()) {
237
                        TerminationProcess process = Launcher.getTerminationProcess();
238
                        UnsavedDataPanel panel = process.getUnsavedDataPanel();
239
                        panel.setHeaderText(PluginServices.getText(this,
240
                                        "_Select_resources_to_save_before_closing_current_project"));
241
                        panel.setAcceptText(
242
                                        PluginServices.getText(this, "save_resources"),
243
                                        PluginServices
244
                                                        .getText(this,
245
                                                                        "Save_the_selected_resources_and_close_current_project"));
246
                        panel.setCancelText(PluginServices.getText(this, "Cancel"),
247
                                        PluginServices.getText(this, "Return_to_current_project"));
248
                        int closeCurrProj;
249
                        try {
250
                                closeCurrProj = process.manageUnsavedData();
251
                                if (closeCurrProj == JOptionPane.NO_OPTION) {
252
                                        // the user chose to return to current project
253
                                        return false;
254
                                }
255
                        } catch (Exception e) {
256
                                LOG.error("Some data can not be saved", e);
257
                        }
258
                }
259
                return true;
260
        }
261

    
262
        public void execute(String command) {
263
                this.execute(command, null);
264
        }
265

    
266
        public void execute(String actionCommand, Object[] args) {
267
                if (actionCommand.equals("application-project-new")) {
268
                        if (!askSave()) {
269
                                return;
270
                        }
271

    
272
                        projectPath = null;
273
                        // ProjectDocument.initializeNUMS();
274
                        PluginServices.getMDIManager().closeAllWindows();
275
                        setProject(ProjectManager.getInstance().createProject());
276
                        getProjectFrame().setProject(p);
277
                        showProjectWindow();
278
                        PluginServices.getMainFrame().setTitle(
279
                                        PluginServices.getText(this, "sin_titulo"));
280
                } else if (actionCommand.equals("application-project-open")) {
281
                        if (!askSave()) {
282
                                return;
283
                        }
284
                        File projectFile = null;
285

    
286
                        if (args != null && args.length > 0 && args[0] != null) {
287
                                if (args[0] instanceof File) {
288
                                        projectFile = (File) args[0];
289
                                } else if (args[0] instanceof String) {
290
                                        projectFile = new File((String) args[0]);
291
                                        if (!projectFile.exists()) {
292
                                                LOG.warn("Can't load project '"
293
                                                                + projectFile.getAbsolutePath()
294
                                                                + "', file not exist.");
295
                                                projectFile = null;
296
                                        }
297
                                }
298
                        }
299

    
300
                        if (projectFile == null) {
301
                                Preferences prefs = Preferences.userRoot().node(
302
                                                "gvsig.foldering");
303
                                JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
304
                                                prefs.get("ProjectsFolder", null));
305
                                jfc.addChoosableFileFilter(new GenericFileFilter(
306
                                                Project.FILE_EXTENSION, PluginServices.getText(this,
307
                                                                "tipo_fichero_proyecto")));
308

    
309
                                if (jfc.showOpenDialog((Component) PluginServices
310
                                                .getMainFrame()) != JFileChooser.APPROVE_OPTION) {
311
                                        return;
312
                                }
313
                                // ProjectDocument.initializeNUMS();
314
                                
315

    
316
                                projectFile = jfc.getSelectedFile();
317
                        }
318
                        
319
                        PluginServices.getMDIManager().closeAllWindows();
320

    
321
                        Project o = readProject(projectFile);
322
                        setPath(projectFile.getAbsolutePath());
323
                        // lastPath = getPath();
324
                        if (o != null) {
325
                                setProject(o);
326
                        }
327

    
328
                        getProjectFrame().setProject(p);
329
                        PluginServices.getMainFrame().setTitle(projectFile.getName());
330
                        getProjectFrame().refreshControls();
331

    
332
                        // p.restoreWindowProperties();
333

    
334
                } else if (actionCommand.equals("application-project-save")) {
335
                        saveProject();
336
                } else if (actionCommand.equals("application-project-save-as")) {
337
                        File file = null;
338
                        if (args != null && args.length > 0 && args[0] != null) {
339
                                if (args[0] instanceof File) {
340
                                        file = (File) args[0];
341
                                } else if (args[0] instanceof String) {
342
                                        file = new File((String) args[0]);
343
                                }
344
                        }
345
                        saveAsProject(file);
346
                }
347

    
348
        }
349

    
350
        
351
    private void createEmptyProject() {
352
        setProject(ProjectManager.getInstance().createProject());
353
        p.setName(PluginServices.getText(this, "untitled"));
354
        p.setModified(false);
355
        PluginServices.getMainFrame().setTitle(
356
                PluginServices.getText(this, "sin_titulo"));
357
        setProject(p);
358
        showProjectWindow();
359
    }
360

    
361
    /**
362
     * @see com.iver.mdiApp.plugins.IExtension#postInitialize()
363
     */
364
    public void postInitialize() {
365
        try {
366
            if( !SwingUtilities.isEventDispatchThread() ) {
367
                SwingUtilities.invokeAndWait(new Runnable() {
368
                    public void run() {
369
                        createEmptyProject();
370
                    }
371
                });
372
            } else {
373
                createEmptyProject();
374
            }
375
        } catch (Exception e) {
376
            LOG.warn("Can't load initial project.",e);
377
        }
378
    }        
379
        
380
        
381
        /**
382
         * Escribe el proyecto en XML.
383
         * 
384
         * @param file
385
         *            Fichero.
386
         * @param p
387
         *            Proyecto.
388
         */
389
        public boolean writeProject(File file, Project p) {
390
                return writeProject(file, p, true);
391
        }
392

    
393
        /**
394
         * Escribe el proyecto en XML. Pero permite decidir si se pide confirmaci?n
395
         * para sobreescribir
396
         * 
397
         * @param file
398
         *            Fichero.
399
         * @param p
400
         *            Proyecto.
401
         * @param askConfirmation
402
         *            boolean
403
         */
404
        public boolean writeProject(File file, Project p, boolean askConfirmation) {
405
                if (askConfirmation && file.exists()) {
406
                        int resp = JOptionPane.showConfirmDialog((Component) PluginServices
407
                                        .getMainFrame(), PluginServices.getText(this,
408
                                        "fichero_ya_existe_seguro_desea_guardarlo"), PluginServices
409
                                        .getText(this, "guardar"), JOptionPane.YES_NO_OPTION);
410
                        if (resp != JOptionPane.YES_OPTION) {
411
                                return false;
412
                        }
413
                }
414
                NotificationManager.addInfo(PluginServices.getText(this,
415
                                "writinng_project") + ": " + file.getName());
416

    
417
                // write it out as XML
418
                try {
419
                        fireBeforeSavingFileEvent(new SaveEvent(this,
420
                                        SaveEvent.BEFORE_SAVING, file));
421
                        p.saveState(file);
422
                        fireAfterSavingFileEvent(new SaveEvent(this,
423
                                        SaveEvent.AFTER_SAVING, file));
424

    
425
                        PluginServices.getMainFrame().setTitle(file.getName());
426
                        setPath(file.toString());
427

    
428
                } catch (PersistenceException e) {
429
                        String messagestack = e.getLocalizedMessageStack();
430
                        NotificationManager.addError(
431
                                        PluginServices.getText(this, "error_writing_project")
432
                                                        + ": " + file.getName() + "\n" + messagestack, e);
433
                        return false;
434
                } catch (Exception e) {
435
                        NotificationManager.addError(
436
                                        PluginServices.getText(this, "error_writing_project")
437
                                                        + ": " + file.getName(), e);
438
                        return false;
439
                }
440
                NotificationManager.addInfo(PluginServices.getText(this,
441
                                "wrote_project") + ": " + file.getName());
442
                return true;
443
        }
444

    
445
        public Project readProject(String path) {
446
                Project project = ProjectManager.getInstance().createProject();
447

    
448
                project.loadState(new File(path));
449
                return (Project) project;
450
        }
451

    
452
        /**
453
         * Lee del XML el proyecto.<br>
454
         * <br>
455
         * 
456
         * Reads the XML of the project.<br>
457
         * It returns a project object holding all needed info that is not linked to
458
         * the Project Dialog. <br>
459
         * In case you want the project to be linked to the window you must set this
460
         * object to the extension:<br>
461
         * 
462
         * <b>Example:</b><br>
463
         * 
464
         * ...<br>
465
         * ...<br>
466
         * Project p = ProjectExtension.readProject(projectFile);<br>
467
         * ProjectExtension.setProject(p); ...<br>
468
         * ...<br>
469
         * 
470
         * @param file
471
         *            Fichero.
472
         * 
473
         * @return Project
474
         * 
475
         */
476
        public Project readProject(File file) {
477
                Project project = ProjectManager.getInstance().createProject();
478

    
479
                project.loadState(file);
480
                return (Project) project;
481
        }
482

    
483
        /**
484
         * Devuelve el proyecto.
485
         * 
486
         * @return Proyecto.
487
         */
488
        public Project getProject() {
489
                return p;
490
        }
491

    
492
        /**
493
         * @see org.gvsig.andami.plugins.IExtension#isEnabled()
494
         */
495
        public boolean isEnabled() {
496
                return true;
497
        }
498

    
499
        /**
500
         * @see org.gvsig.andami.plugins.IExtension#isVisible()
501
         */
502
        public boolean isVisible() {
503
                return true;
504
        }
505

    
506
        /**
507
         * Sets the project
508
         * 
509
         * @param p
510
         */
511
        public void setProject(Project p) {
512
                getProjectFrame().setProject(p);
513
                this.p = p;
514
        }
515

    
516
        private void registerDocuments() {
517
                ViewManager.register();
518
        }
519

    
520
        private void initializeDocumentActionsExtensionPoint() {
521
                ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
522
                epMan.add(
523
                                "DocumentActions_View",
524
                                "Context menu options of the view document list"
525
                                                + " in the project window "
526
                                                + "(register instances of "
527
                                                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
528
        }
529

    
530
        public static String getPath() {
531
                return projectPath;
532
        }
533

    
534
        public static void setPath(String path) {
535
                projectPath = path;
536
        }
537

    
538
        public IWindow getProjectWindow() {
539
                return getProjectFrame();
540
        }
541

    
542
        public IExtensionStatus getStatus() {
543
                return this;
544
        }
545

    
546
        public boolean hasUnsavedData() {
547
                return p.hasChanged();
548
        }
549

    
550
        public IUnsavedData[] getUnsavedData() {
551
                if (hasUnsavedData()) {
552
                        UnsavedProject data = new UnsavedProject(this);
553
                        IUnsavedData[] dataArray = { data };
554
                        return dataArray;
555
                } else {
556
                        return null;
557
                }
558
        }
559

    
560
        /**
561
         * Implements the IUnsavedData interface to show unsaved projects in the
562
         * Unsavad Data dialog.
563
         * 
564
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
565
         */
566
        public class UnsavedProject extends UnsavedData {
567

    
568
                public UnsavedProject(IExtension extension) {
569
                        super(extension);
570
                }
571

    
572
                public String getDescription() {
573
                        if (getPath() == null) {
574
                                return PluginServices.getText(ProjectExtension.this,
575
                                                "Unnamed_new_gvsig_project_");
576
                        } else {
577
                                return PluginServices.getText(ProjectExtension.this,
578
                                                "Modified_project_");
579
                        }
580
                }
581

    
582
                public String getResourceName() {
583
                        if (getPath() == null) {
584
                                return PluginServices.getText(ProjectExtension.this, "Unnamed");
585
                        } else {
586
                                return getPath();
587
                        }
588

    
589
                }
590

    
591
                public boolean saveData() {
592
                        return saveProject();
593
                }
594

    
595
                public String getIcon() {
596
                        return "project-icon";
597
                }
598
        }
599

    
600
        public IMonitorableTask[] getRunningProcesses() {
601
                // TODO Auto-generated method stub
602
                return null;
603
        }
604

    
605
        public boolean hasRunningProcesses() {
606
                // TODO Auto-generated method stub
607
                return false;
608
        }
609

    
610
        /**
611
         * Adds the specified before saving listener to receive
612
         * "before saving file events" from this component. If l is null, no
613
         * exception is thrown and no action is performed.
614
         * 
615
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
616
         * 
617
         * @param l
618
         *            the before saving listener.
619
         * @see SaveEvent
620
         * @see BeforeSavingListener
621
         * @see #removeListener(BeforeSavingListener)
622
         * @see #getBeforeSavingListeners
623
         */
624
        public synchronized void addListener(BeforeSavingListener l) {
625
                if (l == null) {
626
                        return;
627
                }
628
                if (!this.beforeSavingListeners.contains(l)) {
629
                        this.beforeSavingListeners.add(l);
630
                }
631
        }
632

    
633
        /**
634
         * Adds the specified after saving listener to receive
635
         * "after saving file events" from this component. If l is null, no
636
         * exception is thrown and no action is performed.
637
         * 
638
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
639
         * 
640
         * @param l
641
         *            the after saving listener.
642
         * @see SaveEvent
643
         * @see AfterSavingListener
644
         * @see #removeListener(AfterSavingListener)
645
         * @see #getAfterSavingListeners()
646
         */
647
        public synchronized void addListener(AfterSavingListener l) {
648
                if (l == null) {
649
                        return;
650
                }
651

    
652
                if (!this.afterSavingListeners.contains(l)) {
653
                        this.afterSavingListeners.add(l);
654
                }
655

    
656
        }
657

    
658
        /**
659
         * Returns an array of all the before saving listeners registered on this
660
         * component.
661
         * 
662
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
663
         * 
664
         * @return all of this component's <code>BeforeSavingListener</code>s or an
665
         *         empty array if no key listeners are currently registered
666
         * 
667
         * @see #addBeforeSavingListener(BeforeSavingListener)
668
         * @see #removeBeforeSavingListener(BeforeSavingListener)
669
         */
670
        public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
671
                return this.beforeSavingListeners
672
                                .toArray(new BeforeSavingListener[] {});
673
        }
674

    
675
        /**
676
         * Returns an array of all the after saving listeners registered on this
677
         * component.
678
         * 
679
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
680
         * 
681
         * @return all of this component's <code>AfterSavingListener</code>s or an
682
         *         empty array if no key listeners are currently registered
683
         * 
684
         * @see #addAfterSavingListener(AfterSavingListener)
685
         * @see #removeAfterSavingListener
686
         */
687
        public synchronized AfterSavingListener[] getAfterSavingListeners() {
688
                return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
689

    
690
        }
691

    
692
        /**
693
         * Removes the specified before saving listener so that it no longer
694
         * receives save file events from this component. This method performs no
695
         * function, nor does it throw an exception, if the listener specified by
696
         * the argument was not previously added to this component. If listener
697
         * <code>l</code> is <code>null</code>, no exception is thrown and no action
698
         * is performed.
699
         * 
700
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
701
         * 
702
         * @param l
703
         *            the before saving listener
704
         * @see SaveEvent
705
         * @see BeforeSavingListener
706
         * @see #addListener(BeforeSavingListener)
707
         * @see #getBeforeSavingListeners()
708
         */
709
        public synchronized void removeListener(BeforeSavingListener l) {
710
                if (l == null) {
711
                        return;
712
                }
713

    
714
                this.beforeSavingListeners.remove(l);
715
        }
716

    
717
        /**
718
         * Removes the specified after saving listener so that it no longer receives
719
         * save file events from this component. This method performs no function,
720
         * nor does it throw an exception, if the listener specified by the argument
721
         * was not previously added to this component. If listener <code>l</code> is
722
         * <code>null</code>, no exception is thrown and no action is performed.
723
         * 
724
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
725
         * 
726
         * @param l
727
         *            the after saving listener
728
         * @see SaveEvent
729
         * @see AfterSavingListener
730
         * @see #addListener(AfterSavingListener)
731
         * @see #getAfterSavingListeners()
732
         */
733
        public synchronized void removeListener(AfterSavingListener l) {
734
                if (l == null) {
735
                        return;
736
                }
737

    
738
                this.afterSavingListeners.remove(l);
739
        }
740

    
741
        /**
742
         * Reports a before saving file event.
743
         * 
744
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
745
         * 
746
         * @param evt
747
         *            the before saving file event
748
         */
749
        protected void fireBeforeSavingFileEvent(SaveEvent evt) {
750
                if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
751
                        return;
752
                }
753

    
754
                Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
755
                                .iterator();
756

    
757
                while (iter.hasNext()) {
758
                        iter.next().beforeSaving(evt);
759
                }
760
        }
761

    
762
        /**
763
         * Reports a after saving file event.
764
         * 
765
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
766
         * 
767
         * @param evt
768
         *            the after saving file event
769
         */
770
        protected void fireAfterSavingFileEvent(SaveEvent evt) {
771
                if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
772
                        return;
773
                }
774
                Iterator<AfterSavingListener> iter = this.afterSavingListeners
775
                                .iterator();
776

    
777
                while (iter.hasNext()) {
778
                        iter.next().afterSaving(evt);
779
                }
780

    
781
        }
782
}