Statistics
| Revision:

root / branches / v2_0_0_prep / applications / appgvSIG / src / org / gvsig / app / extension / ProjectExtension.java @ 30580

History | View | Annotate | Download (33.8 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 org.gvsig.app.extension;
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.Iterator;
62
import java.util.List;
63
import java.util.prefs.Preferences;
64

    
65
import javax.swing.JOptionPane;
66

    
67
import org.exolab.castor.xml.MarshalException;
68
import org.exolab.castor.xml.Marshaller;
69
import org.exolab.castor.xml.ValidationException;
70
import org.gvsig.andami.Launcher;
71
import org.gvsig.andami.PluginServices;
72
import org.gvsig.andami.Launcher.TerminationProcess;
73
import org.gvsig.andami.messages.NotificationManager;
74
import org.gvsig.andami.plugins.Extension;
75
import org.gvsig.andami.plugins.IExtension;
76
import org.gvsig.andami.plugins.status.IExtensionStatus;
77
import org.gvsig.andami.plugins.status.IUnsavedData;
78
import org.gvsig.andami.plugins.status.UnsavedData;
79
import org.gvsig.andami.ui.mdiManager.IWindow;
80
import org.gvsig.andami.ui.mdiManager.WindowInfo;
81
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
82
import org.gvsig.app.project.Project;
83
import org.gvsig.app.project.ProjectFactory;
84
import org.gvsig.app.project.documents.ProjectDocument;
85
import org.gvsig.app.project.documents.exceptions.OpenException;
86
import org.gvsig.app.project.documents.gui.ProjectWindow;
87
import org.gvsig.app.project.documents.layout.ProjectMap;
88
import org.gvsig.app.project.documents.layout.ProjectMapFactory;
89
import org.gvsig.app.project.documents.layout.gui.Layout;
90
import org.gvsig.app.project.documents.table.FeatureTableDocumentFactory;
91
import org.gvsig.app.project.documents.view.ProjectViewFactory;
92
import org.gvsig.gui.beans.swing.JFileChooser;
93
import org.gvsig.tools.ToolsLocator;
94
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
95
import org.gvsig.utils.GenericFileFilter;
96
import org.gvsig.utils.XMLEntity;
97
import org.gvsig.utils.save.AfterSavingListener;
98
import org.gvsig.utils.save.BeforeSavingListener;
99
import org.gvsig.utils.save.SaveEvent;
100
import org.gvsig.utils.swing.threads.IMonitorableTask;
101
import org.gvsig.utils.xml.XMLEncodingUtils;
102
import org.gvsig.utils.xmlEntity.generate.XmlTag;
103

    
104

    
105

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

    
134
        private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
135
        //        /**
136
        //         * <p>Identifier of the extension point used by <code>ProjectExtension</code> to manage {@link BeforeSavingListener BeforeSavingListener}s.</p>
137
        //         */
138
        //        public static final String BEFORE_SAVING_ID = "Before_Saving_PrjExt";
139

    
140
        private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
141

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

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

    
157
//                LayerFactory.setWritersPath(PluginServices.getPluginServices(this)
158
//                                  .getPluginDirectory()
159
//                                  .getAbsolutePath() +
160
//                                  File.separator + "drivers");
161
//
162
//        LayerFactory.setDriversPath(PluginServices.getPluginServices(this)
163
//                                  .getPluginDirectory()
164
//                                  .getAbsolutePath() +
165
//                                  File.separator + "drivers");
166

    
167
        initializeDocumentActionsExtensionPoint();
168
        registerDocuments();
169

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

    
177
            registerIcons();
178

    
179
        }
180

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

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

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

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

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

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

    
241
        public ProjectWindow getProjectFrame() {
242
                if (projectFrame==null) {
243
                        projectFrame = new ProjectWindow();
244
                }
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
                } else {
262
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
263
                }
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

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

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

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

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

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

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

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

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

    
375
                        if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
376
                                ProjectDocument.initializeNUMS();
377
                                PluginServices.getMDIManager().closeAllWindows();
378

    
379
                                File projectFile = jfc.getSelectedFile();
380
                                Project o = readProject(projectFile);
381
                                setPath(projectFile.getAbsolutePath());
382
                                lastPath = getPath();
383
                                if (o != null) {
384
                                        setProject(o);
385
                                }
386

    
387
                                getProjectFrame().setProject(p);
388
                                PluginServices.getMainFrame().setTitle(p.getName());
389
                                getProjectFrame().refreshControls();
390

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

    
411
                if (templatesPath == null) {
412
                        Preferences prefs = Preferences.userRoot().node( "gvsig.foldering" );
413
                        templatesPath = prefs.get("TemplatesFolder", null);
414
                }
415

    
416
                JFileChooser jfc = new JFileChooser(LAYOUT_TEMPLATE_FILECHOOSER_ID, templatesPath);
417
                jfc.addChoosableFileFilter(new GenericFileFilter("gvt",
418
                                PluginServices.getText(this, "plantilla")));
419

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

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

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

    
460

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

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

    
509
                } catch (Exception e) {
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
                                                proj = 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
                                proj = Project.createFromXML(xml);
668
                                NotificationManager.addInfo(PluginServices.getText(this,"opened_project")+ ": "+xml.getStringProperty("name"));
669

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

    
686
                return null;
687
        }
688

    
689
        /**
690
         * Devuelve el proyecto.
691
         *
692
         * @return Proyecto.
693
         */
694
        public Project getProject() {
695
                return p;
696
        }
697

    
698
        /**
699
         * @see org.gvsig.andami.plugins.IExtension#isEnabled()
700
         */
701
        public boolean isEnabled() {
702
                return true;
703
        }
704

    
705
        /**
706
         * @see org.gvsig.andami.plugins.IExtension#isVisible()
707
         */
708
        public boolean isVisible() {
709
                return true;
710
        }
711

    
712
        /**
713
         * Sets the project
714
         * @param p
715
         */
716
        public void setProject(Project p){
717
                getProjectFrame().setProject(p);
718
                this.p=p;
719
        }
720

    
721
        private void registerDocuments() {
722
                ProjectViewFactory.register();
723
                FeatureTableDocumentFactory.register();
724
                ProjectMapFactory.register();
725
        }
726

    
727
        private void initializeDocumentActionsExtensionPoint() {
728
                ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
729
                epMan.add(
730
                        "DocumentActions_View",
731
                        "Context menu options of the view document list"
732
                                + " in the project window "
733
                                + "(register instances of "
734
                                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
735
                epMan.add(
736
                        "DocumentActions_Table",
737
                        "Context menu options of the table document list"
738
                                + " in the project window "
739
                                + "(register instances of "
740
                                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
741
                epMan.add(
742
                        "DocumentActions_Map",
743
                        "Context menu options of the map document list"
744
                                + " in the project window "
745
                                + "(register instances of "
746
                                + "org.gvsig.app.project.AbstractDocumentContextMenuAction)");
747
        }
748

    
749
        public static String getPath() {
750
                return projectPath;
751
        }
752

    
753
        public static void setPath(String path) {
754
                projectPath = path;
755
        }
756

    
757
        public IWindow getProjectWindow() {
758
                return getProjectFrame();
759
        }
760

    
761

    
762
        public IExtensionStatus getStatus() {
763
                return this;
764
        }
765

    
766
        public boolean hasUnsavedData() {
767
                return p.hasChanged();
768
        }
769

    
770
        public IUnsavedData[] getUnsavedData() {
771
                if (hasUnsavedData()) {
772
                        UnsavedProject data = new UnsavedProject(this);
773
                        IUnsavedData[] dataArray = {data};
774
                        return dataArray;
775
                } else {
776
                        return null;
777
                }
778
        }
779

    
780
        /**
781
         * Implements the IUnsavedData interface to show unsaved projects
782
         * in the Unsavad Data dialog.
783
         *
784
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
785
         */
786
        public class UnsavedProject  extends UnsavedData {
787

    
788
                public UnsavedProject(IExtension extension) {
789
                        super(extension);
790
                }
791

    
792
                public String getDescription() {
793
                        if (getPath()==null) {
794
                                return PluginServices.getText(ProjectExtension.this, "Unnamed_new_gvsig_project_");
795
                        }
796
                        else {
797
                                return PluginServices.getText(ProjectExtension.this, "Modified_project_");
798
                        }
799
                }
800

    
801
                public String getResourceName() {
802
                        if (getPath()==null) {
803
                                return PluginServices.getText(ProjectExtension.this, "Unnamed");
804
                        }
805
                        else {
806
                                return getPath();
807
                        }
808

    
809
                }
810

    
811
                public boolean saveData() {
812
                        return guardar();
813
                }
814

    
815
                public String getIcon() {
816
                        try {
817
                                URL imagePath = PluginServices.getPluginServices(ProjectExtension.this).getClassLoader().getResource("images/logoGVA.gif");
818
                                //TEST-ICON
819
                                //return new ImageIcon(imagePath);
820
                                return "images/logoGVA.gif"; 
821
                        }
822
                        catch (Exception ex) {}
823
                        return null;
824
                }
825
        }
826

    
827
        public IMonitorableTask[] getRunningProcesses() {
828
                // TODO Auto-generated method stub
829
                return null;
830
        }
831
        public boolean hasRunningProcesses() {
832
                // TODO Auto-generated method stub
833
                return false;
834
        }
835

    
836
    /**
837
     * Adds the specified before saving listener to receive "before saving file events" from
838
     * this component.
839
     * If l is null, no exception is thrown and no action is performed.
840
     *
841
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
842
     *
843
     * @param    l the before saving listener.
844
     * @see      SaveEvent
845
     * @see      BeforeSavingListener
846
     * @see      #removeListener(BeforeSavingListener)
847
     * @see      #getBeforeSavingListeners
848
     */
849
    public synchronized void addListener(BeforeSavingListener l) {
850
            if (l == null) {
851
                        return;
852
                }
853
                //
854
                //        ExtensionPoints ePs = (ExtensionPointsSingleton.getInstance());
855
                //
856
                //        if (ePs.get(BEFORE_SAVING_ID) == null) {
857
                //                ArrayList aL = new ArrayList();
858
                //                aL.add(l);
859
                //
860
                //                ePs.add(BEFORE_SAVING_ID, "", aL);
861
                //                return;
862
                //        }
863
                //
864
                //        ((ArrayList)((ExtensionPoint)ePs.get(BEFORE_SAVING_ID)).get("")).add(l);
865
                if (!this.beforeSavingListeners.contains(l)) {
866
                        this.beforeSavingListeners.add(l);
867
                }
868
    }
869

    
870
    /**
871
     * Adds the specified after saving listener to receive "after saving file events" from
872
     * this component.
873
     * If l is null, no exception is thrown and no action is performed.
874
     *
875
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
876
     *
877
     * @param    l the after saving listener.
878
     * @see      SaveEvent
879
     * @see      AfterSavingListener
880
     * @see      #removeListener(AfterSavingListener)
881
     * @see      #getAfterSavingListeners()
882
     */
883
    public synchronized void addListener(AfterSavingListener l) {
884
        if (l == null) {
885
            return;
886
        }
887

    
888
                //        ExtensionPoints ePs = (ExtensionPointsSingleton.getInstance());
889
                //
890
                //        if (ePs.get(AFTER_SAVING_ID) == null) {
891
                //                ArrayList aL = new ArrayList();
892
                //                aL.add(l);
893
                //
894
                //                ePs.add(AFTER_SAVING_ID, "", aL);
895
                //                return;
896
                //        }
897
                //
898
                //        ((ArrayList)((ExtensionPoint)ePs.get(AFTER_SAVING_ID)).get("")).add(l);
899
                if (!this.afterSavingListeners.contains(l)) {
900
                        this.afterSavingListeners.add(l);
901
                }
902

    
903
    }
904

    
905
    /**
906
     * Returns an array of all the before saving listeners
907
     * registered on this component.
908
     *
909
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
910
     *
911
     * @return all of this component's <code>BeforeSavingListener</code>s
912
     *         or an empty array if no key
913
     *         listeners are currently registered
914
     *
915
     * @see      #addBeforeSavingListener(BeforeSavingListener)
916
     * @see      #removeBeforeSavingListener(BeforeSavingListener)
917
     */
918
    public synchronized BeforeSavingListener[] getBeforeSavingListeners() {
919
                //            ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
920
                //
921
                //            if (eP == null) {
922
                //                        return null;
923
                //                }
924
                //
925
                //            return eP.get("") == null ? null : (BeforeSavingListener[]) ((ArrayList)eP.get("")).toArray(new BeforeSavingListener[0]);
926
            return this.beforeSavingListeners
927
                                .toArray(new BeforeSavingListener[] {});
928
    }
929

    
930
    /**
931
     * Returns an array of all the after saving listeners
932
     * registered on this component.
933
     *
934
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
935
     *
936
     * @return all of this component's <code>AfterSavingListener</code>s
937
     *         or an empty array if no key
938
     *         listeners are currently registered
939
     *
940
     * @see      #addAfterSavingListener(AfterSavingListener)
941
     * @see      #removeAfterSavingListener
942
     */
943
    public synchronized AfterSavingListener[] getAfterSavingListeners() {
944
                //            ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
945
                //
946
                //            if (eP == null) {
947
                //                        return null;
948
                //                }
949
                //
950
                //            return eP.get("") == null ? null : (AfterSavingListener[]) ((ArrayList)eP.get("")).toArray(new AfterSavingListener[0]);
951
                return this.afterSavingListeners.toArray(new AfterSavingListener[] {});
952

    
953
    }
954

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

    
976
                //        ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
977
                //
978
                //        if (eP != null) {
979
                //                ((ArrayList)eP.get("")).remove(l);
980
                //        }
981
                this.beforeSavingListeners.remove(l);
982
    }
983

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

    
1005
                //        ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
1006
                //
1007
                //        if (eP != null) {
1008
                //                ((ArrayList)eP.get("")).remove(l);
1009
                //        }
1010
                this.afterSavingListeners.remove(l);
1011
    }
1012

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

    
1025
                //        ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
1026

    
1027
                        //                ArrayList listeners = ((ArrayList)eP.get(""));
1028
        Iterator<BeforeSavingListener> iter = this.beforeSavingListeners
1029
                                .iterator();
1030

    
1031
        while (iter.hasNext()) {
1032
                        iter.next().beforeSaving(evt);
1033
        }
1034
    }
1035

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

    
1050
        while (iter.hasNext()) {
1051
                        iter.next().afterSaving(evt);
1052
                }
1053

    
1054
    }
1055
}