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 @ 41313

History | View | Annotate | Download (23.2 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.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
import javax.swing.SwingUtilities;
36

    
37
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39
import org.gvsig.tools.util.ArrayUtils;
40
import org.apache.commons.lang.StringUtils;
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.PluginsLocator;
46
import org.gvsig.andami.actioninfo.ActionInfo;
47
import org.gvsig.andami.actioninfo.ActionInfoManager;
48
import org.gvsig.andami.messages.NotificationManager;
49
import org.gvsig.andami.plugins.Extension;
50
import org.gvsig.andami.plugins.IExtension;
51
import org.gvsig.andami.plugins.status.IExtensionStatus;
52
import org.gvsig.andami.plugins.status.IUnsavedData;
53
import org.gvsig.andami.plugins.status.UnsavedData;
54
import org.gvsig.andami.ui.mdiManager.IWindow;
55
import org.gvsig.andami.ui.mdiManager.WindowInfo;
56
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
57
import org.gvsig.app.project.Project;
58
import org.gvsig.app.project.ProjectManager;
59
import org.gvsig.app.project.documents.gui.ProjectWindow;
60
import org.gvsig.app.project.documents.view.ViewManager;
61
import org.gvsig.gui.beans.swing.JFileChooser;
62
import org.gvsig.tools.ToolsLocator;
63
import org.gvsig.tools.dataTypes.DataTypes;
64
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
65
import org.gvsig.tools.persistence.exception.PersistenceException;
66
import org.gvsig.utils.GenericFileFilter;
67
import org.gvsig.utils.save.AfterSavingListener;
68
import org.gvsig.utils.save.BeforeSavingListener;
69
import org.gvsig.utils.save.SaveEvent;
70
import org.gvsig.utils.swing.threads.IMonitorableTask;
71

    
72

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

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

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

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

    
105
        public void initialize() {
106
            initializeDocumentActionsExtensionPoint();
107
            registerDocuments();
108
            registerIcons();
109
            PluginsLocator.getManager().addStartupTask(
110
                    "Open project",
111
                    new OpenInitialProjectTask(), true, 1000);
112
        }
113

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

    
123
                IconThemeHelper.registerIcon("project", "project-icon", this);
124
        }
125

    
126
        private class OpenInitialProjectTask implements Runnable {
127
            public void run() {
128
                File pf = getInitialProjectFile();
129
                if (pf == null) {
130
                    LOG.info("No initial file opened.");
131
                    return;
132
                }
133
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
134
                ActionInfo action = actionManager.getAction("application-project-open");
135
                action.execute(pf);
136
            }
137
            /**
138
             * Returns the file to be opened or null if no parameter
139
             * or file does not exist
140
             * 
141
             * @return
142
             */
143
            private File getInitialProjectFile() {
144
                String[] theArgs = PluginServices.getArguments();
145
                String lastArg = theArgs[theArgs.length - 1];
146
                if ( StringUtils.isEmpty(lastArg) ) {
147
                    return null;
148
                }
149
                if( lastArg.startsWith("-") ) {
150
                    return null;
151
                }
152
                if (!lastArg.toLowerCase().endsWith(Project.FILE_EXTENSION.toLowerCase())) {
153
                    LOG.info("Do not open project file, does not have the expected extension '" + 
154
                            Project.FILE_EXTENSION +"' ("+lastArg+").");
155
                    return null;
156
                }
157
                File projectFile = new File(lastArg);
158
                if ( !projectFile.exists()) {
159
                    LOG.info("Do not open project file, '" +projectFile.getAbsolutePath() + "' do not exist.");
160
                    return null;
161
                }
162
                return projectFile;
163
            }   
164
        }
165

    
166
        public ProjectWindow getProjectFrame() {
167
                if (projectFrame == null) {
168
                        projectFrame = new ProjectWindow();
169
                }
170
                return projectFrame;
171
        }
172

    
173
        /**
174
         * Muestra la ventana con el gestor de proyectos.
175
         */
176
        public void showProjectWindow() {
177
                if (seedProjectWindow != null) {
178
                        if (seedProjectWindow.isClosed()) {
179
                                // if it was closed, we just don't open the window now
180
                                seedProjectWindow.setClosed(false);
181
                                return;
182
                        }
183
                        WindowInfo winProps = seedProjectWindow;
184
                        seedProjectWindow = null;
185
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
186
                        PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
187
                                        winProps);
188
                } else {
189
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
190
                }
191
        }
192

    
193
        /**
194
         * Muestra la ventana con el gestor de proyectos, con las propiedades de
195
         * ventana especificadas.
196
         */
197
        public void showProjectWindow(WindowInfo wi) {
198
                seedProjectWindow = wi;
199
                showProjectWindow();
200
        }
201

    
202
        /**
203
         * Guarda el proyecto actual en disco.
204
         */
205
        private boolean saveProject() {
206
                boolean saved = false;
207
                // if (p.getPath() == null) {
208
                if (projectPath == null) {
209
                        saved = saveAsProject(null);
210
                } else {
211
                        long t1, t2;
212
                        t1 = System.currentTimeMillis();
213
                        saved = writeProject(new File(projectPath), p, false);
214
                        t2 = System.currentTimeMillis();
215
                        PluginServices.getLogger().info(
216
                                        "Project saved. " + (t2 - t1) + " miliseconds");
217
                        getProjectFrame().refreshControls();
218
                }
219
                return saved;
220
        }
221

    
222
        private boolean saveAsProject(File file) {
223
                boolean saved = false;
224

    
225
                if (lastSavePath == null) {
226
                        lastSavePath = projectPath;
227
                }
228

    
229
                if (file == null) {
230
                        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
231
                        JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
232
                                        prefs.get("ProjectsFolder", null));
233

    
234
                        jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
235
                        jfc.addChoosableFileFilter(new GenericFileFilter(
236
                                        Project.FILE_EXTENSION, MessageFormat.format(PluginServices
237
                                                        .getText(this, "tipo_fichero_proyecto"),
238
                                                        Project.FILE_EXTENSION)));
239

    
240
                        if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
241
                                return saved;
242
                        }
243
                        file = jfc.getSelectedFile();
244
                }
245

    
246
                if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
247
                                .toLowerCase()))) {
248
                        file = new File(file.getPath() + Project.FILE_EXTENSION);
249
                }
250
                saved = writeProject(file, p);
251
                String filePath = file.getAbsolutePath();
252
                lastSavePath = filePath.substring(0,
253
                                filePath.lastIndexOf(File.separatorChar));
254

    
255
                getProjectFrame().refreshControls();
256
                return saved;
257
        }
258

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

    
292
        public void execute(String command) {
293
                this.execute(command, null);
294
        }
295
        
296
        public void execute(String actionCommand, Object[] args) {
297
                if (actionCommand.equals("application-project-new")) {
298
                        if (!askSave()) {
299
                                return;
300
                        }
301

    
302
                        projectPath = null;
303
                        PluginServices.getMDIManager().closeAllWindows();
304
                        setProject(ProjectManager.getInstance().createProject());
305
                        getProjectFrame().setProject(p);
306
                        showProjectWindow();
307
                        PluginServices.getMainFrame().setTitle(
308
                                        PluginServices.getText(this, "sin_titulo"));
309

    
310
                } else if (actionCommand.equals("application-project-open")) {
311
                        if (!askSave()) {
312
                                return;
313
                        }
314
                        File projectFile = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
315
                        if ( projectFile != null && !projectFile.exists() ) {
316
                            LOG.warn("Can't load project '"
317
                                    + projectFile.getAbsolutePath()
318
                                    + "', file not exist.");
319
                            projectFile = null;
320
                        }
321

    
322
                        if (projectFile == null) {
323
                                Preferences prefs = Preferences.userRoot().node(
324
                                                "gvsig.foldering");
325
                                JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
326
                                                prefs.get("ProjectsFolder", null));
327
                                jfc.addChoosableFileFilter(new GenericFileFilter(
328
                                                Project.FILE_EXTENSION, PluginServices.getText(this,
329
                                                                "tipo_fichero_proyecto")));
330

    
331
                                if (jfc.showOpenDialog((Component) PluginServices
332
                                                .getMainFrame()) != JFileChooser.APPROVE_OPTION) {
333
                                        return;
334
                                }
335
                                // ProjectDocument.initializeNUMS();
336
                                
337

    
338
                                projectFile = jfc.getSelectedFile();
339
                        }
340
                        
341
                        PluginServices.getMDIManager().closeAllWindows();
342

    
343
                        Project o = readProject(projectFile);
344
                        setPath(projectFile.getAbsolutePath());
345
                        // lastPath = getPath();
346
                        if (o != null) {
347
                                setProject(o);
348
                        }
349

    
350
                        getProjectFrame().setProject(p);
351
                        PluginServices.getMainFrame().setTitle(projectFile.getName());
352
                        getProjectFrame().refreshControls();
353

    
354
                        // p.restoreWindowProperties();
355

    
356
                } else if (actionCommand.equals("application-project-save")) {
357
                        saveProject();
358
                } else if (actionCommand.equals("application-project-save-as")) {
359
                        File file = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
360
                        saveAsProject(file);
361
                }
362

    
363
        }
364

    
365
        
366
    private void createEmptyProject() {
367
        setProject(ProjectManager.getInstance().createProject());
368
        p.setName(PluginServices.getText(this, "untitled"));
369
        p.setModified(false);
370
        PluginServices.getMainFrame().setTitle(
371
                PluginServices.getText(this, "sin_titulo"));
372
        setProject(p);
373
        showProjectWindow();
374
    }
375

    
376
    /**
377
     * @see com.iver.mdiApp.plugins.IExtension#postInitialize()
378
     */
379
    public void postInitialize() {
380
        try {
381
            if( !SwingUtilities.isEventDispatchThread() ) {
382
                SwingUtilities.invokeAndWait(new Runnable() {
383
                    public void run() {
384
                        createEmptyProject();
385
                    }
386
                });
387
            } else {
388
                createEmptyProject();
389
            }
390
        } catch (Exception e) {
391
            LOG.warn("Can't load initial project.",e);
392
        }
393
    }        
394
        
395
        
396
        /**
397
         * Escribe el proyecto en XML.
398
         * 
399
         * @param file
400
         *            Fichero.
401
         * @param p
402
         *            Proyecto.
403
         */
404
        public boolean writeProject(File file, Project p) {
405
                return writeProject(file, p, true);
406
        }
407

    
408
        /**
409
         * Escribe el proyecto en XML. Pero permite decidir si se pide confirmaci?n
410
         * para sobreescribir
411
         * 
412
         * @param file
413
         *            Fichero.
414
         * @param p
415
         *            Proyecto.
416
         * @param askConfirmation
417
         *            boolean
418
         */
419
        public boolean writeProject(File file, Project p, boolean askConfirmation) {
420
                if (askConfirmation && file.exists()) {
421
                        int resp = JOptionPane.showConfirmDialog((Component) PluginServices
422
                                        .getMainFrame(), PluginServices.getText(this,
423
                                        "fichero_ya_existe_seguro_desea_guardarlo"), PluginServices
424
                                        .getText(this, "guardar"), JOptionPane.YES_NO_OPTION);
425
                        if (resp != JOptionPane.YES_OPTION) {
426
                                return false;
427
                        }
428
                }
429
                NotificationManager.addInfo(PluginServices.getText(this,
430
                                "writinng_project") + ": " + file.getName());
431

    
432
                // write it out as XML
433
                try {
434
                        fireBeforeSavingFileEvent(new SaveEvent(this,
435
                                        SaveEvent.BEFORE_SAVING, file));
436
                        p.saveState(file);
437
                        fireAfterSavingFileEvent(new SaveEvent(this,
438
                                        SaveEvent.AFTER_SAVING, file));
439

    
440
                        PluginServices.getMainFrame().setTitle(file.getName());
441
                        setPath(file.toString());
442

    
443
                } catch (PersistenceException e) {
444
                        String messagestack = e.getLocalizedMessageStack();
445
                        NotificationManager.addError(
446
                                        PluginServices.getText(this, "error_writing_project")
447
                                                        + ": " + file.getName() + "\n" + messagestack, e);
448
                        return false;
449
                } catch (Exception e) {
450
                        NotificationManager.addError(
451
                                        PluginServices.getText(this, "error_writing_project")
452
                                                        + ": " + file.getName(), e);
453
                        return false;
454
                }
455
                NotificationManager.addInfo(PluginServices.getText(this,
456
                                "wrote_project") + ": " + file.getName());
457
                return true;
458
        }
459

    
460
        public Project readProject(String path) {
461
                Project project = ProjectManager.getInstance().createProject();
462

    
463
                project.loadState(new File(path));
464
                return (Project) project;
465
        }
466

    
467
        /**
468
         * Lee del XML el proyecto.<br>
469
         * <br>
470
         * 
471
         * Reads the XML of the project.<br>
472
         * It returns a project object holding all needed info that is not linked to
473
         * the Project Dialog. <br>
474
         * In case you want the project to be linked to the window you must set this
475
         * object to the extension:<br>
476
         * 
477
         * <b>Example:</b><br>
478
         * 
479
         * ...<br>
480
         * ...<br>
481
         * Project p = ProjectExtension.readProject(projectFile);<br>
482
         * ProjectExtension.setProject(p); ...<br>
483
         * ...<br>
484
         * 
485
         * @param file
486
         *            Fichero.
487
         * 
488
         * @return Project
489
         * 
490
         */
491
        public Project readProject(File file) {
492
                Project project = ProjectManager.getInstance().createProject();
493

    
494
                project.loadState(file);
495
                return (Project) project;
496
        }
497

    
498
        /**
499
         * Devuelve el proyecto.
500
         * 
501
         * @return Proyecto.
502
         */
503
        public Project getProject() {
504
                return p;
505
        }
506

    
507
        /**
508
         * @see org.gvsig.andami.plugins.IExtension#isEnabled()
509
         */
510
        public boolean isEnabled() {
511
                return true;
512
        }
513

    
514
        /**
515
         * @see org.gvsig.andami.plugins.IExtension#isVisible()
516
         */
517
        public boolean isVisible() {
518
                return true;
519
        }
520

    
521
        /**
522
         * Sets the project
523
         * 
524
         * @param p
525
         */
526
        public void setProject(Project p) {
527
                getProjectFrame().setProject(p);
528
                this.p = p;
529
        }
530

    
531
        private void registerDocuments() {
532
                ViewManager.register();
533
        }
534

    
535
        private void initializeDocumentActionsExtensionPoint() {
536
                ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
537
                epMan.add(
538
                                "DocumentActions_View",
539
                                "Context menu options of the view document list"
540
                                                + " in the project window "
541
                                                + "(register instances of "
542
                                                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
543
        }
544

    
545
        public static String getPath() {
546
                return projectPath;
547
        }
548

    
549
        public static void setPath(String path) {
550
                projectPath = path;
551
        }
552

    
553
        public IWindow getProjectWindow() {
554
                return getProjectFrame();
555
        }
556

    
557
        public IExtensionStatus getStatus() {
558
                return this;
559
        }
560

    
561
        public boolean hasUnsavedData() {
562
                return p.hasChanged();
563
        }
564

    
565
        public IUnsavedData[] getUnsavedData() {
566
                if (hasUnsavedData()) {
567
                        UnsavedProject data = new UnsavedProject(this);
568
                        IUnsavedData[] dataArray = { data };
569
                        return dataArray;
570
                } else {
571
                        return null;
572
                }
573
        }
574

    
575
        /**
576
         * Implements the IUnsavedData interface to show unsaved projects in the
577
         * Unsavad Data dialog.
578
         * 
579
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
580
         */
581
        public class UnsavedProject extends UnsavedData {
582

    
583
                public UnsavedProject(IExtension extension) {
584
                        super(extension);
585
                }
586

    
587
                public String getDescription() {
588
                        if (getPath() == null) {
589
                                return PluginServices.getText(ProjectExtension.this,
590
                                                "Unnamed_new_gvsig_project_");
591
                        } else {
592
                                return PluginServices.getText(ProjectExtension.this,
593
                                                "Modified_project_");
594
                        }
595
                }
596

    
597
                public String getResourceName() {
598
                        if (getPath() == null) {
599
                                return PluginServices.getText(ProjectExtension.this, "Unnamed");
600
                        } else {
601
                                return getPath();
602
                        }
603

    
604
                }
605

    
606
                public boolean saveData() {
607
                        return saveProject();
608
                }
609

    
610
                public String getIcon() {
611
                        return "project-icon";
612
                }
613
        }
614

    
615
        public IMonitorableTask[] getRunningProcesses() {
616
                // TODO Auto-generated method stub
617
                return null;
618
        }
619

    
620
        public boolean hasRunningProcesses() {
621
                // TODO Auto-generated method stub
622
                return false;
623
        }
624

    
625
        /**
626
         * Adds the specified before saving listener to receive
627
         * "before saving file events" from this component. If l is null, no
628
         * exception is thrown and no action is performed.
629
         * 
630
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
631
         * 
632
         * @param l
633
         *            the before saving listener.
634
         * @see SaveEvent
635
         * @see BeforeSavingListener
636
         * @see #removeListener(BeforeSavingListener)
637
         * @see #getBeforeSavingListeners
638
         */
639
        public synchronized void addListener(BeforeSavingListener l) {
640
                if (l == null) {
641
                        return;
642
                }
643
                if (!this.beforeSavingListeners.contains(l)) {
644
                        this.beforeSavingListeners.add(l);
645
                }
646
        }
647

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

    
667
                if (!this.afterSavingListeners.contains(l)) {
668
                        this.afterSavingListeners.add(l);
669
                }
670

    
671
        }
672

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

    
690
        /**
691
         * Returns an array of all the after saving listeners registered on this
692
         * component.
693
         * 
694
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
695
         * 
696
         * @return all of this component's <code>AfterSavingListener</code>s or an
697
         *         empty array if no key listeners are currently registered
698
         * 
699
         * @see #addAfterSavingListener(AfterSavingListener)
700
         * @see #removeAfterSavingListener
701
         */
702
        public synchronized AfterSavingListener[] getAfterSavingListeners() {
703
                return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
704

    
705
        }
706

    
707
        /**
708
         * Removes the specified before saving listener so that it no longer
709
         * receives save file events from this component. This method performs no
710
         * function, nor does it throw an exception, if the listener specified by
711
         * the argument was not previously added to this component. If listener
712
         * <code>l</code> is <code>null</code>, no exception is thrown and no action
713
         * is performed.
714
         * 
715
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
716
         * 
717
         * @param l
718
         *            the before saving listener
719
         * @see SaveEvent
720
         * @see BeforeSavingListener
721
         * @see #addListener(BeforeSavingListener)
722
         * @see #getBeforeSavingListeners()
723
         */
724
        public synchronized void removeListener(BeforeSavingListener l) {
725
                if (l == null) {
726
                        return;
727
                }
728

    
729
                this.beforeSavingListeners.remove(l);
730
        }
731

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

    
753
                this.afterSavingListeners.remove(l);
754
        }
755

    
756
        /**
757
         * Reports a before saving file event.
758
         * 
759
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
760
         * 
761
         * @param evt
762
         *            the before saving file event
763
         */
764
        protected void fireBeforeSavingFileEvent(SaveEvent evt) {
765
                if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
766
                        return;
767
                }
768

    
769
                Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
770
                                .iterator();
771

    
772
                while (iter.hasNext()) {
773
                        iter.next().beforeSaving(evt);
774
                }
775
        }
776

    
777
        /**
778
         * Reports a after saving file event.
779
         * 
780
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
781
         * 
782
         * @param evt
783
         *            the after saving file event
784
         */
785
        protected void fireAfterSavingFileEvent(SaveEvent evt) {
786
                if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
787
                        return;
788
                }
789
                Iterator<AfterSavingListener> iter = this.afterSavingListeners
790
                                .iterator();
791

    
792
                while (iter.hasNext()) {
793
                        iter.next().afterSaving(evt);
794
                }
795

    
796
        }
797
}