Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2052 / applications / appgvSIG / src / org / gvsig / app / extension / ProjectExtension.java @ 38815

History | View | Annotate | Download (24.4 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.app.extension;
23

    
24
import java.awt.Component;
25
import java.io.File;
26
import java.text.MessageFormat;
27
import java.util.ArrayList;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.prefs.Preferences;
31

    
32
import javax.swing.JOptionPane;
33

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

    
63
/**
64
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
65
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos
66
 * en esta clase.
67
 * 
68
 * @author Fernando Gonz?lez Cort?s
69
 */
70
public class ProjectExtension extends Extension implements IExtensionStatus {
71
    private static final Logger LOG =
72
        LoggerFactory.getLogger(ProjectExtension.class);
73
    
74
    private static String projectPath = null;
75
    private ProjectWindow projectFrame;
76
    private Project p;
77
    private String lastSavePath;
78
    private WindowInfo seedProjectWindow;
79
    public static final String PROJECT_FILE_CHOOSER_ID =
80
        "PROJECT_FILECHOOSER_ID";
81
    /**
82
     * Use UTF-8 for encoding, as it can represent characters from
83
     * any language.
84
     * 
85
     * Another sensible option would be
86
     * encoding = System.getProperty("file.encoding");
87
     * but this would need some extra testing.
88
     * 
89
     * @deprecated see PersistentManager
90
     */
91
    public static String PROJECTENCODING = "UTF-8";
92

    
93
    private List<BeforeSavingListener> beforeSavingListeners =
94
        new ArrayList<BeforeSavingListener>();
95

    
96
    private List<AfterSavingListener> afterSavingListeners =
97
        new ArrayList<AfterSavingListener>();
98

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

    
112
        initializeDocumentActionsExtensionPoint();
113
        registerIcons();
114
    }
115

    
116
    private void registerIcons() {
117
            IconThemeHelper.registerIcon("action", "application-project-new", this);
118
            IconThemeHelper.registerIcon("action", "application-project-open", this);
119
            IconThemeHelper.registerIcon("action", "application-project-save", this);
120
            IconThemeHelper.registerIcon("action", "application-project-save-as", this);
121
            IconThemeHelper.registerIcon("action", "application-exit", this);
122
    }
123

    
124
    private void loadInitialProject() {
125
        String[] theArgs = PluginServices.getArguments();
126
        String lastArg = theArgs[theArgs.length - 1];
127
        if ((lastArg.toLowerCase().endsWith(Project.FILE_EXTENSION
128
            .toLowerCase()))) {
129
            PluginServices.getLogger().debug(
130
                "Intentando cargar el proyecto " + lastArg);
131
            // File projectFile = new File(lastArg);
132
            setProject(readProject(lastArg));
133
            PluginServices.getMainFrame().setTitle(p.getName());
134
            projectPath = lastArg;
135
        } else {
136
            setProject(ProjectManager.getInstance().createProject());
137
            p.setName(PluginServices.getText(this, "untitled"));
138
            p.setModified(false);
139
            PluginServices.getMainFrame().setTitle(
140
                PluginServices.getText(this, "sin_titulo"));
141
        }
142

    
143
    }
144

    
145
    /**
146
     * @see com.iver.mdiApp.plugins.IExtension#postInitialize()
147
     */
148
    public void postInitialize() {
149
        registerDocuments();
150
        loadInitialProject();
151
        getProjectFrame().setProject(p);
152
        showProjectWindow();
153
    }
154

    
155
    public ProjectWindow getProjectFrame() {
156
        if (projectFrame == null) {
157
            projectFrame = new ProjectWindow();
158
        }
159
        return projectFrame;
160
    }
161

    
162
    /**
163
     * Muestra la ventana con el gestor de proyectos.
164
     */
165
    public void showProjectWindow() {
166
        if (seedProjectWindow != null) {
167
            if (seedProjectWindow.isClosed()) {
168
                // if it was closed, we just don't open the window now
169
                seedProjectWindow.setClosed(false);
170
                return;
171
            }
172
            WindowInfo winProps = seedProjectWindow;
173
            seedProjectWindow = null;
174
            PluginServices.getMDIManager().addWindow(getProjectFrame());
175
            PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
176
                winProps);
177
        } else {
178
            PluginServices.getMDIManager().addWindow(getProjectFrame());
179
        }
180
    }
181

    
182
    /**
183
     * Muestra la ventana con el gestor de proyectos, con las propiedades
184
     * de ventana especificadas.
185
     */
186
    public void showProjectWindow(WindowInfo wi) {
187
        seedProjectWindow = wi;
188
        showProjectWindow();
189
    }
190

    
191
    /**
192
     * Guarda el proyecto actual en disco.
193
     */
194
    private boolean guardar() {
195
        boolean saved = false;
196
        // if (p.getPath() == null) {
197
        if (projectPath == null) {
198
            saved = guardarDialogo();
199
        } else {
200
            long t1, t2;
201
            t1 = System.currentTimeMillis();
202
            saved = writeProject(new File(projectPath), p, false);
203
            t2 = System.currentTimeMillis();
204
            PluginServices.getLogger().info(
205
                "Project saved. " + (t2 - t1) + " miliseconds");
206
            getProjectFrame().refreshControls();
207
        }
208
        return saved;
209
    }
210

    
211
    private boolean guardarDialogo() {
212
        boolean saved = false;
213

    
214
        if (lastSavePath == null) {
215
            lastSavePath = projectPath;
216
        }
217

    
218
        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
219
        JFileChooser jfc =
220
            new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get(
221
                "ProjectsFolder", null));
222

    
223
        jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
224
        jfc.addChoosableFileFilter(new GenericFileFilter(
225
            Project.FILE_EXTENSION, MessageFormat.format(
226
                PluginServices.getText(this, "_gvSIG_file_project_({0})"),
227
                Project.FILE_EXTENSION)));
228

    
229
        if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
230
            File file = jfc.getSelectedFile();
231
            if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
232
                .toLowerCase()))) {
233
                file = new File(file.getPath() + Project.FILE_EXTENSION);
234
            }
235
            saved = writeProject(file, p);
236
            String filePath = file.getAbsolutePath();
237
            lastSavePath =
238
                filePath.substring(0, filePath.lastIndexOf(File.separatorChar));
239

    
240
            getProjectFrame().refreshControls();
241
        }
242
        return saved;
243
    }
244

    
245
    /**
246
     * Checks whether the project and related unsaved data is modified,
247
     * and allows the user to save it.
248
     * 
249
     * @return true if the data has been correctly saved, false otherwise
250
     */
251
    private boolean askSave() {
252
        if (p != null && p.hasChanged()) {
253
            TerminationProcess process = Launcher.getTerminationProcess();
254
            UnsavedDataPanel panel = process.getUnsavedDataPanel();
255
            panel.setHeaderText(PluginServices.getText(this,
256
                "Select_resources_to_save_before_closing_current_project"));
257
            panel.setAcceptText(PluginServices.getText(this, "save_resources"),
258
                PluginServices.getText(this,
259
                    "Save_the_selected_resources_and_close_current_project"));
260
            panel.setCancelText(PluginServices.getText(this, "Dont_close"),
261
                PluginServices.getText(this, "Return_to_current_project"));
262
            int closeCurrProj;
263
            try {
264
                closeCurrProj = process.manageUnsavedData();
265
                if (closeCurrProj == JOptionPane.NO_OPTION) {
266
                    // the user chose to return to current project
267
                    return false;
268
                }
269
            } catch (Exception e) {
270
                LOG.error("Some data can not be saved", e);
271
            }           
272
        }
273
        return true;
274
    }
275

    
276
    /**
277
     * @see com.iver.mdiApp.plugins.IExtension#updateUI(java.lang.String)
278
     */
279
    public void execute(String actionCommand) {
280
        if (actionCommand.equals("application-project-new")) {
281
            if (!askSave()) {
282
                return;
283
            }
284

    
285
            projectPath = null;
286
            // ProjectDocument.initializeNUMS();
287
            PluginServices.getMDIManager().closeAllWindows();
288
            setProject(ProjectManager.getInstance().createProject());
289
            getProjectFrame().setProject(p);
290
            showProjectWindow();
291
            PluginServices.getMainFrame().setTitle(
292
                PluginServices.getText(this, "sin_titulo"));
293
        } else
294
            if (actionCommand.equals("application-project-open")) {
295
                if (!askSave()) {
296
                    return;
297
                }
298

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

    
308
                if (jfc.showOpenDialog((Component) PluginServices
309
                    .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
310
                    // ProjectDocument.initializeNUMS();
311
                    PluginServices.getMDIManager().closeAllWindows();
312

    
313
                    File projectFile = jfc.getSelectedFile();
314
                    Project o = readProject(projectFile);
315
                    setPath(projectFile.getAbsolutePath());
316
                    // lastPath = getPath();
317
                    if (o != null) {
318
                        setProject(o);
319
                    }
320

    
321
                    getProjectFrame().setProject(p);
322
                    PluginServices.getMainFrame().setTitle(p.getName());
323
                    getProjectFrame().refreshControls();
324

    
325
                    // p.restoreWindowProperties();
326
                }
327
            } else
328
                if (actionCommand.equals("application-project-save")) {
329
                    guardar();
330
                } else
331
                    if (actionCommand.equals("application-project-save-as")) {
332
                        guardarDialogo();
333
                    } else
334
                        if (actionCommand.equals("application-exit")) {
335
                            Launcher.closeApplication();
336
                        }
337
    }
338

    
339
    /**
340
     * Escribe el proyecto en XML.
341
     * 
342
     * @param file
343
     *            Fichero.
344
     * @param p
345
     *            Proyecto.
346
     */
347
    public boolean writeProject(File file, Project p) {
348
        return writeProject(file, p, true);
349
    }
350

    
351
    /**
352
     * Escribe el proyecto en XML. Pero permite decidir si se
353
     * pide confirmaci?n para sobreescribir
354
     * 
355
     * @param file
356
     *            Fichero.
357
     * @param p
358
     *            Proyecto.
359
     * @param askConfirmation
360
     *            boolean
361
     */
362
    public boolean writeProject(File file, Project p, boolean askConfirmation) {
363
        if (askConfirmation && file.exists()) {
364
            int resp =
365
                JOptionPane.showConfirmDialog((Component) PluginServices
366
                    .getMainFrame(), PluginServices.getText(this,
367
                    "fichero_ya_existe_seguro_desea_guardarlo"), PluginServices
368
                    .getText(this, "guardar"), JOptionPane.YES_NO_OPTION);
369
            if (resp != JOptionPane.YES_OPTION) {
370
                return false;
371
            }
372
        }
373
        NotificationManager.addInfo(PluginServices.getText(this,
374
            "writinng_project") + ": " + file.getName());
375

    
376
        // write it out as XML
377
        try {
378
            fireBeforeSavingFileEvent(new SaveEvent(this,
379
                SaveEvent.BEFORE_SAVING, file));
380
            p.saveState(file);
381
            fireAfterSavingFileEvent(new SaveEvent(this,
382
                SaveEvent.AFTER_SAVING, file));
383
            PluginServices.getMainFrame().setTitle(file.getName());
384
            setPath(file.toString());
385

    
386
        } catch (PersistenceException e) {
387
            String messagestack = e.getLocalizedMessageStack();
388
            NotificationManager.addError(
389
                PluginServices.getText(this, "error_writing_project") + ": "
390
                    + file.getName() + "\n" + messagestack, e);
391
            return false;
392
        } catch (Exception e) {
393
            NotificationManager.addError(
394
                PluginServices.getText(this, "error_writing_project") + ": "
395
                    + file.getName(), e);
396
            return false;
397
        }
398
        NotificationManager.addInfo(PluginServices.getText(this,
399
            "wrote_project") + ": " + file.getName());
400
        return true;
401
    }
402

    
403
    public Project readProject(String path) {
404
        Project project = ProjectManager.getInstance().createProject();
405

    
406
        project.loadState(new File(path));
407
        return (Project) project;
408
    }
409

    
410
    /**
411
     * Lee del XML el proyecto.<br>
412
     * <br>
413
     * 
414
     * Reads the XML of the project.<br>
415
     * It returns a project object holding all needed info that is not linked to
416
     * the Project Dialog. <br>
417
     * In case you want the project to be
418
     * linked to the window you must set this object to the extension:<br>
419
     * 
420
     * <b>Example:</b><br>
421
     * 
422
     * ...<br>
423
     * ...<br>
424
     * Project p = ProjectExtension.readProject(projectFile);<br>
425
     * ProjectExtension.setProject(p);
426
     * ...<br>
427
     * ...<br>
428
     * 
429
     * @param file
430
     *            Fichero.
431
     * 
432
     * @return Project
433
     * 
434
     */
435
    public Project readProject(File file) {
436
        Project project = ProjectManager.getInstance().createProject();
437

    
438
        project.loadState(file);
439
        return (Project) project;
440
    }
441

    
442
    /**
443
     * Devuelve el proyecto.
444
     * 
445
     * @return Proyecto.
446
     */
447
    public Project getProject() {
448
        return p;
449
    }
450

    
451
    /**
452
     * @see org.gvsig.andami.plugins.IExtension#isEnabled()
453
     */
454
    public boolean isEnabled() {
455
        return true;
456
    }
457

    
458
    /**
459
     * @see org.gvsig.andami.plugins.IExtension#isVisible()
460
     */
461
    public boolean isVisible() {
462
        return true;
463
    }
464

    
465
    /**
466
     * Sets the project
467
     * 
468
     * @param p
469
     */
470
    public void setProject(Project p) {
471
        getProjectFrame().setProject(p);
472
        this.p = p;
473
    }
474

    
475
    private void registerDocuments() {
476
        ViewManager.register();
477
    }
478

    
479
    private void initializeDocumentActionsExtensionPoint() {
480
        ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
481
        epMan.add("DocumentActions_View",
482
            "Context menu options of the view document list"
483
                + " in the project window " + "(register instances of "
484
                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
485
    }
486

    
487
    public static String getPath() {
488
        return projectPath;
489
    }
490

    
491
    public static void setPath(String path) {
492
        projectPath = path;
493
    }
494

    
495
    public IWindow getProjectWindow() {
496
        return getProjectFrame();
497
    }
498

    
499
    public IExtensionStatus getStatus() {
500
        return this;
501
    }
502

    
503
    public boolean hasUnsavedData() {
504
        return p.hasChanged();
505
    }
506

    
507
    public IUnsavedData[] getUnsavedData() {
508
        if (hasUnsavedData()) {
509
            UnsavedProject data = new UnsavedProject(this);
510
            IUnsavedData[] dataArray = { data };
511
            return dataArray;
512
        } else {
513
            return null;
514
        }
515
    }
516

    
517
    /**
518
     * Implements the IUnsavedData interface to show unsaved projects
519
     * in the Unsavad Data dialog.
520
     * 
521
     * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
522
     */
523
    public class UnsavedProject extends UnsavedData {
524

    
525
        public UnsavedProject(IExtension extension) {
526
            super(extension);
527
        }
528

    
529
        public String getDescription() {
530
            if (getPath() == null) {
531
                return PluginServices.getText(ProjectExtension.this,
532
                    "Unnamed_new_gvsig_project_");
533
            } else {
534
                return PluginServices.getText(ProjectExtension.this,
535
                    "Modified_project_");
536
            }
537
        }
538

    
539
        public String getResourceName() {
540
            if (getPath() == null) {
541
                return PluginServices.getText(ProjectExtension.this, "Unnamed");
542
            } else {
543
                return getPath();
544
            }
545

    
546
        }
547

    
548
        public boolean saveData() {
549
            return guardar();
550
        }
551

    
552
        public String getIcon() {
553
            return "images/logoGVA.gif";
554
        }
555
    }
556

    
557
    public IMonitorableTask[] getRunningProcesses() {
558
        // TODO Auto-generated method stub
559
        return null;
560
    }
561

    
562
    public boolean hasRunningProcesses() {
563
        // TODO Auto-generated method stub
564
        return false;
565
    }
566

    
567
    /**
568
     * Adds the specified before saving listener to receive
569
     * "before saving file events" from
570
     * this component.
571
     * If l is null, no exception is thrown and no action is performed.
572
     * 
573
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
574
     * 
575
     * @param l
576
     *            the before saving listener.
577
     * @see SaveEvent
578
     * @see BeforeSavingListener
579
     * @see #removeListener(BeforeSavingListener)
580
     * @see #getBeforeSavingListeners
581
     */
582
    public synchronized void addListener(BeforeSavingListener l) {
583
        if (l == null) {
584
            return;
585
        }
586
        if (!this.beforeSavingListeners.contains(l)) {
587
            this.beforeSavingListeners.add(l);
588
        }
589
    }
590

    
591
    /**
592
     * Adds the specified after saving listener to receive
593
     * "after saving file events" from
594
     * this component.
595
     * If l is null, no exception is thrown and no action is performed.
596
     * 
597
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
598
     * 
599
     * @param l
600
     *            the after saving listener.
601
     * @see SaveEvent
602
     * @see AfterSavingListener
603
     * @see #removeListener(AfterSavingListener)
604
     * @see #getAfterSavingListeners()
605
     */
606
    public synchronized void addListener(AfterSavingListener l) {
607
        if (l == null) {
608
            return;
609
        }
610

    
611
        if (!this.afterSavingListeners.contains(l)) {
612
            this.afterSavingListeners.add(l);
613
        }
614

    
615
    }
616

    
617
    /**
618
     * Returns an array of all the before saving listeners
619
     * registered on this component.
620
     * 
621
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
622
     * 
623
     * @return all of this component's <code>BeforeSavingListener</code>s
624
     *         or an empty array if no key
625
     *         listeners are currently registered
626
     * 
627
     * @see #addBeforeSavingListener(BeforeSavingListener)
628
     * @see #removeBeforeSavingListener(BeforeSavingListener)
629
     */
630
    public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
631
        return this.beforeSavingListeners
632
            .toArray(new BeforeSavingListener[] {});
633
    }
634

    
635
    /**
636
     * Returns an array of all the after saving listeners
637
     * registered on this component.
638
     * 
639
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
640
     * 
641
     * @return all of this component's <code>AfterSavingListener</code>s
642
     *         or an empty array if no key
643
     *         listeners are currently registered
644
     * 
645
     * @see #addAfterSavingListener(AfterSavingListener)
646
     * @see #removeAfterSavingListener
647
     */
648
    public synchronized AfterSavingListener[] getAfterSavingListeners() {
649
        return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
650

    
651
    }
652

    
653
    /**
654
     * Removes the specified before saving listener so that it no longer
655
     * receives save file events from this component. This method performs
656
     * no function, nor does it throw an exception, if the listener
657
     * specified by the argument was not previously added to this component.
658
     * If listener <code>l</code> is <code>null</code>,
659
     * no exception is thrown and no action is performed.
660
     * 
661
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
662
     * 
663
     * @param l
664
     *            the before saving listener
665
     * @see SaveEvent
666
     * @see BeforeSavingListener
667
     * @see #addListener(BeforeSavingListener)
668
     * @see #getBeforeSavingListeners()
669
     */
670
    public synchronized void removeListener(BeforeSavingListener l) {
671
        if (l == null) {
672
            return;
673
        }
674

    
675
        this.beforeSavingListeners.remove(l);
676
    }
677

    
678
    /**
679
     * Removes the specified after saving listener so that it no longer
680
     * receives save file events from this component. This method performs
681
     * no function, nor does it throw an exception, if the listener
682
     * specified by the argument was not previously added to this component.
683
     * If listener <code>l</code> is <code>null</code>,
684
     * no exception is thrown and no action is performed.
685
     * 
686
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
687
     * 
688
     * @param l
689
     *            the after saving listener
690
     * @see SaveEvent
691
     * @see AfterSavingListener
692
     * @see #addListener(AfterSavingListener)
693
     * @see #getAfterSavingListeners()
694
     */
695
    public synchronized void removeListener(AfterSavingListener l) {
696
        if (l == null) {
697
            return;
698
        }
699

    
700
        this.afterSavingListeners.remove(l);
701
    }
702

    
703
    /**
704
     * Reports a before saving file event.
705
     * 
706
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
707
     * 
708
     * @param evt
709
     *            the before saving file event
710
     */
711
    protected void fireBeforeSavingFileEvent(SaveEvent evt) {
712
        if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
713
            return;
714
        }
715

    
716
        Iterator<BeforeSavingListener> iter =
717
            this.beforeSavingListeners.iterator();
718

    
719
        while (iter.hasNext()) {
720
            iter.next().beforeSaving(evt);
721
        }
722
    }
723

    
724
    /**
725
     * Reports a after saving file event.
726
     * 
727
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
728
     * 
729
     * @param evt
730
     *            the after saving file event
731
     */
732
    protected void fireAfterSavingFileEvent(SaveEvent evt) {
733
        if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
734
            return;
735
        }
736
        Iterator<AfterSavingListener> iter =
737
            this.afterSavingListeners.iterator();
738

    
739
        while (iter.hasNext()) {
740
            iter.next().afterSaving(evt);
741
        }
742

    
743
    }
744
}