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

History | View | Annotate | Download (25.8 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.Set;
33
import java.util.prefs.Preferences;
34

    
35
import javax.swing.JOptionPane;
36
import javax.swing.SwingUtilities;
37
import org.apache.commons.collections.CollectionUtils;
38

    
39
import org.slf4j.Logger;
40
import org.slf4j.LoggerFactory;
41

    
42
import org.gvsig.tools.util.ArrayUtils;
43

    
44
import org.apache.commons.lang.StringUtils;
45

    
46
import org.gvsig.andami.IconThemeHelper;
47
import org.gvsig.andami.Launcher;
48
import org.gvsig.andami.Launcher.TerminationProcess;
49
import org.gvsig.andami.PluginServices;
50
import org.gvsig.andami.PluginsLocator;
51
import org.gvsig.andami.actioninfo.ActionInfo;
52
import org.gvsig.andami.actioninfo.ActionInfoManager;
53
import org.gvsig.andami.messages.NotificationManager;
54
import org.gvsig.andami.plugins.Extension;
55
import org.gvsig.andami.plugins.IExtension;
56
import org.gvsig.andami.plugins.status.IExtensionStatus;
57
import org.gvsig.andami.plugins.status.IUnsavedData;
58
import org.gvsig.andami.plugins.status.UnsavedData;
59
import org.gvsig.andami.ui.mdiManager.IWindow;
60
import org.gvsig.andami.ui.mdiManager.WindowInfo;
61
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
62
import org.gvsig.app.ApplicationLocator;
63
import org.gvsig.app.ApplicationManager;
64
import org.gvsig.app.project.Project;
65
import org.gvsig.app.project.ProjectManager;
66
import org.gvsig.app.project.documents.gui.ProjectWindow;
67
import org.gvsig.app.project.documents.view.ViewManager;
68
import org.gvsig.gui.beans.swing.JFileChooser;
69
import org.gvsig.tools.ToolsLocator;
70
import org.gvsig.tools.dataTypes.DataTypes;
71
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
72
import org.gvsig.tools.i18n.I18nManager;
73
import org.gvsig.tools.persistence.exception.PersistenceException;
74
import org.gvsig.utils.GenericFileFilter;
75
import org.gvsig.utils.save.AfterSavingListener;
76
import org.gvsig.utils.save.BeforeSavingListener;
77
import org.gvsig.utils.save.SaveEvent;
78
import org.gvsig.utils.swing.threads.IMonitorableTask;
79

    
80

    
81
/**
82
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
83
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos en
84
 * esta clase.
85
 *
86
 * @author Fernando Gonz?lez Cort?s
87
 */
88
public class ProjectExtension extends Extension implements IExtensionStatus {
89
        private static final Logger LOG = LoggerFactory
90
                        .getLogger(ProjectExtension.class);
91

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

    
109
        private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
110

    
111
        private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
112

    
113
        public void initialize() {
114
            initializeDocumentActionsExtensionPoint();
115
            registerDocuments();
116
            registerIcons();
117

    
118
            File projectFile = getProjectFileFromArguments();
119
            if( projectFile!=null ) {
120
                // Posponemos la apertura del proyecto ya que en este momento
121
                // puede que no este inicializado algun plugin que precise el
122
                // proyecto para poderse cargar.
123
                PluginsLocator.getManager().addStartupTask(
124
                    "Open project",
125
                    new OpenInitialProjectTask(projectFile), true, 1000);
126
            }
127
        }
128

    
129
        private void registerIcons() {
130
                IconThemeHelper.registerIcon("action", "application-project-new", this);
131
                IconThemeHelper
132
                                .registerIcon("action", "application-project-open", this);
133
                IconThemeHelper
134
                                .registerIcon("action", "application-project-save", this);
135
                IconThemeHelper.registerIcon("action", "application-project-save-as",
136
                                this);
137

    
138
                IconThemeHelper.registerIcon("project", "project-icon", this);
139
        }
140

    
141
        /**
142
         * Returns the file to be opened or null if no parameter
143
         * or file does not exist
144
         *
145
         * @return
146
         */
147
        private File getProjectFileFromArguments() {
148
            String[] theArgs = PluginServices.getArguments();
149
            if( theArgs.length< 3 ) {
150
                // application-name and extensions-folder are fixed arguments
151
                return null;
152
            }
153
            String lastArg = theArgs[theArgs.length - 1];
154
            if ( StringUtils.isEmpty(lastArg) ) {
155
                return null;
156
            }
157
            if( lastArg.startsWith("-") ) {
158
                // Args starts with "-" are flags
159
                return null;
160
            }
161
            if (!lastArg.toLowerCase().endsWith(Project.FILE_EXTENSION.toLowerCase())) {
162
                LOG.info("Do not open project file, does not have the expected extension '" +
163
                        Project.FILE_EXTENSION +"' ("+lastArg+").");
164
                return null;
165
            }
166
            File projectFile = new File(lastArg);
167
            if ( !projectFile.exists()) {
168
                LOG.info("Do not open project file, '" +projectFile.getAbsolutePath() + "' do not exist.");
169
                return null;
170
            }
171
            return projectFile;
172
        }
173

    
174
        private class OpenInitialProjectTask implements Runnable {
175
            private File projectFile;
176
            public OpenInitialProjectTask(File projectFile) {
177
                this.projectFile = projectFile;
178
            }
179
            public void run() {
180
                if (this.projectFile == null) {
181
                    return;
182
                }
183
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
184
                ActionInfo action = actionManager.getAction("application-project-open");
185
                action.execute(this.projectFile);
186
            }
187
        }
188

    
189
        public ProjectWindow getProjectFrame() {
190
                if (projectFrame == null) {
191
                        projectFrame = new ProjectWindow();
192
                }
193
                return projectFrame;
194
        }
195

    
196
        /**
197
         * Muestra la ventana con el gestor de proyectos.
198
         */
199
        public void showProjectWindow() {
200
                if (seedProjectWindow != null) {
201
                        if (seedProjectWindow.isClosed()) {
202
                                // if it was closed, we just don't open the window now
203
                                seedProjectWindow.setClosed(false);
204
                                return;
205
                        }
206
                        WindowInfo winProps = seedProjectWindow;
207
                        seedProjectWindow = null;
208
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
209
                        PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
210
                                        winProps);
211
                } else {
212
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
213
                }
214
        }
215

    
216
        /**
217
         * Muestra la ventana con el gestor de proyectos, con las propiedades de
218
         * ventana especificadas.
219
         */
220
        public void showProjectWindow(WindowInfo wi) {
221
                seedProjectWindow = wi;
222
                showProjectWindow();
223
        }
224

    
225
        /**
226
         * Guarda el proyecto actual en disco.
227
         */
228
        private boolean saveProject() {
229
                boolean saved = false;
230
                // if (p.getPath() == null) {
231
                if (projectPath == null) {
232
                        saved = saveAsProject(null);
233
                } else {
234
                        long t1, t2;
235
                        t1 = System.currentTimeMillis();
236
                        saved = writeProject(new File(projectPath), p, false);
237
                        t2 = System.currentTimeMillis();
238
                        PluginServices.getLogger().info(
239
                                        "Project saved. " + (t2 - t1) + " miliseconds");
240
                        getProjectFrame().refreshControls();
241
                }
242
                return saved;
243
        }
244

    
245
        private boolean saveAsProject(File file) {
246
                boolean saved = false;
247

    
248
                if (lastSavePath == null) {
249
                        lastSavePath = projectPath;
250
                }
251

    
252
                if (file == null) {
253
                        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
254
                        JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
255
                                        prefs.get("ProjectsFolder", null));
256

    
257
                        jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
258

    
259
                        GenericFileFilter projExtensionFilter = new GenericFileFilter(
260
                                        Project.FILE_EXTENSION, MessageFormat.format(PluginServices
261
                                                        .getText(this, "tipo_fichero_proyecto"),
262
                                                        Project.FILE_EXTENSION));
263
      jfc.addChoosableFileFilter(projExtensionFilter);
264
      jfc.setFileFilter(projExtensionFilter);
265

    
266
                        if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
267
                                return saved;
268
                        }
269
                        file = jfc.getSelectedFile();
270
                }
271

    
272
                if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
273
                                .toLowerCase()))) {
274
                        file = new File(file.getPath() + Project.FILE_EXTENSION);
275
                }
276
                saved = writeProject(file, p);
277
                String filePath = file.getAbsolutePath();
278
                lastSavePath = filePath.substring(0,
279
                                filePath.lastIndexOf(File.separatorChar));
280

    
281
                getProjectFrame().refreshControls();
282
                return saved;
283
        }
284

    
285
        /**
286
         * Checks whether the project and related unsaved data is modified, and
287
         * allows the user to save it.
288
         *
289
         * @return true if the data has been correctly saved, false otherwise
290
         */
291
        private boolean askSave() {
292
                if (p != null && p.hasChanged()) {
293
                        TerminationProcess process = Launcher.getTerminationProcess();
294
                        UnsavedDataPanel panel = process.getUnsavedDataPanel();
295
                        panel.setHeaderText(PluginServices.getText(this,
296
                                        "_Select_resources_to_save_before_closing_current_project"));
297
                        panel.setAcceptText(
298
                                        PluginServices.getText(this, "save_resources"),
299
                                        PluginServices
300
                                                        .getText(this,
301
                                                                        "Save_the_selected_resources_and_close_current_project"));
302
                        panel.setCancelText(PluginServices.getText(this, "Cancel"),
303
                                        PluginServices.getText(this, "Return_to_current_project"));
304
                        int closeCurrProj;
305
                        try {
306
                                closeCurrProj = process.manageUnsavedData();
307
                                if (closeCurrProj == JOptionPane.NO_OPTION) {
308
                                        // the user chose to return to current project
309
                                        return false;
310
                                }
311
                        } catch (Exception e) {
312
                                LOG.error("Some data can not be saved", e);
313
                        }
314
                }
315
                return true;
316
        }
317

    
318
        public void execute(String command) {
319
                this.execute(command, null);
320
        }
321

    
322
    public void execute(String actionCommand, Object[] args) {
323
        if (actionCommand.equals("application-project-new")) {
324
            if (!askSave()) {
325
                return;
326
            }
327

    
328
            projectPath = null;
329
            PluginServices.getMDIManager().closeAllWindows();
330
            setProject(ProjectManager.getInstance().createProject());
331

    
332
            showProjectWindow();
333
            PluginServices.getMainFrame().setTitle(PluginServices.getText(this, "sin_titulo"));
334

    
335
        } else if (actionCommand.equals("application-project-open")) {
336
            if (!askSave()) {
337
                return;
338
            }
339

    
340
            setProject(ProjectManager.getInstance().createProject());
341

    
342
            File projectFile = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
343
            if (projectFile != null && !projectFile.exists()) {
344
                LOG.warn("Can't load project '" + projectFile.getAbsolutePath() + "', file not exist.");
345
                projectFile = null;
346
            }
347

    
348
            if (projectFile == null) {
349
                Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
350
                JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get("ProjectsFolder", null));
351

    
352
                GenericFileFilter projExtensionFilter =
353
                    new GenericFileFilter(Project.FILE_EXTENSION, PluginServices.getText(this, "tipo_fichero_proyecto"));
354
                jfc.addChoosableFileFilter(projExtensionFilter);
355
                jfc.setFileFilter(projExtensionFilter);
356

    
357
                if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
358
                    return;
359
                }
360
                // ProjectDocument.initializeNUMS();
361

    
362
                projectFile = jfc.getSelectedFile();
363
            }
364

    
365
            PluginServices.getMDIManager().closeAllWindows();
366

    
367
            Project o = readProject(projectFile);
368
            setPath(projectFile.getAbsolutePath());
369
            // lastPath = getPath();
370
            if (o != null) {
371
                setProject(o);
372
            }
373

    
374
            getProjectFrame().setProject(p);
375
            PluginServices.getMainFrame().setTitle(projectFile.getName());
376
            getProjectFrame().refreshControls();
377

    
378
            // p.restoreWindowProperties();
379

    
380
        } else if (actionCommand.equals("application-project-save")) {
381
            // saveProject();
382
            try {
383
                Launcher.manageUnsavedData("there_are_unsaved_resources");
384
            } catch (Exception e) {
385
                LOG.warn("Can't manage unsaved data", e);
386
            }
387
        } else if (actionCommand.equals("application-project-save-as")) {
388
            File file = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
389
            saveAsProject(file);
390
        }
391

    
392
    }
393

    
394

    
395
    private void createEmptyProject() {
396
        setProject(ProjectManager.getInstance().createProject());
397
        p.setName(PluginServices.getText(this, "untitled"));
398
        p.setModified(false);
399
        PluginServices.getMainFrame().setTitle(
400
                PluginServices.getText(this, "sin_titulo"));
401
        setProject(p);
402
        showProjectWindow();
403
    }
404

    
405
    /**
406
     * @see com.iver.mdiApp.plugins.IExtension#postInitialize()
407
     */
408
    public void postInitialize() {
409
        try {
410
            if( !SwingUtilities.isEventDispatchThread() ) {
411
                SwingUtilities.invokeAndWait(new Runnable() {
412
                    public void run() {
413
                        createEmptyProject();
414
                    }
415
                });
416
            } else {
417
                createEmptyProject();
418
            }
419
        } catch (Exception e) {
420
            LOG.warn("Can't load initial project.",e);
421
        }
422
    }
423

    
424

    
425
        /**
426
         * Escribe el proyecto en XML.
427
         *
428
         * @param file
429
         *            Fichero.
430
         * @param p
431
         *            Proyecto.
432
         */
433
        public boolean writeProject(File file, Project p) {
434
                return writeProject(file, p, true);
435
        }
436

    
437
        /**
438
         * Escribe el proyecto en XML. Pero permite decidir si se pide confirmaci?n
439
         * para sobreescribir
440
         *
441
         * @param file
442
         *            Fichero.
443
         * @param p
444
         *            Proyecto.
445
         * @param askConfirmation
446
         *            boolean
447
         */
448
        public boolean writeProject(File file, Project p, boolean askConfirmation) {
449
                if (askConfirmation && file.exists()) {
450
                        int resp = JOptionPane.showConfirmDialog((Component) PluginServices
451
                                        .getMainFrame(), PluginServices.getText(this,
452
                                        "fichero_ya_existe_seguro_desea_guardarlo"), PluginServices
453
                                        .getText(this, "guardar"), JOptionPane.YES_NO_OPTION);
454
                        if (resp != JOptionPane.YES_OPTION) {
455
                                return false;
456
                        }
457
                }
458
                NotificationManager.addInfo(PluginServices.getText(this,
459
                                "writing_project") + ": " + file.getName());
460

    
461
                // write it out as XML
462
                try {
463
                        fireBeforeSavingFileEvent(new SaveEvent(this,
464
                                        SaveEvent.BEFORE_SAVING, file));
465
                        p.saveState(file);
466
                        fireAfterSavingFileEvent(new SaveEvent(this,
467
                                        SaveEvent.AFTER_SAVING, file));
468

    
469
                        PluginServices.getMainFrame().setTitle(file.getName());
470
                        setPath(file.toString());
471

    
472
                } catch (PersistenceException e) {
473
                        String messagestack = e.getLocalizedMessageStack();
474
                        NotificationManager.addError(
475
                                        PluginServices.getText(this, "error_writing_project")
476
                                                        + ": " + file.getName() + "\n" + messagestack, e);
477
                        return false;
478
                } catch (Exception e) {
479
                        NotificationManager.addError(
480
                                        PluginServices.getText(this, "error_writing_project")
481
                                                        + ": " + file.getName(), e);
482
                        return false;
483
                }
484
                NotificationManager.addInfo(PluginServices.getText(this,
485
                                "wrote_project") + ": " + file.getName());
486
                return true;
487
        }
488

    
489
        public Project readProject(String path) {
490
                Project project = ProjectManager.getInstance().createProject();
491

    
492
                project.loadState(new File(path));
493
                return (Project) project;
494
        }
495

    
496
        /**
497
         * Lee del XML el proyecto.<br>
498
         * <br>
499
         *
500
         * Reads the XML of the project.<br>
501
         * It returns a project object holding all needed info that is not linked to
502
         * the Project Dialog. <br>
503
         * In case you want the project to be linked to the window you must set this
504
         * object to the extension:<br>
505
         *
506
         * <b>Example:</b><br>
507
         *
508
         * ...<br>
509
         * ...<br>
510
         * Project p = ProjectExtension.readProject(projectFile);<br>
511
         * ProjectExtension.setProject(p); ...<br>
512
         * ...<br>
513
         *
514
         * @param file
515
         *            Fichero.
516
         *
517
         * @return Project
518
         *
519
         */
520
        public Project readProject(File file) {
521
                Project project = ProjectManager.getInstance().createProject();
522

    
523
                project.loadState(file);
524
                Set<String> unloadedObjects = project.getUnloadedObjects();
525
        List<Exception> errors = project.getLoadErrors();
526
        
527
                if( !CollectionUtils.isEmpty(unloadedObjects) ) {
528
                    StringBuilder builder = new StringBuilder();
529
                    builder.append("Unloaded elements loading the project:\n");
530
                    Iterator<String> it = unloadedObjects.iterator();
531
                    while(it.hasNext()){
532
                builder.append("\t");
533
                        builder.append(it.next());
534
                        builder.append("\n");
535
                    }
536

    
537
                    LOG.warn(builder.toString());
538
        }
539
                if( !CollectionUtils.isEmpty(unloadedObjects) || !CollectionUtils.isEmpty(errors) ) {
540
                    ApplicationManager application = ApplicationLocator.getManager();
541
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
542

    
543
                    application.messageDialog(
544
                        i18nManager.getTranslation("_some_project_elements_could_not_be_loaded")+"\n"+
545
                        i18nManager.getTranslation("_maybe_you_need_to_install_any_plugins")+"\n"+
546
                        i18nManager.getTranslation("_Recovered_data_may_be_corrupted")+"\n\n"+
547
                        i18nManager.getTranslation("_see_error_log_for_more_information"),
548
                    i18nManager.getTranslation("warning"),
549
                    JOptionPane.WARNING_MESSAGE);
550

    
551
                } else {
552
            
553
        }
554
                return (Project) project;
555
        }
556

    
557
        /**
558
         * Devuelve el proyecto.
559
         *
560
         * @return Proyecto.
561
         */
562
        public Project getProject() {
563
                return p;
564
        }
565

    
566
        /**
567
         * @see org.gvsig.andami.plugins.IExtension#isEnabled()
568
         */
569
        public boolean isEnabled() {
570
                return true;
571
        }
572

    
573
        /**
574
         * @see org.gvsig.andami.plugins.IExtension#isVisible()
575
         */
576
        public boolean isVisible() {
577
                return true;
578
        }
579

    
580
        /**
581
         * Sets the project
582
         *
583
         * @param p
584
         */
585
        public void setProject(Project p) {
586
                this.p = p;
587
                getProjectFrame().setProject(p);
588
        }
589

    
590
        private void registerDocuments() {
591
                ViewManager.register();
592
        }
593

    
594
        private void initializeDocumentActionsExtensionPoint() {
595
                ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
596
                epMan.add(
597
                                "DocumentActions_View",
598
                                "Context menu options of the view document list"
599
                                                + " in the project window "
600
                                                + "(register instances of "
601
                                                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
602
        }
603

    
604
        public static String getPath() {
605
                return projectPath;
606
        }
607

    
608
        public static void setPath(String path) {
609
                projectPath = path;
610
        }
611

    
612
        public IWindow getProjectWindow() {
613
                return getProjectFrame();
614
        }
615

    
616
        public IExtensionStatus getStatus() {
617
                return this;
618
        }
619

    
620
        public boolean hasUnsavedData() {
621
                return p.hasChanged();
622
        }
623

    
624
        public IUnsavedData[] getUnsavedData() {
625
                if (hasUnsavedData()) {
626
                        UnsavedProject data = new UnsavedProject(this);
627
                        IUnsavedData[] dataArray = { data };
628
                        return dataArray;
629
                } else {
630
                        return null;
631
                }
632
        }
633

    
634
        /**
635
         * Implements the IUnsavedData interface to show unsaved projects in the
636
         * Unsavad Data dialog.
637
         *
638
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
639
         */
640
        public class UnsavedProject extends UnsavedData {
641

    
642
                public UnsavedProject(IExtension extension) {
643
                        super(extension);
644
                }
645

    
646
                public String getDescription() {
647
                        if (getPath() == null) {
648
                                return PluginServices.getText(ProjectExtension.this,
649
                                                "Unnamed_new_gvsig_project_");
650
                        } else {
651
                                return PluginServices.getText(ProjectExtension.this,
652
                                                "Modified_project_");
653
                        }
654
                }
655

    
656
                public String getResourceName() {
657
                        if (getPath() == null) {
658
                                return PluginServices.getText(ProjectExtension.this, "Unnamed");
659
                        } else {
660
                                return getPath();
661
                        }
662

    
663
                }
664

    
665
                public boolean saveData() {
666
                        return saveProject();
667
                }
668

    
669
                public String getIcon() {
670
                        return "project-icon";
671
                }
672
        }
673

    
674
        public IMonitorableTask[] getRunningProcesses() {
675
                // TODO Auto-generated method stub
676
                return null;
677
        }
678

    
679
        public boolean hasRunningProcesses() {
680
                // TODO Auto-generated method stub
681
                return false;
682
        }
683

    
684
        /**
685
         * Adds the specified before saving listener to receive
686
         * "before saving file events" from this component. If l is null, no
687
         * exception is thrown and no action is performed.
688
         *
689
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
690
         *
691
         * @param l
692
         *            the before saving listener.
693
         * @see SaveEvent
694
         * @see BeforeSavingListener
695
         * @see #removeListener(BeforeSavingListener)
696
         * @see #getBeforeSavingListeners
697
         */
698
        public synchronized void addListener(BeforeSavingListener l) {
699
                if (l == null) {
700
                        return;
701
                }
702
                if (!this.beforeSavingListeners.contains(l)) {
703
                        this.beforeSavingListeners.add(l);
704
                }
705
        }
706

    
707
        /**
708
         * Adds the specified after saving listener to receive
709
         * "after saving file events" from this component. If l is null, no
710
         * exception is thrown and no action is performed.
711
         *
712
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
713
         *
714
         * @param l
715
         *            the after saving listener.
716
         * @see SaveEvent
717
         * @see AfterSavingListener
718
         * @see #removeListener(AfterSavingListener)
719
         * @see #getAfterSavingListeners()
720
         */
721
        public synchronized void addListener(AfterSavingListener l) {
722
                if (l == null) {
723
                        return;
724
                }
725

    
726
                if (!this.afterSavingListeners.contains(l)) {
727
                        this.afterSavingListeners.add(l);
728
                }
729

    
730
        }
731

    
732
        /**
733
         * Returns an array of all the before saving listeners registered on this
734
         * component.
735
         *
736
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
737
         *
738
         * @return all of this component's <code>BeforeSavingListener</code>s or an
739
         *         empty array if no key listeners are currently registered
740
         *
741
         * @see #addBeforeSavingListener(BeforeSavingListener)
742
         * @see #removeBeforeSavingListener(BeforeSavingListener)
743
         */
744
        public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
745
                return this.beforeSavingListeners
746
                                .toArray(new BeforeSavingListener[] {});
747
        }
748

    
749
        /**
750
         * Returns an array of all the after saving listeners registered on this
751
         * component.
752
         *
753
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
754
         *
755
         * @return all of this component's <code>AfterSavingListener</code>s or an
756
         *         empty array if no key listeners are currently registered
757
         *
758
         * @see #addAfterSavingListener(AfterSavingListener)
759
         * @see #removeAfterSavingListener
760
         */
761
        public synchronized AfterSavingListener[] getAfterSavingListeners() {
762
                return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
763

    
764
        }
765

    
766
        /**
767
         * Removes the specified before saving listener so that it no longer
768
         * receives save file events from this component. This method performs no
769
         * function, nor does it throw an exception, if the listener specified by
770
         * the argument was not previously added to this component. If listener
771
         * <code>l</code> is <code>null</code>, no exception is thrown and no action
772
         * is performed.
773
         *
774
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
775
         *
776
         * @param l
777
         *            the before saving listener
778
         * @see SaveEvent
779
         * @see BeforeSavingListener
780
         * @see #addListener(BeforeSavingListener)
781
         * @see #getBeforeSavingListeners()
782
         */
783
        public synchronized void removeListener(BeforeSavingListener l) {
784
                if (l == null) {
785
                        return;
786
                }
787

    
788
                this.beforeSavingListeners.remove(l);
789
        }
790

    
791
        /**
792
         * Removes the specified after saving listener so that it no longer receives
793
         * save file events from this component. This method performs no function,
794
         * nor does it throw an exception, if the listener specified by the argument
795
         * was not previously added to this component. If listener <code>l</code> is
796
         * <code>null</code>, no exception is thrown and no action is performed.
797
         *
798
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
799
         *
800
         * @param l
801
         *            the after saving listener
802
         * @see SaveEvent
803
         * @see AfterSavingListener
804
         * @see #addListener(AfterSavingListener)
805
         * @see #getAfterSavingListeners()
806
         */
807
        public synchronized void removeListener(AfterSavingListener l) {
808
                if (l == null) {
809
                        return;
810
                }
811

    
812
                this.afterSavingListeners.remove(l);
813
        }
814

    
815
        /**
816
         * Reports a before saving file event.
817
         *
818
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
819
         *
820
         * @param evt
821
         *            the before saving file event
822
         */
823
        protected void fireBeforeSavingFileEvent(SaveEvent evt) {
824
                if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
825
                        return;
826
                }
827

    
828
                Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
829
                                .iterator();
830

    
831
                while (iter.hasNext()) {
832
                        iter.next().beforeSaving(evt);
833
                }
834
        }
835

    
836
        /**
837
         * Reports a after saving file event.
838
         *
839
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
840
         *
841
         * @param evt
842
         *            the after saving file event
843
         */
844
        protected void fireAfterSavingFileEvent(SaveEvent evt) {
845
                if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
846
                        return;
847
                }
848
                Iterator<AfterSavingListener> iter = this.afterSavingListeners
849
                                .iterator();
850

    
851
                while (iter.hasNext()) {
852
                        iter.next().afterSaving(evt);
853
                }
854

    
855
        }
856
}