Statistics
| Revision:

root / branches / v2_0_0_prep / applications / appgvSIG / src / org / gvsig / app / project / DefaultProject.java @ 34833

History | View | Annotate | Download (33.6 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2009 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2004-2009 IVER TI
26
 *   
27
 */
28

    
29
package org.gvsig.app.project;
30

    
31
import java.awt.Color;
32
import java.beans.PropertyChangeEvent;
33
import java.beans.PropertyChangeListener;
34
import java.beans.PropertyChangeSupport;
35
import java.io.File;
36
import java.io.FileInputStream;
37
import java.io.FileNotFoundException;
38
import java.io.FileOutputStream;
39
import java.io.IOException;
40
import java.io.InputStream;
41
import java.io.OutputStream;
42
import java.io.Serializable;
43
import java.net.MalformedURLException;
44
import java.net.URI;
45
import java.net.URISyntaxException;
46
import java.net.URL;
47
import java.net.URLDecoder;
48
import java.net.URLEncoder;
49
import java.text.DateFormat;
50
import java.text.MessageFormat;
51
import java.util.ArrayList;
52
import java.util.Arrays;
53
import java.util.Collections;
54
import java.util.Date;
55
import java.util.HashMap;
56
import java.util.Iterator;
57
import java.util.List;
58
import java.util.Map;
59
import java.util.regex.Pattern;
60

    
61
import org.apache.bcel.generic.DCONST;
62
import org.cresques.cts.IProjection;
63
import org.gvsig.andami.PluginServices;
64
import org.gvsig.andami.ui.mdiManager.IWindow;
65
import org.gvsig.andami.ui.mdiManager.SingletonWindow;
66
import org.gvsig.andami.ui.mdiManager.WindowInfo;
67
import org.gvsig.app.extension.ProjectExtension;
68
import org.gvsig.app.extension.Version;
69
import org.gvsig.app.project.documents.AbstractDocument;
70
import org.gvsig.app.project.documents.Document;
71
import org.gvsig.app.project.documents.exceptions.SaveException;
72
import org.gvsig.app.project.documents.gui.IDocumentWindow;
73
import org.gvsig.app.project.documents.gui.ProjectWindow;
74
import org.gvsig.app.project.documents.layout.LayoutDocument;
75
import org.gvsig.app.project.documents.layout.LayoutManager;
76
import org.gvsig.app.project.documents.table.TableDocument;
77
import org.gvsig.app.project.documents.table.TableManager;
78
import org.gvsig.app.project.documents.view.DefaultViewDocument;
79
import org.gvsig.app.project.documents.view.ViewManager;
80
import org.gvsig.fmap.dal.DataTypes;
81
import org.gvsig.fmap.mapcontext.MapContext;
82
import org.gvsig.fmap.mapcontext.layers.FLayer;
83
import org.gvsig.fmap.mapcontext.layers.FLayers;
84
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
85
import org.gvsig.tools.ToolsLocator;
86
import org.gvsig.tools.dynobject.DynField;
87
import org.gvsig.tools.dynobject.DynStruct;
88
import org.gvsig.tools.persistence.PersistenceManager;
89
import org.gvsig.tools.persistence.Persistent;
90
import org.gvsig.tools.persistence.PersistentContext;
91
import org.gvsig.tools.persistence.PersistentState;
92
import org.gvsig.tools.persistence.exception.PersistenceException;
93
import org.gvsig.tools.persistence.exception.PersistenceValidateExceptions;
94
import org.gvsig.utils.StringUtilities;
95
import org.slf4j.Logger;
96
import org.slf4j.LoggerFactory;
97

    
98
/**
99
 * Clase que representa un proyecto de gvSIG
100
 * 
101
 * @author 2004-2005 Fernando Gonz?lez Cort?s
102
 * @author 2006-2009 Jose Manuel Vivo
103
 * @author 2005- Vicente Caballero
104
 * @author 2009- Joaquin del Cerro
105
 * 
106
 */
107

    
108
public class DefaultProject implements Serializable, PropertyChangeListener,
109
                Project {
110

    
111
        private Logger LOG = LoggerFactory.getLogger(DefaultProject.class);
112
        /**
113
         * @deprecated see ApplicationLocator.getManager().getVersion()
114
         */
115
        public static String VERSION = Version.format();
116

    
117
        /**
118
         * 
119
         */
120
        private static final long serialVersionUID = -4449622027521773178L;
121

    
122
        // private static final Logger logger = LoggerFactory.getLogger(Project
123
        // .class);
124

    
125
        private static ProjectPreferences preferences = new ProjectPreferences();
126

    
127
        /**
128
         * Index used by the generator of unique names of documents.
129
         */
130
        private Map<String, Integer> nextDocumentIndexByType = new HashMap<String, Integer>();
131

    
132
        private PropertyChangeSupport change;
133

    
134
        private boolean modified = false;
135

    
136
        private String name = null;
137

    
138
        private String creationDate = null;
139

    
140
        private String modificationDate = null;
141

    
142
        private String owner = null;
143

    
144
        private String comments = null;
145

    
146
        private Color selectionColor = null;
147

    
148
        private List<Document> documents = null;
149

    
150
        private List<ProjectExtent> extents = null;
151

    
152
        private IProjection projection;
153

    
154
        /**
155
         * Creates a new Project object.
156
         */
157
        DefaultProject() {
158
                this.change = new PropertyChangeSupport(this);
159
                this.clean();
160
        }
161

    
162
        protected void clean() {
163
                this.owner = "";
164
                this.comments = "";
165
                this.name = PluginServices.getText(this, "untitled");
166
                this.creationDate = DateFormat.getDateInstance().format(new Date());
167
                this.modificationDate = this.creationDate;
168

    
169
                this.documents = new ArrayList<Document>();
170
                this.extents = new ArrayList<ProjectExtent>();
171

    
172
                this.setSelectionColor(getPreferences().getDefaultSelectionColor());
173

    
174
                this.projection = null; // se inicializa en el getProjection()
175
        }
176

    
177
        public static ProjectPreferences getPreferences() {
178
                return preferences;
179
        }
180

    
181
        public void propertyChange(PropertyChangeEvent evt) {
182
                change.firePropertyChange(evt);
183
        }
184

    
185
        public synchronized void addPropertyChangeListener(
186
                        PropertyChangeListener arg0) {
187
                change.addPropertyChangeListener(arg0);
188
        }
189

    
190
        /**
191
         * Return the creation date of the project
192
         * 
193
         * @return
194
         */
195
        public String getCreationDate() {
196
                return creationDate;
197
        }
198

    
199
        protected void setCreationDate(String creationDate) {
200
                this.creationDate = creationDate;
201
                change.firePropertyChange("setCreationDate", null, null);
202
        }
203

    
204
        /**
205
         * Return the name of the project
206
         * 
207
         * @return
208
         */
209
        public String getName() {
210
                return name;
211
        }
212

    
213
        /**
214
         * Set the name of he project.
215
         * 
216
         * @param string
217
         */
218
        public void setName(String name) {
219
                this.name = name;
220
                change.firePropertyChange("setName", null, null);
221
        }
222

    
223
        /**
224
         * Return the comments associateds with the project
225
         * 
226
         * @return comments
227
         */
228
        public String getComments() {
229
                return comments;
230
        }
231

    
232
        /**
233
         * Set the comments associateds with the project
234
         * 
235
         * @param comments
236
         *            as string
237
         */
238
        public void setComments(String string) {
239
                comments = string;
240
                change.firePropertyChange("setComments", null, null);
241
        }
242

    
243
        /**
244
         * Retuen the modification date of the project.
245
         * 
246
         * @return modification date as string
247
         */
248
        public String getModificationDate() {
249
                return modificationDate;
250
        }
251

    
252
        protected void setModificationDate(String string) {
253
                modificationDate = string;
254
                change.firePropertyChange("setModificationDate", null, null);
255
        }
256

    
257
        /**
258
         * Return the author of the project,
259
         * 
260
         * @return author as string
261
         */
262
        public String getOwner() {
263
                return owner;
264
        }
265

    
266
        /**
267
         * Sets the author of the project
268
         * 
269
         * @param author
270
         *            name as string
271
         */
272
        public void setOwner(String owner) {
273
                this.owner = owner;
274
                change.firePropertyChange("setOwner", null, null);
275
        }
276

    
277
        /**
278
         * Obtiene el color de selecci?n que se usar? en el proyecto
279
         * 
280
         * @return
281
         */
282
        public Color getSelectionColor() {
283
                if (selectionColor == null) {
284
                        selectionColor = getPreferences().getDefaultSelectionColor();
285
                }
286
                return selectionColor;
287
        }
288

    
289
        /**
290
         * Sets the selecction color
291
         * 
292
         * @param selection
293
         *            color as string
294
         */
295
        public void setSelectionColor(String selectionColor) {
296
                this.setSelectionColor(StringUtilities.string2Color(selectionColor));
297
        }
298

    
299
        /**
300
         * Sets the selecction color
301
         * 
302
         * @param selection
303
         *            color as Color
304
         */
305
        public void setSelectionColor(Color selectionColor) {
306
                this.selectionColor = selectionColor;
307
                MapContext.setSelectionColor(selectionColor);
308
                change.firePropertyChange("selectionColor", null, selectionColor);
309
        }
310

    
311
        public IProjection getProjection() {
312
                if (projection == null) {
313
                        projection = getPreferences().getDefaultProjection();
314
                }
315
                return projection;
316
        }
317

    
318
        public void setProjection(IProjection projection) {
319
                this.projection = projection;
320
        }
321

    
322
        /**
323
         * Sets the modified state of project.
324
         * 
325
         * Can't set to not modified.
326
         * 
327
         * @param modified
328
         *            as boolean
329
         */
330
        public void setModified(boolean modified) {
331
                this.modified = modified;
332
                if (modified == false) {
333
                        List<Document> documents = this.getDocuments();
334
                        for (int i = 0; i < documents.size(); i++) {
335
                                documents.get(i).setModified(false);
336
                        }
337
                }
338
        }
339

    
340
        public boolean hasChanged() {
341
                // we return true if the project is not empty (until we have a better
342
                // method...)
343
                if ((this.getDocuments().size() != 0) || modified) {
344
                        return true;
345
                }
346
                return false;
347
        }
348

    
349
        /**
350
         * Return a list of documents in the project.
351
         * 
352
         * @return documents as List of IProjectDocument
353
         */
354
        public List<Document> getDocuments() {
355
                return Collections.unmodifiableList(documents);
356
        }
357

    
358
        /**
359
         * Return a list with all documents of especified type.
360
         * 
361
         * @param type
362
         *            of document
363
         * 
364
         * @return List of IProjectDocument
365
         */
366
        public List<Document> getDocuments(String type) {
367
                List<Document> docs = new ArrayList<Document>();
368
                if (type != null) {
369
                        for (Document document : this.documents) {
370
                                if (type.equalsIgnoreCase(document.getTypeName())) {
371
                                        docs.add(document);
372
                                }
373
                        }
374
                }
375
                return Collections.unmodifiableList(docs);
376
        }
377

    
378
        /**
379
         * Adds a document to the project
380
         * 
381
         * @param document
382
         *            as IProjectDocument
383
         */
384
        public void add(Document document) {
385
                document.addPropertyChangeListener(this);
386
                document.setProject(this);
387
                document.setName(this.getUniqueNameForDocument(document.getTypeName(),
388
                                document.getName()));
389
                documents.add(document);
390
                document.afterAdd();
391
                this.setModified(true);
392
                change.firePropertyChange("addDocument", null, null);
393
        }
394

    
395
        /**
396
         * Remove a document of the project
397
         * 
398
         * @param document
399
         *            as IProjectDocument
400
         */
401
        public void remove(Document doc) {
402
                documents.remove(doc);
403
                this.setModified(true);
404
                change.firePropertyChange("delDocument", null, null);
405
                doc.afterRemove();
406
        }
407

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

    
412
        public boolean isEmpty() {
413
                return documents.isEmpty();
414
        }
415

    
416
        /**
417
         * Return the FeatureTableDocument associated with a layer
418
         * 
419
         * @param layer
420
         * 
421
         * @return FeatureTableDocument associated with the layer.
422
         */
423
        public TableDocument getTable(FLyrVect layer) {
424
                List<Document> tables = getDocuments(TableManager.TYPENAME);
425
                for (int i = 0; i < tables.size(); i++) {
426
                        TableDocument table = (TableDocument) tables.get(i);
427
                        if (table.getStore().equals(layer.getFeatureStore())) {
428
                                return table;
429
                        }
430
                }
431

    
432
                return null;
433
        }
434

    
435
        /**
436
         * Return the view that contains the especified layer.
437
         * 
438
         * @param layer
439
         * 
440
         * @return name of the view that contains the layer
441
         * 
442
         * @throws RuntimeException
443
         *             Si la capa que se pasa como par?metro no se encuentra en
444
         *             ninguna vista
445
         */
446
        public String getViewName(FLayer layer) {
447
                List<Document> views = getDocuments(ViewManager.TYPENAME);
448
                for (int v = 0; v < views.size(); v++) {
449
                        DefaultViewDocument pView = (DefaultViewDocument) views.get(v);
450
                        FLayers layers = pView.getMapContext().getLayers();
451
                        if (isView(layers, layer)) {
452
                                return pView.getName();
453
                        }
454
                }
455

    
456
                throw new RuntimeException(MessageFormat.format(
457
                                "The layer '{1}' is not in a view", layer.getName()));
458
        }
459

    
460
        private boolean isView(FLayers layers, FLayer layer) {
461
                for (int i = 0; i < layers.getLayersCount(); i++) {
462
                        if (layers.getLayer(i) instanceof FLayers) {
463
                                if (isView((FLayers) layers.getLayer(i), layer)) {
464
                                        return true;
465
                                }
466
                        }
467
                        if (layers.getLayer(i) == layer) {
468
                                return true;
469
                        }
470
                }
471
                return false;
472
        }
473

    
474
        public void addExtent(ProjectExtent arg1) {
475
                extents.add(arg1);
476
                change.firePropertyChange("addExtent", null, null);
477
        }
478

    
479
        public ProjectExtent removeExtent(int arg0) {
480
                change.firePropertyChange("delExtent", null, null);
481
                return extents.remove(arg0);
482
        }
483

    
484
        public ProjectExtent[] getExtents() {
485
                return (ProjectExtent[]) extents.toArray(new ProjectExtent[0]);
486
        }
487

    
488
        /**
489
         * Obtiene un documento a partir de su nombre y el nombre de registro en el
490
         * pointExtension, este ?ltimo se puede obtener del
491
         * Project****Factory.registerName.
492
         * 
493
         * @param name
494
         *            Nombre del documento
495
         * @param type
496
         *            nombre de registro en el extensionPoint
497
         * 
498
         * @return Documento
499
         */
500
        public Document getDocument(String name, String type) {
501
                if (type != null) {
502
                        for (int i = 0; i < documents.size(); i++) {
503
                                Document document = documents.get(i);
504
                                if (type.equalsIgnoreCase(document.getTypeName())
505
                                                && name.equalsIgnoreCase(document.getName())) {
506
                                        return document;
507
                                }
508
                        }
509
                }
510
                return null;
511
        }
512

    
513
        public String getUniqueNameForDocument(String type, String name) {
514
                Document document = getDocument(name, type);
515
                if (document == null) {
516
                        return name;
517
                }
518

    
519
                String newName = null;
520
                int num = this.getNextDocumentIndex(type);
521
                while (document != null) {
522
                        newName = name + " - " + num++;
523
                        document = getDocument(newName, type);
524
                }
525
                this.setNextDocumentIndex(type, num);
526
                return newName;
527
        }
528

    
529
        private int getNextDocumentIndex(String type) {
530
                if (nextDocumentIndexByType.get(type) == null) {
531
                        nextDocumentIndexByType.put(type, new Integer(1));
532
                        return 1;
533
                }
534
                return nextDocumentIndexByType.get(type).intValue();
535
        }
536

    
537
        private void setNextDocumentIndex(String type, int newIndex) {
538
                if (nextDocumentIndexByType.get(type) == null) {
539
                        nextDocumentIndexByType.put(type, new Integer(newIndex));
540
                } else {
541
                        nextDocumentIndexByType.put(type, new Integer(newIndex));
542
                }
543
        }
544

    
545
        public void saveState(File out) throws PersistenceException {
546
                FileOutputStream fout;
547
                try {
548
                        fout = new FileOutputStream(out);
549
                        saveState(fout, new File(out.getParent()));
550
                } catch (FileNotFoundException e) {
551
                        throw new PersistenceException(e);
552
                }
553
        }
554

    
555
        public void saveState(OutputStream out) throws PersistenceException {
556
                saveState(out, null);
557
        }
558

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

    
577
        private void relativizeFiles(PersistentState state, File rootFolder) {
578
                PersistentContext context = state.getContext();
579

    
580
                URI cwd = new File(System.getProperty("user.dir")).toURI();
581
                @SuppressWarnings("unchecked")
582
                Iterator<PersistentState> statesIterator = context.iterator();
583
                while (statesIterator.hasNext()) {
584
                        PersistentState aState = statesIterator.next();
585
                        DynStruct definition = aState.getDefinition();
586
                        DynField[] fields = definition.getDynFields();
587
                        for (DynField field : fields) {
588
                                if (field.getType() == DataTypes.FILE
589
                                                || field.getType() == DataTypes.FOLDER) {
590
                                        try {
591
                                                File value = aState.getFile(field.getName());
592
                                                value = relativizeFile(value, rootFolder);
593
                                                aState.set(field.getName(), value);
594
                                        } catch (PersistenceException e) {
595
                                                LOG.warn(
596
                                                                "Can't relativice field '" + field.getName()
597
                                                                                + "' for class '"
598
                                                                                + definition.getName() + "'.", e);
599
                                        }
600
                                } else if (field.getType() == DataTypes.URL) {
601
                                        try {
602
                                                URL value = aState.getURL(field.getName());
603
                                                if ("FILE".equalsIgnoreCase(value.getProtocol())) {
604
                                                        File file = new File(value.toURI());
605
                                                        file = relativizeFile(file, rootFolder);
606
                                                        value = new URL("file","",file.toURI().toString().substring(cwd.toString().length()));
607
                                                        aState.set(field.getName(), value);
608
                                                }
609
                                        } catch (PersistenceException e) {
610
                                                // do nothind
611
                                        } catch (MalformedURLException e) {
612
                                                // do nothind
613
                                        } catch (URISyntaxException e) {
614
                                                // do nothind
615
                                        }
616
                                }
617
                        }
618
                }
619
        }
620

    
621
        private File relativizeFile(File file, File rootFolder) {
622
                if (rootFolder == null) {
623
                        return file;
624
                }
625
                if (file == null) {
626
                        return null;
627
                }
628
                boolean isDir = false;
629
                // isDir = file.isDirectory();
630
                isDir = rootFolder.isDirectory();
631
                String basePath = rootFolder.getAbsolutePath();
632
                String targetPath = file.getPath();
633
                String pathSeparator = File.separator;
634
                // We need the -1 argument to split to make sure we get a trailing
635
                // "" token if the base ends in the path separator and is therefore
636
                // a directory. We require directory paths to end in the path
637
                // separator -- otherwise they are indistinguishable from files.
638
                String[] base = basePath.split(Pattern.quote(pathSeparator), -1);
639
                String[] target = targetPath.split(Pattern.quote(pathSeparator), 0);
640

    
641
                // First get all the common elements. Store them as a string,
642
                // and also count how many of them there are.
643
                String common = "";
644
                int commonIndex = 0;
645
                for (int i = 0; i < target.length && i < base.length; i++) {
646
                        if (target[i].equals(base[i])) {
647
                                common += target[i] + pathSeparator;
648
                                commonIndex++;
649
                        } else
650
                                break;
651
                }
652

    
653
                if (commonIndex == 0) {
654
                        // Whoops -- not even a single common path element. This most
655
                        // likely indicates differing drive letters, like C: and D:.
656
                        // These paths cannot be relativized. Return the target path.
657
                        return file;
658
                        // This should never happen when all absolute paths
659
                        // begin with / as in *nix.
660
                }
661

    
662
                String relative = "";
663
                if (base.length == commonIndex) {
664
                        // Comment this out if you prefer that a relative path not start
665
                        // with ./
666
                        relative = "." + pathSeparator;
667
                } else {
668
                        int numDirsUp = base.length - commonIndex - (isDir ? 0 : 1); /*
669
                                                                                                                                                 * only
670
                                                                                                                                                 * subtract
671
                                                                                                                                                 * 1 if
672
                                                                                                                                                 * it is
673
                                                                                                                                                 * a
674
                                                                                                                                                 * file.
675
                                                                                                                                                 */
676
                        // The number of directories we have to backtrack is the length of
677
                        // the base path MINUS the number of common path elements, minus
678
                        // one because the last element in the path isn't a directory.
679
                        for (int i = 1; i <= (numDirsUp); i++) {
680
                                relative += ".." + pathSeparator;
681
                        }
682
                }
683
                // if we are comparing directories then we
684
                if (targetPath.length() > common.length()) {
685
                        // it's OK, it isn't a directory
686
                        relative += targetPath.substring(common.length());
687
                }
688

    
689
                return new File(relative);
690
        }
691

    
692
        private void fixFiles(PersistentState state, File rootFolder) {
693
                PersistentContext context = state.getContext();
694
                URI cwd = new File(System.getProperty("user.dir")).toURI();
695

    
696
                @SuppressWarnings("unchecked")
697
                Iterator<PersistentState> statesIterator = context.iterator();
698
                while (statesIterator.hasNext()) {
699
                        PersistentState aState = statesIterator.next();
700
                        DynStruct definition = aState.getDefinition();
701
                        DynField[] fields = definition.getDynFields();
702
                        for (DynField field : fields) {
703
                                if (field.getType() == DataTypes.FILE
704
                                                || field.getType() == DataTypes.FOLDER) {
705
                                        try {
706
                                                File value = aState.getFile(field.getName());
707
                                                value = fixFile(value, rootFolder);
708
                                                aState.set(field.getName(), value);
709
                                        } catch (PersistenceException e) {
710
                                                LOG.warn(
711
                                                                "Can't fix field '" + field.getName()
712
                                                                                + "' for class '"
713
                                                                                + definition.getName() + "'.", e);
714
                                        }
715
                                } else if (field.getType() == DataTypes.URL) {
716
                                        try {
717
                                                URL value = aState.getURL(field.getName());
718
                                                if ("FILE".equalsIgnoreCase(value.getProtocol())) {
719
                                                        if (!value.getFile().startsWith("/")){
720
                                                                value = new URL("file","",cwd.getRawPath()+value.getFile());
721
                                                                File file = new File(value.toURI().getPath().substring(cwd.getPath().length()));
722
                                                                file = fixFile(file, rootFolder);
723
                                                                aState.set(field.getName(), file.toURI().toURL());
724
                                                        }
725
                                                }
726
                                        } catch (PersistenceException e) {
727
                                                // do nothing
728
                                        } catch (MalformedURLException e) {
729
                                                // do nothing
730
                                        } catch (URISyntaxException e) {
731
                                                // do nothing
732
                                        }
733

    
734
                                }
735
                        }
736
                }
737
        }
738

    
739
        private File fixFile(File file, File rootFolder) {
740
                if (file.isAbsolute()) {
741
                        return file;
742
                }
743
                try {
744
                        return new File(rootFolder, file.getPath()).getCanonicalFile();
745
                } catch (IOException e) {
746
                        return new File(rootFolder, file.getPath());
747
                }
748
        }
749

    
750
        public void loadState(InputStream in) {
751
                loadState(in, null);
752
        }
753

    
754
        public void loadState(InputStream in, File rootFolder) {
755
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
756
                try {
757
                        PersistentState state = manager.loadState(in);
758
                        try {
759
                                if (rootFolder != null) {
760
                                        fixFiles(state, rootFolder);
761
                                }
762
                        } catch (Exception ex) {
763
                                state.getContext().addError(ex);
764
                        }
765
                        this.loadFromState(state);
766
                } catch (PersistenceException e) {
767
                        // TODO Auto-generated catch block
768
                        e.printStackTrace();
769
                }
770

    
771
        }
772

    
773
        public void loadState(File in) {
774
                FileInputStream fin;
775
                try {
776
                        fin = new FileInputStream(in);
777
                        loadState(fin, new File(in.getParent()));
778
                } catch (FileNotFoundException e) {
779
                        // TODO Auto-generated catch block
780
                        e.printStackTrace();
781
                }
782
        }
783

    
784
        @SuppressWarnings("unchecked")
785
        public void loadFromState(PersistentState state)
786
                        throws PersistenceException {
787
                this.clean();
788

    
789
                this.setComments(state.getString("comments"));
790
                this.setCreationDate(state.getString("creationDate"));
791
                this.setModificationDate(state.getString("modificationDate"));
792
                this.setName(state.getString("name"));
793
                this.setOwner(state.getString("owner"));
794
                this.setSelectionColor((Color) state.get("selectionColor"));
795
                this.setProjection((IProjection) state.get("projection"));
796

    
797
                List<ProjectExtent> extents = (List<ProjectExtent>) state
798
                                .get("extents");
799
                for (int i = 0; i < extents.size(); i++) {
800
                        this.addExtent(extents.get(i));
801
                }
802

    
803
                List<AbstractDocument> documents = (List<AbstractDocument>) state
804
                                .get("documents");
805
                for (int i = 0; i < documents.size(); i++) {
806
                        this.add(documents.get(i));
807
                }
808

    
809
                List<DocumentWindowInfo> persistentWindows = (List<DocumentWindowInfo>) state.get("documentWindowsInformation");
810
                                
811
                for (int i = 0; i < persistentWindows.size(); i++) {
812
                        DocumentWindowInfo persistentWindow = persistentWindows.get(i);
813
                        String docName = persistentWindow.getDocumentName();
814
                        String docType = persistentWindow.getDocumentType();
815
                        Document doc = this.getDocument(docName, docType);
816
                        IWindow win = doc.getFactory().getMainWindow(doc);
817
                        win.getWindowInfo().setWindowInfo(persistentWindow.getWindowInfo());
818
                        PluginServices.getMDIManager().addWindow(win);
819
                }
820
                
821
                if (state.hasValue("projectWindowInfo")){
822
                        WindowInfo projectWindowInfo = (WindowInfo)state.get("projectWindowInfo"); 
823
                        ProjectExtension pe = (ProjectExtension) PluginServices.getExtension(org.gvsig.app.extension.ProjectExtension.class);
824
                        pe.setProject(this);
825
                        pe.showProjectWindow(projectWindowInfo);
826
                }
827

    
828
        }
829

    
830
        public void saveToState(PersistentState state) throws PersistenceException {
831
                state.set("version", VERSION);
832
                state.set("comments", getComments());
833
                state.set("creationDate", this.getCreationDate());
834

    
835
                state.set("modificationDate", this.getModificationDate());
836
                state.set("name", this.getName());
837
                state.set("owner", this.getOwner());
838
                state.set("selectionColor", this.getSelectionColor());
839

    
840
                state.set("projection", this.getProjection());
841

    
842
                state.set("extents", this.extents);
843
                state.set("documents", this.getDocuments());
844

    
845
                List<DocumentWindowInfo> persistentWindows = new ArrayList<DocumentWindowInfo>();
846
                IWindow[] windows = PluginServices.getMDIManager().getOrderedWindows();
847
                for (int i = windows.length - 1; i >= 0; i--) {
848
                        IWindow window = windows[i];
849
                        if (window instanceof IDocumentWindow){
850
                                DocumentWindowInfo dwi = new DocumentWindowInfo(
851
                                                window.getWindowInfo(),
852
                                                ((IDocumentWindow) window).getDocument().getTypeName(),
853
                                                ((IDocumentWindow) window).getDocument().getName());
854
                                persistentWindows.add(dwi);
855
                        } else if (window instanceof ProjectWindow){
856
                                state.set("projectWindowInfo", ((ProjectWindow)window).getWindowInfo());
857
                        }
858
                }
859
                state.set("documentWindowsInformation", persistentWindows);
860

    
861
        }
862

    
863
        public static class DocumentWindowInfo implements Persistent {
864

    
865
                public static final String PERSISTENCE_DEFINITION_NAME = "DocumentWindowInfo";
866

    
867
                private WindowInfo windowInfo;
868
                private String documentType;
869
                private String documentName;
870

    
871
                public DocumentWindowInfo(){
872
                }
873
                
874
                DocumentWindowInfo(WindowInfo wi, String docType, String docName){
875
                        windowInfo = wi;
876
                        documentType = docType;
877
                        documentName = docName;
878
                }
879

    
880
                public WindowInfo getWindowInfo() {
881
                        return windowInfo;
882
                }
883
                
884
                public String getDocumentType() {
885
                        return documentType;
886
                }
887

    
888
                public String getDocumentName() {
889
                        return documentName;
890
                }
891

    
892
                public void saveToState(PersistentState state)
893
                                throws PersistenceException {
894
                        state.set("windowInfo", this.windowInfo);
895
                        state.set("documentType", this.documentType);
896
                        state.set("documentName", this.documentName);
897
                }
898

    
899
                public void loadFromState(PersistentState state)
900
                                throws PersistenceException {
901
                        this.windowInfo = (WindowInfo) state.get("windowInfo");
902
                        this.documentType = state.getString("documentType");
903
                        this.documentName = state.getString("documentName");
904
                }
905
                
906
                public static void registerPersistent() {
907
                        PersistenceManager manager = ToolsLocator.getPersistenceManager();
908
                        DynStruct definition = manager.getDefinition(PERSISTENCE_DEFINITION_NAME);
909
                        if ( definition == null ){
910
                                definition = manager.addDefinition(
911
                                                DocumentWindowInfo.class,
912
                                                PERSISTENCE_DEFINITION_NAME,
913
                                                "DocumentWindowInfo persistence definition",
914
                                                null, 
915
                                                null
916
                                );
917
                                definition.addDynFieldObject("windowInfo").setMandatory(true).setClassOfValue(WindowInfo.class);
918
                                definition.addDynFieldString("documentType").setMandatory(true);
919
                                definition.addDynFieldString("documentName").setMandatory(true);
920
                        }
921

    
922
                }
923
        }
924
        
925
        public static void registerPersistent() {
926
                AbstractDocument.registerPersistent();
927
                DocumentWindowInfo.registerPersistent();
928

    
929
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
930
                DynStruct definition = manager.addDefinition(DefaultProject.class,
931
                                "Project", "Project Persistence definition", null, null);
932
                definition.addDynFieldString("version").setMandatory(true);
933
                definition.addDynFieldString("comments").setMandatory(true);
934
                definition.addDynFieldString("creationDate").setMandatory(true);
935
                definition.addDynFieldString("modificationDate").setMandatory(true);
936
                definition.addDynFieldString("name").setMandatory(true);
937
                definition.addDynFieldString("owner").setMandatory(true);
938

    
939
                definition.addDynFieldObject("selectionColor")
940
                                .setClassOfValue(Color.class).setMandatory(true);
941
                definition.addDynFieldObject("projection")
942
                                .setClassOfValue(IProjection.class).setMandatory(true);
943

    
944
                definition.addDynFieldList("extents")
945
                                .setClassOfItems(ProjectExtent.class).setMandatory(true);
946

    
947
                definition.addDynFieldList("documents").setClassOfItems(Document.class)
948
                                .setMandatory(true);
949

    
950
                definition.addDynFieldObject("projectWindowInfo").setClassOfValue(WindowInfo.class).setMandatory(false);
951

    
952
                definition.addDynFieldList("documentWindowsInformation").setClassOfItems(WindowInfo.class).setMandatory(false);
953

    
954
        }
955

    
956
        /**
957
         * @deprecated use getPreferences().setDefaultSelectionColor()
958
         */
959
        public static void setDefaultSelectionColor(Color color) {
960
                getPreferences().setDefaultSelectionColor(color);
961
        }
962

    
963
        /**
964
         * @deprecated use getPreferences().getDefaultSelectionColor()
965
         */
966

    
967
        public static Color getDefaultSelectionColor() {
968
                return getPreferences().getDefaultSelectionColor();
969
        }
970

    
971
        /**
972
         * @deprecated use getPreferences().getDefaultMapUnits()
973
         */
974
        public static int getDefaultMapUnits() {
975
                return getPreferences().getDefaultMapUnits();
976
        }
977

    
978
        /**
979
         * @deprecated use getPreferences().getDefaultDistanceUnits()
980
         */
981
        public static int getDefaultDistanceUnits() {
982
                return getPreferences().getDefaultDistanceUnits();
983
        }
984

    
985
        /**
986
         * @deprecated use getPreferences().getDefaultDistanceArea()
987
         */
988
        public static int getDefaultDistanceArea() {
989
                return getPreferences().getDefaultDistanceArea();
990
        }
991

    
992
        /**
993
         * @deprecated use getPreferences().setDefaultMapUnits()
994
         */
995
        public static void setDefaultMapUnits(int mapUnits) {
996
                getPreferences().setDefaultMapUnits(mapUnits);
997
        }
998

    
999
        /**
1000
         * @deprecated use getPreferences().setDefaultDistanceUnits()
1001
         */
1002
        public static void setDefaultDistanceUnits(int distanceUnits) {
1003
                getPreferences().setDefaultDistanceUnits(distanceUnits);
1004
        }
1005

    
1006
        /**
1007
         * @deprecated use getPreferences().setDefaultDistanceArea()
1008
         */
1009
        public static void setDefaultDistanceArea(int distanceArea) {
1010
                getPreferences().setDefaultDistanceArea(distanceArea);
1011
        }
1012

    
1013
        /**
1014
         * @deprecated use getPreferences().setDefaultProjection()
1015
         */
1016
        public static void setDefaultProjection(IProjection defaultProjection) {
1017
                getPreferences().setDefaultProjection(defaultProjection);
1018
        }
1019

    
1020
        /**
1021
         * @deprecated use getPreferences().getDefaultProjection()
1022
         */
1023
        public static IProjection getDefaultProjection() {
1024
                return getPreferences().getDefaultProjection();
1025
        }
1026

    
1027
        /**
1028
         * @deprecated see {@link #setSelectionColor(String)}, to be remove in gvSIG
1029
         *             2.1.0
1030
         */
1031
        public void setColor(String color) {
1032
                this.setSelectionColor(StringUtilities.string2Color(color));
1033
        }
1034

    
1035
        /**
1036
         * Return the selection color
1037
         * 
1038
         * @return selection color as string
1039
         * @deprecated use {@link #getSelectionColor()}
1040
         */
1041
        public String getColor() {
1042
                return StringUtilities.color2String(selectionColor);
1043
        }
1044

    
1045
        /**
1046
         * Devuelve a partir del nombre la tabla asociada.
1047
         * 
1048
         * @param name
1049
         *            Nombre.
1050
         * @deprecated utilizar getProjectDocumentByName(...);
1051
         * @return ProjectTable de la tabla asociada.
1052
         */
1053
        public TableDocument getTable(String name) {
1054
                return (TableDocument) this.getDocument(name, TableManager.TYPENAME);
1055
        }
1056

    
1057
        /**
1058
         * Return the list of maps of the project
1059
         * 
1060
         * @return tables as ArrayList of IProjectDocument
1061
         * 
1062
         * @deprecated see {@link #getDocumentsByType(String)}
1063
         */
1064
        public List<Document> getMaps() {
1065
                return getDocuments(LayoutManager.TYPENAME);
1066
        }
1067

    
1068
        /**
1069
         * Add a {@link LayoutDocument} to the project
1070
         * 
1071
         * @deprecated see {@link #add(Document)}
1072
         */
1073
        public void addMap(LayoutDocument m) {
1074
                add(m);
1075
        }
1076

    
1077
        /**
1078
         * Remove a map of the project
1079
         * 
1080
         * @param index
1081
         *            of the map as integer
1082
         * 
1083
         * @deprecated see {@link #remove(Document)}
1084
         */
1085
        public void delMap(int i) {
1086
                List<Document> list = getDocuments(LayoutManager.TYPENAME);
1087
                remove(list.get(i));
1088
        }
1089

    
1090
        /**
1091
         * Return the list of tables of the project
1092
         * 
1093
         * @return tables as ArrayList of ProjectDocument
1094
         * 
1095
         * @deprecated see {@link #getDocumentsByType(String)}
1096
         */
1097
        public List<Document> getTables() {
1098
                return getDocuments(TableManager.TYPENAME);
1099
        }
1100

    
1101
        /**
1102
         * Add a {@link TableDocument } to the project
1103
         * 
1104
         * @deprecated see {@link #add(AbstractDocument)}
1105
         */
1106
        public void addTable(TableDocument t) {
1107
                add(t);
1108
        }
1109

    
1110
        /**
1111
         * Remove a {@link TableDocument } of the project
1112
         * 
1113
         * @param index
1114
         *            of the table as integer
1115
         * 
1116
         * @deprecated see {@link #remove(AbstractDocument)}
1117
         */
1118
        public void delTable(int i) {
1119
                List<Document> list = getDocuments(TableManager.TYPENAME);
1120
                remove(list.get(i));
1121
        }
1122

    
1123
        /**
1124
         * Return the list of views of the project
1125
         * 
1126
         * @return views as ArrayList of ProjectDocument
1127
         * 
1128
         * @deprecated see {@link #getDocumentsByType(String)}
1129
         */
1130
        public List<Document> getViews() {
1131
                return getDocuments(ViewManager.TYPENAME);
1132
        }
1133

    
1134
        /**
1135
         * Add a view to the project
1136
         * 
1137
         * @deprecated see {@link #add(AbstractDocument)}
1138
         */
1139
        public void addView(DefaultViewDocument v) {
1140
                add(v);
1141
        }
1142

    
1143
        /**
1144
         * Remove a view of the project
1145
         * 
1146
         * @param index
1147
         *            of the view as integer
1148
         * 
1149
         * @deprecated see {@link #remove(AbstractDocument)}
1150
         */
1151
        public void delView(int i) {
1152
                List<Document> list = getDocuments(ViewManager.TYPENAME);
1153
                remove(list.get(i));
1154
        }
1155

    
1156
        /**
1157
         * @deprecated see {@link #getDocument(String, String)}
1158
         */
1159
        public Document getProjectDocumentByName(String name, String type) {
1160
                return this.getDocument(name, type);
1161
        }
1162

    
1163
        /**
1164
         * @deprecated see {@link #getDocuments(String)}
1165
         */
1166
        public List<Document> getDocumentsByType(String type) {
1167
                return this.getDocuments(type);
1168
        }
1169

    
1170
        /**
1171
         * @deprecated aun por decidir que API darle al copy/paste
1172
         */
1173
        public String exportToXML(AbstractDocument[] selectedItems)
1174
                        throws SaveException {
1175
                // FIXME jjdc:hay que decirdir que API darle al copy/paste
1176
                throw new UnsupportedOperationException("This method is not supported");
1177
        }
1178

    
1179
        /**
1180
         * @deprecated aun por decidir que API darle al copy/paste
1181
         */
1182
        public void importFromXML(String sourceString, String docType) {
1183
                // FIXME jjdc:hay que decirdir que API darle al copy/paste
1184
                throw new UnsupportedOperationException("This method is not supported");
1185
        }
1186

    
1187
        /**
1188
         * @deprecated aun por decidir que API darle al copy/paste
1189
         */
1190
        public boolean isValidXMLForImport(String sourceString, String docType) {
1191
                // FIXME jjdc:hay que decirdir que API darle al copy/paste
1192
                throw new UnsupportedOperationException("This method is not supported");
1193
        }
1194

    
1195
        public boolean canImportDocuments(String data, String doctype) {
1196
                // TODO Auto-generated method stub
1197
                return false;
1198
        }
1199

    
1200
        public String exportDocumentsAsText(List<Document> documents) {
1201
                // TODO Auto-generated method stub
1202
                return null;
1203
        }
1204

    
1205
        public void importDocuments(String data, String doctype) {
1206
                // TODO Auto-generated method stub
1207

    
1208
        }
1209

    
1210
        public Document getActiveDocument() {
1211
                try {
1212
                        SingletonWindow window = (SingletonWindow) PluginServices
1213
                                        .getMDIManager().getActiveWindow();
1214
                        Document doc = (Document) window.getWindowModel();
1215
                        return doc;
1216
                } catch (Exception ex) {
1217
                        return null;
1218
                }
1219
        }
1220
}