Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / applications / appgvSIG / src / org / gvsig / app / extension / ProjectExtension.java @ 36443

History | View | Annotate | Download (27.8 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.io.FileInputStream;
27
import java.io.FileNotFoundException;
28
import java.text.MessageFormat;
29
import java.util.ArrayList;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.prefs.Preferences;
33

    
34
import javax.swing.JOptionPane;
35

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

    
68
/**
69
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
70
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos
71
 * en esta clase.
72
 * 
73
 * @author Fernando Gonz?lez Cort?s
74
 */
75
public class ProjectExtension extends Extension implements IExtensionStatus {
76

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

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

    
102
    private List<AfterSavingListener> afterSavingListeners =
103
        new ArrayList<AfterSavingListener>();
104

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

    
118
        initializeDocumentActionsExtensionPoint();
119
        registerIcons();
120
    }
121

    
122
    private void registerIcons() {
123
        PluginServices.getIconTheme().registerDefault("project-new",
124
            this.getClass().getClassLoader().getResource("images/new.png"));
125

    
126
        PluginServices.getIconTheme().registerDefault("project-open",
127
            this.getClass().getClassLoader().getResource("images/open.png"));
128

    
129
        PluginServices.getIconTheme().registerDefault("project-save",
130
            this.getClass().getClassLoader().getResource("images/save.png"));
131

    
132
        PluginServices.getIconTheme().registerDefault("project-save-as",
133
            this.getClass().getClassLoader().getResource("images/save.png"));
134

    
135
        PluginServices.getIconTheme().registerDefault(
136
            "layout-template-open",
137
            this.getClass().getClassLoader()
138
                .getResource("images/opentemplate.png"));
139

    
140
        PluginServices.getIconTheme().registerDefault("application-exit",
141
            this.getClass().getClassLoader().getResource("images/salir.png"));
142
    }
143

    
144
    private void loadInitialProject() {
145
        String[] theArgs = PluginServices.getArguments();
146
        String lastArg = theArgs[theArgs.length - 1];
147
        if ((lastArg.toLowerCase().endsWith(Project.FILE_EXTENSION
148
            .toLowerCase()))) {
149
            PluginServices.getLogger().debug(
150
                "Intentando cargar el proyecto " + lastArg);
151
            // File projectFile = new File(lastArg);
152
            setProject(readProject(lastArg));
153
            PluginServices.getMainFrame().setTitle(p.getName());
154
            projectPath = lastArg;
155
        } else {
156
            setProject(ProjectManager.getInstance().createProject());
157
            p.setName(PluginServices.getText(this, "untitled"));
158
            p.setModified(false);
159
            PluginServices.getMainFrame().setTitle(
160
                PluginServices.getText(this, "sin_titulo"));
161
        }
162

    
163
    }
164

    
165
    /**
166
     * @see com.iver.mdiApp.plugins.IExtension#postInitialize()
167
     */
168
    public void postInitialize() {
169
        registerDocuments();
170
        loadInitialProject();
171
        getProjectFrame().setProject(p);
172
        showProjectWindow();
173
    }
174

    
175
    public ProjectWindow getProjectFrame() {
176
        if (projectFrame == null) {
177
            projectFrame = new ProjectWindow();
178
        }
179
        return projectFrame;
180
    }
181

    
182
    /**
183
     * Muestra la ventana con el gestor de proyectos.
184
     */
185
    public void showProjectWindow() {
186
        if (seedProjectWindow != null) {
187
            if (seedProjectWindow.isClosed()) {
188
                // if it was closed, we just don't open the window now
189
                seedProjectWindow.setClosed(false);
190
                return;
191
            }
192
            WindowInfo winProps = seedProjectWindow;
193
            seedProjectWindow = null;
194
            PluginServices.getMDIManager().addWindow(getProjectFrame());
195
            PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
196
                winProps);
197
        } else {
198
            PluginServices.getMDIManager().addWindow(getProjectFrame());
199
        }
200
    }
201

    
202
    /**
203
     * Muestra la ventana con el gestor de proyectos, con las propiedades
204
     * de ventana especificadas.
205
     */
206
    public void showProjectWindow(WindowInfo wi) {
207
        seedProjectWindow = wi;
208
        showProjectWindow();
209
    }
210

    
211
    /**
212
     * Guarda el proyecto actual en disco.
213
     */
214
    private boolean guardar() {
215
        boolean saved = false;
216
        // if (p.getPath() == null) {
217
        if (projectPath == null) {
218
            saved = guardarDialogo();
219
        } else {
220
            long t1, t2;
221
            t1 = System.currentTimeMillis();
222
            saved = writeProject(new File(projectPath), p, false);
223
            t2 = System.currentTimeMillis();
224
            PluginServices.getLogger().info(
225
                "Project saved. " + (t2 - t1) + " miliseconds");
226
            getProjectFrame().refreshControls();
227
        }
228
        return saved;
229
    }
230

    
231
    private boolean guardarDialogo() {
232
        boolean saved = false;
233

    
234
        if (lastSavePath == null) {
235
            lastSavePath = projectPath;
236
        }
237

    
238
        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
239
        JFileChooser jfc =
240
            new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get(
241
                "ProjectsFolder", null));
242

    
243
        jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
244
        jfc.addChoosableFileFilter(new GenericFileFilter(
245
            Project.FILE_EXTENSION, MessageFormat.format(
246
                PluginServices.getText(this, "_gvSIG_file_project_({0})"),
247
                Project.FILE_EXTENSION)));
248

    
249
        if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
250
            File file = jfc.getSelectedFile();
251
            if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
252
                .toLowerCase()))) {
253
                file = new File(file.getPath() + Project.FILE_EXTENSION);
254
            }
255
            saved = writeProject(file, p);
256
            String filePath = file.getAbsolutePath();
257
            lastSavePath =
258
                filePath.substring(0, filePath.lastIndexOf(File.separatorChar));
259

    
260
            getProjectFrame().refreshControls();
261
        }
262
        return saved;
263
    }
264

    
265
    /**
266
     * Checks whether the project and related unsaved data is modified,
267
     * and allows the user to save it.
268
     * 
269
     * @return true if the data has been correctly saved, false otherwise
270
     */
271
    private boolean askSave() {
272
        if (p != null && p.hasChanged()) {
273
            TerminationProcess process = Launcher.getTerminationProcess();
274
            UnsavedDataPanel panel = process.getUnsavedDataPanel();
275
            panel.setHeaderText(PluginServices.getText(this,
276
                "Select_resources_to_save_before_closing_current_project"));
277
            panel.setAcceptText(PluginServices.getText(this, "save_resources"),
278
                PluginServices.getText(this,
279
                    "Save_the_selected_resources_and_close_current_project"));
280
            panel.setCancelText(PluginServices.getText(this, "Dont_close"),
281
                PluginServices.getText(this, "Return_to_current_project"));
282
            int closeCurrProj = process.manageUnsavedData();
283
            if (closeCurrProj == JOptionPane.NO_OPTION) {
284
                // the user chose to return to current project
285
                return false;
286
            }
287
        }
288
        return true;
289
    }
290

    
291
    /**
292
     * @see com.iver.mdiApp.plugins.IExtension#updateUI(java.lang.String)
293
     */
294
    public void execute(String actionCommand) {
295
        if (actionCommand.equals("NUEVO")) {
296
            if (!askSave()) {
297
                return;
298
            }
299

    
300
            projectPath = null;
301
            // ProjectDocument.initializeNUMS();
302
            PluginServices.getMDIManager().closeAllWindows();
303
            setProject(ProjectManager.getInstance().createProject());
304
            getProjectFrame().setProject(p);
305
            showProjectWindow();
306
            PluginServices.getMainFrame().setTitle(
307
                PluginServices.getText(this, "sin_titulo"));
308
        } else
309
            if (actionCommand.equals("ABRIR")) {
310
                if (!askSave()) {
311
                    return;
312
                }
313

    
314
                Preferences prefs =
315
                    Preferences.userRoot().node("gvsig.foldering");
316
                JFileChooser jfc =
317
                    new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get(
318
                        "ProjectsFolder", null));
319
                jfc.addChoosableFileFilter(new GenericFileFilter(
320
                    Project.FILE_EXTENSION, PluginServices.getText(this,
321
                        "tipo_fichero_proyecto")));
322

    
323
                if (jfc.showOpenDialog((Component) PluginServices
324
                    .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
325
                    // ProjectDocument.initializeNUMS();
326
                    PluginServices.getMDIManager().closeAllWindows();
327

    
328
                    File projectFile = jfc.getSelectedFile();
329
                    Project o = readProject(projectFile);
330
                    setPath(projectFile.getAbsolutePath());
331
                    // lastPath = getPath();
332
                    if (o != null) {
333
                        setProject(o);
334
                    }
335

    
336
                    getProjectFrame().setProject(p);
337
                    PluginServices.getMainFrame().setTitle(p.getName());
338
                    getProjectFrame().refreshControls();
339

    
340
                    // p.restoreWindowProperties();
341
                }
342
            } else
343
                if (actionCommand.equals("GUARDAR")) {
344
                    guardar();
345
                } else
346
                    if (actionCommand.equals("GUARDAR_COMO")) {
347
                        guardarDialogo();
348
                    } else
349
                        if (actionCommand.equals("SALIR")) {
350
                            Launcher.closeApplication();
351
                        } else
352
                            if (actionCommand.compareTo("OPENTEMPLATE") == 0) {
353
                                openLayout();
354
                            }
355
    }
356

    
357
    private void openLayout() {
358
        // Project project = ((ProjectExtension)
359
        // PluginServices.getExtension(ProjectExtension.class)).getProject();
360
        LayoutPanel layout = null;
361

    
362
        if (templatesPath == null) {
363
            Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
364
            templatesPath = prefs.get("TemplatesFolder", null);
365
        }
366

    
367
        JFileChooser jfc =
368
            new JFileChooser(LAYOUT_TEMPLATE_FILECHOOSER_ID, templatesPath);
369
        jfc.addChoosableFileFilter(new GenericFileFilter(
370
            LayoutManager.TEMPLATE_FILE_EXTENSION, PluginServices.getText(this,
371
                "_Layout_template")));
372

    
373
        if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
374
            File file = jfc.getSelectedFile();
375
            if (!file.getPath().toLowerCase()
376
                .endsWith(LayoutManager.TEMPLATE_FILE_EXTENSION.toLowerCase())) {
377
                file =
378
                    new File(file.getPath()
379
                        + LayoutManager.TEMPLATE_FILE_EXTENSION);
380
            }
381
            try {
382
                File xmlFile = new File(file.getAbsolutePath());
383
                FileInputStream is = new FileInputStream(xmlFile);
384

    
385
                PersistenceManager persistenceManager =
386
                    ToolsLocator.getPersistenceManager();
387
                PersistentState persistentState =
388
                    persistenceManager.loadState(is);
389
                layout =
390
                    (LayoutPanel) persistenceManager.create(persistentState);
391

    
392
            } catch (FileNotFoundException e) {
393
                NotificationManager.addError(MessageFormat.format(
394
                    PluginServices.getText(this,
395
                        "_Cant_load_layout_template_{0}"), file.getPath()), e);
396
            } catch (PersistenceException e) {
397
                NotificationManager.addError(MessageFormat.format(
398
                    PluginServices.getText(this,
399
                        "_Cant_load_layout_template_{0}"), file.getPath()), e);
400
            }
401

    
402
            LayoutDocument layoutDocument =
403
                (LayoutDocument) ProjectManager.getInstance().createDocument(
404
                    DefaultLayoutManager.TYPENAME, file.getName());
405
            p.add(layoutDocument);
406
            PluginServices.getMDIManager().addWindow(layout);
407

    
408
        }
409
    }
410

    
411
    /**
412
     * Escribe el proyecto en XML.
413
     * 
414
     * @param file
415
     *            Fichero.
416
     * @param p
417
     *            Proyecto.
418
     */
419
    public boolean writeProject(File file, Project p) {
420
        return writeProject(file, p, true);
421
    }
422

    
423
    /**
424
     * Escribe el proyecto en XML. Pero permite decidir si se
425
     * pide confirmaci?n para sobreescribir
426
     * 
427
     * @param file
428
     *            Fichero.
429
     * @param p
430
     *            Proyecto.
431
     * @param askConfirmation
432
     *            boolean
433
     */
434
    public boolean writeProject(File file, Project p, boolean askConfirmation) {
435
        if (askConfirmation && file.exists()) {
436
            int resp =
437
                JOptionPane.showConfirmDialog((Component) PluginServices
438
                    .getMainFrame(), PluginServices.getText(this,
439
                    "fichero_ya_existe_seguro_desea_guardarlo"), PluginServices
440
                    .getText(this, "guardar"), JOptionPane.YES_NO_OPTION);
441
            if (resp != JOptionPane.YES_OPTION) {
442
                return false;
443
            }
444
        }
445
        NotificationManager.addInfo(PluginServices.getText(this,
446
            "writinng_project") + ": " + file.getName());
447

    
448
        // write it out as XML
449
        try {
450
            fireBeforeSavingFileEvent(new SaveEvent(this,
451
                SaveEvent.BEFORE_SAVING, file));
452
            p.saveState(file);
453
            fireAfterSavingFileEvent(new SaveEvent(this,
454
                SaveEvent.AFTER_SAVING, file));
455
            PluginServices.getMainFrame().setTitle(file.getName());
456
            setPath(file.toString());
457

    
458
        } catch (PersistenceException e) {
459
            String messagestack = e.getLocalizedMessageStack();
460
            NotificationManager.addError(
461
                PluginServices.getText(this, "error_writing_project") + ": "
462
                    + file.getName() + "\n" + messagestack, e);
463
            return false;
464
        } catch (Exception e) {
465
            NotificationManager.addError(
466
                PluginServices.getText(this, "error_writing_project") + ": "
467
                    + file.getName(), e);
468
            return false;
469
        }
470
        NotificationManager.addInfo(PluginServices.getText(this,
471
            "wrote_project") + ": " + file.getName());
472
        return true;
473
    }
474

    
475
    public Project readProject(String path) {
476
        Project project = ProjectManager.getInstance().createProject();
477

    
478
        project.loadState(new File(path));
479
        return (Project) project;
480
    }
481

    
482
    /**
483
     * Lee del XML el proyecto.<br>
484
     * <br>
485
     * 
486
     * Reads the XML of the project.<br>
487
     * It returns a project object holding all needed info that is not linked to
488
     * the Project Dialog. <br>
489
     * In case you want the project to be
490
     * linked to the window you must set this object to the extension:<br>
491
     * 
492
     * <b>Example:</b><br>
493
     * 
494
     * ...<br>
495
     * ...<br>
496
     * Project p = ProjectExtension.readProject(projectFile);<br>
497
     * ProjectExtension.setProject(p);
498
     * ...<br>
499
     * ...<br>
500
     * 
501
     * @param file
502
     *            Fichero.
503
     * 
504
     * @return Project
505
     * 
506
     */
507
    public Project readProject(File file) {
508
        Project project = ProjectManager.getInstance().createProject();
509

    
510
        project.loadState(file);
511
        return (Project) project;
512
    }
513

    
514
    /**
515
     * Devuelve el proyecto.
516
     * 
517
     * @return Proyecto.
518
     */
519
    public Project getProject() {
520
        return p;
521
    }
522

    
523
    /**
524
     * @see org.gvsig.andami.plugins.IExtension#isEnabled()
525
     */
526
    public boolean isEnabled() {
527
        return true;
528
    }
529

    
530
    /**
531
     * @see org.gvsig.andami.plugins.IExtension#isVisible()
532
     */
533
    public boolean isVisible() {
534
        return true;
535
    }
536

    
537
    /**
538
     * Sets the project
539
     * 
540
     * @param p
541
     */
542
    public void setProject(Project p) {
543
        getProjectFrame().setProject(p);
544
        this.p = p;
545
    }
546

    
547
    private void registerDocuments() {
548
        ViewManager.register();
549
        DefaultLayoutManager.register();
550
    }
551

    
552
    private void initializeDocumentActionsExtensionPoint() {
553
        ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
554
        epMan.add("DocumentActions_View",
555
            "Context menu options of the view document list"
556
                + " in the project window " + "(register instances of "
557
                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
558
        epMan.add("DocumentActions_Map",
559
            "Context menu options of the map document list"
560
                + " in the project window " + "(register instances of "
561
                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
562
    }
563

    
564
    public static String getPath() {
565
        return projectPath;
566
    }
567

    
568
    public static void setPath(String path) {
569
        projectPath = path;
570
    }
571

    
572
    public IWindow getProjectWindow() {
573
        return getProjectFrame();
574
    }
575

    
576
    public IExtensionStatus getStatus() {
577
        return this;
578
    }
579

    
580
    public boolean hasUnsavedData() {
581
        return p.hasChanged();
582
    }
583

    
584
    public IUnsavedData[] getUnsavedData() {
585
        if (hasUnsavedData()) {
586
            UnsavedProject data = new UnsavedProject(this);
587
            IUnsavedData[] dataArray = { data };
588
            return dataArray;
589
        } else {
590
            return null;
591
        }
592
    }
593

    
594
    /**
595
     * Implements the IUnsavedData interface to show unsaved projects
596
     * in the Unsavad Data dialog.
597
     * 
598
     * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
599
     */
600
    public class UnsavedProject extends UnsavedData {
601

    
602
        public UnsavedProject(IExtension extension) {
603
            super(extension);
604
        }
605

    
606
        public String getDescription() {
607
            if (getPath() == null) {
608
                return PluginServices.getText(ProjectExtension.this,
609
                    "Unnamed_new_gvsig_project_");
610
            } else {
611
                return PluginServices.getText(ProjectExtension.this,
612
                    "Modified_project_");
613
            }
614
        }
615

    
616
        public String getResourceName() {
617
            if (getPath() == null) {
618
                return PluginServices.getText(ProjectExtension.this, "Unnamed");
619
            } else {
620
                return getPath();
621
            }
622

    
623
        }
624

    
625
        public boolean saveData() {
626
            return guardar();
627
        }
628

    
629
        public String getIcon() {
630
            return "images/logoGVA.gif";
631
        }
632
    }
633

    
634
    public IMonitorableTask[] getRunningProcesses() {
635
        // TODO Auto-generated method stub
636
        return null;
637
    }
638

    
639
    public boolean hasRunningProcesses() {
640
        // TODO Auto-generated method stub
641
        return false;
642
    }
643

    
644
    /**
645
     * Adds the specified before saving listener to receive
646
     * "before saving file events" from
647
     * this component.
648
     * If l is null, no exception is thrown and no action is performed.
649
     * 
650
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
651
     * 
652
     * @param l
653
     *            the before saving listener.
654
     * @see SaveEvent
655
     * @see BeforeSavingListener
656
     * @see #removeListener(BeforeSavingListener)
657
     * @see #getBeforeSavingListeners
658
     */
659
    public synchronized void addListener(BeforeSavingListener l) {
660
        if (l == null) {
661
            return;
662
        }
663
        if (!this.beforeSavingListeners.contains(l)) {
664
            this.beforeSavingListeners.add(l);
665
        }
666
    }
667

    
668
    /**
669
     * Adds the specified after saving listener to receive
670
     * "after saving file events" from
671
     * this component.
672
     * If l is null, no exception is thrown and no action is performed.
673
     * 
674
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
675
     * 
676
     * @param l
677
     *            the after saving listener.
678
     * @see SaveEvent
679
     * @see AfterSavingListener
680
     * @see #removeListener(AfterSavingListener)
681
     * @see #getAfterSavingListeners()
682
     */
683
    public synchronized void addListener(AfterSavingListener l) {
684
        if (l == null) {
685
            return;
686
        }
687

    
688
        if (!this.afterSavingListeners.contains(l)) {
689
            this.afterSavingListeners.add(l);
690
        }
691

    
692
    }
693

    
694
    /**
695
     * Returns an array of all the before saving listeners
696
     * registered on this component.
697
     * 
698
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
699
     * 
700
     * @return all of this component's <code>BeforeSavingListener</code>s
701
     *         or an empty array if no key
702
     *         listeners are currently registered
703
     * 
704
     * @see #addBeforeSavingListener(BeforeSavingListener)
705
     * @see #removeBeforeSavingListener(BeforeSavingListener)
706
     */
707
    public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
708
        return this.beforeSavingListeners
709
            .toArray(new BeforeSavingListener[] {});
710
    }
711

    
712
    /**
713
     * Returns an array of all the after saving listeners
714
     * registered on this component.
715
     * 
716
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
717
     * 
718
     * @return all of this component's <code>AfterSavingListener</code>s
719
     *         or an empty array if no key
720
     *         listeners are currently registered
721
     * 
722
     * @see #addAfterSavingListener(AfterSavingListener)
723
     * @see #removeAfterSavingListener
724
     */
725
    public synchronized AfterSavingListener[] getAfterSavingListeners() {
726
        return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
727

    
728
    }
729

    
730
    /**
731
     * Removes the specified before saving listener so that it no longer
732
     * receives save file events from this component. This method performs
733
     * no function, nor does it throw an exception, if the listener
734
     * specified by the argument was not previously added to this component.
735
     * If listener <code>l</code> is <code>null</code>,
736
     * no exception is thrown and no action is performed.
737
     * 
738
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
739
     * 
740
     * @param l
741
     *            the before saving listener
742
     * @see SaveEvent
743
     * @see BeforeSavingListener
744
     * @see #addListener(BeforeSavingListener)
745
     * @see #getBeforeSavingListeners()
746
     */
747
    public synchronized void removeListener(BeforeSavingListener l) {
748
        if (l == null) {
749
            return;
750
        }
751

    
752
        this.beforeSavingListeners.remove(l);
753
    }
754

    
755
    /**
756
     * Removes the specified after saving listener so that it no longer
757
     * receives save file events from this component. This method performs
758
     * no function, nor does it throw an exception, if the listener
759
     * specified by the argument was not previously added to this component.
760
     * If listener <code>l</code> is <code>null</code>,
761
     * no exception is thrown and no action is performed.
762
     * 
763
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
764
     * 
765
     * @param l
766
     *            the after saving listener
767
     * @see SaveEvent
768
     * @see AfterSavingListener
769
     * @see #addListener(AfterSavingListener)
770
     * @see #getAfterSavingListeners()
771
     */
772
    public synchronized void removeListener(AfterSavingListener l) {
773
        if (l == null) {
774
            return;
775
        }
776

    
777
        this.afterSavingListeners.remove(l);
778
    }
779

    
780
    /**
781
     * Reports a before saving file event.
782
     * 
783
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
784
     * 
785
     * @param evt
786
     *            the before saving file event
787
     */
788
    protected void fireBeforeSavingFileEvent(SaveEvent evt) {
789
        if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
790
            return;
791
        }
792

    
793
        Iterator<BeforeSavingListener> iter =
794
            this.beforeSavingListeners.iterator();
795

    
796
        while (iter.hasNext()) {
797
            iter.next().beforeSaving(evt);
798
        }
799
    }
800

    
801
    /**
802
     * Reports a after saving file event.
803
     * 
804
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
805
     * 
806
     * @param evt
807
     *            the after saving file event
808
     */
809
    protected void fireAfterSavingFileEvent(SaveEvent evt) {
810
        if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
811
            return;
812
        }
813
        Iterator<AfterSavingListener> iter =
814
            this.afterSavingListeners.iterator();
815

    
816
        while (iter.hasNext()) {
817
            iter.next().afterSaving(evt);
818
        }
819

    
820
    }
821
}