Statistics
| Revision:

root / branches / v2_0_0_prep / applications / appgvSIG / src / com / iver / cit / gvsig / ProjectExtension.java @ 24962

History | View | Annotate | Download (33.6 KB)

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

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

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

    
66
import org.exolab.castor.xml.MarshalException;
67
import org.exolab.castor.xml.Marshaller;
68
import org.exolab.castor.xml.ValidationException;
69
import org.gvsig.gui.beans.swing.JFileChooser;
70
import org.gvsig.project.document.table.FeatureTableDocumentFactory;
71
import org.gvsig.tools.ToolsLocator;
72
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
73

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

    
107

    
108
/**
109
 * Extension que proporciona controles para crear proyectos nuevos, abrirlos y
110
 * guardarlos. Adem?s los tipos de tabla que soporta el proyecto son a?adidos
111
 * en esta clase.
112
 *
113
 * @author Fernando Gonz?lez Cort?s
114
 */
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
                }
244
                return projectFrame;
245
        }
246
        /**
247
         * Muestra la ventana con el gestor de proyectos.
248
         */
249
        public void showProjectWindow() {
250
                if (seedProjectWindow!=null) {
251
                        if (seedProjectWindow.isClosed()) {
252
                                // if it was closed, we just don't open the window now
253
                                seedProjectWindow.setClosed(false);
254
                                return;
255
                        }
256
                        WindowInfo winProps = seedProjectWindow;
257
                        seedProjectWindow = null;
258
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
259
                        PluginServices.getMDIManager().changeWindowInfo(getProjectFrame(), winProps);
260
                } else {
261
                        PluginServices.getMDIManager().addWindow(getProjectFrame());
262
                }
263
        }
264

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

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

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

    
296
                if (lastSavePath == null) {
297
                        lastSavePath = projectPath;
298
                }
299

    
300

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
459

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

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

    
508
                } catch (Exception e) {
509
                        NotificationManager.addError(PluginServices.getText(this,"error_writing_project")+ ": "+file.getName(), e);
510
                        return false;
511
                }
512
                NotificationManager.addInfo(PluginServices.getText(this,"wrote_project")+ ": "+file.getName());
513
                return true;
514
        }
515

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

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

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

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

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

    
665
                        try {
666
                                proj = Project.createFromXML(xml);
667
                                NotificationManager.addInfo(PluginServices.getText(this,"opened_project")+ ": "+xml.getStringProperty("name"));
668

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

    
685
                return null;
686
        }
687

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

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

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

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

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

    
726
        private void initializeDocumentActionsExtensionPoint() {
727
                ExtensionPointManager epMan = ToolsLocator.getExtensionPointManager();
728
                if (!epMan.has("DocumentActions_View")) {
729
                        epMan.add("DocumentActions_View",
730
                                        "Context menu options of the view document list" +
731
                                                " in the project window "+
732
                                                "(register instances of " +
733
                                                "com.iver.cit.gvsig.project.AbstractDocumentContextMenuAction)"
734
                        );
735
                }
736
                if (!epMan.has("DocumentActions_Table")) {
737
                        epMan.add(
738
                                        "DocumentActions_Table",
739
                                        "Context menu options of the table document list" +
740
                                                " in the project window "+
741
                                                "(register instances of " +
742
                                                "com.iver.cit.gvsig.project.AbstractDocumentContextMenuAction)"
743
                        );
744
                }
745
                if (!epMan.has("DocumentActions_Map")) {
746
                        epMan.add(
747
                                        "DocumentActions_Map",
748
                                        "Context menu options of the map document list" +
749
                                                " in the project window "+
750
                                                "(register instances of " +
751
                                                "com.iver.cit.gvsig.project.AbstractDocumentContextMenuAction)"
752
                        );
753
                }
754
        }
755

    
756
        public static String getPath() {
757
                return projectPath;
758
        }
759

    
760
        public static void setPath(String path) {
761
                projectPath = path;
762
        }
763

    
764
        public IWindow getProjectWindow() {
765
                return getProjectFrame();
766
        }
767

    
768

    
769
        public IExtensionStatus getStatus() {
770
                return this;
771
        }
772

    
773
        public boolean hasUnsavedData() {
774
                return p.hasChanged();
775
        }
776

    
777
        public IUnsavedData[] getUnsavedData() {
778
                if (hasUnsavedData()) {
779
                        UnsavedProject data = new UnsavedProject(this);
780
                        IUnsavedData[] dataArray = {data};
781
                        return dataArray;
782
                } else {
783
                        return null;
784
                }
785
        }
786

    
787
        /**
788
         * Implements the IUnsavedData interface to show unsaved projects
789
         * in the Unsavad Data dialog.
790
         *
791
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
792
         */
793
        public class UnsavedProject  extends UnsavedData {
794

    
795
                public UnsavedProject(IExtension extension) {
796
                        super(extension);
797
                }
798

    
799
                public String getDescription() {
800
                        if (getPath()==null) {
801
                                return PluginServices.getText(ProjectExtension.this, "Unnamed_new_gvsig_project_");
802
                        }
803
                        else {
804
                                return PluginServices.getText(ProjectExtension.this, "Modified_project_");
805
                        }
806
                }
807

    
808
                public String getResourceName() {
809
                        if (getPath()==null) {
810
                                return PluginServices.getText(ProjectExtension.this, "Unnamed");
811
                        }
812
                        else {
813
                                return getPath();
814
                        }
815

    
816
                }
817

    
818
                public boolean saveData() {
819
                        return guardar();
820
                }
821

    
822
                public ImageIcon getIcon() {
823
                        try {
824
                                URL imagePath = PluginServices.getPluginServices(ProjectExtension.this).getClassLoader().getResource("images/logoGVA.gif");
825
                                return new ImageIcon(imagePath);
826
                        }
827
                        catch (Exception ex) {}
828
                        return null;
829
                }
830
        }
831

    
832
        public IMonitorableTask[] getRunningProcesses() {
833
                // TODO Auto-generated method stub
834
                return null;
835
        }
836
        public boolean hasRunningProcesses() {
837
                // TODO Auto-generated method stub
838
                return false;
839
        }
840

    
841
    /**
842
     * Adds the specified before saving listener to receive "before saving file events" from
843
     * this component.
844
     * If l is null, no exception is thrown and no action is performed.
845
     *
846
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
847
     *
848
     * @param    l the before saving listener.
849
     * @see      SaveEvent
850
     * @see      BeforeSavingListener
851
     * @see      #removeListener(BeforeSavingListener)
852
     * @see      #getBeforeSavingListeners
853
     */
854
    public synchronized void addListener(BeforeSavingListener l) {
855

    
856
            // FIXME ARREGLAR ESTO !!! porque se usa EP para eso???
857
        if (l == null) {
858
            return;
859
        }
860

    
861
        ExtensionPoints ePs = (ExtensionPointsSingleton.getInstance());
862

    
863
        if (ePs.get(BEFORE_SAVING_ID) == null) {
864
                ArrayList aL = new ArrayList();
865
                aL.add(l);
866

    
867
                ePs.add(BEFORE_SAVING_ID, "", aL);
868
                return;
869
        }
870

    
871
        ((ArrayList)((ExtensionPoint)ePs.get(BEFORE_SAVING_ID)).get("")).add(l);
872
    }
873

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

    
892
        ExtensionPoints ePs = (ExtensionPointsSingleton.getInstance());
893

    
894
        if (ePs.get(AFTER_SAVING_ID) == null) {
895
                ArrayList aL = new ArrayList();
896
                aL.add(l);
897

    
898
                ePs.add(AFTER_SAVING_ID, "", aL);
899
                return;
900
        }
901

    
902
        ((ArrayList)((ExtensionPoint)ePs.get(AFTER_SAVING_ID)).get("")).add(l);
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
    }
927

    
928
    /**
929
     * Returns an array of all the after saving listeners
930
     * registered on this component.
931
     *
932
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
933
     *
934
     * @return all of this component's <code>AfterSavingListener</code>s
935
     *         or an empty array if no key
936
     *         listeners are currently registered
937
     *
938
     * @see      #addAfterSavingListener(AfterSavingListener)
939
     * @see      #removeAfterSavingListener
940
     */
941
    public synchronized AfterSavingListener[] getAfterSavingListeners() {
942
            ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
943

    
944
            if (eP == null) {
945
                        return null;
946
                }
947

    
948
            return eP.get("") == null ? null : (AfterSavingListener[]) ((ArrayList)eP.get("")).toArray(new AfterSavingListener[0]);
949
    }
950

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

    
972
        ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
973

    
974
        if (eP != null) {
975
                ((ArrayList)eP.get("")).remove(l);
976
        }
977
    }
978

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

    
1000
        ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
1001

    
1002
        if (eP != null) {
1003
                ((ArrayList)eP.get("")).remove(l);
1004
        }
1005
    }
1006

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

    
1019
        ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(BEFORE_SAVING_ID);
1020

    
1021
        if (eP != null) {
1022
                ArrayList listeners = ((ArrayList)eP.get(""));
1023

    
1024
                for (int i = 0; i < listeners.size(); i++) {
1025
                                ((BeforeSavingListener)listeners.get(i)).beforeSaving(evt);
1026
                        }
1027
        }
1028
    }
1029

    
1030
    /**
1031
     * Reports a after saving file event.
1032
     *
1033
     * @author Pablo Piqueras Bartolom? <pablo.piqueras@iver.es>
1034
     *
1035
     * @param evt the after saving file event
1036
     */
1037
    protected void fireAfterSavingFileEvent(SaveEvent evt) {
1038
        if ((evt.getID() != SaveEvent.AFTER_SAVING) || (evt.getFile() == null)) {
1039
            return;
1040
        }
1041

    
1042
        ExtensionPoint eP = (ExtensionPoint)(ExtensionPointsSingleton.getInstance()).get(AFTER_SAVING_ID);
1043

    
1044
        if (eP != null) {
1045
                ArrayList listeners = ((ArrayList)eP.get(""));
1046

    
1047
                for (int i = 0; i < listeners.size(); i++) {
1048
                                ((AfterSavingListener)listeners.get(i)).afterSaving(evt);
1049
                        }
1050
        }
1051
    }
1052
}