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

History | View | Annotate | Download (28.5 KB)

1 40558 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40558 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
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 40558 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * 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 40558 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24
package org.gvsig.app.extension;
25
26
import java.awt.Component;
27 43506 jjdelcerro
import java.awt.geom.AffineTransform;
28
import java.awt.image.AffineTransformOp;
29
import java.awt.image.BufferedImage;
30 40435 jjdelcerro
import java.io.File;
31 43506 jjdelcerro
import java.io.FileOutputStream;
32
import java.io.IOException;
33 40435 jjdelcerro
import java.text.MessageFormat;
34
import java.util.ArrayList;
35
import java.util.Iterator;
36
import java.util.List;
37 42711 fdiaz
import java.util.Set;
38 40435 jjdelcerro
import java.util.prefs.Preferences;
39 43506 jjdelcerro
import java.util.zip.ZipEntry;
40 43820 jjdelcerro
import java.util.zip.ZipException;
41
import java.util.zip.ZipFile;
42 43506 jjdelcerro
import java.util.zip.ZipOutputStream;
43
import javax.imageio.ImageIO;
44 40435 jjdelcerro
45
import javax.swing.JOptionPane;
46 41076 jjdelcerro
import javax.swing.SwingUtilities;
47 43439 jjdelcerro
import org.apache.commons.collections.CollectionUtils;
48 43506 jjdelcerro
import org.apache.commons.io.IOUtils;
49 40435 jjdelcerro
50
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52 42200 fdiaz
53 41312 jjdelcerro
import org.gvsig.tools.util.ArrayUtils;
54 42200 fdiaz
55 41312 jjdelcerro
import org.apache.commons.lang.StringUtils;
56 42200 fdiaz
57 40435 jjdelcerro
import org.gvsig.andami.IconThemeHelper;
58
import org.gvsig.andami.Launcher;
59
import org.gvsig.andami.Launcher.TerminationProcess;
60
import org.gvsig.andami.PluginServices;
61 41312 jjdelcerro
import org.gvsig.andami.PluginsLocator;
62
import org.gvsig.andami.actioninfo.ActionInfo;
63
import org.gvsig.andami.actioninfo.ActionInfoManager;
64 40435 jjdelcerro
import org.gvsig.andami.messages.NotificationManager;
65
import org.gvsig.andami.plugins.Extension;
66
import org.gvsig.andami.plugins.IExtension;
67
import org.gvsig.andami.plugins.status.IExtensionStatus;
68
import org.gvsig.andami.plugins.status.IUnsavedData;
69
import org.gvsig.andami.plugins.status.UnsavedData;
70
import org.gvsig.andami.ui.mdiManager.IWindow;
71
import org.gvsig.andami.ui.mdiManager.WindowInfo;
72
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
73 42711 fdiaz
import org.gvsig.app.ApplicationLocator;
74
import org.gvsig.app.ApplicationManager;
75 43506 jjdelcerro
import org.gvsig.app.gui.ProjectPreviewPanel;
76 40435 jjdelcerro
import org.gvsig.app.project.Project;
77
import org.gvsig.app.project.ProjectManager;
78
import org.gvsig.app.project.documents.gui.ProjectWindow;
79
import org.gvsig.app.project.documents.view.ViewManager;
80
import org.gvsig.gui.beans.swing.JFileChooser;
81
import org.gvsig.tools.ToolsLocator;
82 41312 jjdelcerro
import org.gvsig.tools.dataTypes.DataTypes;
83 40435 jjdelcerro
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
84 42711 fdiaz
import org.gvsig.tools.i18n.I18nManager;
85 40435 jjdelcerro
import org.gvsig.tools.persistence.exception.PersistenceException;
86
import org.gvsig.utils.GenericFileFilter;
87
import org.gvsig.utils.save.AfterSavingListener;
88
import org.gvsig.utils.save.BeforeSavingListener;
89
import org.gvsig.utils.save.SaveEvent;
90
import org.gvsig.utils.swing.threads.IMonitorableTask;
91
92 41313 jjdelcerro
93 40435 jjdelcerro
/**
94
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
95 41076 jjdelcerro
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos en
96
 * esta clase.
97 42200 fdiaz
 *
98 40435 jjdelcerro
 */
99
public class ProjectExtension extends Extension implements IExtensionStatus {
100 41076 jjdelcerro
        private static final Logger LOG = LoggerFactory
101
                        .getLogger(ProjectExtension.class);
102 40435 jjdelcerro
103 41076 jjdelcerro
        private static String projectPath = null;
104
        private ProjectWindow projectFrame;
105
        private Project p;
106
        private String lastSavePath;
107
        private WindowInfo seedProjectWindow;
108
        public static final String PROJECT_FILE_CHOOSER_ID = "PROJECT_FILECHOOSER_ID";
109
        /**
110
         * Use UTF-8 for encoding, as it can represent characters from any language.
111 42200 fdiaz
         *
112 41076 jjdelcerro
         * Another sensible option would be encoding =
113
         * System.getProperty("file.encoding"); but this would need some extra
114
         * testing.
115 42200 fdiaz
         *
116 41076 jjdelcerro
         * @deprecated see PersistentManager
117
         */
118
        public static String PROJECTENCODING = "UTF-8";
119 40435 jjdelcerro
120 41076 jjdelcerro
        private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
121 40435 jjdelcerro
122 41076 jjdelcerro
        private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
123 40435 jjdelcerro
124 41312 jjdelcerro
        public void initialize() {
125
            initializeDocumentActionsExtensionPoint();
126
            registerDocuments();
127
            registerIcons();
128 42200 fdiaz
129 41314 jjdelcerro
            File projectFile = getProjectFileFromArguments();
130
            if( projectFile!=null ) {
131
                // Posponemos la apertura del proyecto ya que en este momento
132
                // puede que no este inicializado algun plugin que precise el
133
                // proyecto para poderse cargar.
134
                PluginsLocator.getManager().addStartupTask(
135 41312 jjdelcerro
                    "Open project",
136 41314 jjdelcerro
                    new OpenInitialProjectTask(projectFile), true, 1000);
137
            }
138 41312 jjdelcerro
        }
139 40435 jjdelcerro
140 41076 jjdelcerro
        private void registerIcons() {
141
                IconThemeHelper.registerIcon("action", "application-project-new", this);
142
                IconThemeHelper
143
                                .registerIcon("action", "application-project-open", this);
144
                IconThemeHelper
145
                                .registerIcon("action", "application-project-save", this);
146
                IconThemeHelper.registerIcon("action", "application-project-save-as",
147
                                this);
148 40435 jjdelcerro
149 41076 jjdelcerro
                IconThemeHelper.registerIcon("project", "project-icon", this);
150
        }
151 40435 jjdelcerro
152 41314 jjdelcerro
        /**
153
         * Returns the file to be opened or null if no parameter
154
         * or file does not exist
155 42200 fdiaz
         *
156 41314 jjdelcerro
         * @return
157
         */
158
        private File getProjectFileFromArguments() {
159
            String[] theArgs = PluginServices.getArguments();
160
            if( theArgs.length< 3 ) {
161
                // application-name and extensions-folder are fixed arguments
162
                return null;
163
            }
164
            String lastArg = theArgs[theArgs.length - 1];
165
            if ( StringUtils.isEmpty(lastArg) ) {
166
                return null;
167
            }
168
            if( lastArg.startsWith("-") ) {
169
                // Args starts with "-" are flags
170
                return null;
171
            }
172
            if (!lastArg.toLowerCase().endsWith(Project.FILE_EXTENSION.toLowerCase())) {
173 42200 fdiaz
                LOG.info("Do not open project file, does not have the expected extension '" +
174 41314 jjdelcerro
                        Project.FILE_EXTENSION +"' ("+lastArg+").");
175
                return null;
176
            }
177
            File projectFile = new File(lastArg);
178
            if ( !projectFile.exists()) {
179
                LOG.info("Do not open project file, '" +projectFile.getAbsolutePath() + "' do not exist.");
180
                return null;
181
            }
182
            return projectFile;
183 42200 fdiaz
        }
184 41314 jjdelcerro
185 41312 jjdelcerro
        private class OpenInitialProjectTask implements Runnable {
186 41314 jjdelcerro
            private File projectFile;
187
            public OpenInitialProjectTask(File projectFile) {
188
                this.projectFile = projectFile;
189
            }
190 41312 jjdelcerro
            public void run() {
191 41314 jjdelcerro
                if (this.projectFile == null) {
192 41312 jjdelcerro
                    return;
193
                }
194
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
195
                ActionInfo action = actionManager.getAction("application-project-open");
196 41314 jjdelcerro
                action.execute(this.projectFile);
197 41312 jjdelcerro
            }
198
        }
199 40435 jjdelcerro
200 41076 jjdelcerro
        public ProjectWindow getProjectFrame() {
201
                if (projectFrame == null) {
202
                        projectFrame = new ProjectWindow();
203
                }
204
                return projectFrame;
205
        }
206 40435 jjdelcerro
207 41076 jjdelcerro
        /**
208
         * Muestra la ventana con el gestor de proyectos.
209
         */
210
        public void showProjectWindow() {
211
                if (seedProjectWindow != null) {
212
                        if (seedProjectWindow.isClosed()) {
213
                                // if it was closed, we just don't open the window now
214
                                seedProjectWindow.setClosed(false);
215
                                return;
216
                        }
217
                        WindowInfo winProps = seedProjectWindow;
218
                        seedProjectWindow = null;
219
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
220
                        PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(),
221
                                        winProps);
222
                } else {
223
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
224
                }
225
        }
226 40435 jjdelcerro
227 41076 jjdelcerro
        /**
228
         * Muestra la ventana con el gestor de proyectos, con las propiedades de
229
         * ventana especificadas.
230
         */
231
        public void showProjectWindow(WindowInfo wi) {
232
                seedProjectWindow = wi;
233
                showProjectWindow();
234
        }
235 40435 jjdelcerro
236 41076 jjdelcerro
        /**
237
         * Guarda el proyecto actual en disco.
238
         */
239
        private boolean saveProject() {
240
                boolean saved = false;
241
                // if (p.getPath() == null) {
242
                if (projectPath == null) {
243
                        saved = saveAsProject(null);
244
                } else {
245
                        long t1, t2;
246
                        t1 = System.currentTimeMillis();
247
                        saved = writeProject(new File(projectPath), p, false);
248
                        t2 = System.currentTimeMillis();
249
                        PluginServices.getLogger().info(
250
                                        "Project saved. " + (t2 - t1) + " miliseconds");
251
                        getProjectFrame().refreshControls();
252
                }
253
                return saved;
254
        }
255 40435 jjdelcerro
256 41076 jjdelcerro
        private boolean saveAsProject(File file) {
257
                boolean saved = false;
258 40435 jjdelcerro
259 41076 jjdelcerro
                if (lastSavePath == null) {
260
                        lastSavePath = projectPath;
261
                }
262 40435 jjdelcerro
263 41076 jjdelcerro
                if (file == null) {
264
                        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
265
                        JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID,
266
                                        prefs.get("ProjectsFolder", null));
267 40435 jjdelcerro
268 41076 jjdelcerro
                        jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
269 42200 fdiaz
270 42186 mcompany
                        GenericFileFilter projExtensionFilter = new GenericFileFilter(
271 41076 jjdelcerro
                                        Project.FILE_EXTENSION, MessageFormat.format(PluginServices
272
                                                        .getText(this, "tipo_fichero_proyecto"),
273 42186 mcompany
                                                        Project.FILE_EXTENSION));
274
      jfc.addChoosableFileFilter(projExtensionFilter);
275
      jfc.setFileFilter(projExtensionFilter);
276 40435 jjdelcerro
277 41076 jjdelcerro
                        if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
278
                                return saved;
279
                        }
280
                        file = jfc.getSelectedFile();
281
                }
282 40435 jjdelcerro
283 41076 jjdelcerro
                if (!(file.getPath().toLowerCase().endsWith(Project.FILE_EXTENSION
284
                                .toLowerCase()))) {
285
                        file = new File(file.getPath() + Project.FILE_EXTENSION);
286
                }
287
                saved = writeProject(file, p);
288
                String filePath = file.getAbsolutePath();
289
                lastSavePath = filePath.substring(0,
290
                                filePath.lastIndexOf(File.separatorChar));
291 40435 jjdelcerro
292 41076 jjdelcerro
                getProjectFrame().refreshControls();
293
                return saved;
294
        }
295 40435 jjdelcerro
296 41076 jjdelcerro
        /**
297
         * Checks whether the project and related unsaved data is modified, and
298
         * allows the user to save it.
299 42200 fdiaz
         *
300 41076 jjdelcerro
         * @return true if the data has been correctly saved, false otherwise
301
         */
302
        private boolean askSave() {
303
                if (p != null && p.hasChanged()) {
304
                        TerminationProcess process = Launcher.getTerminationProcess();
305
                        UnsavedDataPanel panel = process.getUnsavedDataPanel();
306
                        panel.setHeaderText(PluginServices.getText(this,
307
                                        "_Select_resources_to_save_before_closing_current_project"));
308
                        panel.setAcceptText(
309
                                        PluginServices.getText(this, "save_resources"),
310
                                        PluginServices
311
                                                        .getText(this,
312
                                                                        "Save_the_selected_resources_and_close_current_project"));
313
                        panel.setCancelText(PluginServices.getText(this, "Cancel"),
314
                                        PluginServices.getText(this, "Return_to_current_project"));
315
                        int closeCurrProj;
316
                        try {
317
                                closeCurrProj = process.manageUnsavedData();
318
                                if (closeCurrProj == JOptionPane.NO_OPTION) {
319
                                        // the user chose to return to current project
320
                                        return false;
321
                                }
322
                        } catch (Exception e) {
323
                                LOG.error("Some data can not be saved", e);
324
                        }
325
                }
326
                return true;
327
        }
328 40435 jjdelcerro
329 41076 jjdelcerro
        public void execute(String command) {
330
                this.execute(command, null);
331
        }
332 42200 fdiaz
333 43293 fdiaz
    public void execute(String actionCommand, Object[] args) {
334
        if (actionCommand.equals("application-project-new")) {
335
            if (!askSave()) {
336
                return;
337
            }
338 40435 jjdelcerro
339 43293 fdiaz
            projectPath = null;
340
            PluginServices.getMDIManager().closeAllWindows();
341
            setProject(ProjectManager.getInstance().createProject());
342 41312 jjdelcerro
343 43293 fdiaz
            showProjectWindow();
344
            PluginServices.getMainFrame().setTitle(PluginServices.getText(this, "sin_titulo"));
345 40435 jjdelcerro
346 43293 fdiaz
        } else if (actionCommand.equals("application-project-open")) {
347
            if (!askSave()) {
348
                return;
349
            }
350 42200 fdiaz
351 43293 fdiaz
            setProject(ProjectManager.getInstance().createProject());
352 40893 jjdelcerro
353 43293 fdiaz
            File projectFile = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
354
            if (projectFile != null && !projectFile.exists()) {
355
                LOG.warn("Can't load project '" + projectFile.getAbsolutePath() + "', file not exist.");
356
                projectFile = null;
357
            }
358 40435 jjdelcerro
359 43293 fdiaz
            if (projectFile == null) {
360
                Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
361
                JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get("ProjectsFolder", null));
362 43506 jjdelcerro
                ProjectPreviewPanel preview = new ProjectPreviewPanel();
363
                jfc.setAccessory(preview);
364
                jfc.addPropertyChangeListener(preview);
365 42200 fdiaz
366 43293 fdiaz
                GenericFileFilter projExtensionFilter =
367
                    new GenericFileFilter(Project.FILE_EXTENSION, PluginServices.getText(this, "tipo_fichero_proyecto"));
368
                jfc.addChoosableFileFilter(projExtensionFilter);
369
                jfc.setFileFilter(projExtensionFilter);
370 42200 fdiaz
371 43293 fdiaz
                if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) != JFileChooser.APPROVE_OPTION) {
372
                    return;
373
                }
374
                // ProjectDocument.initializeNUMS();
375 40435 jjdelcerro
376 43293 fdiaz
                projectFile = jfc.getSelectedFile();
377
            }
378 40435 jjdelcerro
379 43293 fdiaz
            PluginServices.getMDIManager().closeAllWindows();
380 40435 jjdelcerro
381 43293 fdiaz
            Project o = readProject(projectFile);
382
            setPath(projectFile.getAbsolutePath());
383
            // lastPath = getPath();
384
            if (o != null) {
385
                setProject(o);
386
            }
387 40435 jjdelcerro
388 43293 fdiaz
            getProjectFrame().setProject(p);
389
            PluginServices.getMainFrame().setTitle(projectFile.getName());
390
            getProjectFrame().refreshControls();
391
392
            // p.restoreWindowProperties();
393
394
        } else if (actionCommand.equals("application-project-save")) {
395
            // saveProject();
396
            try {
397 42200 fdiaz
                Launcher.manageUnsavedData("there_are_unsaved_resources");
398
            } catch (Exception e) {
399
                LOG.warn("Can't manage unsaved data", e);
400
            }
401 43293 fdiaz
        } else if (actionCommand.equals("application-project-save-as")) {
402
            File file = (File) ArrayUtils.get(args, 0, DataTypes.FILE);
403
            saveAsProject(file);
404
        }
405 40435 jjdelcerro
406 43293 fdiaz
    }
407 40435 jjdelcerro
408 42200 fdiaz
409 41217 jldominguez
    private void createEmptyProject() {
410
        setProject(ProjectManager.getInstance().createProject());
411
        p.setName(PluginServices.getText(this, "untitled"));
412
        p.setModified(false);
413
        PluginServices.getMainFrame().setTitle(
414
                PluginServices.getText(this, "sin_titulo"));
415
        setProject(p);
416
        showProjectWindow();
417
    }
418
419
    /**
420
     * @see com.iver.mdiApp.plugins.IExtension#postInitialize()
421
     */
422
    public void postInitialize() {
423
        try {
424
            if( !SwingUtilities.isEventDispatchThread() ) {
425
                SwingUtilities.invokeAndWait(new Runnable() {
426
                    public void run() {
427
                        createEmptyProject();
428
                    }
429
                });
430
            } else {
431
                createEmptyProject();
432
            }
433
        } catch (Exception e) {
434
            LOG.warn("Can't load initial project.",e);
435
        }
436 42200 fdiaz
    }
437
438
439 41076 jjdelcerro
        /**
440
         * Escribe el proyecto en XML.
441 42200 fdiaz
         *
442 41076 jjdelcerro
         * @param file
443
         *            Fichero.
444
         * @param p
445
         *            Proyecto.
446
         */
447
        public boolean writeProject(File file, Project p) {
448
                return writeProject(file, p, true);
449
        }
450 40435 jjdelcerro
451 43820 jjdelcerro
    /**
452
     * Escribe el proyecto en disco.
453
     * Pero permite decidir si se pide confirmaci?n para sobreescribir
454
     *
455
     * @param file Fichero.
456
     * @param p Proyecto.
457
     * @param askConfirmation boolean
458
     * @return
459
     */
460
public boolean writeProject(File file, Project p, boolean askConfirmation) {
461
        I18nManager i18n = ToolsLocator.getI18nManager();
462
        ApplicationManager application = ApplicationLocator.getManager();
463
        if (askConfirmation && file.exists()) {
464
            int resp = application.confirmDialog(
465
                    i18n.getTranslation("fichero_ya_existe_seguro_desea_guardarlo"),
466
                    i18n.getTranslation("guardar"),
467
                    JOptionPane.YES_NO_OPTION,
468
                    JOptionPane.QUESTION_MESSAGE,
469
                    "Overwrite_project_file"
470
            );
471
            if (resp != JOptionPane.YES_OPTION) {
472
                return false;
473
            }
474
        }
475
        FileOutputStream fout=null;
476
        ZipOutputStream zout=null;
477
        LOG.info("Writing project '"+ file.getAbsolutePath()+"'.");
478
        try {
479
            fireBeforeSavingFileEvent(new SaveEvent(this,SaveEvent.BEFORE_SAVING, file));
480 40435 jjdelcerro
481 43820 jjdelcerro
            fout = new FileOutputStream(file);
482
            zout = new ZipOutputStream(fout);
483 43506 jjdelcerro
            p.saveState(zout);
484 43820 jjdelcerro
485 43506 jjdelcerro
            zout.putNextEntry(new ZipEntry("preview.jpg"));
486
            BufferedImage img = ApplicationLocator.getManager().getUIManager().getImagePreview();
487
            img = scale(img, 0.40);
488
            try {
489
                ImageIO.write(img, "jpg", zout);
490
            } catch (IOException ex) {
491 43820 jjdelcerro
                LOG.warn("Can't save preview image'.", ex);
492 43506 jjdelcerro
            }
493 43820 jjdelcerro
            fireAfterSavingFileEvent(new SaveEvent(this, SaveEvent.AFTER_SAVING, file));
494 43506 jjdelcerro
            IOUtils.closeQuietly(zout);
495
            IOUtils.closeQuietly(fout);
496 43820 jjdelcerro
497
            if( !isValidZIP(file) ) {
498
                throw new ZipException("Invalid project file '"+file.getAbsolutePath()+"'");
499
            }
500 43506 jjdelcerro
501 43820 jjdelcerro
            PluginServices.getMainFrame().setTitle(file.getName());
502
            setPath(file.toString());
503 40435 jjdelcerro
504 43820 jjdelcerro
        } catch (Exception e) {
505
            application.messageDialog(
506
                    i18n.getTranslation("_Problems_saving_the_project_XnlX_It_is_possible_that_this_was_not_saved_properly_and_can_not_be_loaded_again"),
507
                    null,
508
                    i18n.getTranslation("guardar"),
509
                    JOptionPane.ERROR_MESSAGE,
510
                    "Problems_saving_the_project"
511
            );
512
            LOG.warn("Error writing project '"+file.getAbsolutePath()+"'.", e);
513
            return false;
514
        } finally {
515
            IOUtils.closeQuietly(zout);
516
            IOUtils.closeQuietly(fout);
517
        }
518
519
        LOG.warn("Wrote project '"+file.getAbsolutePath()+"'.");
520
        return true;
521
    }
522 40435 jjdelcerro
523 43820 jjdelcerro
    boolean isValidZIP(final File file) {
524
        ZipFile zipfile = null;
525
        try {
526
            zipfile = new ZipFile(file);
527
            return true;
528
        } catch (IOException e) {
529
            return false;
530
        } finally {
531
            try {
532
                if (zipfile != null) {
533
                    zipfile.close();
534
                    zipfile = null;
535
                }
536
            } catch (IOException e) {
537
            }
538
        }
539
    }
540 40435 jjdelcerro
541 43506 jjdelcerro
    private BufferedImage scale(BufferedImage before, double factor) {
542
        int w = (int) (before.getWidth()*factor);
543
        int h = (int) (before.getHeight()*factor);
544
        BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
545
        AffineTransform at = new AffineTransform();
546
        at.scale(factor, factor);
547
        AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
548
        after = scaleOp.filter(before, after);
549
        return after;
550
    }
551
552 41076 jjdelcerro
        public Project readProject(String path) {
553
                Project project = ProjectManager.getInstance().createProject();
554 40435 jjdelcerro
555 41076 jjdelcerro
                project.loadState(new File(path));
556
                return (Project) project;
557
        }
558 40435 jjdelcerro
559 41076 jjdelcerro
        /**
560
         * Lee del XML el proyecto.<br>
561
         * <br>
562 42200 fdiaz
         *
563 41076 jjdelcerro
         * Reads the XML of the project.<br>
564
         * It returns a project object holding all needed info that is not linked to
565
         * the Project Dialog. <br>
566
         * In case you want the project to be linked to the window you must set this
567
         * object to the extension:<br>
568 42200 fdiaz
         *
569 41076 jjdelcerro
         * <b>Example:</b><br>
570 42200 fdiaz
         *
571 41076 jjdelcerro
         * ...<br>
572
         * ...<br>
573
         * Project p = ProjectExtension.readProject(projectFile);<br>
574
         * ProjectExtension.setProject(p); ...<br>
575
         * ...<br>
576 42200 fdiaz
         *
577 41076 jjdelcerro
         * @param file
578
         *            Fichero.
579 42200 fdiaz
         *
580 41076 jjdelcerro
         * @return Project
581 42200 fdiaz
         *
582 41076 jjdelcerro
         */
583
        public Project readProject(File file) {
584
                Project project = ProjectManager.getInstance().createProject();
585 40435 jjdelcerro
586 41076 jjdelcerro
                project.loadState(file);
587 42711 fdiaz
                Set<String> unloadedObjects = project.getUnloadedObjects();
588 43439 jjdelcerro
        List<Exception> errors = project.getLoadErrors();
589
590
                if( !CollectionUtils.isEmpty(unloadedObjects) ) {
591 42711 fdiaz
                    StringBuilder builder = new StringBuilder();
592
                    builder.append("Unloaded elements loading the project:\n");
593
                    Iterator<String> it = unloadedObjects.iterator();
594
                    while(it.hasNext()){
595
                builder.append("\t");
596
                        builder.append(it.next());
597
                        builder.append("\n");
598
                    }
599
600
                    LOG.warn(builder.toString());
601 43439 jjdelcerro
        }
602
                if( !CollectionUtils.isEmpty(unloadedObjects) || !CollectionUtils.isEmpty(errors) ) {
603 42711 fdiaz
                    ApplicationManager application = ApplicationLocator.getManager();
604
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
605
606
                    application.messageDialog(
607
                        i18nManager.getTranslation("_some_project_elements_could_not_be_loaded")+"\n"+
608 43439 jjdelcerro
                        i18nManager.getTranslation("_maybe_you_need_to_install_any_plugins")+"\n"+
609
                        i18nManager.getTranslation("_Recovered_data_may_be_corrupted")+"\n\n"+
610 42711 fdiaz
                        i18nManager.getTranslation("_see_error_log_for_more_information"),
611
                    i18nManager.getTranslation("warning"),
612
                    JOptionPane.WARNING_MESSAGE);
613
614 43439 jjdelcerro
                } else {
615
616
        }
617 41076 jjdelcerro
                return (Project) project;
618
        }
619 40435 jjdelcerro
620 41076 jjdelcerro
        /**
621
         * Devuelve el proyecto.
622 42200 fdiaz
         *
623 41076 jjdelcerro
         * @return Proyecto.
624
         */
625
        public Project getProject() {
626
                return p;
627
        }
628 40435 jjdelcerro
629 41076 jjdelcerro
        /**
630
         * @see org.gvsig.andami.plugins.IExtension#isEnabled()
631
         */
632
        public boolean isEnabled() {
633
                return true;
634
        }
635 40435 jjdelcerro
636 41076 jjdelcerro
        /**
637
         * @see org.gvsig.andami.plugins.IExtension#isVisible()
638
         */
639
        public boolean isVisible() {
640
                return true;
641
        }
642 40435 jjdelcerro
643 41076 jjdelcerro
        /**
644
         * Sets the project
645 42200 fdiaz
         *
646 41076 jjdelcerro
         * @param p
647
         */
648
        public void setProject(Project p) {
649
                this.p = p;
650 43293 fdiaz
                getProjectFrame().setProject(p);
651 41076 jjdelcerro
        }
652 40435 jjdelcerro
653 41076 jjdelcerro
        private void registerDocuments() {
654
                ViewManager.register();
655
        }
656 40435 jjdelcerro
657 41076 jjdelcerro
        private void initializeDocumentActionsExtensionPoint() {
658
                ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
659
                epMan.add(
660
                                "DocumentActions_View",
661
                                "Context menu options of the view document list"
662
                                                + " in the project window "
663
                                                + "(register instances of "
664
                                                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
665
        }
666 40435 jjdelcerro
667 41076 jjdelcerro
        public static String getPath() {
668
                return projectPath;
669
        }
670 40435 jjdelcerro
671 41076 jjdelcerro
        public static void setPath(String path) {
672
                projectPath = path;
673
        }
674 40435 jjdelcerro
675 41076 jjdelcerro
        public IWindow getProjectWindow() {
676
                return getProjectFrame();
677
        }
678 40435 jjdelcerro
679 41076 jjdelcerro
        public IExtensionStatus getStatus() {
680
                return this;
681
        }
682 40435 jjdelcerro
683 41076 jjdelcerro
        public boolean hasUnsavedData() {
684
                return p.hasChanged();
685
        }
686 40435 jjdelcerro
687 41076 jjdelcerro
        public IUnsavedData[] getUnsavedData() {
688
                if (hasUnsavedData()) {
689
                        UnsavedProject data = new UnsavedProject(this);
690
                        IUnsavedData[] dataArray = { data };
691
                        return dataArray;
692
                } else {
693
                        return null;
694
                }
695
        }
696 40435 jjdelcerro
697 41076 jjdelcerro
        /**
698
         * Implements the IUnsavedData interface to show unsaved projects in the
699
         * Unsavad Data dialog.
700 42200 fdiaz
         *
701 41076 jjdelcerro
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
702
         */
703
        public class UnsavedProject extends UnsavedData {
704 40435 jjdelcerro
705 41076 jjdelcerro
                public UnsavedProject(IExtension extension) {
706
                        super(extension);
707
                }
708 40435 jjdelcerro
709 41076 jjdelcerro
                public String getDescription() {
710
                        if (getPath() == null) {
711
                                return PluginServices.getText(ProjectExtension.this,
712
                                                "Unnamed_new_gvsig_project_");
713
                        } else {
714
                                return PluginServices.getText(ProjectExtension.this,
715
                                                "Modified_project_");
716
                        }
717
                }
718 40435 jjdelcerro
719 41076 jjdelcerro
                public String getResourceName() {
720
                        if (getPath() == null) {
721
                                return PluginServices.getText(ProjectExtension.this, "Unnamed");
722
                        } else {
723
                                return getPath();
724
                        }
725 40435 jjdelcerro
726 41076 jjdelcerro
                }
727 40435 jjdelcerro
728 41076 jjdelcerro
                public boolean saveData() {
729
                        return saveProject();
730
                }
731 40435 jjdelcerro
732 41076 jjdelcerro
                public String getIcon() {
733
                        return "project-icon";
734
                }
735
        }
736 40435 jjdelcerro
737 41076 jjdelcerro
        public IMonitorableTask[] getRunningProcesses() {
738
                // TODO Auto-generated method stub
739
                return null;
740
        }
741 40435 jjdelcerro
742 41076 jjdelcerro
        public boolean hasRunningProcesses() {
743
                // TODO Auto-generated method stub
744
                return false;
745
        }
746 40435 jjdelcerro
747 41076 jjdelcerro
        /**
748
         * Adds the specified before saving listener to receive
749
         * "before saving file events" from this component. If l is null, no
750
         * exception is thrown and no action is performed.
751 42200 fdiaz
         *
752 41076 jjdelcerro
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
753 42200 fdiaz
         *
754 41076 jjdelcerro
         * @param l
755
         *            the before saving listener.
756
         * @see SaveEvent
757
         * @see BeforeSavingListener
758
         * @see #removeListener(BeforeSavingListener)
759
         * @see #getBeforeSavingListeners
760
         */
761
        public synchronized void addListener(BeforeSavingListener l) {
762
                if (l == null) {
763
                        return;
764
                }
765
                if (!this.beforeSavingListeners.contains(l)) {
766
                        this.beforeSavingListeners.add(l);
767
                }
768
        }
769 40435 jjdelcerro
770 41076 jjdelcerro
        /**
771
         * Adds the specified after saving listener to receive
772
         * "after saving file events" from this component. If l is null, no
773
         * exception is thrown and no action is performed.
774 42200 fdiaz
         *
775 41076 jjdelcerro
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
776 42200 fdiaz
         *
777 41076 jjdelcerro
         * @param l
778
         *            the after saving listener.
779
         * @see SaveEvent
780
         * @see AfterSavingListener
781
         * @see #removeListener(AfterSavingListener)
782
         * @see #getAfterSavingListeners()
783
         */
784
        public synchronized void addListener(AfterSavingListener l) {
785
                if (l == null) {
786
                        return;
787
                }
788 40435 jjdelcerro
789 41076 jjdelcerro
                if (!this.afterSavingListeners.contains(l)) {
790
                        this.afterSavingListeners.add(l);
791
                }
792 40435 jjdelcerro
793 41076 jjdelcerro
        }
794 40435 jjdelcerro
795 41076 jjdelcerro
        /**
796
         * Returns an array of all the before saving listeners registered on this
797
         * component.
798 42200 fdiaz
         *
799 41076 jjdelcerro
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
800 42200 fdiaz
         *
801 41076 jjdelcerro
         * @return all of this component's <code>BeforeSavingListener</code>s or an
802
         *         empty array if no key listeners are currently registered
803 42200 fdiaz
         *
804 41076 jjdelcerro
         * @see #addBeforeSavingListener(BeforeSavingListener)
805
         * @see #removeBeforeSavingListener(BeforeSavingListener)
806
         */
807
        public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
808
                return this.beforeSavingListeners
809
                                .toArray(new BeforeSavingListener[] {});
810
        }
811 40435 jjdelcerro
812 41076 jjdelcerro
        /**
813
         * Returns an array of all the after saving listeners registered on this
814
         * component.
815 42200 fdiaz
         *
816 41076 jjdelcerro
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
817 42200 fdiaz
         *
818 41076 jjdelcerro
         * @return all of this component's <code>AfterSavingListener</code>s or an
819
         *         empty array if no key listeners are currently registered
820 42200 fdiaz
         *
821 41076 jjdelcerro
         * @see #addAfterSavingListener(AfterSavingListener)
822
         * @see #removeAfterSavingListener
823
         */
824
        public synchronized AfterSavingListener[] getAfterSavingListeners() {
825
                return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
826 40435 jjdelcerro
827 41076 jjdelcerro
        }
828 40435 jjdelcerro
829 41076 jjdelcerro
        /**
830
         * Removes the specified before saving listener so that it no longer
831
         * receives save file events from this component. This method performs no
832
         * function, nor does it throw an exception, if the listener specified by
833
         * the argument was not previously added to this component. If listener
834
         * <code>l</code> is <code>null</code>, no exception is thrown and no action
835
         * is performed.
836 42200 fdiaz
         *
837 41076 jjdelcerro
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
838 42200 fdiaz
         *
839 41076 jjdelcerro
         * @param l
840
         *            the before saving listener
841
         * @see SaveEvent
842
         * @see BeforeSavingListener
843
         * @see #addListener(BeforeSavingListener)
844
         * @see #getBeforeSavingListeners()
845
         */
846
        public synchronized void removeListener(BeforeSavingListener l) {
847
                if (l == null) {
848
                        return;
849
                }
850 40435 jjdelcerro
851 41076 jjdelcerro
                this.beforeSavingListeners.remove(l);
852
        }
853 40435 jjdelcerro
854 41076 jjdelcerro
        /**
855
         * Removes the specified after saving listener so that it no longer receives
856
         * save file events from this component. This method performs no function,
857
         * nor does it throw an exception, if the listener specified by the argument
858
         * was not previously added to this component. If listener <code>l</code> is
859
         * <code>null</code>, no exception is thrown and no action is performed.
860 42200 fdiaz
         *
861 41076 jjdelcerro
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
862 42200 fdiaz
         *
863 41076 jjdelcerro
         * @param l
864
         *            the after saving listener
865
         * @see SaveEvent
866
         * @see AfterSavingListener
867
         * @see #addListener(AfterSavingListener)
868
         * @see #getAfterSavingListeners()
869
         */
870
        public synchronized void removeListener(AfterSavingListener l) {
871
                if (l == null) {
872
                        return;
873
                }
874
875
                this.afterSavingListeners.remove(l);
876
        }
877
878
        /**
879
         * Reports a before saving file event.
880 42200 fdiaz
         *
881 41076 jjdelcerro
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
882 42200 fdiaz
         *
883 41076 jjdelcerro
         * @param evt
884
         *            the before saving file event
885
         */
886
        protected void fireBeforeSavingFileEvent(SaveEvent evt) {
887
                if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
888
                        return;
889
                }
890
891
                Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
892
                                .iterator();
893
894
                while (iter.hasNext()) {
895
                        iter.next().beforeSaving(evt);
896
                }
897
        }
898
899
        /**
900
         * Reports a after saving file event.
901 42200 fdiaz
         *
902 41076 jjdelcerro
         * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
903 42200 fdiaz
         *
904 41076 jjdelcerro
         * @param evt
905
         *            the after saving file event
906
         */
907
        protected void fireAfterSavingFileEvent(SaveEvent evt) {
908
                if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
909
                        return;
910
                }
911
                Iterator<AfterSavingListener> iter = this.afterSavingListeners
912
                                .iterator();
913
914
                while (iter.hasNext()) {
915
                        iter.next().afterSaving(evt);
916
                }
917
918
        }
919 40435 jjdelcerro
}