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

History | View | Annotate | Download (32.5 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.awt.geom.AffineTransform;
28
import java.awt.image.AffineTransformOp;
29
import java.awt.image.BufferedImage;
30
import java.io.File;
31
import java.io.IOException;
32
import java.text.MessageFormat;
33
import java.util.ArrayList;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Set;
37
import java.util.prefs.Preferences;
38
import java.util.zip.ZipFile;
39

    
40
import javax.swing.JOptionPane;
41
import javax.swing.SwingUtilities;
42
import org.apache.commons.collections.CollectionUtils;
43
import org.apache.commons.io.FilenameUtils;
44

    
45
import org.slf4j.Logger;
46
import org.slf4j.LoggerFactory;
47

    
48
import org.gvsig.tools.util.ArrayUtils;
49

    
50
import org.apache.commons.lang.StringUtils;
51

    
52
import org.gvsig.andami.IconThemeHelper;
53
import org.gvsig.andami.Launcher;
54
import org.gvsig.andami.Launcher.TerminationProcess;
55
import org.gvsig.andami.PluginServices;
56
import org.gvsig.andami.PluginsLocator;
57
import org.gvsig.andami.PluginsManager;
58
import org.gvsig.andami.actioninfo.ActionInfo;
59
import org.gvsig.andami.actioninfo.ActionInfoManager;
60
import org.gvsig.andami.plugins.Extension;
61
import org.gvsig.andami.plugins.IExtension;
62
import org.gvsig.andami.plugins.status.IExtensionStatus;
63
import org.gvsig.andami.plugins.status.IUnsavedData;
64
import org.gvsig.andami.plugins.status.UnsavedData;
65
import org.gvsig.andami.ui.mdiManager.IWindow;
66
import org.gvsig.andami.ui.mdiManager.WindowInfo;
67
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
68
import org.gvsig.app.ApplicationLocator;
69
import org.gvsig.app.ApplicationManager;
70
import org.gvsig.app.gui.ProjectPreviewPanel;
71
import org.gvsig.app.project.Project;
72
import org.gvsig.app.project.ProjectManager;
73
import org.gvsig.app.project.documents.gui.ProjectWindow;
74
import org.gvsig.app.project.documents.gui.projectpanel.ProjectDocumentsPanelPageFactory;
75
import org.gvsig.app.project.documents.view.ViewManager;
76
import org.gvsig.filedialogchooser.FileDialogChooser;
77
import org.gvsig.filedialogchooser.FileDialogChooserManager;
78
import org.gvsig.gui.beans.swing.JFileChooser;
79
import org.gvsig.propertypage.PropertiesPageManager;
80
import org.gvsig.tools.ToolsLocator;
81
import org.gvsig.tools.dataTypes.DataTypes;
82
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
83
import org.gvsig.tools.folders.FoldersManager;
84
import org.gvsig.tools.i18n.I18nManager;
85
import org.gvsig.tools.locator.LocatorException;
86
import org.gvsig.tools.util.ToolsUtilLocator;
87
import org.gvsig.utils.GenericFileFilter;
88
import org.gvsig.utils.save.AfterSavingListener;
89
import org.gvsig.utils.save.BeforeSavingListener;
90
import org.gvsig.utils.save.SaveEvent;
91
import org.gvsig.utils.swing.threads.IMonitorableTask;
92

    
93
/**
94
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
95
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos en
96
 * esta clase.
97
 *
98
 */
99
public class ProjectExtension extends Extension implements IExtensionStatus {
100

    
101
    private static final Logger LOG = LoggerFactory
102
            .getLogger(ProjectExtension.class);
103

    
104
    private static String projectPath = null;
105
    private ProjectWindow projectFrame;
106
    private Project p;
107
    private String lastSavePath;
108
    private WindowInfo seedProjectWindow;
109
    public static final String PROJECT_FILE_CHOOSER_ID = "PROJECT_FILECHOOSER_ID";
110
    /**
111
     * Use UTF-8 for encoding, as it can represent characters from any language.
112
     *
113
     * Another sensible option would be encoding =
114
     * System.getProperty("file.encoding"); but this would need some extra
115
     * testing.
116
     *
117
     * @deprecated see PersistentManager
118
     */
119
    public static String PROJECTENCODING = "UTF-8";
120

    
121
    private final List<BeforeSavingListener> beforeSavingListeners;
122

    
123
    private final List<AfterSavingListener> afterSavingListeners;
124

    
125
    public ProjectExtension() {
126
        this.afterSavingListeners = new ArrayList<>();
127
        this.beforeSavingListeners = new ArrayList<>();
128
    }
129

    
130
    @Override
131
    public void initialize() {
132
        initializeDocumentActionsExtensionPoint();
133
        registerDocuments();
134
        registerIcons();
135

    
136
        PropertiesPageManager propertiesManager = ToolsUtilLocator.getPropertiesPageManager();
137
        propertiesManager.registerFactory(new ProjectDocumentsPanelPageFactory());
138

    
139
        File projectFile = getProjectFileFromArguments();
140
        if (projectFile != null) {
141
            // Posponemos la apertura del proyecto ya que en este momento
142
            // puede que no este inicializado algun plugin que precise el
143
            // proyecto para poderse cargar.
144
            PluginsLocator.getManager().addStartupTask(
145
                    "Open project",
146
                    new OpenInitialProjectTask(projectFile), true, 1000);
147
        }
148
    }
149

    
150
    private void registerIcons() {
151
        IconThemeHelper.registerIcon("action", "application-project-new", this);
152
        IconThemeHelper
153
                .registerIcon("action", "application-project-open", this);
154
        IconThemeHelper
155
                .registerIcon("action", "application-project-save", this);
156
        IconThemeHelper.registerIcon("action", "application-project-save-as",
157
                this);
158

    
159
        IconThemeHelper.registerIcon("project", "project-icon", this);
160
        IconThemeHelper.registerIcon("project", "temporary-table-icon", this);
161
    }
162

    
163
    /**
164
     * Returns the file to be opened or null if no parameter or file does not
165
     * exist
166
     *
167
     * @return
168
     */
169
    private File getProjectFileFromArguments() {
170
        String[] theArgs = PluginServices.getArguments();
171
        if (theArgs.length < 3) {
172
            // application-name and extensions-folder are fixed arguments
173
            return null;
174
        }
175
        String lastArg = theArgs[theArgs.length - 1];
176
        if (StringUtils.isEmpty(lastArg)) {
177
            return null;
178
        }
179
        if (lastArg.startsWith("-")) {
180
            // Args starts with "-" are flags
181
            return null;
182
        }
183
        if (!lastArg.toLowerCase().endsWith(Project.FILE_EXTENSION.toLowerCase())) {
184
            LOG.info("Do not open project file, does not have the expected extension '"
185
                    + Project.FILE_EXTENSION + "' (" + lastArg + ").");
186
            return null;
187
        }
188
        File projectFile = new File(lastArg);
189
        if (!projectFile.exists()) {
190
            LOG.info("Do not open project file, '" + projectFile.getAbsolutePath() + "' do not exist.");
191
            return null;
192
        }
193
        return projectFile;
194
    }
195

    
196
    private class OpenInitialProjectTask implements Runnable {
197

    
198
        private final File projectFile;
199

    
200
        public OpenInitialProjectTask(File projectFile) {
201
            this.projectFile = projectFile;
202
        }
203

    
204
        @Override
205
        public void run() {
206
            if (this.projectFile == null) {
207
                return;
208
            }
209
            ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
210
            ActionInfo action = actionManager.getAction("application-project-open");
211
            action.execute(this.projectFile);
212
        }
213
    }
214

    
215
    public ProjectWindow getProjectFrame() {
216
        if (projectFrame == null) {
217
            projectFrame = new ProjectWindow();
218
        }
219
        return projectFrame;
220
    }
221

    
222
    /**
223
     * Muestra la ventana con el gestor de proyectos.
224
     */
225
    public void showProjectWindow() {
226
        if (seedProjectWindow != null) {
227
            if (seedProjectWindow.isClosed()) {
228
                // if it was closed, we just don't open the window now
229
                seedProjectWindow.setClosed(false);
230
                return;
231
            }
232
            WindowInfo winProps = seedProjectWindow;
233
            seedProjectWindow = null;
234
            PluginServices.getMDIManager().addWindow(getProjectFrame());
235
            PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
236
                    winProps);
237
        } else {
238
            PluginServices.getMDIManager().addWindow(getProjectFrame());
239
        }
240
    }
241

    
242
    /**
243
     * Muestra la ventana con el gestor de proyectos, con las propiedades de
244
     * ventana especificadas.
245
     * @param wi
246
     */
247
    public void showProjectWindow(WindowInfo wi) {
248
        seedProjectWindow = wi;
249
        showProjectWindow();
250
    }
251

    
252
    /**
253
     * Guarda el proyecto actual en disco.
254
     */
255
    private boolean saveProject() {
256
        boolean saved;
257
        if (projectPath == null) {
258
            saved = saveAsProject(null);
259
        } else {
260
            long t1, t2;
261
            t1 = System.currentTimeMillis();
262
            saved = writeProject(new File(projectPath), p, false);
263
            t2 = System.currentTimeMillis();
264
            PluginServices.getLogger().info(
265
                    "Project saved. " + (t2 - t1) + " miliseconds");
266
            getProjectFrame().setProject(p);
267
        }
268
        return saved;
269
    }
270

    
271
    private boolean saveAsProject(File file) {
272
        boolean saved = false;
273

    
274
        if (lastSavePath == null) {
275
            lastSavePath = projectPath;
276
        }
277

    
278
        if (file == null) {
279
            FileDialogChooserManager fileDialogChooserManager = ToolsUtilLocator.getFileDialogChooserManager();
280
            FileDialogChooser jfc = fileDialogChooserManager.create(PROJECT_FILE_CHOOSER_ID);
281
            if (lastSavePath == null) {
282
                jfc.setCurrentDirectory(getPreferredProjectsFolder());
283
            } else {
284
                jfc.setCurrentDirectory(new File(lastSavePath));
285
            }
286
            jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
287

    
288
            GenericFileFilter projExtensionFilter = new GenericFileFilter(
289
                    Project.FILE_EXTENSION, MessageFormat.format(PluginServices
290
                            .getText(this, "tipo_fichero_proyecto"),
291
                            Project.FILE_EXTENSION));
292
            jfc.addChoosableFileFilter(projExtensionFilter);
293
            jfc.setFileFilter(projExtensionFilter);
294
            
295
            if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
296
                return saved;
297
            }
298
            file = jfc.getSelectedFile();
299
        }
300

    
301
        if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
302
                .toLowerCase()))) {
303
            file = new File(file.getPath() + Project.FILE_EXTENSION);
304
        }
305
        saved = writeProject(file, p);
306
        String filePath = file.getAbsolutePath();
307
        lastSavePath = FilenameUtils.getPath(filePath);
308

    
309
        getProjectFrame().setProject(p);
310
        return saved;
311
    }
312

    
313
    /**
314
     * Checks whether the project and related unsaved data is modified, and
315
     * allows the user to save it.
316
     *
317
     * @return true if the data has been correctly saved, false otherwise
318
     */
319
    private boolean askSave() {
320
        if (p != null && p.hasChanged()) {
321
            TerminationProcess process = Launcher.getTerminationProcess();
322
            UnsavedDataPanel panel = process.getUnsavedDataPanel();
323
            panel.setHeaderText(PluginServices.getText(this,
324
                    "_Select_resources_to_save_before_closing_current_project"));
325
            panel.setAcceptText(
326
                    PluginServices.getText(this, "save_resources"),
327
                    PluginServices
328
                            .getText(this,
329
                                    "Save_the_selected_resources_and_close_current_project"));
330
            panel.setCancelText(PluginServices.getText(this, "Cancel"),
331
                    PluginServices.getText(this, "Return_to_current_project"));
332
            int closeCurrProj;
333
            try {
334
                closeCurrProj = process.manageUnsavedData();
335
                if (closeCurrProj == JOptionPane.NO_OPTION) {
336
                    // the user chose to return to current project
337
                    return false;
338
                }
339
            } catch (Exception e) {
340
                LOG.error("Some data can not be saved", e);
341
            }
342
        }
343
        return true;
344
    }
345

    
346
    @Override
347
    public void execute(String command) {
348
        this.execute(command, null);
349
    }
350

    
351
    @Override
352
    public void execute(String actionCommand, Object[] args) {
353
        ApplicationManager application = ApplicationLocator.getApplicationManager();
354
        I18nManager i18n = ToolsLocator.getI18nManager();
355
        
356
        switch (actionCommand) {
357
            case "application-project-new":
358
                if (!askSave()) {
359
                    return;
360
                }   projectPath = null;
361
                application.getUIManager().closeAllWindows();
362
                setProject(ProjectManager.getInstance().createProject());
363
                showProjectWindow();
364
                application.getMainFrame().setTitle(i18n.getTranslation("sin_titulo"));
365
                break;
366
            case "application-project-open":
367
                if (!askSave()) {
368
                    return;
369
                }   
370
                File projectFile = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
371
                if (projectFile != null && !projectFile.exists()) {
372
                    LOG.warn("Can't load project '" + projectFile.getAbsolutePath() + "', file not exist.");
373
                    projectFile = null;
374
                }   if (projectFile == null) {
375
                    FileDialogChooserManager fileDialogChooserManager = ToolsUtilLocator.getFileDialogChooserManager();
376
                    FileDialogChooser jfc = fileDialogChooserManager.create(PROJECT_FILE_CHOOSER_ID);
377
                    if (lastSavePath == null) {
378
                        jfc.setCurrentDirectory(getPreferredProjectsFolder());
379
                    } else {
380
                        jfc.setCurrentDirectory(new File(lastSavePath));
381
                    }
382
                    ProjectPreviewPanel preview = new ProjectPreviewPanel();
383
                    jfc.setAccessory(preview);
384
                    jfc.addPropertyChangeListener(preview);
385
                    
386
                    GenericFileFilter projExtensionFilter
387
                            = new GenericFileFilter(Project.FILE_EXTENSION, i18n.getTranslation("tipo_fichero_proyecto"));
388
                    jfc.addChoosableFileFilter(projExtensionFilter);
389
                    GenericFileFilter bakExtensionFilter
390
                            = new GenericFileFilter(Project.FILE_BAK, i18n.getTranslation("tipo_fichero_proyecto_bak"));
391
                    jfc.addChoosableFileFilter(bakExtensionFilter);
392
                    jfc.setFileFilter(projExtensionFilter);
393
                    
394
                    if (jfc.showOpenDialog((Component) application.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
395
                        return;
396
                    }
397
                    projectFile = jfc.getSelectedFile();
398
                }   
399
                setProject(ProjectManager.getInstance().createProject());
400
                loadProject(projectFile);
401
                break;
402

    
403
            case "application-project-save":
404
                // saveProject();
405
                try {
406
                    Launcher.manageUnsavedData("there_are_unsaved_resources");
407
                } catch (Exception e) {
408
                    LOG.warn("Can't manage unsaved data", e);
409
                }   break;
410
            case "application-project-save-as":
411
                File file = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
412
                saveAsProject(file);
413
                break;
414
            default:
415
                break;
416
        }
417

    
418
    }
419
    
420
    private void loadProject(File projectFile) {
421
        ApplicationManager application = ApplicationLocator.getApplicationManager();
422
        application.getUIManager().closeAllWindows();
423
        PluginsLocator.getActionInfoManager().setAllDisabled(true);
424
        application.refreshMenusAndToolBars();
425
        Thread task = new Thread(() -> {
426
            Project o = readProject(projectFile);
427
            SwingUtilities.invokeLater(new Runnable() {
428
                @Override
429
                public void run() {
430
                    try {
431
                        if ("bak".equals(FilenameUtils.getExtension(projectFile.getAbsolutePath()))) {
432
                            setPath(null);
433
                        } else {
434
                            setPath(projectFile.getAbsolutePath());
435
                        }
436
                        if (o != null) {
437
                            setProject(o);
438
                        }   
439
                        getProjectFrame().setProject(p);
440
                        application.getMainFrame().setTitle(projectFile.getName());
441
                    } finally {
442
                        PluginsLocator.getActionInfoManager().setAllDisabled(false);
443
                        application.message("", JOptionPane.INFORMATION_MESSAGE);
444
                        application.refreshMenusAndToolBars();
445
                    }
446
                }
447
            });
448
        }, "LoadProject");
449
        task.start();
450
    }
451

    
452
    private File getPreferredProjectsFolder() throws LocatorException {
453
        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
454
        FoldersManager folderManager = ToolsLocator.getFoldersManager();
455
        String v;
456
        
457
        v = prefs.get(InitializeApplicationExtension.PROJECTS_FOLDER_PROPERTY_NAME, folderManager.getHome().getAbsolutePath());
458
        return new File(v);
459
    }
460

    
461
    private void createEmptyProject() {
462
        setProject(ProjectManager.getInstance().createProject());
463
        p.setName(PluginServices.getText(this, "untitled"));
464
        p.setModified(false);
465
        PluginServices.getMainFrame().setTitle(
466
                PluginServices.getText(this, "sin_titulo"));
467
        setProject(p);
468
        showProjectWindow();
469
    }
470

    
471
    @Override
472
    public void postInitialize() {
473
        PluginsManager pluginsManager = PluginsLocator.getManager();
474
        pluginsManager.addStartupTask("createEmptyProject", () -> {
475
            createEmptyProject();
476
        },
477
                true,
478
                1000
479
        );
480
    }
481

    
482
    /**
483
     * Escribe el proyecto en XML.
484
     *
485
     * @param file Fichero.
486
     * @param p Proyecto.
487
     * @return 
488
     */
489
    public boolean writeProject(File file, Project p) {
490
        return writeProject(file, p, true);
491
    }
492

    
493
    /**
494
     * Escribe el proyecto en disco. Pero permite decidir si se pide
495
     * confirmaci?n para sobreescribir
496
     *
497
     * @param file Fichero.
498
     * @param p Proyecto.
499
     * @param askConfirmation boolean
500
     * @return
501
     */
502
    public boolean writeProject(File file, Project p, boolean askConfirmation) {
503
        I18nManager i18n = ToolsLocator.getI18nManager();
504
        ApplicationManager application = ApplicationLocator.getManager();
505
        if (askConfirmation && file.exists()) {
506
            int resp = application.confirmDialog(
507
                    i18n.getTranslation("fichero_ya_existe_seguro_desea_guardarlo"),
508
                    i18n.getTranslation("guardar"),
509
                    JOptionPane.YES_NO_OPTION,
510
                    JOptionPane.QUESTION_MESSAGE,
511
                    "Overwrite_project_file"
512
            );
513
            if (resp != JOptionPane.YES_OPTION) {
514
                return false;
515
            }
516
        }
517
        LOG.info("Writing project '" + file.getAbsolutePath() + "'.");
518
        try {
519
            fireBeforeSavingFileEvent(new SaveEvent(this, SaveEvent.BEFORE_SAVING, file));
520
            BufferedImage img = ApplicationLocator.getManager().getUIManager().getImagePreview();
521
            img = scale(img, 0.40);
522
            p.saveState(file, img);
523

    
524
            PluginServices.getMainFrame().setTitle(file.getName());
525
            setPath(file.toString());
526

    
527
        } catch (LocatorException e) {
528
            application.messageDialog(
529
                    i18n.getTranslation("_Problems_saving_the_project_XnlX_It_is_possible_that_this_was_not_saved_properly_and_can_not_be_loaded_again"),
530
                    null,
531
                    i18n.getTranslation("guardar"),
532
                    JOptionPane.ERROR_MESSAGE,
533
                    "Problems_saving_the_project"
534
            );
535
            LOG.warn("Error writing project '" + file.getAbsolutePath() + "'.", e);
536
            return false;
537
        }
538
        LOG.warn("Wrote project '" + file.getAbsolutePath() + "'.");
539
        return true;
540
    }
541

    
542
    boolean isValidZIP(final File file) {
543
        ZipFile zipfile = null;
544
        try {
545
            zipfile = new ZipFile(file);
546
            return true;
547
        } catch (IOException e) {
548
            return false;
549
        } finally {
550
            try {
551
                if (zipfile != null) {
552
                    zipfile.close();
553
                }
554
            } catch (IOException e) {
555
            }
556
        }
557
    }
558

    
559
    private BufferedImage scale(BufferedImage before, double factor) {
560
        int w = (int) (before.getWidth() * factor);
561
        int h = (int) (before.getHeight() * factor);
562
        BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
563
        AffineTransform at = new AffineTransform();
564
        at.scale(factor, factor);
565
        AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
566
        after = scaleOp.filter(before, after);
567
        return after;
568
    }
569

    
570
    public Project readProject(String path) {
571
        Project project = ProjectManager.getInstance().createProject();
572

    
573
        project.loadState(new File(path));
574
        return (Project) project;
575
    }
576

    
577
    /**
578
     * Lee del XML el proyecto.<br>
579
     * <br>
580
     *
581
     * Reads the XML of the project.<br>
582
     * It returns a project object holding all needed info that is not linked to
583
     * the Project Dialog. <br>
584
     * In case you want the project to be linked to the window you must set this
585
     * object to the extension:<br>
586
     *
587
     * <b>Example:</b><br>
588
     *
589
     * ...<br>
590
     * .
591
     * ..<br>
592
     * Project p = ProjectExtension.readProject(projectFile);<br>
593
     * ProjectExtension.setProject(p); ...<br>
594
     * .
595
     * ..<br>
596
     *
597
     * @param file Fichero.
598
     *
599
     * @return Project
600
     *
601
     */
602
    public Project readProject(File file) {
603
        Project project = ProjectManager.getInstance().createProject();
604

    
605
        project.loadState(file);
606
        Set<String> unloadedObjects = project.getUnloadedObjects();
607
        List<Exception> errors = project.getLoadErrors();
608

    
609
        if (!CollectionUtils.isEmpty(unloadedObjects)) {
610
            StringBuilder builder = new StringBuilder();
611
            builder.append("Unloaded elements loading the project:\n");
612
            Iterator<String> it = unloadedObjects.iterator();
613
            while (it.hasNext()) {
614
                builder.append("\t");
615
                builder.append(it.next());
616
                builder.append("\n");
617
            }
618

    
619
            LOG.warn(builder.toString());
620
        }
621
        if (!CollectionUtils.isEmpty(unloadedObjects) || !CollectionUtils.isEmpty(errors)) {
622
            ApplicationManager application = ApplicationLocator.getManager();
623
            I18nManager i18nManager = ToolsLocator.getI18nManager();
624

    
625
            application.messageDialog(
626
                    i18nManager.getTranslation("_some_project_elements_could_not_be_loaded") + "\n"
627
                    + i18nManager.getTranslation("_maybe_you_need_to_install_any_plugins") + "\n"
628
                    + i18nManager.getTranslation("_Recovered_data_may_be_corrupted") + "\n\n"
629
                    + i18nManager.getTranslation("_see_error_log_for_more_information"),
630
                    i18nManager.getTranslation("warning"),
631
                    JOptionPane.WARNING_MESSAGE);
632

    
633
        } else {
634

    
635
        }
636
        return (Project) project;
637
    }
638

    
639
    /**
640
     * Devuelve el proyecto.
641
     *
642
     * @return Proyecto.
643
     */
644
    public Project getProject() {
645
        return p;
646
    }
647

    
648
    /**
649
     * @see org.gvsig.andami.plugins.IExtension#isEnabled()
650
     */
651
    @Override
652
    public boolean isEnabled() {
653
        return true;
654
    }
655

    
656
    /**
657
     * @see org.gvsig.andami.plugins.IExtension#isVisible()
658
     */
659
    @Override
660
    public boolean isVisible() {
661
        return true;
662
    }
663

    
664
    /**
665
     * Sets the project
666
     *
667
     * @param p
668
     */
669
    public void setProject(Project p) {
670
        this.p = p;
671
        getProjectFrame().setProject(p);
672
    }
673

    
674
    private void registerDocuments() {
675
        ViewManager.register();
676
    }
677

    
678
    private void initializeDocumentActionsExtensionPoint() {
679
        ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
680
        epMan.add(
681
                "DocumentActions_View",
682
                "Context menu options of the view document list"
683
                + " in the project window "
684
                + "(register instances of "
685
                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
686
    }
687

    
688
    public static String getPath() {
689
        return projectPath;
690
    }
691

    
692
    public static void setPath(String path) {
693
        projectPath = path;
694
    }
695

    
696
    public IWindow getProjectWindow() {
697
        return getProjectFrame();
698
    }
699

    
700
    @Override
701
    public IExtensionStatus getStatus() {
702
        return this;
703
    }
704

    
705
    @Override
706
    public boolean hasUnsavedData() {
707
        return p.hasChanged();
708
    }
709

    
710
    @Override
711
    public IUnsavedData[] getUnsavedData() {
712
        if (hasUnsavedData()) {
713
            UnsavedProject data = new UnsavedProject(this);
714
            IUnsavedData[] dataArray = {data};
715
            return dataArray;
716
        } else {
717
            return null;
718
        }
719
    }
720

    
721
    /**
722
     * Implements the IUnsavedData interface to show unsaved projects in the
723
     * Unsavad Data dialog.
724
     *
725
     * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
726
     */
727
    public class UnsavedProject extends UnsavedData {
728

    
729
        public UnsavedProject(IExtension extension) {
730
            super(extension);
731
        }
732

    
733
        @Override
734
        public String getDescription() {
735
            if (getPath() == null) {
736
                return PluginServices.getText(ProjectExtension.this,
737
                        "Unnamed_new_gvsig_project_");
738
            } else {
739
                return PluginServices.getText(ProjectExtension.this,
740
                        "Modified_project_");
741
            }
742
        }
743

    
744
        @Override
745
        public String getResourceName() {
746
            if (getPath() == null) {
747
                return PluginServices.getText(ProjectExtension.this, "_Project_not_saved");
748
            } else {
749
                return getPath();
750
            }
751

    
752
        }
753

    
754
        @Override
755
        public boolean saveData() {
756
            return saveProject();
757
        }
758

    
759
        @Override
760
        public String getIcon() {
761
            return "project-icon";
762
        }
763
    }
764

    
765
    @Override
766
    public IMonitorableTask[] getRunningProcesses() {
767
        // TODO Auto-generated method stub
768
        return null;
769
    }
770

    
771
    @Override
772
    public boolean hasRunningProcesses() {
773
        // TODO Auto-generated method stub
774
        return false;
775
    }
776

    
777
    /**
778
     * Adds the specified before saving listener to receive "before saving file
779
     * events" from this component. If l is null, no exception is thrown and no
780
     * action is performed.
781
     *
782
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
783
     *
784
     * @param l the before saving listener.
785
     * @see SaveEvent
786
     * @see BeforeSavingListener
787
     * @see #removeListener(BeforeSavingListener)
788
     * @see #getBeforeSavingListeners
789
     */
790
    public synchronized void addListener(BeforeSavingListener l) {
791
        if (l == null) {
792
            return;
793
        }
794
        if (!this.beforeSavingListeners.contains(l)) {
795
            this.beforeSavingListeners.add(l);
796
        }
797
    }
798

    
799
    /**
800
     * Adds the specified after saving listener to receive "after saving file
801
     * events" from this component. If l is null, no exception is thrown and no
802
     * action is performed.
803
     *
804
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
805
     *
806
     * @param l the after saving listener.
807
     * @see SaveEvent
808
     * @see AfterSavingListener
809
     * @see #removeListener(AfterSavingListener)
810
     * @see #getAfterSavingListeners()
811
     */
812
    public synchronized void addListener(AfterSavingListener l) {
813
        if (l == null) {
814
            return;
815
        }
816

    
817
        if (!this.afterSavingListeners.contains(l)) {
818
            this.afterSavingListeners.add(l);
819
        }
820

    
821
    }
822

    
823
    /**
824
     * Returns an array of all the before saving listeners registered on this
825
     * component.
826
     *
827
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
828
     *
829
     * @return all of this component's <code>BeforeSavingListener</code>s or an
830
     * empty array if no key listeners are currently registered
831
     *
832
     * @see #addBeforeSavingListener(BeforeSavingListener)
833
     * @see #removeBeforeSavingListener(BeforeSavingListener)
834
     */
835
    public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
836
        return this.beforeSavingListeners
837
                .toArray(new BeforeSavingListener[]{});
838
    }
839

    
840
    /**
841
     * Returns an array of all the after saving listeners registered on this
842
     * component.
843
     *
844
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
845
     *
846
     * @return all of this component's <code>AfterSavingListener</code>s or an
847
     * empty array if no key listeners are currently registered
848
     *
849
     * @see #addAfterSavingListener(AfterSavingListener)
850
     * @see #removeAfterSavingListener
851
     */
852
    public synchronized AfterSavingListener[] getAfterSavingListeners() {
853
        return this.afterSavingListeners.toArray(new AfterSavingListener[]{});
854

    
855
    }
856

    
857
    /**
858
     * Removes the specified before saving listener so that it no longer
859
     * receives save file events from this component. This method performs no
860
     * function, nor does it throw an exception, if the listener specified by
861
     * the argument was not previously added to this component. If listener
862
     * <code>l</code> is <code>null</code>, no exception is thrown and no action
863
     * is performed.
864
     *
865
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
866
     *
867
     * @param l the before saving listener
868
     * @see SaveEvent
869
     * @see BeforeSavingListener
870
     * @see #addListener(BeforeSavingListener)
871
     * @see #getBeforeSavingListeners()
872
     */
873
    public synchronized void removeListener(BeforeSavingListener l) {
874
        if (l == null) {
875
            return;
876
        }
877

    
878
        this.beforeSavingListeners.remove(l);
879
    }
880

    
881
    /**
882
     * Removes the specified after saving listener so that it no longer receives
883
     * save file events from this component. This method performs no function,
884
     * nor does it throw an exception, if the listener specified by the argument
885
     * was not previously added to this component. If listener <code>l</code> is
886
     * <code>null</code>, no exception is thrown and no action is performed.
887
     *
888
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
889
     *
890
     * @param l the after saving listener
891
     * @see SaveEvent
892
     * @see AfterSavingListener
893
     * @see #addListener(AfterSavingListener)
894
     * @see #getAfterSavingListeners()
895
     */
896
    public synchronized void removeListener(AfterSavingListener l) {
897
        if (l == null) {
898
            return;
899
        }
900

    
901
        this.afterSavingListeners.remove(l);
902
    }
903

    
904
    /**
905
     * Reports a before saving file event.
906
     *
907
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
908
     *
909
     * @param evt the before saving file event
910
     */
911
    protected void fireBeforeSavingFileEvent(SaveEvent evt) {
912
        if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
913
            return;
914
        }
915

    
916
        Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
917
                .iterator();
918

    
919
        while (iter.hasNext()) {
920
            iter.next().beforeSaving(evt);
921
        }
922
    }
923

    
924
    /**
925
     * Reports a after saving file event.
926
     *
927
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
928
     *
929
     * @param evt the after saving file event
930
     */
931
    protected void fireAfterSavingFileEvent(SaveEvent evt) {
932
        if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
933
            return;
934
        }
935
        Iterator<AfterSavingListener> iter = this.afterSavingListeners
936
                .iterator();
937

    
938
        while (iter.hasNext()) {
939
            iter.next().afterSaving(evt);
940
        }
941

    
942
    }
943
}