Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / applications / appgvSIG / src / com / iver / cit / gvsig / ProjectExtension.java @ 27390

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 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.Iterator;
62
import java.util.List;
63
import java.util.prefs.Preferences;
64

    
65
import javax.swing.ImageIcon;
66
import javax.swing.JOptionPane;
67

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

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

    
106

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

    
135
        private List<BeforeSavingListener> beforeSavingListeners = new ArrayList<BeforeSavingListener>();
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
        private List<AfterSavingListener> afterSavingListeners = new ArrayList<AfterSavingListener>();
142

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

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

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

    
168
        initializeDocumentActionsExtensionPoint();
169
        registerDocuments();
170

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

    
178
            registerIcons();
179

    
180
        }
181

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

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

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

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

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

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

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

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

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

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

    
298
                if (lastSavePath == null) {
299
                        lastSavePath = projectPath;
300
                }
301

    
302

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
461

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

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

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

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

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

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

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

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

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

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

    
687
                return null;
688
        }
689

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

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

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

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

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

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

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

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

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

    
762

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

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

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

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

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

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

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

    
810
                }
811

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

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

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

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

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

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

    
902
    }
903

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

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

    
952
    }
953

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

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

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

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

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

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

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

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

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

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

    
1053
    }
1054
}