Statistics
| Revision:

svn-gvsig-desktop / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / ProjectExtension.java @ 39770

History | View | Annotate | Download (34.6 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004-2007 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig;
42

    
43
import java.awt.Component;
44
import java.io.BufferedReader;
45
import java.io.File;
46
import java.io.FileInputStream;
47
import java.io.FileNotFoundException;
48
import java.io.FileOutputStream;
49
import java.io.FileReader;
50
import java.io.IOException;
51
import java.io.InputStream;
52
import java.io.InputStreamReader;
53
import java.io.OutputStreamWriter;
54
import java.io.Reader;
55
import java.io.UnsupportedEncodingException;
56
import java.net.MalformedURLException;
57
import java.net.URL;
58
import java.text.DateFormat;
59
import java.util.ArrayList;
60
import java.util.Date;
61
import java.util.prefs.Preferences;
62

    
63
import javax.swing.ImageIcon;
64
import javax.swing.JOptionPane;
65

    
66
import org.exolab.castor.xml.MarshalException;
67
import org.exolab.castor.xml.Marshaller;
68
import org.exolab.castor.xml.ValidationException;
69
import org.gvsig.gui.beans.swing.JFileChooser;
70
import org.gvsig.tools.file.PathGenerator;
71

    
72
import com.iver.andami.Launcher;
73
import com.iver.andami.PluginServices;
74
import com.iver.andami.Launcher.TerminationProcess;
75
import com.iver.andami.messages.NotificationManager;
76
import com.iver.andami.plugins.Extension;
77
import com.iver.andami.plugins.IExtension;
78
import com.iver.andami.plugins.status.IExtensionStatus;
79
import com.iver.andami.plugins.status.IUnsavedData;
80
import com.iver.andami.plugins.status.UnsavedData;
81
import com.iver.andami.ui.mdiManager.IWindow;
82
import com.iver.andami.ui.mdiManager.WindowInfo;
83
import com.iver.andami.ui.wizard.UnsavedDataPanel;
84
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
85
import com.iver.cit.gvsig.project.Project;
86
import com.iver.cit.gvsig.project.ProjectFactory;
87
import com.iver.cit.gvsig.project.documents.ProjectDocument;
88
import com.iver.cit.gvsig.project.documents.exceptions.OpenException;
89
import com.iver.cit.gvsig.project.documents.gui.ProjectWindow;
90
import com.iver.cit.gvsig.project.documents.layout.ProjectMap;
91
import com.iver.cit.gvsig.project.documents.layout.ProjectMapFactory;
92
import com.iver.cit.gvsig.project.documents.layout.gui.Layout;
93
import com.iver.cit.gvsig.project.documents.table.ProjectTableFactory;
94
import com.iver.cit.gvsig.project.documents.view.ProjectViewFactory;
95
import com.iver.utiles.GenericFileFilter;
96
import com.iver.utiles.XMLEntity;
97
import com.iver.utiles.extensionPoints.ExtensionPoint;
98
import com.iver.utiles.extensionPoints.ExtensionPoints;
99
import com.iver.utiles.extensionPoints.ExtensionPointsSingleton;
100
import com.iver.utiles.save.AfterSavingListener;
101
import com.iver.utiles.save.BeforeSavingListener;
102
import com.iver.utiles.save.SaveEvent;
103
import com.iver.utiles.swing.threads.IMonitorableTask;
104
import com.iver.utiles.xml.XMLEncodingUtils;
105
import com.iver.utiles.xmlEntity.generate.XmlTag;
106

    
107

    
108
/**
109
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
110
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos
111
 * en esta clase.
112
 *
113
 * @author Fernando Gonz?lez Cort?s
114
 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es)
115
 */
116
public class ProjectExtension extends Extension implements IExtensionStatus {
117
        private static String projectPath = null;
118
        //private ProjectWindow projectFrame;
119
        private ProjectWindow projectFrame;
120
        private Project p;
121
        private String lastSavePath;
122
        private String templatesPath;
123
        private WindowInfo seedProjectWindow;
124
        public static final String LAYOUT_TEMPLATE_FILECHOOSER_ID = "LAYOUT_TEMPLATE_FILECHOOSER_ID";
125
        public static final String PROJECT_FILE_CHOOSER_ID = "PROJECT_FILECHOOSER_ID";
126
        
127
        private static PathGenerator pathGenerator=PathGenerator.getInstance();
128
        /**
129
         * Use UTF-8 for encoding, as it can represent characters from
130
         * any language.
131
         *
132
         * Another sensible option would be
133
         * encoding = System.getProperty("file.encoding");
134
         * but this would need some extra testing.
135
         */
136
        public static String PROJECTENCODING = "UTF-8";
137

    
138
        /**
139
         * <p>Identifier of the extension point used by <code>ProjectExtension</code> to manage {@link BeforeSavingListener BeforeSavingListener}s.</p>
140
         */
141
        public static final String BEFORE_SAVING_ID = "Before_Saving_PrjExt";
142

    
143
        /**
144
         * <p>Identifier of the extension point used by <code>ProjectExtension</code> to manage {@link BeforeSavingListener BeforeSavingListener}s.</p>
145
         */
146
        public static final String AFTER_SAVING_ID = "After_Saving_PrjExt";
147

    
148
        /**
149
         * @see com.iver.mdiApp.plugins.IExtension#initialize()
150
         */
151
        public void initialize() {
152
            try {
153
            Class.forName("javax.media.jai.EnumeratedParameter");
154
        } catch (ClassNotFoundException e) {
155
            NotificationManager.addError("La m?quina virtual con la que se ejecuta gvSIG no tiene JAI instalado", e);
156
        }
157

    
158
                LayerFactory.setWritersPath(PluginServices.getPluginServices(this)
159
                                  .getPluginDirectory()
160
                                  .getAbsolutePath() +
161
                                  File.separator + "drivers");
162

    
163
        LayerFactory.setDriversPath(PluginServices.getPluginServices(this)
164
                                  .getPluginDirectory()
165
                                  .getAbsolutePath() +
166
                                  File.separator + "drivers");
167

    
168
        initializeDocumentActionsExtensionPoint();
169
        registerDocuments();
170

    
171
        // Recuperamos el ?ltimo argumento, que se supone
172
        // que ser? el fichero .gvp que queremos abrir.
173
        // (por enmedio pueden venir o no otros argumentos,
174
        // por ejemplo el idioma)
175
        // TODO: Aqu? Jaume podr?a meter lo del backup del proyecto
176
        // que ha hecho para ValenciaUrban?stica
177

    
178
            registerIcons();
179

    
180
        }
181

    
182
        private void registerIcons(){
183
                PluginServices.getIconTheme().registerDefault(
184
                                "project-new",
185
                                this.getClass().getClassLoader().getResource("images/new.png")
186
                        );
187

    
188
                PluginServices.getIconTheme().registerDefault(
189
                                "project-open",
190
                                this.getClass().getClassLoader().getResource("images/open.png")
191
                        );
192

    
193
                PluginServices.getIconTheme().registerDefault(
194
                                "project-save",
195
                                this.getClass().getClassLoader().getResource("images/save.png")
196
                        );
197

    
198
                PluginServices.getIconTheme().registerDefault(
199
                                "project-save-as",
200
                                this.getClass().getClassLoader().getResource("images/save.png")
201
                        );
202

    
203
                PluginServices.getIconTheme().registerDefault(
204
                                "layout-template-open",
205
                                this.getClass().getClassLoader().getResource("images/opentemplate.png")
206
                        );
207

    
208
                PluginServices.getIconTheme().registerDefault(
209
                                "application-exit",
210
                                this.getClass().getClassLoader().getResource("images/salir.png")
211
                        );
212
        }
213
        private void loadInitialProject(){
214
                String[] theArgs = PluginServices.getArguments();
215
        String lastArg = theArgs[theArgs.length-1];
216
        if ((lastArg.endsWith(".gvp")) ||
217
                        (lastArg.endsWith(".GVP")))
218
        {
219
                PluginServices.getLogger().debug("Intentando cargar el proyecto " + lastArg);
220
                //File projectFile = new File(lastArg);
221
                setProject(readProject(lastArg));
222
                PluginServices.getMainFrame().setTitle(p.getName());
223
                projectPath = lastArg;
224
        }
225
        else
226
        {
227
                        setProject(ProjectFactory.createProject());
228
                        p.setName(PluginServices.getText(this, "untitled"));
229
                        p.setModified(false);
230
                        PluginServices.getMainFrame().setTitle(PluginServices.getText(this, "sin_titulo"));
231
        }
232
        }
233
        /**
234
         * @see com.iver.mdiApp.plugins.IExtension#postInitialize()
235
         */
236
        public void postInitialize() {
237
                loadInitialProject();
238
                getProjectFrame().setProject(p);
239
                p.restoreWindowProperties();
240
        }
241

    
242
        public ProjectWindow getProjectFrame() {
243
                if (projectFrame==null)
244
                                projectFrame = new ProjectWindow();
245
                return projectFrame;
246
        }
247
        /**
248
         * Muestra la ventana con el gestor de proyectos.
249
         */
250
        public void showProjectWindow() {
251
                if (seedProjectWindow!=null) {
252
                        if (seedProjectWindow.isClosed()) {
253
                                // if it was closed, we just don't open the window now
254
                                seedProjectWindow.setClosed(false);
255
                                return;
256
                        }
257
                        WindowInfo winProps = seedProjectWindow;
258
                        seedProjectWindow = null;
259
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
260
                        PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(), winProps);
261
                }
262
                else
263
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
264
        }
265

    
266
        /**
267
         * Muestra la ventana con el gestor de proyectos, con las propiedades
268
         * de ventana especificadas.
269
         */
270
        public void showProjectWindow(WindowInfo wi) {
271
                seedProjectWindow = wi;
272
                showProjectWindow();
273
        }
274

    
275
        /**
276
         * Guarda el proyecto actual en disco.
277
         */
278
        private boolean guardar() {
279
                boolean saved=false;
280
//                if (p.getPath() == null) {
281
                if (projectPath == null) {
282
                        saved=guardarDialogo();
283
                } else {
284
                        long t1,t2;
285
                        t1 = System.currentTimeMillis();
286
                        saved=writeProject(new File(projectPath), p, false);
287
                        t2 = System.currentTimeMillis();
288
                        PluginServices.getLogger().info("Project saved. " +  (t2-t1) + " miliseconds");
289
                        getProjectFrame().refreshControls();
290
                }
291
                return saved;
292
        }
293

    
294
        private boolean guardarDialogo(){
295
                boolean saved=false;
296

    
297
                if (lastSavePath == null)
298
                        lastSavePath = projectPath;
299

    
300

    
301
                Preferences prefs = Preferences.userRoot().node( "gvsig.foldering");
302
                JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get("ProjectsFolder", null));
303

    
304
                jfc.setDialogTitle(PluginServices.getText(this, "guardar_proyecto"));
305
                jfc.addChoosableFileFilter(new GenericFileFilter("gvp",
306
                                PluginServices.getText(this, "tipo_fichero_proyecto")));
307

    
308
                if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
309
                        File file=jfc.getSelectedFile();
310
                        if (!(file.getPath().toLowerCase().endsWith(".gvp"))){
311
                                file=new File(file.getPath()+".gvp");
312
                        }
313
                        saved=writeProject(file, p);
314
                        String filePath = file.getAbsolutePath();
315
                        lastSavePath = filePath.substring(0, filePath.lastIndexOf(File.separatorChar));
316

    
317
                        getProjectFrame().refreshControls();
318
                }
319
                return saved;
320
        }
321

    
322
        /**
323
         * Checks whether the project and related unsaved data is modified,
324
         *  and allows the user to save it.
325
         *
326
         * @return true if the data has been correctly saved, false otherwise
327
         */
328
        private boolean askSave() {
329
                if (p != null && p.hasChanged()) {
330
                        TerminationProcess process = Launcher.getTerminationProcess();
331
                        UnsavedDataPanel panel = process.getUnsavedDataPanel();
332
                        panel.setHeaderText(PluginServices.getText(this, "Select_resources_to_save_before_closing_current_project"));
333
                        panel.setAcceptText(
334
                                        PluginServices.getText(this, "save_resources"),
335
                                        PluginServices.getText(this, "Save_the_selected_resources_and_close_current_project"));
336
                        panel.setCancelText(
337
                                        PluginServices.getText(this, "Dont_close"),
338
                                        PluginServices.getText(this, "Return_to_current_project"));
339
                        int closeCurrProj = process.manageUnsavedData();
340
                        if (closeCurrProj==JOptionPane.NO_OPTION) {
341
                                // the user chose to return to current project
342
                                return false;
343
                        }
344
                }
345
                return true;
346
        }
347

    
348
        /**
349
         * @see com.iver.mdiApp.plugins.IExtension#updateUI(java.lang.String)
350
         */
351
        public void execute(String actionCommand) {
352
                if (actionCommand.equals("NUEVO")) {
353
                        if (!askSave()) {
354
                                return;
355
                        }
356

    
357
                        projectPath=null;
358
                        ProjectDocument.initializeNUMS();
359
                        PluginServices.getMDIManager().closeAllWindows();
360
                        setProject(ProjectFactory.createProject());
361
                        getProjectFrame().setProject(p);
362
                        showProjectWindow();
363
                        PluginServices.getMainFrame().setTitle(PluginServices.getText(this, "sin_titulo"));
364
                } else if (actionCommand.equals("ABRIR")) {
365
                        if (!askSave())
366
                                return;
367

    
368
                        Preferences prefs = Preferences.userRoot().node( "gvsig.foldering" );
369
                        JFileChooser jfc = new JFileChooser(PROJECT_FILE_CHOOSER_ID, prefs.get("ProjectsFolder", null));
370
                        jfc.addChoosableFileFilter(new GenericFileFilter("gvp",
371
                                        PluginServices.getText(this, "tipo_fichero_proyecto")));
372

    
373
                        if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
374
                                File projectFile = jfc.getSelectedFile();
375
                                openProject(projectFile);
376
                        }
377
                } else if (actionCommand.equals("GUARDAR")) {
378
                        guardar();
379
//jaume                        p.setModified(false);
380
                } else if (actionCommand.equals("GUARDAR_COMO")) {
381
                        guardarDialogo();
382
//jaume                        p.setModified(false);
383
                } else if (actionCommand.equals("SALIR")){
384
                        Launcher.closeApplication();
385
                } else if (actionCommand.compareTo("OPENTEMPLATE")==0){
386
                        openLayout();
387
//jaume                        p.setModified(true);
388
                }
389
        }
390
        
391
        public void openProject(File projectFile) {
392
            ProjectDocument.initializeNUMS();
393
            PluginServices.getMDIManager().closeAllWindows();
394
            Project o = readProject(projectFile);
395
            setPath(projectFile.getAbsolutePath());
396
            if (o != null) {
397
                setProject(o);
398
            }
399
            PluginServices.getMainFrame().setTitle(p.getName());
400
            getProjectFrame().refreshControls();
401
            p.restoreWindowProperties();
402
        }
403
        
404
        public void openLayout() {
405
                //Project project = ((ProjectExtension) PluginServices.getExtension(ProjectExtension.class)).getProject();
406
                Layout layout=null;
407

    
408
                if (templatesPath == null) {
409
                        Preferences prefs = Preferences.userRoot().node( "gvsig.foldering" );
410
                        templatesPath = prefs.get("TemplatesFolder", null);
411
                }
412

    
413
                JFileChooser jfc = new JFileChooser(LAYOUT_TEMPLATE_FILECHOOSER_ID, templatesPath);
414
                jfc.addChoosableFileFilter(new GenericFileFilter("gvt",
415
                                PluginServices.getText(this, "plantilla")));
416

    
417
                if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
418
                        File file=jfc.getSelectedFile();
419
                        if (!(file.getPath().endsWith(".gvt") || file.getPath().endsWith(".GVT"))){
420
                                file=new File(file.getPath()+".gvt");
421
                        }
422
                        try {
423
                                File xmlFile = new File(file.getAbsolutePath());
424
                                FileInputStream is = new FileInputStream(xmlFile);
425
                                Reader reader = XMLEncodingUtils.getReader(is);
426

    
427
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
428
                                try {
429
                                        XMLEntity xml=new XMLEntity(tag);
430
                                        if (xml.contains("followHeaderEncoding")) {
431
                                                layout = Layout.createLayout(xml,p);
432
                                        }
433
                                        else {
434
                                                reader = new FileReader(xmlFile);
435
                                                tag = (XmlTag) XmlTag.unmarshal(reader);
436
                                                xml=new XMLEntity(tag);
437
                                                layout = Layout.createLayout(xml,p);
438
                                        }
439

    
440
                                } catch (OpenException e) {
441
                                        e.showError();
442
                                }
443
                                //fPanelLegendManager.setRenderer(LegendFactory.createFromXML(new XMLEntity(tag)));
444
                        } catch (FileNotFoundException e) {
445
                                NotificationManager.addError(PluginServices.getText(this, "Al_leer_la_leyenda"), e);
446
                        } catch (MarshalException e) {
447
                                NotificationManager.addError(PluginServices.getText(this, "Al_leer_la_leyenda"), e);
448
                        } catch (ValidationException e) {
449
                                NotificationManager.addError(PluginServices.getText(this, "Al_leer_la_leyenda"), e);
450
                        }
451
                        ProjectMap pmap = ProjectFactory.createMap(file.getName());
452
                        pmap.setModel(layout);
453
                        pmap.getModel().setProjectMap(pmap);
454
                        p.addDocument(pmap);
455
                        PluginServices.getMDIManager().addWindow(layout);
456

    
457

    
458
                }
459
        }
460
        /**
461
         * Escribe el proyecto en XML.
462
         *
463
         * @param file Fichero.
464
         * @param p Proyecto.
465
         */
466
        public boolean writeProject(File file, Project p) {
467
                return writeProject(file, p, true);
468
        }
469

    
470
        /**
471
         * Escribe el proyecto en XML. Pero permite decidir si se
472
         * pide confirmaci?n para sobreescribir
473
         *
474
         * @param file Fichero.
475
         * @param p Proyecto.
476
         * @param askConfirmation boolean
477
         */
478
        public boolean writeProject(File file, Project p, boolean askConfirmation) {
479
                pathGenerator.setBasePath(file.getParent());
480
                if( askConfirmation && file.exists()){
481
                        int resp = JOptionPane.showConfirmDialog(
482
                                        (Component) PluginServices.getMainFrame(),PluginServices.getText(this,"fichero_ya_existe_seguro_desea_guardarlo"),
483
                                        PluginServices.getText(this,"guardar"), JOptionPane.YES_NO_OPTION);
484
                        if (resp != JOptionPane.YES_OPTION) {
485
                                return false;
486
                        }
487
                }
488
                NotificationManager.addInfo(PluginServices.getText(this,"writinng_project")+ ": "+file.getName());
489
                // write it out as XML
490
                try {
491
                        fireBeforeSavingFileEvent(new SaveEvent(this, SaveEvent.BEFORE_SAVING, file));
492
            FileOutputStream fos = new FileOutputStream(file.getAbsolutePath());
493
            OutputStreamWriter writer = new OutputStreamWriter(fos, PROJECTENCODING);
494
                        Marshaller m = new Marshaller(writer);
495
                        m.setEncoding(PROJECTENCODING);
496
                        p.setName(file.getName());
497
                        // p.setPath(file.toString());
498
                        p.setModificationDate(DateFormat.getDateInstance().format(new Date()));
499
                        p.setModified(false);
500
                        XMLEntity xml = p.getXMLEntity();
501
                        xml.putProperty("followHeaderEncoding", true, false);
502
                        m.marshal(xml.getXmlTag());
503
                        fireAfterSavingFileEvent(new SaveEvent(this, SaveEvent.AFTER_SAVING, file));
504
                        PluginServices.getMainFrame().setTitle(file.getName());
505
                        setPath(file.toString());
506

    
507
                } catch (Exception e) {
508
                        JOptionPane.showMessageDialog(
509
                                        (Component) PluginServices.getMainFrame(),PluginServices.getText(this,"error_writing_project")+":\n-"
510
                                        + PluginServices.getText(this,"the_user_cannot_edit_the_project_because_it_has_not_write_permissions")+".",
511
                                        PluginServices.getText(this,"warning"), JOptionPane.OK_OPTION);
512
//                        NotificationManager.addError(PluginServices.getText(this,"error_writing_project")+ ": "+file.getName(), e);
513
                        return false;
514
                }
515
                NotificationManager.addInfo(PluginServices.getText(this,"wrote_project")+ ": "+file.getName());
516
                return true;
517
        }
518

    
519
        public Project readProject(String path) {
520
                pathGenerator.setBasePath(new File(path).getParent());
521
                BufferedReader reader =null;
522
                try {
523
                URL url=null;
524
                        url = new URL(path);
525
                        String encoding = XMLEncodingUtils.getEncoding(url.openStream());
526
                        InputStream is = url.openStream();
527
                        if (encoding!=null) {
528
                                Project proj=null;
529
                                try {
530
                                        reader = new BufferedReader(new InputStreamReader(is, encoding));
531
                                        proj=readProject(reader, true);
532
                                } catch (UnsupportedEncodingException e) {
533
                                        reader = new BufferedReader(new InputStreamReader(is));
534
                                        try {
535
                                                Project p=readProject(reader, false);
536
                                        } catch (UnsupportedEncodingException e1) {
537
                                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this, e1.getLocalizedMessage()));
538
                                                return null;
539
                                        }
540
                                }
541
                                ProjectExtension.setPath(path);
542
                                return proj;
543
                        }
544
                        else {
545
                                reader = new BufferedReader(new InputStreamReader(is));
546
                                Project p;
547
                                try {
548
                                        p = readProject(reader, false);
549
                                } catch (UnsupportedEncodingException e) {
550
                                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this, e.getLocalizedMessage()));
551
                                        return null;
552
                                }
553
                                ProjectExtension.setPath(path); //p.setPath(null);
554
                                return p;
555
                        }
556
                } catch (MalformedURLException e) {
557
                        File file=new File(path);
558
                        return readProject(file);
559
                } catch (IOException e) {
560
                        e.printStackTrace();
561
                        return null;
562
                }
563
        }
564

    
565
        /**
566
         * Lee del XML el proyecto.<br><br>
567
         *
568
         * Reads the XML of the project.<br>
569
         * It returns a project object holding all needed info that is not linked to the Project Dialog. <br>In case you want the project to be
570
         * linked to the window you must set this object to the extension:<br>
571
         *
572
         * <b>Example:</b><br>
573
         *
574
         * ...<br>
575
         * ...<br>
576
         * Project p = ProjectExtension.readProject(projectFile);<br>
577
         * ProjectExtension.setProject(p);
578
         * ...<br>
579
         * ...<br>
580
         * @param file Fichero.
581
         *
582
         * @return Project
583
         *
584
         */
585
        public Project readProject(File file) {
586
                pathGenerator.setBasePath(file.getParent());
587
                File xmlFile = new File(file.getAbsolutePath());
588
                try {
589
                        String encoding = XMLEncodingUtils.getEncoding(new FileInputStream(xmlFile));
590
                        InputStreamReader reader=null;
591
                        if (encoding!=null) {
592
                                try {
593
                                        reader = new InputStreamReader(new FileInputStream(xmlFile), encoding);
594
                                        return readProject(reader, true);
595
                                } catch (UnsupportedEncodingException e) {
596
                                        reader = new InputStreamReader(new FileInputStream(xmlFile));
597
                                        try {
598
                                                return readProject(reader, false);
599
                                        } catch (UnsupportedEncodingException e1) {
600
                                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this, e1.getLocalizedMessage()));
601
                                                return null;
602
                                        }
603
                                }
604
                        }
605
                        else {
606
                                reader = new InputStreamReader(new FileInputStream(xmlFile));
607
                                try {
608
                                        return readProject(reader, false);
609
                                } catch (UnsupportedEncodingException e1) {
610
                                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this, e1.getLocalizedMessage()));
611
                                        return null;
612
                                }
613
                        }
614
                } catch (FileNotFoundException e) {
615
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this, "fichero_incorrecto"));
616
                        return null;
617
                }
618
        }
619

    
620
        /**
621
         * Lee del XML el proyecto.<br><br>
622
         *
623
         * Reads the XML of the project.<br>
624
         * It returns a project object holding all needed info that is not linked to the Project Dialog. <br>In case you want the project to be
625
         * linked to the window you must set this object to the extension:<br>
626
         *
627
         * <b>Example:</b><br>
628
         *
629
         * ...<br>
630
         * ...<br>
631
         * Project p = ProjectExtension.readProject(projectFile);<br>
632
         * ProjectExtension.setProject(p);
633
         * ...<br>
634
         * ...<br>
635
         * @param reader File reader
636
         * @param encodingFollowed Whether the encoded specified in the xml header was followed
637
         * when creating the reader. If the property followHeaderEncoding is false or not set,
638
         * then the encoding should have not been used when creating the reader, so it must be
639
         * recreated.
640
         *
641
         * @return Project
642
         * @throws UnsupportedEncodingException
643
         *
644
         */
645
        public Project readProject(Reader reader, boolean encodingFollowed) throws UnsupportedEncodingException {
646
                Project proj = null;
647

    
648
                try {
649
                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
650
                        XMLEntity xml=new XMLEntity(tag);
651
                        String VERSION=xml.getStringProperty("VERSION");
652
                        NotificationManager.addInfo(PluginServices.getText(this,"openning_project")+ ": "+xml.getStringProperty("name"));
653

    
654
                        if (encodingFollowed) {
655
                                if (xml.contains("followHeaderEncoding")) {
656
                                        boolean useEncoding = xml.getBooleanProperty("followHeaderEncoding");
657
                                        if (!useEncoding) {
658
                                                throw new UnsupportedEncodingException("the encoding specified in the xml header is not safe");
659
                                        }
660
                                }
661
                                else {
662
                                        // Old projects didn't contain followHeaderEncoding and they were
663
                                        // not correctly encoded. We throw an exception now, and we'll try
664
                                        // to reopen the project
665
                                        // using the default system encoding.
666
                                        throw new UnsupportedEncodingException("the encoding specified in the xml header is not safe");
667
                                }
668
                        }
669

    
670
                        try {
671
                                // if ((VERSION!=null) && (VERSION.equals("0.5") || VERSION.equals("0.4") || (VERSION.indexOf("GISPLANET") != -1))){
672
                                if (VERSION != null) {
673
                                        proj = Project.createFromXML(xml);
674
                                }else{
675
                                        proj = Project.createFromXML03(new XMLEntity(tag));
676
                                }
677
                                if (!VERSION.equals(Version.format())){
678
                                        NotificationManager.showMessageInfo(PluginServices.getText(this, "this_project_is_a_previous_version"),null);
679
                                }
680
                                return proj;
681
                        } catch (OpenException e){
682
                                e.showError();
683
                                //NotificationManager.addInfo("Al leer el proyecto", e);
684
                        }
685
                }  catch (MarshalException e) {
686
                        PluginServices.getLogger().error(PluginServices.getText(this, "formato_incorrecto"),e);
687
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this, "formato_incorrecto"));
688
                        //NotificationManager.addError("Al leer el proyecto", e);
689
                } catch (ValidationException e) {
690
                        PluginServices.getLogger().error(PluginServices.getText(this, "formato_incorrecto"),e);
691
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this, "formato_incorrecto"));
692
                        //NotificationManager.addError("Al leer el proyecto", e);
693
                }
694
                NotificationManager.addInfo(PluginServices.getText(this,"error_openning_project"));
695

    
696
                return null;
697
        }
698

    
699
        /**
700
         * Devuelve el proyecto.
701
         *
702
         * @return Proyecto.
703
         */
704
        public Project getProject() {
705
                return p;
706
        }
707

    
708
        /**
709
         * @see com.iver.andami.plugins.IExtension#isEnabled()
710
         */
711
        public boolean isEnabled() {
712
                return true;
713
        }
714

    
715
        /**
716
         * @see com.iver.andami.plugins.IExtension#isVisible()
717
         */
718
        public boolean isVisible() {
719
                return true;
720
        }
721

    
722
        /**
723
         * Sets the project
724
         * @param p
725
         */
726
        public void setProject(Project p){
727
                getProjectFrame().setProject(p);
728
                this.p=p;
729
        }
730

    
731
        private void registerDocuments() {
732
                ProjectViewFactory.register();
733
                ProjectTableFactory.register();
734
                ProjectMapFactory.register();
735
        }
736

    
737
        private void initializeDocumentActionsExtensionPoint() {
738
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
739
                if (!extensionPoints.containsKey("DocumentActions_View")) {
740
                        extensionPoints.put(
741
                                new ExtensionPoint(
742
                                        "DocumentActions_View",
743
                                        "Context menu options of the view document list" +
744
                                                " in the project window "+
745
                                                "(register instances of " +
746
                                                "com.iver.cit.gvsig.project.AbstractDocumentContextMenuAction)"
747
                                )
748
                        );
749
                }
750
                if (!extensionPoints.containsKey("DocumentActions_Table")) {
751
                        extensionPoints.put(
752
                                new ExtensionPoint(
753
                                        "DocumentActions_Table",
754
                                        "Context menu options of the table document list" +
755
                                                " in the project window "+
756
                                                "(register instances of " +
757
                                                "com.iver.cit.gvsig.project.AbstractDocumentContextMenuAction)"
758
                                )
759
                        );
760
                }
761
                if (!extensionPoints.containsKey("DocumentActions_Map")) {
762
                        extensionPoints.put(
763
                                new ExtensionPoint(
764
                                        "DocumentActions_Map",
765
                                        "Context menu options of the map document list" +
766
                                                " in the project window "+
767
                                                "(register instances of " +
768
                                                "com.iver.cit.gvsig.project.AbstractDocumentContextMenuAction)"
769
                                )
770
                        );
771
                }
772
        }
773

    
774
        public static String getPath() {
775
                return projectPath;
776
        }
777

    
778
        public static void setPath(String path) {
779
                projectPath = path;
780
        }
781

    
782
        public IWindow getProjectWindow() {
783
                return getProjectFrame();
784
        }
785

    
786

    
787
        public IExtensionStatus getStatus() {
788
                return this;
789
        }
790

    
791
        public boolean hasUnsavedData() {
792
                return p.hasChanged();
793
        }
794

    
795
        public IUnsavedData[] getUnsavedData() {
796
                if (hasUnsavedData()) {
797
                        UnsavedProject data = new UnsavedProject(this);
798
                        IUnsavedData[] dataArray = {data};
799
                        return dataArray;
800
                }
801
                else
802
                        return null;
803
        }
804

    
805
        /**
806
         * Implements the IUnsavedData interface to show unsaved projects
807
         * in the Unsavad Data dialog.
808
         *
809
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
810
         */
811
        public class UnsavedProject  extends UnsavedData {
812

    
813
                public UnsavedProject(IExtension extension) {
814
                        super(extension);
815
                }
816

    
817
                public String getDescription() {
818
                        if (getPath()==null) {
819
                                return PluginServices.getText(ProjectExtension.this, "Unnamed_new_gvsig_project_");
820
                        }
821
                        else {
822
                                return PluginServices.getText(ProjectExtension.this, "Modified_project_");
823
                        }
824
                }
825

    
826
                public String getResourceName() {
827
                        if (getPath()==null) {
828
                                return PluginServices.getText(ProjectExtension.this, "Unnamed");
829
                        }
830
                        else {
831
                                return getPath();
832
                        }
833

    
834
                }
835

    
836
                public boolean saveData() {
837
                        return guardar();
838
                }
839

    
840
                public ImageIcon getIcon() {
841
                        try {
842
                                URL imagePath = PluginServices.getPluginServices(ProjectExtension.this).getClassLoader().getResource("images/logoGVA.gif");
843
                                return new ImageIcon(imagePath);
844
                        }
845
                        catch (Exception ex) {}
846
                        return null;
847
                }
848
        }
849

    
850
        public IMonitorableTask[] getRunningProcesses() {
851
                // TODO Auto-generated method stub
852
                return null;
853
        }
854
        public boolean hasRunningProcesses() {
855
                // TODO Auto-generated method stub
856
                return false;
857
        }
858

    
859
    /**
860
     * Adds the specified before saving listener to receive "before saving file events" from
861
     * this component.
862
     * If l is null, no exception is thrown and no action is performed.
863
     *
864
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
865
     *
866
     * @param    l the before saving listener.
867
     * @see      SaveEvent
868
     * @see      BeforeSavingListener
869
     * @see      #removeListener(BeforeSavingListener)
870
     * @see      #getBeforeSavingListeners
871
     */
872
    public synchronized void addListener(BeforeSavingListener l) {
873
        if (l == null) {
874
            return;
875
        }
876

    
877
        ExtensionPoints ePs = ((ExtensionPoints) ExtensionPointsSingleton.getInstance());
878

    
879
        if (ePs.get(BEFORE_SAVING_ID) == null) {
880
                ArrayList aL = new ArrayList();
881
                aL.add(l);
882

    
883
                ePs.add(BEFORE_SAVING_ID, "", aL);
884
                return;
885
        }
886

    
887
        ((ArrayList)((ExtensionPoint)ePs.get(BEFORE_SAVING_ID)).get("")).add(l);
888
    }
889

    
890
    /**
891
     * Adds the specified after saving listener to receive "after saving file events" from
892
     * this component.
893
     * If l is null, no exception is thrown and no action is performed.
894
     *
895
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
896
     *
897
     * @param    l the after saving listener.
898
     * @see      SaveEvent
899
     * @see      AfterSavingListener
900
     * @see      #removeListener(AfterSavingListener)
901
     * @see      #getAfterSavingListeners()
902
     */
903
    public synchronized void addListener(AfterSavingListener l) {
904
        if (l == null) {
905
            return;
906
        }
907

    
908
        ExtensionPoints ePs = ((ExtensionPoints) ExtensionPointsSingleton.getInstance());
909

    
910
        if (ePs.get(AFTER_SAVING_ID) == null) {
911
                ArrayList aL = new ArrayList();
912
                aL.add(l);
913

    
914
                ePs.add(AFTER_SAVING_ID, "", aL);
915
                return;
916
        }
917

    
918
        ((ArrayList)((ExtensionPoint)ePs.get(AFTER_SAVING_ID)).get("")).add(l);
919
    }
920

    
921
    /**
922
     * Returns an array of all the before saving listeners
923
     * registered on this component.
924
     *
925
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
926
     *
927
     * @return all of this component's <code>BeforeSavingListener</code>s
928
     *         or an empty array if no key
929
     *         listeners are currently registered
930
     *
931
     * @see      #addBeforeSavingListener(BeforeSavingListener)
932
     * @see      #removeBeforeSavingListener(BeforeSavingListener)
933
     */
934
    public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
935
            ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
936

    
937
            if (eP == null)
938
                    return null;
939

    
940
            return eP.get("") == null ? null : (BeforeSavingListener[]) ((ArrayList)eP.get("")).toArray(new BeforeSavingListener[0]);
941
    }
942

    
943
    /**
944
     * Returns an array of all the after saving listeners
945
     * registered on this component.
946
     *
947
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
948
     *
949
     * @return all of this component's <code>AfterSavingListener</code>s
950
     *         or an empty array if no key
951
     *         listeners are currently registered
952
     *
953
     * @see      #addAfterSavingListener(AfterSavingListener)
954
     * @see      #removeAfterSavingListener
955
     */
956
    public synchronized AfterSavingListener[] getAfterSavingListeners() {
957
            ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
958

    
959
            if (eP == null)
960
                    return null;
961

    
962
            return eP.get("") == null ? null : (AfterSavingListener[]) ((ArrayList)eP.get("")).toArray(new AfterSavingListener[0]);
963
    }
964

    
965
    /**
966
     * Removes the specified before saving listener so that it no longer
967
     * receives save file events from this component. This method performs
968
     * no function, nor does it throw an exception, if the listener
969
     * specified by the argument was not previously added to this component.
970
     * If listener <code>l</code> is <code>null</code>,
971
     * no exception is thrown and no action is performed.
972
     *
973
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
974
     *
975
     * @param    l   the before saving listener
976
     * @see      SaveEvent
977
     * @see      BeforeSavingListener
978
     * @see      #addListener(BeforeSavingListener)
979
     * @see      #getBeforeSavingListeners()
980
     */
981
    public synchronized void removeListener(BeforeSavingListener l) {
982
        if (l == null) {
983
            return;
984
        }
985

    
986
        ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
987

    
988
        if (eP != null) {
989
                ((ArrayList)eP.get("")).remove(l);
990
        }
991
    }
992

    
993
    /**
994
     * Removes the specified after saving listener so that it no longer
995
     * receives save file events from this component. This method performs
996
     * no function, nor does it throw an exception, if the listener
997
     * specified by the argument was not previously added to this component.
998
     * If listener <code>l</code> is <code>null</code>,
999
     * no exception is thrown and no action is performed.
1000
     *
1001
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
1002
     *
1003
     * @param    l   the after saving listener
1004
     * @see      SaveEvent
1005
     * @see      AfterSavingListener
1006
     * @see      #addListener(AfterSavingListener)
1007
     * @see      #getAfterSavingListeners()
1008
     */
1009
    public synchronized void removeListener(AfterSavingListener l) {
1010
        if (l == null) {
1011
            return;
1012
        }
1013

    
1014
        ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
1015

    
1016
        if (eP != null) {
1017
                ((ArrayList)eP.get("")).remove(l);
1018
        }
1019
    }
1020

    
1021
    /**
1022
     * Reports a before saving file event.
1023
     *
1024
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
1025
     *
1026
     * @param evt the before saving file event
1027
     */
1028
    protected void fireBeforeSavingFileEvent(SaveEvent evt) {
1029
        if ((evt.getID() != SaveEvent.BEFORE_SAVING) || (evt.getFile() == null)) {
1030
            return;
1031
        }
1032

    
1033
        ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
1034

    
1035
        if (eP != null) {
1036
                ArrayList listeners = ((ArrayList)eP.get(""));
1037

    
1038
                for (int i = 0; i < listeners.size(); i++)
1039
                                ((BeforeSavingListener)listeners.get(i)).beforeSaving(evt);
1040
        }
1041
    }
1042

    
1043
    /**
1044
     * Reports a after saving file event.
1045
     *
1046
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
1047
     *
1048
     * @param evt the after saving file event
1049
     */
1050
    protected void fireAfterSavingFileEvent(SaveEvent evt) {
1051
        if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
1052
            return;
1053
        }
1054

    
1055
        ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
1056

    
1057
        if (eP != null) {
1058
                ArrayList listeners = ((ArrayList)eP.get(""));
1059

    
1060
                for (int i = 0; i < listeners.size(); i++)
1061
                                ((AfterSavingListener)listeners.get(i)).afterSaving(evt);
1062
        }
1063
    }
1064
}