Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / ProjectExtension.java @ 27352

History | View | Annotate | Download (34.3 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

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

    
106

    
107
/**
108
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
109
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos
110
 * en esta clase.
111
 *
112
 * @author Fernando Gonz?lez Cort?s
113
 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es)
114
 */
115
public class ProjectExtension extends Extension implements IExtensionStatus {
116
        private static String projectPath = null;
117
        //private ProjectWindow projectFrame;
118
        private ProjectWindow projectFrame;
119
        private Project p;
120
        private String lastPath;
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
         * Use UTF-8 for encoding, as it can represent characters from
128
         * any language.
129
         *
130
         * Another sensible option would be
131
         * encoding = System.getProperty("file.encoding");
132
         * but this would need some extra testing.
133
         */
134
        public static String PROJECTENCODING = "UTF-8";
135

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

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

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

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

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

    
166
        initializeDocumentActionsExtensionPoint();
167
        registerDocuments();
168

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

    
176
            registerIcons();
177

    
178
        }
179

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

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

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

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

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

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

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

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

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

    
292
        private boolean guardarDialogo(){
293
                boolean saved=false;
294

    
295
                if (lastSavePath == null)
296
                        lastSavePath = projectPath;
297

    
298

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

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

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

    
315
                        getProjectFrame().refreshControls();
316
                }
317
                return saved;
318
        }
319

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

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

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

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

    
371
                        if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
372
                                ProjectDocument.initializeNUMS();
373
                                PluginServices.getMDIManager().closeAllWindows();
374

    
375
                                File projectFile = jfc.getSelectedFile();
376
                                Project o = readProject(projectFile);
377
                                setPath(projectFile.getAbsolutePath());
378
                                lastPath = getPath();
379
                                if (o != null) {
380
                                        setProject(o);
381
                                }
382

    
383
                                getProjectFrame().setProject(p);
384
                                PluginServices.getMainFrame().setTitle(p.getName());
385
                                getProjectFrame().refreshControls();
386

    
387
//jaume                                p.setModified(true);
388
                                p.restoreWindowProperties();
389
                        }
390
                } else if (actionCommand.equals("GUARDAR")) {
391
                        guardar();
392
//jaume                        p.setModified(false);
393
                } else if (actionCommand.equals("GUARDAR_COMO")) {
394
                        guardarDialogo();
395
//jaume                        p.setModified(false);
396
                } else if (actionCommand.equals("SALIR")){
397
                        Launcher.closeApplication();
398
                } else if (actionCommand.compareTo("OPENTEMPLATE")==0){
399
                        openLayout();
400
//jaume                        p.setModified(true);
401
                }
402
        }
403
        public void openLayout() {
404
                //Project project = ((ProjectExtension) PluginServices.getExtension(ProjectExtension.class)).getProject();
405
                Layout layout=null;
406

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

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

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

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

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

    
456

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

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

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

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

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

    
616
        /**
617
         * Lee del XML el proyecto.<br><br>
618
         *
619
         * Reads the XML of the project.<br>
620
         * 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
621
         * linked to the window you must set this object to the extension:<br>
622
         *
623
         * <b>Example:</b><br>
624
         *
625
         * ...<br>
626
         * ...<br>
627
         * Project p = ProjectExtension.readProject(projectFile);<br>
628
         * ProjectExtension.setProject(p);
629
         * ...<br>
630
         * ...<br>
631
         * @param reader File reader
632
         * @param encodingFollowed Whether the encoded specified in the xml header was followed
633
         * when creating the reader. If the property followHeaderEncoding is false or not set,
634
         * then the encoding should have not been used when creating the reader, so it must be
635
         * recreated.
636
         *
637
         * @return Project
638
         * @throws UnsupportedEncodingException
639
         *
640
         */
641
        public Project readProject(Reader reader, boolean encodingFollowed) throws UnsupportedEncodingException {
642
                Project proj = null;
643

    
644
                try {
645
                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
646
                        XMLEntity xml=new XMLEntity(tag);
647
                        String VERSION=xml.getStringProperty("VERSION");
648
                        NotificationManager.addInfo(PluginServices.getText(this,"openning_project")+ ": "+xml.getStringProperty("name"));
649

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

    
666
                        try {
667
                                // if ((VERSION!=null) && (VERSION.equals("0.5") || VERSION.equals("0.4") || (VERSION.indexOf("GISPLANET") != -1))){
668
                                if (VERSION != null) {
669
                                        proj = Project.createFromXML(xml);
670
                                }else{
671
                                        proj = Project.createFromXML03(new XMLEntity(tag));
672
                                }
673
                                NotificationManager.addInfo(PluginServices.getText(this,"opened_project")+ ": "+xml.getStringProperty("name"));
674

    
675
                                return proj;
676
                        } catch (OpenException e){
677
                                e.showError();
678
                                //NotificationManager.addInfo("Al leer el proyecto", e);
679
                        }
680
                }  catch (MarshalException e) {
681
                        PluginServices.getLogger().error(PluginServices.getText(this, "formato_incorrecto"),e);
682
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this, "formato_incorrecto"));
683
                        //NotificationManager.addError("Al leer el proyecto", e);
684
                } catch (ValidationException e) {
685
                        PluginServices.getLogger().error(PluginServices.getText(this, "formato_incorrecto"),e);
686
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this, "formato_incorrecto"));
687
                        //NotificationManager.addError("Al leer el proyecto", e);
688
                }
689
                NotificationManager.addInfo(PluginServices.getText(this,"error_openning_project"));
690

    
691
                return null;
692
        }
693

    
694
        /**
695
         * Devuelve el proyecto.
696
         *
697
         * @return Proyecto.
698
         */
699
        public Project getProject() {
700
                return p;
701
        }
702

    
703
        /**
704
         * @see com.iver.andami.plugins.IExtension#isEnabled()
705
         */
706
        public boolean isEnabled() {
707
                return true;
708
        }
709

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

    
717
        /**
718
         * Sets the project
719
         * @param p
720
         */
721
        public void setProject(Project p){
722
                getProjectFrame().setProject(p);
723
                this.p=p;
724
        }
725

    
726
        private void registerDocuments() {
727
                ProjectViewFactory.register();
728
                ProjectTableFactory.register();
729
                ProjectMapFactory.register();
730
        }
731

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

    
769
        public static String getPath() {
770
                return projectPath;
771
        }
772

    
773
        public static void setPath(String path) {
774
                projectPath = path;
775
        }
776

    
777
        public IWindow getProjectWindow() {
778
                return getProjectFrame();
779
        }
780

    
781

    
782
        public IExtensionStatus getStatus() {
783
                return this;
784
        }
785

    
786
        public boolean hasUnsavedData() {
787
                return p.hasChanged();
788
        }
789

    
790
        public IUnsavedData[] getUnsavedData() {
791
                if (hasUnsavedData()) {
792
                        UnsavedProject data = new UnsavedProject(this);
793
                        IUnsavedData[] dataArray = {data};
794
                        return dataArray;
795
                }
796
                else
797
                        return null;
798
        }
799

    
800
        /**
801
         * Implements the IUnsavedData interface to show unsaved projects
802
         * in the Unsavad Data dialog.
803
         *
804
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
805
         */
806
        public class UnsavedProject  extends UnsavedData {
807

    
808
                public UnsavedProject(IExtension extension) {
809
                        super(extension);
810
                }
811

    
812
                public String getDescription() {
813
                        if (getPath()==null) {
814
                                return PluginServices.getText(ProjectExtension.this, "Unnamed_new_gvsig_project_");
815
                        }
816
                        else {
817
                                return PluginServices.getText(ProjectExtension.this, "Modified_project_");
818
                        }
819
                }
820

    
821
                public String getResourceName() {
822
                        if (getPath()==null) {
823
                                return PluginServices.getText(ProjectExtension.this, "Unnamed");
824
                        }
825
                        else {
826
                                return getPath();
827
                        }
828

    
829
                }
830

    
831
                public boolean saveData() {
832
                        return guardar();
833
                }
834

    
835
                public ImageIcon getIcon() {
836
                        try {
837
                                URL imagePath = PluginServices.getPluginServices(ProjectExtension.this).getClassLoader().getResource("images/logoGVA.gif");
838
                                return new ImageIcon(imagePath);
839
                        }
840
                        catch (Exception ex) {}
841
                        return null;
842
                }
843
        }
844

    
845
        public IMonitorableTask[] getRunningProcesses() {
846
                // TODO Auto-generated method stub
847
                return null;
848
        }
849
        public boolean hasRunningProcesses() {
850
                // TODO Auto-generated method stub
851
                return false;
852
        }
853

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

    
872
        ExtensionPoints ePs = ((ExtensionPoints) ExtensionPointsSingleton.getInstance());
873

    
874
        if (ePs.get(BEFORE_SAVING_ID) == null) {
875
                ArrayList aL = new ArrayList();
876
                aL.add(l);
877

    
878
                ePs.add(BEFORE_SAVING_ID, "", aL);
879
                return;
880
        }
881

    
882
        ((ArrayList)((ExtensionPoint)ePs.get(BEFORE_SAVING_ID)).get("")).add(l);
883
    }
884

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

    
903
        ExtensionPoints ePs = ((ExtensionPoints) ExtensionPointsSingleton.getInstance());
904

    
905
        if (ePs.get(AFTER_SAVING_ID) == null) {
906
                ArrayList aL = new ArrayList();
907
                aL.add(l);
908

    
909
                ePs.add(AFTER_SAVING_ID, "", aL);
910
                return;
911
        }
912

    
913
        ((ArrayList)((ExtensionPoint)ePs.get(AFTER_SAVING_ID)).get("")).add(l);
914
    }
915

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

    
932
            if (eP == null)
933
                    return null;
934

    
935
            return eP.get("") == null ? null : (BeforeSavingListener[]) ((ArrayList)eP.get("")).toArray(new BeforeSavingListener[0]);
936
    }
937

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

    
954
            if (eP == null)
955
                    return null;
956

    
957
            return eP.get("") == null ? null : (AfterSavingListener[]) ((ArrayList)eP.get("")).toArray(new AfterSavingListener[0]);
958
    }
959

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

    
981
        ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
982

    
983
        if (eP != null) {
984
                ((ArrayList)eP.get("")).remove(l);
985
        }
986
    }
987

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

    
1009
        ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
1010

    
1011
        if (eP != null) {
1012
                ((ArrayList)eP.get("")).remove(l);
1013
        }
1014
    }
1015

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

    
1028
        ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
1029

    
1030
        if (eP != null) {
1031
                ArrayList listeners = ((ArrayList)eP.get(""));
1032

    
1033
                for (int i = 0; i < listeners.size(); i++)
1034
                                ((BeforeSavingListener)listeners.get(i)).beforeSaving(evt);
1035
        }
1036
    }
1037

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

    
1050
        ExtensionPoint eP = (ExtensionPoint)((ExtensionPoints) ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
1051

    
1052
        if (eP != null) {
1053
                ArrayList listeners = ((ArrayList)eP.get(""));
1054

    
1055
                for (int i = 0; i < listeners.size(); i++)
1056
                                ((AfterSavingListener)listeners.get(i)).afterSaving(evt);
1057
        }
1058
    }
1059
}