Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / DefaultProject.java @ 43077

History | View | Annotate | Download (38 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.app.project;
24

    
25
import java.awt.Color;
26
import java.beans.PropertyChangeEvent;
27
import java.beans.PropertyChangeListener;
28
import java.beans.PropertyChangeSupport;
29
import java.io.File;
30
import java.io.FileInputStream;
31
import java.io.FileNotFoundException;
32
import java.io.FileOutputStream;
33
import java.io.InputStream;
34
import java.io.OutputStream;
35
import java.io.Serializable;
36
import java.text.DateFormat;
37
import java.text.MessageFormat;
38
import java.util.ArrayList;
39
import java.util.Collections;
40
import java.util.Date;
41
import java.util.HashMap;
42
import java.util.HashSet;
43
import java.util.Iterator;
44
import java.util.List;
45
import java.util.Map;
46
import java.util.Set;
47

    
48
import org.cresques.cts.IProjection;
49

    
50
import org.gvsig.andami.PluginServices;
51
import org.gvsig.andami.ui.mdiManager.IWindow;
52
import org.gvsig.andami.ui.mdiManager.MDIManager;
53
import org.gvsig.andami.ui.mdiManager.SingletonWindow;
54
import org.gvsig.andami.ui.mdiManager.WindowInfo;
55
import org.gvsig.app.ApplicationLocator;
56
import org.gvsig.app.ApplicationManager;
57
import org.gvsig.app.extension.ProjectExtension;
58
import org.gvsig.app.extension.Version;
59
import org.gvsig.app.project.documents.AbstractDocument;
60
import org.gvsig.app.project.documents.Document;
61
import org.gvsig.app.project.documents.exceptions.SaveException;
62
import org.gvsig.app.project.documents.gui.IDocumentWindow;
63
import org.gvsig.app.project.documents.gui.ProjectWindow;
64
import org.gvsig.app.project.documents.view.DefaultViewDocument;
65
import org.gvsig.app.project.documents.view.ViewManager;
66
import org.gvsig.fmap.mapcontext.MapContext;
67
import org.gvsig.fmap.mapcontext.layers.ExtendedPropertiesHelper;
68
import org.gvsig.fmap.mapcontext.layers.FLayer;
69
import org.gvsig.fmap.mapcontext.layers.FLayers;
70
import org.gvsig.tools.ToolsLocator;
71
import org.gvsig.tools.dynobject.DynStruct;
72
import org.gvsig.tools.observer.ObservableHelper;
73
import org.gvsig.tools.observer.Observer;
74
import org.gvsig.tools.persistence.PersistenceManager;
75
import org.gvsig.tools.persistence.Persistent;
76
import org.gvsig.tools.persistence.PersistentContext;
77
import org.gvsig.tools.persistence.PersistentState;
78
import org.gvsig.tools.persistence.exception.PersistenceException;
79
import org.gvsig.utils.StringUtilities;
80

    
81
import org.slf4j.Logger;
82
import org.slf4j.LoggerFactory;
83

    
84
/**
85
 * Clase que representa un proyecto de gvSIG
86
 *
87
 */
88
public class DefaultProject implements Serializable, PropertyChangeListener,
89
        Project {
90

    
91
    private Logger LOG = LoggerFactory.getLogger(DefaultProject.class);
92
    /**
93
     * @deprecated see ApplicationLocator.getManager().getVersion()
94
     */
95
    public static String VERSION = Version.format();
96

    
97
    private ExtendedPropertiesHelper propertiesHelper = new ExtendedPropertiesHelper();
98

    
99
    private ObservableHelper observableHelper = new ObservableHelper();
100

    
101
    /**
102
     *
103
     */
104
    private static final long serialVersionUID = -4449622027521773178L;
105

    
106
    private static final Logger logger = LoggerFactory.getLogger(Project.class);
107

    
108
    private static ProjectPreferences preferences = new ProjectPreferences();
109

    
110
    /**
111
     * Index used by the generator of unique names of documents.
112
     */
113
    private Map<String, Integer> nextDocumentIndexByType = new HashMap<String, Integer>();
114

    
115
    private PropertyChangeSupport change;
116

    
117
    private boolean modified = false;
118

    
119
    private String name = null;
120

    
121
    private String creationDate = null;
122

    
123
    private String modificationDate = null;
124

    
125
    private String owner = null;
126

    
127
    private String comments = null;
128

    
129
    private Color selectionColor = null;
130

    
131
    private List<Document> documents = null;
132

    
133
    private List<ProjectExtent> extents = null;
134

    
135
    private IProjection projection;
136

    
137
    private File fname = null;
138

    
139
    private Set<String> unloadedObjects;
140

    
141
    /**
142
     * Creates a new Project object.
143
     */
144
    DefaultProject() {
145
        this.change = new PropertyChangeSupport(this);
146
        this.clean();
147
    }
148

    
149
    protected void clean() {
150
        this.owner = "";
151
        this.comments = "";
152
        this.name = PluginServices.getText(this, "untitled");
153
        this.creationDate = DateFormat.getDateInstance().format(new Date());
154
        this.modificationDate = this.creationDate;
155

    
156
        this.documents = new ArrayList<Document>();
157
        this.extents = new ArrayList<ProjectExtent>();
158

    
159
        this.setSelectionColor(getPreferences().getDefaultSelectionColor());
160

    
161
        this.projection = null; // se inicializa en el getProjection()
162
    }
163

    
164
    public static ProjectPreferences getPreferences() {
165
        return preferences;
166
    }
167

    
168
    public void propertyChange(PropertyChangeEvent evt) {
169
        change.firePropertyChange(evt);
170
    }
171

    
172
    public synchronized void addPropertyChangeListener(
173
            PropertyChangeListener arg0) {
174
        change.addPropertyChangeListener(arg0);
175
    }
176

    
177
    /**
178
     * Return the creation date of the project
179
     *
180
     * @return
181
     */
182
    public String getCreationDate() {
183
        return creationDate;
184
    }
185

    
186
    protected void setCreationDate(String creationDate) {
187
        this.creationDate = creationDate;
188
        change.firePropertyChange("setCreationDate", null, null);
189
    }
190

    
191
    public Document createDocument(String type) {
192
        logger.info("createDocument('{}')", type);
193
        return ProjectManager.getInstance().createDocument(type);
194
    }
195

    
196
    /**
197
     * Return the name of the project
198
     *
199
     * @return
200
     */
201
    public String getName() {
202
        return name;
203
    }
204

    
205
    /**
206
     * Set the name of he project.
207
     *
208
     * @param string
209
     */
210
    public void setName(String name) {
211
        this.name = name;
212
        change.firePropertyChange("setName", null, null);
213
    }
214

    
215
    /**
216
     * Return the comments associateds with the project
217
     *
218
     * @return comments
219
     */
220
    public String getComments() {
221
        return comments;
222
    }
223

    
224
    /**
225
     * Set the comments associateds with the project
226
     *
227
     * @param comments as string
228
     */
229
    public void setComments(String string) {
230
        comments = string;
231
        change.firePropertyChange("setComments", null, null);
232
    }
233

    
234
    /**
235
     * Retuen the modification date of the project.
236
     *
237
     * @return modification date as string
238
     */
239
    public String getModificationDate() {
240
        return modificationDate;
241
    }
242

    
243
    protected void setModificationDate(String string) {
244
        modificationDate = string;
245
        change.firePropertyChange("setModificationDate", null, null);
246
    }
247

    
248
    /**
249
     * Return the author of the project,
250
     *
251
     * @return author as string
252
     */
253
    public String getOwner() {
254
        return owner;
255
    }
256

    
257
    /**
258
     * Sets the author of the project
259
     *
260
     * @param author name as string
261
     */
262
    public void setOwner(String owner) {
263
        this.owner = owner;
264
        change.firePropertyChange("setOwner", null, null);
265
    }
266

    
267
    /**
268
     * Obtiene el color de selecci�n que se usar� en el proyecto
269
     *
270
     * @return
271
     */
272
    public Color getSelectionColor() {
273
        if (selectionColor == null) {
274
            selectionColor = getPreferences().getDefaultSelectionColor();
275
        }
276
        return selectionColor;
277
    }
278

    
279
    /**
280
     * Sets the selecction color
281
     *
282
     * @param selection color as string
283
     */
284
    public void setSelectionColor(String selectionColor) {
285
        this.setSelectionColor(StringUtilities.string2Color(selectionColor));
286
    }
287

    
288
    /**
289
     * Sets the selecction color
290
     *
291
     * @param selection color as Color
292
     */
293
    public void setSelectionColor(Color selectionColor) {
294
        this.selectionColor = selectionColor;
295
        MapContext.setSelectionColor(selectionColor);
296
        change.firePropertyChange("selectionColor", null, selectionColor);
297
    }
298

    
299
    public IProjection getProjection() {
300
        if (projection == null) {
301
            projection = getPreferences().getDefaultProjection();
302
        }
303
        return projection;
304
    }
305

    
306
    public void setProjection(IProjection projection) {
307
        this.projection = projection;
308
    }
309

    
310
    /**
311
     * Sets the modified state of project.
312
     *
313
     * Can't set to not modified.
314
     *
315
     * @param modified as boolean
316
     */
317
    public void setModified(boolean modified) {
318
        this.modified = modified;
319
        if (modified == false) {
320
            List<Document> documents = this.getDocuments();
321
            for (int i = 0; i < documents.size(); i++) {
322
                documents.get(i).setModified(false);
323
            }
324
        }
325
    }
326

    
327
    public boolean hasChanged() {
328
                // we return true if the project is not empty (until we have a better
329
        // method...)
330
        if ((this.getDocuments().size() != 0) || modified) {
331
            return true;
332
        }
333
        return false;
334
    }
335

    
336
    /**
337
     * Return a list of documents in the project.
338
     *
339
     * @return documents as List of IProjectDocument
340
     */
341
    public List<Document> getDocuments() {
342
        return Collections.unmodifiableList(documents);
343
    }
344

    
345
    /**
346
     * Return a list with all documents of especified type.
347
     *
348
     * @param type of document
349
     *
350
     * @return List of IProjectDocument
351
     */
352
    public List<Document> getDocuments(String type) {
353
        List<Document> docs = new ArrayList<Document>();
354
        if (type != null) {
355
            for (Document document : this.documents) {
356
                if (type.equalsIgnoreCase(document.getTypeName())) {
357
                    docs.add(document);
358
                }
359
            }
360
        }
361
        return Collections.unmodifiableList(docs);
362
    }
363

    
364
    /**
365
     * Adds a document to the project
366
     *
367
     * @param document as Document
368
     */
369
    public void add(Document document) {
370
        this.addDocument(document);
371
    }
372

    
373
    public void addDocument(Document document) {
374
        logger.info("add('{}')", document.toString());
375

    
376
        if (notifyObservers(ProjectNotification.BEFORE_ADD_DOCUMENT, document).isProcessCanceled()) {
377
            return;
378
        }
379
        document.addPropertyChangeListener(this);
380
        document.setProject(this);
381
        document.setName(this.getUniqueNameForDocument(document.getTypeName(),
382
                document.getName()));
383
        documents.add(document);
384
        document.afterAdd();
385
        this.setModified(true);
386
        notifyObservers(ProjectNotification.AFTER_ADD_DOCUMENT, document);
387
        change.firePropertyChange("addDocument", null, document);
388
    }
389

    
390
    public void remove(Document doc) {
391
        this.removeDocument(doc);
392
    }
393

    
394
    public void removeDocument(Document doc) {
395
        logger.info("remove('{}')", doc.toString());
396
        if (notifyObservers(ProjectNotification.BEFORE_REMOVE_DOCUMENT, doc).isProcessCanceled()) {
397
            return;
398
        }
399
        documents.remove(doc);
400
        this.setModified(true);
401
        change.firePropertyChange("delDocument", doc, null);
402
        doc.afterRemove();
403
        notifyObservers(ProjectNotification.AFTER_REMOVE_DOCUMENT, doc);
404
    }
405

    
406
    public Iterator<Document> iterator() {
407
        return documents.iterator();
408
    }
409

    
410
    public boolean isEmpty() {
411
        return documents.isEmpty();
412
    }
413

    
414
    /**
415
     * Return the view that contains the especified layer.
416
     *
417
     * @param layer
418
     *
419
     * @return name of the view that contains the layer
420
     *
421
     * @throws RuntimeException Si la capa que se pasa como par�metro no se
422
     * encuentra en ninguna vista
423
     */
424
    public String getViewName(FLayer layer) {
425
        List<Document> views = getDocuments(ViewManager.TYPENAME);
426
        for (int v = 0; v < views.size(); v++) {
427
            DefaultViewDocument pView = (DefaultViewDocument) views.get(v);
428
            FLayers layers = pView.getMapContext().getLayers();
429
            if (isView(layers, layer)) {
430
                return pView.getName();
431
            }
432
        }
433

    
434
        throw new RuntimeException(MessageFormat.format(
435
                "The layer '{1}' is not in a view", layer.getName()));
436
    }
437

    
438
    private boolean isView(FLayers layers, FLayer layer) {
439
        for (int i = 0; i < layers.getLayersCount(); i++) {
440
            if (layers.getLayer(i) instanceof FLayers) {
441
                if (isView((FLayers) layers.getLayer(i), layer)) {
442
                    return true;
443
                }
444
            }
445
            if (layers.getLayer(i) == layer) {
446
                return true;
447
            }
448
        }
449
        return false;
450
    }
451

    
452
    public void addExtent(ProjectExtent arg1) {
453
        extents.add(arg1);
454
        change.firePropertyChange("addExtent", null, null);
455
    }
456

    
457
    public ProjectExtent removeExtent(int arg0) {
458
        change.firePropertyChange("delExtent", null, null);
459
        return extents.remove(arg0);
460
    }
461

    
462
    public ProjectExtent[] getExtents() {
463
        return (ProjectExtent[]) extents.toArray(new ProjectExtent[0]);
464
    }
465

    
466
    /**
467
     * Obtiene un documento a partir de su nombre y el nombre de registro en el
468
     * pointExtension, este �ltimo se puede obtener del
469
     * Project****Factory.registerName.
470
     *
471
     * @param name Nombre del documento
472
     * @param type nombre de registro en el extensionPoint
473
     *
474
     * @return Documento
475
     */
476
    public Document getDocument(String name, String type) {
477
        if (type == null) {
478
            for (int i = 0; i < documents.size(); i++) {
479
                Document document = documents.get(i);
480
                if ( name.equalsIgnoreCase(document.getName())) {
481
                    return document;
482
                }
483
            }
484
        } else {
485
            for (int i = 0; i < documents.size(); i++) {
486
                Document document = documents.get(i);
487
                if (type.equalsIgnoreCase(document.getTypeName())
488
                        && name.equalsIgnoreCase(document.getName())) {
489
                    return document;
490
                }
491
            }
492
        }
493
        return null;
494
    }
495

    
496
    public Document getDocument(String name) {
497
        return this.getDocument(name, null);
498
    }
499

    
500
    public String getUniqueNameForDocument(String type, String name) {
501
        Document document = getDocument(name, type);
502
        if (document == null) {
503
            return name;
504
        }
505

    
506
        String newName = null;
507
        int num = this.getNextDocumentIndex(type);
508
        while (document != null) {
509
            newName = name + " - " + num++;
510
            document = getDocument(newName, type);
511
        }
512
        this.setNextDocumentIndex(type, num);
513
        return newName;
514
    }
515

    
516
    private int getNextDocumentIndex(String type) {
517
        if (nextDocumentIndexByType.get(type) == null) {
518
            nextDocumentIndexByType.put(type, new Integer(1));
519
            return 1;
520
        }
521
        return nextDocumentIndexByType.get(type).intValue();
522
    }
523

    
524
    private void setNextDocumentIndex(String type, int newIndex) {
525
        if (nextDocumentIndexByType.get(type) == null) {
526
            nextDocumentIndexByType.put(type, new Integer(newIndex));
527
        } else {
528
            nextDocumentIndexByType.put(type, new Integer(newIndex));
529
        }
530
    }
531

    
532
    public void saveState(File out) throws PersistenceException {
533
        FileOutputStream fout;
534
        if (notifyObservers(ProjectNotification.BEFORE_SAVE_TO_FILE, out).isProcessCanceled()) {
535
            return;
536
        }
537
        try {
538
            fout = new FileOutputStream(out);
539
            saveState(fout, new File(out.getParent()));
540
        } catch (FileNotFoundException e) {
541
            throw new PersistenceException(e);
542
        }
543
        this.fname = out;
544
        notifyObservers(ProjectNotification.AFTER_SAVE_TO_FILE, out);
545
    }
546

    
547
    public File getFile() {
548
        return this.fname;
549
    }
550

    
551
    public void saveState(OutputStream out) throws PersistenceException {
552
        saveState(out, null);
553
    }
554

    
555
    public void saveState(OutputStream out, File rootFolder)
556
            throws PersistenceException {
557
        if (notifyObservers(ProjectNotification.BEFORE_SAVE_TO_STREAM).isProcessCanceled()) {
558
            return;
559
        }
560
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
561
        PersistentState state = null;
562
        state = manager.getState(this, true);
563
        try {
564
            if (rootFolder != null) {
565
                state.relativizeFiles(rootFolder);
566
            }
567
        } catch (Exception ex) {
568
            state.getContext().addError(ex);
569
        }
570
        manager.saveState(state, out, true);
571
        if (state.getContext().getErrors() != null) {
572
            throw state.getContext().getErrors();
573
        }
574
        this.fname = null;
575
        notifyObservers(ProjectNotification.AFTER_SAVE_TO_STREAM);
576
    }
577

    
578
    public void loadState(InputStream in) {
579
        loadState(in, null);
580
    }
581

    
582
    public void loadState(InputStream in, File rootFolder) {
583
        if (notifyObservers(ProjectNotification.BEFORE_LOAD_FROM_STREAM).isProcessCanceled()) {
584
            return;
585
        }
586
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
587
        try {
588
            PersistentState state = manager.loadState(in);
589
            state.getContext().setCollectErrors(true);
590
            try {
591
                if (rootFolder != null) {
592
                    state.derelativizeFiles(rootFolder);
593
                }
594
            } catch (Exception ex) {
595
                state.getContext().addError(ex);
596
            }
597
            this.loadFromState(state);
598
            this.unloadedObjects = getUnloadedObjects(state.getContext());
599
        } catch (PersistenceException e) {
600
            LOG.info("Can't load project to stream", e);
601
        }
602
        this.fname = null;
603
        notifyObservers(ProjectNotification.AFTER_LOAD_FROM_STREAM);
604

    
605
    }
606

    
607

    
608

    
609
    /**
610
     * @param context
611
     * @return
612
     */
613
    private Set<String> getUnloadedObjects(PersistentContext context) {
614
        Set unloadedObjects = new HashSet();
615

    
616
        Iterator statesIterator = context.iterator();
617
        String className = null;
618

    
619
        while (statesIterator.hasNext()) {
620
            PersistentState aState = (PersistentState) statesIterator.next();
621
            try {
622
                className = aState.getTheClassName();
623
                DynStruct definition = aState.getDefinition();
624
                if (definition == null) {
625
                    unloadedObjects.add(className);
626
                }
627
            } catch (Throwable e) {
628
                // do nothing
629
            }
630
        }
631

    
632
        if(unloadedObjects.isEmpty()){
633
            return null;
634
        }
635

    
636
        return unloadedObjects;
637
    }
638

    
639
    public Set<String> getUnloadedObjects() {
640
        return this.unloadedObjects;
641
    }
642

    
643
    public void loadState(File in) {
644
        if (notifyObservers(ProjectNotification.BEFORE_LOAD_FROM_FILE, in).isProcessCanceled()) {
645
            return;
646
        }
647
        FileInputStream fin;
648
        try {
649
            fin = new FileInputStream(in);
650
            loadState(fin, new File(in.getParent()));
651
        } catch (FileNotFoundException e) {
652
            LOG.info("Can't load project to stream", e);
653
        }
654
        this.fname = in;
655
        notifyObservers(ProjectNotification.AFTER_LOAD_FROM_FILE, in);
656
    }
657

    
658
    @SuppressWarnings("unchecked")
659
    public void loadFromState(PersistentState state)
660
            throws PersistenceException {
661
        this.clean();
662

    
663
        this.setComments(state.getString("comments"));
664
        this.setCreationDate(state.getString("creationDate"));
665
        this.setModificationDate(state.getString("modificationDate"));
666
        this.setName(state.getString("name"));
667
        this.setOwner(state.getString("owner"));
668
        this.setSelectionColor((Color) state.get("selectionColor"));
669
        this.setProjection((IProjection) state.get("projection"));
670

    
671
        this.propertiesHelper = (ExtendedPropertiesHelper) state.get("propertiesHelper");
672

    
673
        List<ProjectExtent> extents = (List<ProjectExtent>) state
674
                .get("extents");
675
        for (int i = 0; i < extents.size(); i++) {
676
            this.addExtent(extents.get(i));
677
        }
678

    
679
        List<AbstractDocument> documents = (List<AbstractDocument>) state
680
                .get("documents");
681
        for (int i = 0; i < documents.size(); i++) {
682
            this.add(documents.get(i));
683
        }
684

    
685
        List<DocumentWindowInfo> persistentWindows = (List<DocumentWindowInfo>) state.get("documentWindowsInformation");
686

    
687
        for (int i = 0; i < persistentWindows.size(); i++) {
688
            DocumentWindowInfo persistentWindow = persistentWindows.get(i);
689
            String docName = persistentWindow.getDocumentName();
690
            String docType = persistentWindow.getDocumentType();
691
            Document doc = this.getDocument(docName, docType);
692
            IWindow win = doc.getFactory().getMainWindow(doc);
693
            if(win!=null){
694
                win.getWindowInfo().setWindowInfo(persistentWindow.getWindowInfo());
695
                PluginServices.getMDIManager().addWindow(win);
696
            }
697
        }
698

    
699
        if (state.hasValue("projectWindowInfo")) {
700
            WindowInfo projectWindowInfo = (WindowInfo) state.get("projectWindowInfo");
701
            ProjectExtension pe = (ProjectExtension) PluginServices.getExtension(org.gvsig.app.extension.ProjectExtension.class);
702
            pe.setProject(this);
703
            pe.showProjectWindow(projectWindowInfo);
704
        }
705

    
706
    }
707

    
708
    public void saveToState(PersistentState state) throws PersistenceException {
709
        state.set("version", VERSION);
710
        state.set("comments", getComments());
711
        state.set("creationDate", this.getCreationDate());
712

    
713
        state.set("modificationDate", this.getModificationDate());
714
        state.set("name", this.getName());
715
        state.set("owner", this.getOwner());
716
        state.set("selectionColor", this.getSelectionColor());
717

    
718
        state.set("projection", this.getProjection());
719

    
720
        state.set("extents", this.extents);
721
        List<Document> docs = this.getDocuments();
722
        List<Document> noTempDocs = new ArrayList<Document>();
723
        for (Iterator iterator = docs.iterator(); iterator.hasNext();) {
724
            Document document = (Document) iterator.next();
725
            if(!document.isTemporary()){
726
                noTempDocs.add(document);
727
            }
728
        }
729
        state.set("documents", noTempDocs);
730

    
731
        state.set("propertiesHelper",propertiesHelper);
732

    
733
        List<DocumentWindowInfo> persistentWindows = new ArrayList<DocumentWindowInfo>();
734
        MDIManager mdiMan = PluginServices.getMDIManager();
735
        IWindow[] windows = mdiMan.getOrderedWindows();
736
        for (int i = windows.length - 1; i >= 0; i--) {
737
            IWindow window = windows[i];
738
            if (window instanceof IDocumentWindow) {
739
                WindowInfo wi = mdiMan.getWindowInfo(window);
740
                DocumentWindowInfo dwi = new DocumentWindowInfo(
741
                        wi,
742
                        ((IDocumentWindow) window).getDocument().getTypeName(),
743
                        ((IDocumentWindow) window).getDocument().getName());
744
                persistentWindows.add(dwi);
745
            } else if (window instanceof ProjectWindow) {
746
                state.set("projectWindowInfo", mdiMan.getWindowInfo(window));
747
            }
748
        }
749
        state.set("documentWindowsInformation", persistentWindows);
750

    
751
    }
752

    
753
    public Object getProperty(Object key) {
754
        return this.propertiesHelper.getProperty(key);
755
    }
756

    
757
    public void setProperty(Object key, Object obj) {
758
        this.propertiesHelper.setProperty(key, obj);
759
    }
760

    
761
    public Map getExtendedProperties() {
762
        return this.propertiesHelper.getExtendedProperties();
763
    }
764

    
765
    public static class DocumentWindowInfo implements Persistent {
766

    
767
        public static final String PERSISTENCE_DEFINITION_NAME = "DocumentWindowInfo";
768

    
769
        private WindowInfo windowInfo;
770
        private String documentType;
771
        private String documentName;
772

    
773
        public DocumentWindowInfo() {
774
        }
775

    
776
        DocumentWindowInfo(WindowInfo wi, String docType, String docName) {
777
            windowInfo = wi;
778
            documentType = docType;
779
            documentName = docName;
780
        }
781

    
782
        public WindowInfo getWindowInfo() {
783
            return windowInfo;
784
        }
785

    
786
        public String getDocumentType() {
787
            return documentType;
788
        }
789

    
790
        public String getDocumentName() {
791
            return documentName;
792
        }
793

    
794
        public void saveToState(PersistentState state)
795
                throws PersistenceException {
796
            state.set("windowInfo", this.windowInfo);
797
            state.set("documentType", this.documentType);
798
            state.set("documentName", this.documentName);
799
        }
800

    
801
        public void loadFromState(PersistentState state)
802
                throws PersistenceException {
803
            this.windowInfo = (WindowInfo) state.get("windowInfo");
804
            this.documentType = state.getString("documentType");
805
            this.documentName = state.getString("documentName");
806
        }
807

    
808
        public static void registerPersistent() {
809
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
810
            DynStruct definition = manager.getDefinition(PERSISTENCE_DEFINITION_NAME);
811
            if (definition == null) {
812
                definition = manager.addDefinition(
813
                        DocumentWindowInfo.class,
814
                        PERSISTENCE_DEFINITION_NAME,
815
                        "DocumentWindowInfo persistence definition",
816
                        null,
817
                        null
818
                );
819
                definition.addDynFieldObject("windowInfo").setMandatory(true).setClassOfValue(WindowInfo.class);
820
                definition.addDynFieldString("documentType").setMandatory(true);
821
                definition.addDynFieldString("documentName").setMandatory(true);
822
            }
823

    
824
        }
825
    }
826

    
827
    public static void registerPersistent() {
828
        AbstractDocument.registerPersistent();
829
        DocumentWindowInfo.registerPersistent();
830
        ProjectExtent.registerPersistent();
831

    
832
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
833
        DynStruct definition = manager.addDefinition(DefaultProject.class,
834
                "Project", "Project Persistence definition", null, null);
835
        definition.addDynFieldString("version").setMandatory(true);
836
        definition.addDynFieldString("comments").setMandatory(true);
837
        definition.addDynFieldString("creationDate").setMandatory(true);
838
        definition.addDynFieldString("modificationDate").setMandatory(true);
839
        definition.addDynFieldString("name").setMandatory(true);
840
        definition.addDynFieldString("owner").setMandatory(true);
841

    
842
        definition.addDynFieldObject("selectionColor")
843
                .setClassOfValue(Color.class).setMandatory(true);
844
        definition.addDynFieldObject("projection")
845
                .setClassOfValue(IProjection.class).setMandatory(true);
846

    
847
        definition.addDynFieldList("extents")
848
                .setClassOfItems(ProjectExtent.class).setMandatory(true);
849

    
850
        definition.addDynFieldList("documents").setClassOfItems(Document.class)
851
                .setMandatory(true);
852

    
853
        definition.addDynFieldObject("projectWindowInfo").setClassOfValue(WindowInfo.class).setMandatory(false);
854

    
855
        definition.addDynFieldList("documentWindowsInformation").setClassOfItems(WindowInfo.class).setMandatory(false);
856

    
857

    
858
        definition.addDynFieldObject("propertiesHelper").setClassOfValue(ExtendedPropertiesHelper.class)
859
                        .setMandatory(false);
860

    
861
    }
862

    
863
    /**
864
     * @deprecated use getPreferences().setDefaultSelectionColor()
865
     */
866
    public static void setDefaultSelectionColor(Color color) {
867
        getPreferences().setDefaultSelectionColor(color);
868
    }
869

    
870
    /**
871
     * @deprecated use getPreferences().getDefaultSelectionColor()
872
     */
873
    public static Color getDefaultSelectionColor() {
874
        return getPreferences().getDefaultSelectionColor();
875
    }
876

    
877
    /**
878
     * @deprecated use getPreferences().getDefaultMapUnits()
879
     */
880
    public static int getDefaultMapUnits() {
881
        return getPreferences().getDefaultMapUnits();
882
    }
883

    
884
    /**
885
     * @deprecated use getPreferences().getDefaultDistanceUnits()
886
     */
887
    public static int getDefaultDistanceUnits() {
888
        return getPreferences().getDefaultDistanceUnits();
889
    }
890

    
891
    /**
892
     * @deprecated use getPreferences().getDefaultDistanceArea()
893
     */
894
    public static int getDefaultDistanceArea() {
895
        return getPreferences().getDefaultDistanceArea();
896
    }
897

    
898
    /**
899
     * @deprecated use getPreferences().setDefaultMapUnits()
900
     */
901
    public static void setDefaultMapUnits(int mapUnits) {
902
        getPreferences().setDefaultMapUnits(mapUnits);
903
    }
904

    
905
    /**
906
     * @deprecated use getPreferences().setDefaultDistanceUnits()
907
     */
908
    public static void setDefaultDistanceUnits(int distanceUnits) {
909
        getPreferences().setDefaultDistanceUnits(distanceUnits);
910
    }
911

    
912
    /**
913
     * @deprecated use getPreferences().setDefaultDistanceArea()
914
     */
915
    public static void setDefaultDistanceArea(int distanceArea) {
916
        getPreferences().setDefaultDistanceArea(distanceArea);
917
    }
918

    
919
    /**
920
     * @deprecated use getPreferences().setDefaultProjection()
921
     */
922
    public static void setDefaultProjection(IProjection defaultProjection) {
923
        getPreferences().setDefaultProjection(defaultProjection);
924
    }
925

    
926
    /**
927
     * @deprecated use getPreferences().getDefaultProjection()
928
     */
929
    public static IProjection getDefaultProjection() {
930
        return getPreferences().getDefaultProjection();
931
    }
932

    
933
    /**
934
     * @deprecated see {@link #setSelectionColor(String)}, to be remove in gvSIG
935
     * 2.1.0
936
     */
937
    public void setColor(String color) {
938
        this.setSelectionColor(StringUtilities.string2Color(color));
939
    }
940

    
941
    /**
942
     * Return the selection color
943
     *
944
     * @return selection color as string
945
     * @deprecated use {@link #getSelectionColor()}
946
     */
947
    public String getColor() {
948
        return StringUtilities.color2String(selectionColor);
949
    }
950

    
951
    /**
952
     * Return the list of views of the project
953
     *
954
     * @return views as ArrayList of ProjectDocument
955
     *
956
     * @deprecated see {@link #getDocumentsByType(String)}
957
     */
958
    public List<Document> getViews() {
959
        return getDocuments(ViewManager.TYPENAME);
960
    }
961

    
962
    /**
963
     * Add a view to the project
964
     *
965
     * @deprecated see {@link #add(AbstractDocument)}
966
     */
967
    public void addView(DefaultViewDocument v) {
968
        add(v);
969
    }
970

    
971
    /**
972
     * Remove a view of the project
973
     *
974
     * @param index of the view as integer
975
     *
976
     * @deprecated see {@link #remove(AbstractDocument)}
977
     */
978
    public void delView(int i) {
979
        List<Document> list = getDocuments(ViewManager.TYPENAME);
980
        remove(list.get(i));
981
    }
982

    
983
    /**
984
     * @deprecated see {@link #getDocument(String, String)}
985
     */
986
    public Document getProjectDocumentByName(String name, String type) {
987
        return this.getDocument(name, type);
988
    }
989

    
990
    /**
991
     * @deprecated see {@link #getDocuments(String)}
992
     */
993
    public List<Document> getDocumentsByType(String type) {
994
        return this.getDocuments(type);
995
    }
996

    
997
    /**
998
     * @deprecated aun por decidir que API darle al copy/paste
999
     */
1000
    public String exportToXML(AbstractDocument[] selectedItems)
1001
            throws SaveException {
1002
        // FIXME jjdc:hay que decirdir que API darle al copy/paste
1003
        throw new UnsupportedOperationException("This method is not supported");
1004
    }
1005

    
1006
    /**
1007
     * @deprecated aun por decidir que API darle al copy/paste
1008
     */
1009
    public void importFromXML(String sourceString, String docType) {
1010
        // FIXME jjdc:hay que decirdir que API darle al copy/paste
1011
        throw new UnsupportedOperationException("This method is not supported");
1012
    }
1013

    
1014
    /**
1015
     * @deprecated aun por decidir que API darle al copy/paste
1016
     */
1017
    public boolean isValidXMLForImport(String sourceString, String docType) {
1018
        // FIXME jjdc:hay que decirdir que API darle al copy/paste
1019
        throw new UnsupportedOperationException("This method is not supported");
1020
    }
1021

    
1022
    public boolean canImportDocuments(String data, String doctype) {
1023
        // TODO Auto-generated method stub
1024
        return false;
1025
    }
1026

    
1027
    public String exportDocumentsAsText(List<Document> documents) {
1028
        // TODO Auto-generated method stub
1029
        return null;
1030
    }
1031

    
1032
    public void importDocuments(String data, String doctype) {
1033
        // TODO Auto-generated method stub
1034

    
1035
    }
1036

    
1037
    public Document getActiveDocument() {
1038
        return this.getActiveDocument((Class<? extends Document>)null);
1039
    }
1040

    
1041
    public Document getActiveDocument(String documentTypeName) {
1042
        ApplicationManager application = ApplicationLocator.getManager();
1043

    
1044
        Document document = null;
1045
        IWindow[] windows = application.getUIManager().getOrderedWindows();
1046
        IWindow window = null;
1047
        for (int i = 0; i < windows.length; i++) {
1048
            window = windows[i];
1049
            if (window instanceof SingletonWindow) {
1050
                // Cogemos no la primera ventana, si no la primera
1051
                // ventana de tipo documento (SingletonWindow).
1052
                // Y por si las mosca no es un documento, atrapamos
1053
                // los errores y continuamos si no puede hacer un cast
1054
                // del Model a Document
1055
                try {
1056
                    document = (Document) ((SingletonWindow) window).getWindowModel();
1057
                    if (documentTypeName == null) {
1058
                        return document;
1059
                    }
1060
                    if( document.getTypeName().equalsIgnoreCase(documentTypeName) ) {
1061
                        return document;
1062
                    }
1063
                    if( document instanceof DocumentsContainer ) {
1064
                        Document subdoc = ((DocumentsContainer)document).getActiveDocument(documentTypeName);
1065
                        return subdoc;
1066
                    }
1067

    
1068
                } catch (ClassCastException e) {
1069
                    // Do nothing, skip this window
1070
                }
1071
            }
1072
        }
1073
        return null;
1074
    }
1075

    
1076
    public Document getActiveDocument(Class<? extends Document> documentClass) {
1077
        ApplicationManager application = ApplicationLocator.getManager();
1078

    
1079
        Document document = null;
1080
        IWindow[] windows = application.getUIManager().getOrderedWindows();
1081
        IWindow window = null;
1082
        for (int i = 0; i < windows.length; i++) {
1083
            window = windows[i];
1084
            if (window instanceof SingletonWindow && window instanceof IDocumentWindow) {
1085
                // Cogemos no la primera ventana, si no la primera
1086
                // ventana de tipo documento (SingletonWindow).
1087
                // Y por si las mosca no es un documento, atrapamos
1088
                // los errores y continuamos si no puede hacer un cast
1089
                // del Model a Document
1090
                try {
1091
                    document = (Document) ((SingletonWindow) window).getWindowModel();
1092
                    if (documentClass == null) {
1093
                        return document;
1094
                    }
1095
                    if (documentClass.isAssignableFrom(document.getClass())) {
1096
                        return document;
1097
                    }
1098
                    if( document instanceof DocumentsContainer ) {
1099
                        Document subdoc = ((DocumentsContainer)document).getActiveDocument(documentClass);
1100
                        return subdoc;
1101
                    }
1102

    
1103
                } catch (ClassCastException e) {
1104
                    // Do nothing, skip this window
1105
                }
1106
            }
1107
        }
1108
        return null;
1109
    }
1110

    
1111
    public void addObserver(Observer o) {
1112
        observableHelper.addObserver(o);
1113
    }
1114

    
1115
    public void deleteObserver(Observer o) {
1116
        observableHelper.deleteObserver(o);
1117
    }
1118

    
1119
    public void deleteObservers() {
1120
        observableHelper.deleteObservers();
1121
    }
1122

    
1123
//        private void notifyObservers(ProjectNotifycation notifycation) {
1124
//                observableHelper.notifyObservers(this, notifycation);
1125
//        }
1126
    private ProjectNotification notifyObservers(int type) {
1127
        DefaultProjectNotification notifycation
1128
                = new DefaultProjectNotification(type, null, null);
1129
        try {
1130
            observableHelper.notifyObservers(this, notifycation);
1131
        } catch (Exception ex) {
1132
            LOG.info("Can't notify observers", ex);
1133
        }
1134
        return notifycation;
1135
    }
1136

    
1137
    private ProjectNotification notifyObservers(int type, Document document) {
1138
        DefaultProjectNotification notifycation
1139
                = new DefaultProjectNotification(type, document, null);
1140
        try {
1141
            observableHelper.notifyObservers(this, notifycation);
1142
        } catch (Exception ex) {
1143
            LOG.info("Can't notify observers", ex);
1144
        }
1145
        return notifycation;
1146
    }
1147

    
1148
    private ProjectNotification notifyObservers(int type, File file) {
1149
        DefaultProjectNotification notifycation
1150
                = new DefaultProjectNotification(type, null, file);
1151
        try {
1152
            observableHelper.notifyObservers(this, notifycation);
1153
        } catch (Exception ex) {
1154
            LOG.info("Can't notify observers", ex);
1155
        }
1156
        return notifycation;
1157
    }
1158

    
1159
    class DefaultProjectNotification implements ProjectNotification {
1160

    
1161
        private int type;
1162
        private Document document;
1163
        private File file;
1164
        private boolean processCanceled = false;
1165

    
1166
        DefaultProjectNotification(int type, Document document, File file) {
1167
            this.type = type;
1168
            this.document = document;
1169
            this.file = file;
1170
        }
1171

    
1172
        public int getNotificationType() {
1173
            return type;
1174
        }
1175

    
1176
        public Document getDocument() {
1177
            return document;
1178
        }
1179

    
1180
        public void cancelProcess() {
1181
            processCanceled = true;
1182
        }
1183

    
1184
        public boolean isProcessCanceled() {
1185
            return processCanceled;
1186
        }
1187

    
1188
        public File getFile() {
1189
            return file;
1190
        }
1191

    
1192
    }
1193

    
1194
}