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

History | View | Annotate | Download (32.6 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
                    application.refreshMenusAndToolBars();
447
                }
448
            });
449
        }, "LoadProject");
450
        task.start();
451
    }
452

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
634
        } else {
635

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
753
        }
754

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

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

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

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

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

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

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

    
822
    }
823

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

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

    
856
    }
857

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

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

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

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

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

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

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

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

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

    
943
    }
944
}