Statistics
| Revision:

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

History | View | Annotate | Download (31.8 KB)

1 31496 jjdelcerro
/* gvSIG. Geographic Information System of the Valencian Government
2 34300 fdiaz
 *
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 31496 jjdelcerro
23
/*
24 34300 fdiaz
 * AUTHORS (In addition to CIT):
25
 * 2004-2009 IVER TI
26
 *
27
 */
28 31496 jjdelcerro
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.InputStream;
40
import java.io.OutputStream;
41
import java.io.Serializable;
42 34300 fdiaz
import java.net.MalformedURLException;
43
import java.net.URI;
44
import java.net.URISyntaxException;
45
import java.net.URL;
46 31496 jjdelcerro
import java.text.DateFormat;
47
import java.text.MessageFormat;
48
import java.util.ArrayList;
49
import java.util.Collections;
50
import java.util.Date;
51
import java.util.HashMap;
52
import java.util.Iterator;
53
import java.util.List;
54
import java.util.Map;
55 34300 fdiaz
import java.util.regex.Pattern;
56 31496 jjdelcerro
57
import org.cresques.cts.IProjection;
58 36443 cordinyana
import org.slf4j.Logger;
59
import org.slf4j.LoggerFactory;
60
61 31496 jjdelcerro
import org.gvsig.andami.PluginServices;
62
import org.gvsig.andami.ui.mdiManager.IWindow;
63 36473 fdiaz
import org.gvsig.andami.ui.mdiManager.MDIManager;
64 31496 jjdelcerro
import org.gvsig.andami.ui.mdiManager.SingletonWindow;
65 34833 fdiaz
import org.gvsig.andami.ui.mdiManager.WindowInfo;
66 36184 jjdelcerro
import org.gvsig.app.ApplicationLocator;
67
import org.gvsig.app.ApplicationManager;
68 34833 fdiaz
import org.gvsig.app.extension.ProjectExtension;
69 31496 jjdelcerro
import org.gvsig.app.extension.Version;
70
import org.gvsig.app.project.documents.AbstractDocument;
71
import org.gvsig.app.project.documents.Document;
72
import org.gvsig.app.project.documents.exceptions.SaveException;
73 34833 fdiaz
import org.gvsig.app.project.documents.gui.IDocumentWindow;
74
import org.gvsig.app.project.documents.gui.ProjectWindow;
75 31496 jjdelcerro
import org.gvsig.app.project.documents.view.DefaultViewDocument;
76
import org.gvsig.app.project.documents.view.ViewManager;
77 33331 jjdelcerro
import org.gvsig.fmap.dal.DataTypes;
78 31496 jjdelcerro
import org.gvsig.fmap.mapcontext.MapContext;
79
import org.gvsig.fmap.mapcontext.layers.FLayer;
80
import org.gvsig.fmap.mapcontext.layers.FLayers;
81
import org.gvsig.tools.ToolsLocator;
82 33331 jjdelcerro
import org.gvsig.tools.dynobject.DynField;
83 32880 jjdelcerro
import org.gvsig.tools.dynobject.DynStruct;
84 31496 jjdelcerro
import org.gvsig.tools.persistence.PersistenceManager;
85
import org.gvsig.tools.persistence.Persistent;
86 33331 jjdelcerro
import org.gvsig.tools.persistence.PersistentContext;
87 31496 jjdelcerro
import org.gvsig.tools.persistence.PersistentState;
88 32880 jjdelcerro
import org.gvsig.tools.persistence.exception.PersistenceException;
89 31496 jjdelcerro
import org.gvsig.utils.StringUtilities;
90
91
/**
92
 * Clase que representa un proyecto de gvSIG
93 34300 fdiaz
 *
94 31496 jjdelcerro
 * @author 2004-2005 Fernando Gonz?lez Cort?s
95
 * @author 2006-2009 Jose Manuel Vivo
96 34300 fdiaz
 * @author 2005- Vicente Caballero
97
 * @author 2009- Joaquin del Cerro
98 31496 jjdelcerro
 *
99
 */
100
101 34300 fdiaz
public class DefaultProject implements Serializable, PropertyChangeListener,
102
                Project {
103 31496 jjdelcerro
104 33331 jjdelcerro
        private Logger LOG = LoggerFactory.getLogger(DefaultProject.class);
105 31496 jjdelcerro
        /**
106
         * @deprecated see ApplicationLocator.getManager().getVersion()
107
         */
108
        public static String VERSION = Version.format();
109
110
        /**
111
         *
112
         */
113
        private static final long serialVersionUID = -4449622027521773178L;
114
115 37827 jjdelcerro
        private static final Logger logger = LoggerFactory.getLogger(Project.class);
116 31496 jjdelcerro
117
        private static ProjectPreferences preferences = new ProjectPreferences();
118
119
        /**
120
         * Index used by the generator of unique names of documents.
121
         */
122
        private Map<String, Integer> nextDocumentIndexByType = new HashMap<String, Integer>();
123
124
        private PropertyChangeSupport change;
125
126
        private boolean modified = false;
127
128
        private String name = null;
129
130
        private String creationDate = null;
131
132
        private String modificationDate = null;
133
134
        private String owner = null;
135
136
        private String comments = null;
137
138
        private Color selectionColor = null;
139
140
        private List<Document> documents = null;
141
142
        private List<ProjectExtent> extents = null;
143
144
        private IProjection projection;
145
146
        /**
147
         * Creates a new Project object.
148
         */
149
        DefaultProject() {
150
                this.change = new PropertyChangeSupport(this);
151
                this.clean();
152
        }
153
154
        protected void clean() {
155
                this.owner = "";
156
                this.comments = "";
157
                this.name = PluginServices.getText(this, "untitled");
158
                this.creationDate = DateFormat.getDateInstance().format(new Date());
159
                this.modificationDate = this.creationDate;
160
161
                this.documents = new ArrayList<Document>();
162
                this.extents = new ArrayList<ProjectExtent>();
163
164
                this.setSelectionColor(getPreferences().getDefaultSelectionColor());
165 34300 fdiaz
166
                this.projection = null; // se inicializa en el getProjection()
167 31496 jjdelcerro
        }
168 34300 fdiaz
169 31496 jjdelcerro
        public static ProjectPreferences getPreferences() {
170
                return preferences;
171
        }
172
173
        public void propertyChange(PropertyChangeEvent evt) {
174
                change.firePropertyChange(evt);
175
        }
176
177
        public synchronized void addPropertyChangeListener(
178
                        PropertyChangeListener arg0) {
179
                change.addPropertyChangeListener(arg0);
180
        }
181
182
        /**
183
         * Return the creation date of the project
184 34300 fdiaz
         *
185 31496 jjdelcerro
         * @return
186
         */
187
        public String getCreationDate() {
188
                return creationDate;
189
        }
190
191
        protected void setCreationDate(String creationDate) {
192 34300 fdiaz
                this.creationDate = creationDate;
193 31496 jjdelcerro
                change.firePropertyChange("setCreationDate", null, null);
194
        }
195
196 35192 jjdelcerro
    public Document createDocument(String type) {
197 37827 jjdelcerro
            logger.info("createDocument('{}')",type);
198 35192 jjdelcerro
        return ProjectManager.getInstance().createDocument(type);
199
    }
200 31496 jjdelcerro
201 35192 jjdelcerro
    /**
202
     * Return the name of the project
203
     *
204
     * @return
205
     */
206
    public String getName() {
207
        return name;
208
    }
209
210 31496 jjdelcerro
        /**
211
         * Set the name of he project.
212 34300 fdiaz
         *
213 31496 jjdelcerro
         * @param string
214
         */
215
        public void setName(String name) {
216
                this.name = name;
217
                change.firePropertyChange("setName", null, null);
218
        }
219
220
        /**
221
         * Return the comments associateds with the project
222 34300 fdiaz
         *
223 31496 jjdelcerro
         * @return comments
224
         */
225
        public String getComments() {
226
                return comments;
227
        }
228
229
        /**
230
         * Set the comments associateds with the project
231 34300 fdiaz
         *
232
         * @param comments
233
         *            as string
234 31496 jjdelcerro
         */
235
        public void setComments(String string) {
236
                comments = string;
237
                change.firePropertyChange("setComments", null, null);
238
        }
239
240
        /**
241
         * Retuen the modification date of the project.
242 34300 fdiaz
         *
243 31496 jjdelcerro
         * @return modification date as string
244
         */
245
        public String getModificationDate() {
246
                return modificationDate;
247
        }
248
249
        protected void setModificationDate(String string) {
250
                modificationDate = string;
251
                change.firePropertyChange("setModificationDate", null, null);
252
        }
253
254
        /**
255
         * Return the author of the project,
256 34300 fdiaz
         *
257 31496 jjdelcerro
         * @return author as string
258
         */
259
        public String getOwner() {
260
                return owner;
261
        }
262
263
        /**
264
         * Sets the author of the project
265 34300 fdiaz
         *
266
         * @param author
267
         *            name as string
268 31496 jjdelcerro
         */
269
        public void setOwner(String owner) {
270
                this.owner = owner;
271
                change.firePropertyChange("setOwner", null, null);
272
        }
273
274
        /**
275
         * Obtiene el color de selecci?n que se usar? en el proyecto
276 34300 fdiaz
         *
277 31496 jjdelcerro
         * @return
278
         */
279
        public Color getSelectionColor() {
280
                if (selectionColor == null) {
281
                        selectionColor = getPreferences().getDefaultSelectionColor();
282
                }
283
                return selectionColor;
284
        }
285
286
        /**
287
         * Sets the selecction color
288 34300 fdiaz
         *
289
         * @param selection
290
         *            color as string
291 31496 jjdelcerro
         */
292
        public void setSelectionColor(String selectionColor) {
293
                this.setSelectionColor(StringUtilities.string2Color(selectionColor));
294
        }
295
296
        /**
297
         * Sets the selecction color
298 34300 fdiaz
         *
299
         * @param selection
300
         *            color as Color
301 31496 jjdelcerro
         */
302
        public void setSelectionColor(Color selectionColor) {
303
                this.selectionColor = selectionColor;
304
                MapContext.setSelectionColor(selectionColor);
305
                change.firePropertyChange("selectionColor", null, selectionColor);
306
        }
307
308
        public IProjection getProjection() {
309
                if (projection == null) {
310 34300 fdiaz
                        projection = getPreferences().getDefaultProjection();
311 31496 jjdelcerro
                }
312
                return projection;
313
        }
314
315
        public void setProjection(IProjection projection) {
316
                this.projection = projection;
317
        }
318
319
        /**
320
         * Sets the modified state of project.
321
         *
322
         * Can't set to not modified.
323 34300 fdiaz
         *
324
         * @param modified
325
         *            as boolean
326 31496 jjdelcerro
         */
327
        public void setModified(boolean modified) {
328
                this.modified = modified;
329 34300 fdiaz
                if (modified == false) {
330 31496 jjdelcerro
                        List<Document> documents = this.getDocuments();
331 34300 fdiaz
                        for (int i = 0; i < documents.size(); i++) {
332 31496 jjdelcerro
                                documents.get(i).setModified(false);
333
                        }
334
                }
335
        }
336
337 34300 fdiaz
        public boolean hasChanged() {
338
                // we return true if the project is not empty (until we have a better
339
                // method...)
340
                if ((this.getDocuments().size() != 0) || modified) {
341
                        return true;
342 31496 jjdelcerro
                }
343 34300 fdiaz
                return false;
344
        }
345 31496 jjdelcerro
346
        /**
347 34300 fdiaz
         * Return a list of documents in the project.
348
         *
349
         * @return documents as List of IProjectDocument
350
         */
351
        public List<Document> getDocuments() {
352
                return Collections.unmodifiableList(documents);
353
        }
354
355
        /**
356 31496 jjdelcerro
         * Return a list with all documents of especified type.
357 34300 fdiaz
         *
358
         * @param type
359
         *            of document
360
         *
361 31496 jjdelcerro
         * @return List of IProjectDocument
362
         */
363 34300 fdiaz
        public List<Document> getDocuments(String type) {
364
                List<Document> docs = new ArrayList<Document>();
365
                if (type != null) {
366
                        for (Document document : this.documents) {
367
                                if (type.equalsIgnoreCase(document.getTypeName())) {
368
                                        docs.add(document);
369 31496 jjdelcerro
                                }
370
                        }
371
                }
372 34300 fdiaz
                return Collections.unmodifiableList(docs);
373
        }
374 31496 jjdelcerro
375
        /**
376
         * Adds a document to the project
377 34300 fdiaz
         *
378
         * @param document
379
         *            as IProjectDocument
380 31496 jjdelcerro
         */
381
        public void add(Document document) {
382 37827 jjdelcerro
        logger.info("add('{}')", document.toString());
383
384 31496 jjdelcerro
                document.addPropertyChangeListener(this);
385
                document.setProject(this);
386 34300 fdiaz
                document.setName(this.getUniqueNameForDocument(document.getTypeName(),
387
                                document.getName()));
388 34833 fdiaz
                documents.add(document);
389 34300 fdiaz
                document.afterAdd();
390 31496 jjdelcerro
                this.setModified(true);
391 36443 cordinyana
        change.firePropertyChange("addDocument", null, document);
392 31496 jjdelcerro
        }
393
394
        /**
395
         * Remove a document of the project
396 34300 fdiaz
         *
397
         * @param document
398
         *            as IProjectDocument
399 31496 jjdelcerro
         */
400
        public void remove(Document doc) {
401 37827 jjdelcerro
        logger.info("remove('{}')", doc.toString());
402 31496 jjdelcerro
                documents.remove(doc);
403
                this.setModified(true);
404 36443 cordinyana
        change.firePropertyChange("delDocument", doc, null);
405 31496 jjdelcerro
                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 34300 fdiaz
416 36473 fdiaz
        /**
417
         * Return the view that contains the especified layer.
418
         *
419
         * @param layer
420
         *
421
         * @return name of the view that contains the layer
422
         *
423
         * @throws RuntimeException
424
         *             Si la capa que se pasa como par?metro no se encuentra en
425
         *             ninguna vista
426
         */
427 31496 jjdelcerro
        public String getViewName(FLayer layer) {
428
                List<Document> views = getDocuments(ViewManager.TYPENAME);
429
                for (int v = 0; v < views.size(); v++) {
430
                        DefaultViewDocument pView = (DefaultViewDocument) views.get(v);
431
                        FLayers layers = pView.getMapContext().getLayers();
432
                        if (isView(layers, layer)) {
433
                                return pView.getName();
434
                        }
435
                }
436
437 34300 fdiaz
                throw new RuntimeException(MessageFormat.format(
438
                                "The layer '{1}' is not in a view", layer.getName()));
439 31496 jjdelcerro
        }
440
441
        private boolean isView(FLayers layers, FLayer layer) {
442
                for (int i = 0; i < layers.getLayersCount(); i++) {
443
                        if (layers.getLayer(i) instanceof FLayers) {
444 34300 fdiaz
                                if (isView((FLayers) layers.getLayer(i), layer)) {
445 31496 jjdelcerro
                                        return true;
446
                                }
447
                        }
448
                        if (layers.getLayer(i) == layer) {
449
                                return true;
450
                        }
451
                }
452
                return false;
453
        }
454
455
        public void addExtent(ProjectExtent arg1) {
456
                extents.add(arg1);
457
                change.firePropertyChange("addExtent", null, null);
458
        }
459
460
        public ProjectExtent removeExtent(int arg0) {
461
                change.firePropertyChange("delExtent", null, null);
462
                return extents.remove(arg0);
463
        }
464
465
        public ProjectExtent[] getExtents() {
466
                return (ProjectExtent[]) extents.toArray(new ProjectExtent[0]);
467
        }
468
469
        /**
470
         * Obtiene un documento a partir de su nombre y el nombre de registro en el
471
         * pointExtension, este ?ltimo se puede obtener del
472
         * Project****Factory.registerName.
473 34300 fdiaz
         *
474 31496 jjdelcerro
         * @param name
475
         *            Nombre del documento
476
         * @param type
477
         *            nombre de registro en el extensionPoint
478 34300 fdiaz
         *
479 31496 jjdelcerro
         * @return Documento
480
         */
481
        public Document getDocument(String name, String type) {
482 34300 fdiaz
                if (type != null) {
483 31496 jjdelcerro
                        for (int i = 0; i < documents.size(); i++) {
484
                                Document document = documents.get(i);
485 34300 fdiaz
                                if (type.equalsIgnoreCase(document.getTypeName())
486
                                                && name.equalsIgnoreCase(document.getName())) {
487 31496 jjdelcerro
                                        return document;
488
                                }
489
                        }
490
                }
491
                return null;
492
        }
493
494
        public String getUniqueNameForDocument(String type, String name) {
495
                Document document = getDocument(name, type);
496 34300 fdiaz
                if (document == null) {
497 31496 jjdelcerro
                        return name;
498
                }
499 34300 fdiaz
500
                String newName = null;
501
                int num = this.getNextDocumentIndex(type);
502
                while (document != null) {
503
                        newName = name + " - " + num++;
504
                        document = getDocument(newName, type);
505
                }
506
                this.setNextDocumentIndex(type, num);
507
                return newName;
508 31496 jjdelcerro
        }
509 34300 fdiaz
510 31496 jjdelcerro
        private int getNextDocumentIndex(String type) {
511 34300 fdiaz
                if (nextDocumentIndexByType.get(type) == null) {
512 31496 jjdelcerro
                        nextDocumentIndexByType.put(type, new Integer(1));
513
                        return 1;
514
                }
515
                return nextDocumentIndexByType.get(type).intValue();
516
        }
517
518
        private void setNextDocumentIndex(String type, int newIndex) {
519 34300 fdiaz
                if (nextDocumentIndexByType.get(type) == null) {
520 31496 jjdelcerro
                        nextDocumentIndexByType.put(type, new Integer(newIndex));
521
                } else {
522
                        nextDocumentIndexByType.put(type, new Integer(newIndex));
523
                }
524
        }
525
526 33399 jjdelcerro
        public void saveState(File out) throws PersistenceException {
527 33331 jjdelcerro
                FileOutputStream fout;
528
                try {
529
                        fout = new FileOutputStream(out);
530
                        saveState(fout, new File(out.getParent()));
531
                } catch (FileNotFoundException e) {
532 33399 jjdelcerro
                        throw new PersistenceException(e);
533 33331 jjdelcerro
                }
534
        }
535 34300 fdiaz
536 33399 jjdelcerro
        public void saveState(OutputStream out) throws PersistenceException {
537 33331 jjdelcerro
                saveState(out, null);
538
        }
539 34300 fdiaz
540
        public void saveState(OutputStream out, File rootFolder)
541
                        throws PersistenceException {
542 31496 jjdelcerro
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
543 34300 fdiaz
                PersistentState state = null;
544
                state = manager.getState(this, true);
545 33619 jjdelcerro
                try {
546 34300 fdiaz
                        if (rootFolder != null) {
547 33331 jjdelcerro
                                relativizeFiles(state, rootFolder);
548
                        }
549 34300 fdiaz
                } catch (Exception ex) {
550 33619 jjdelcerro
                        state.getContext().addError(ex);
551
                }
552 34300 fdiaz
                manager.saveState(state, out);
553
                if (state.getContext().getErrors() != null) {
554 33619 jjdelcerro
                        throw state.getContext().getErrors();
555
                }
556 31496 jjdelcerro
        }
557 34300 fdiaz
558 33331 jjdelcerro
        private void relativizeFiles(PersistentState state, File rootFolder) {
559
                PersistentContext context = state.getContext();
560 34300 fdiaz
561
                URI cwd = new File(System.getProperty("user.dir")).toURI();
562 33331 jjdelcerro
                @SuppressWarnings("unchecked")
563
                Iterator<PersistentState> statesIterator = context.iterator();
564 34300 fdiaz
                while (statesIterator.hasNext()) {
565 33331 jjdelcerro
                        PersistentState aState = statesIterator.next();
566
                        DynStruct definition = aState.getDefinition();
567
                        DynField[] fields = definition.getDynFields();
568
                        for (DynField field : fields) {
569 34300 fdiaz
                                if (field.getType() == DataTypes.FILE
570
                                                || field.getType() == DataTypes.FOLDER) {
571 33331 jjdelcerro
                                        try {
572
                                                File value = aState.getFile(field.getName());
573
                                                value = relativizeFile(value, rootFolder);
574 34300 fdiaz
                                                aState.set(field.getName(), value);
575 33331 jjdelcerro
                                        } catch (PersistenceException e) {
576 34300 fdiaz
                                                LOG.warn(
577
                                                                "Can't relativice field '" + field.getName()
578
                                                                                + "' for class '"
579
                                                                                + definition.getName() + "'.", e);
580 33331 jjdelcerro
                                        }
581 34300 fdiaz
                                } else if (field.getType() == DataTypes.URL) {
582
                                        try {
583
                                                URL value = aState.getURL(field.getName());
584
                                                if ("FILE".equalsIgnoreCase(value.getProtocol())) {
585
                                                        File file = new File(value.toURI());
586
                                                        file = relativizeFile(file, rootFolder);
587
                                                        value = new URL("file","",file.toURI().toString().substring(cwd.toString().length()));
588
                                                        aState.set(field.getName(), value);
589
                                                }
590
                                        } catch (PersistenceException e) {
591
                                                // do nothind
592
                                        } catch (MalformedURLException e) {
593
                                                // do nothind
594
                                        } catch (URISyntaxException e) {
595
                                                // do nothind
596
                                        }
597 33331 jjdelcerro
                                }
598
                        }
599
                }
600
        }
601 34300 fdiaz
602 33331 jjdelcerro
        private File relativizeFile(File file, File rootFolder) {
603 34300 fdiaz
                if (rootFolder == null) {
604
                        return file;
605
                }
606
                if (file == null) {
607
                        return null;
608
                }
609
                boolean isDir = false;
610
                // isDir = file.isDirectory();
611
                isDir = rootFolder.isDirectory();
612
                String basePath = rootFolder.getAbsolutePath();
613
                String targetPath = file.getPath();
614
                String pathSeparator = File.separator;
615
                // We need the -1 argument to split to make sure we get a trailing
616
                // "" token if the base ends in the path separator and is therefore
617
                // a directory. We require directory paths to end in the path
618
                // separator -- otherwise they are indistinguishable from files.
619
                String[] base = basePath.split(Pattern.quote(pathSeparator), -1);
620
                String[] target = targetPath.split(Pattern.quote(pathSeparator), 0);
621
622
                // First get all the common elements. Store them as a string,
623
                // and also count how many of them there are.
624
                String common = "";
625
                int commonIndex = 0;
626
                for (int i = 0; i < target.length && i < base.length; i++) {
627
                        if (target[i].equals(base[i])) {
628
                                common += target[i] + pathSeparator;
629
                                commonIndex++;
630
                        } else
631
                                break;
632
                }
633
634
                if (commonIndex == 0) {
635
                        // Whoops -- not even a single common path element. This most
636
                        // likely indicates differing drive letters, like C: and D:.
637
                        // These paths cannot be relativized. Return the target path.
638
                        return file;
639
                        // This should never happen when all absolute paths
640
                        // begin with / as in *nix.
641
                }
642
643
                String relative = "";
644
                if (base.length == commonIndex) {
645
                        // Comment this out if you prefer that a relative path not start
646
                        // with ./
647
                        relative = "." + pathSeparator;
648
                } else {
649
                        int numDirsUp = base.length - commonIndex - (isDir ? 0 : 1); /*
650
                                                                                                                                                 * only
651
                                                                                                                                                 * subtract
652
                                                                                                                                                 * 1 if
653
                                                                                                                                                 * it is
654
                                                                                                                                                 * a
655
                                                                                                                                                 * file.
656
                                                                                                                                                 */
657
                        // The number of directories we have to backtrack is the length of
658
                        // the base path MINUS the number of common path elements, minus
659
                        // one because the last element in the path isn't a directory.
660
                        for (int i = 1; i <= (numDirsUp); i++) {
661
                                relative += ".." + pathSeparator;
662
                        }
663
                }
664
                // if we are comparing directories then we
665
                if (targetPath.length() > common.length()) {
666
                        // it's OK, it isn't a directory
667
                        relative += targetPath.substring(common.length());
668
                }
669
670
                return new File(relative);
671 33331 jjdelcerro
        }
672 34300 fdiaz
673
        private void fixFiles(PersistentState state, File rootFolder) {
674
                PersistentContext context = state.getContext();
675
                URI cwd = new File(System.getProperty("user.dir")).toURI();
676
677
                @SuppressWarnings("unchecked")
678
                Iterator<PersistentState> statesIterator = context.iterator();
679
                while (statesIterator.hasNext()) {
680
                        PersistentState aState = statesIterator.next();
681
                        DynStruct definition = aState.getDefinition();
682
                        DynField[] fields = definition.getDynFields();
683
                        for (DynField field : fields) {
684
                                if (field.getType() == DataTypes.FILE
685
                                                || field.getType() == DataTypes.FOLDER) {
686
                                        try {
687
                                                File value = aState.getFile(field.getName());
688
                                                value = fixFile(value, rootFolder);
689
                                                aState.set(field.getName(), value);
690
                                        } catch (PersistenceException e) {
691
                                                LOG.warn(
692
                                                                "Can't fix field '" + field.getName()
693
                                                                                + "' for class '"
694
                                                                                + definition.getName() + "'.", e);
695
                                        }
696
                                } else if (field.getType() == DataTypes.URL) {
697
                                        try {
698
                                                URL value = aState.getURL(field.getName());
699
                                                if ("FILE".equalsIgnoreCase(value.getProtocol())) {
700
                                                        if (!value.getFile().startsWith("/")){
701
                                                                value = new URL("file","",cwd.getRawPath()+value.getFile());
702
                                                                File file = new File(value.toURI().getPath().substring(cwd.getPath().length()));
703
                                                                file = fixFile(file, rootFolder);
704
                                                                aState.set(field.getName(), file.toURI().toURL());
705
                                                        }
706
                                                }
707
                                        } catch (PersistenceException e) {
708
                                                // do nothing
709
                                        } catch (MalformedURLException e) {
710
                                                // do nothing
711
                                        } catch (URISyntaxException e) {
712
                                                // do nothing
713
                                        }
714
715
                                }
716
                        }
717
                }
718
        }
719
720
        private File fixFile(File file, File rootFolder) {
721
                if (file.isAbsolute()) {
722
                        return file;
723
                }
724 36241 fdiaz
                return new File(rootFolder, file.getPath()).getAbsoluteFile();
725 34300 fdiaz
        }
726
727 31496 jjdelcerro
        public void loadState(InputStream in) {
728 34300 fdiaz
                loadState(in, null);
729
        }
730
731
        public void loadState(InputStream in, File rootFolder) {
732 31496 jjdelcerro
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
733
                try {
734
                        PersistentState state = manager.loadState(in);
735 34300 fdiaz
                        try {
736
                                if (rootFolder != null) {
737
                                        fixFiles(state, rootFolder);
738
                                }
739
                        } catch (Exception ex) {
740
                                state.getContext().addError(ex);
741
                        }
742 31496 jjdelcerro
                        this.loadFromState(state);
743
                } catch (PersistenceException e) {
744
                        // TODO Auto-generated catch block
745
                        e.printStackTrace();
746
                }
747 34300 fdiaz
748 31496 jjdelcerro
        }
749 34300 fdiaz
750 31496 jjdelcerro
        public void loadState(File in) {
751
                FileInputStream fin;
752
                try {
753
                        fin = new FileInputStream(in);
754 34300 fdiaz
                        loadState(fin, new File(in.getParent()));
755 31496 jjdelcerro
                } catch (FileNotFoundException e) {
756
                        // TODO Auto-generated catch block
757
                        e.printStackTrace();
758
                }
759
        }
760 34300 fdiaz
761 31496 jjdelcerro
        @SuppressWarnings("unchecked")
762
        public void loadFromState(PersistentState state)
763
                        throws PersistenceException {
764
                this.clean();
765 34300 fdiaz
766
                this.setComments(state.getString("comments"));
767
                this.setCreationDate(state.getString("creationDate"));
768
                this.setModificationDate(state.getString("modificationDate"));
769
                this.setName(state.getString("name"));
770
                this.setOwner(state.getString("owner"));
771
                this.setSelectionColor((Color) state.get("selectionColor"));
772
                this.setProjection((IProjection) state.get("projection"));
773
774
                List<ProjectExtent> extents = (List<ProjectExtent>) state
775
                                .get("extents");
776
                for (int i = 0; i < extents.size(); i++) {
777
                        this.addExtent(extents.get(i));
778 31496 jjdelcerro
                }
779 34300 fdiaz
780
                List<AbstractDocument> documents = (List<AbstractDocument>) state
781
                                .get("documents");
782
                for (int i = 0; i < documents.size(); i++) {
783
                        this.add(documents.get(i));
784 31496 jjdelcerro
                }
785
786 34833 fdiaz
                List<DocumentWindowInfo> persistentWindows = (List<DocumentWindowInfo>) state.get("documentWindowsInformation");
787
788
                for (int i = 0; i < persistentWindows.size(); i++) {
789
                        DocumentWindowInfo persistentWindow = persistentWindows.get(i);
790
                        String docName = persistentWindow.getDocumentName();
791
                        String docType = persistentWindow.getDocumentType();
792
                        Document doc = this.getDocument(docName, docType);
793
                        IWindow win = doc.getFactory().getMainWindow(doc);
794
                        win.getWindowInfo().setWindowInfo(persistentWindow.getWindowInfo());
795
                        PluginServices.getMDIManager().addWindow(win);
796
                }
797
798
                if (state.hasValue("projectWindowInfo")){
799
                        WindowInfo projectWindowInfo = (WindowInfo)state.get("projectWindowInfo");
800
                        ProjectExtension pe = (ProjectExtension) PluginServices.getExtension(org.gvsig.app.extension.ProjectExtension.class);
801
                        pe.setProject(this);
802
                        pe.showProjectWindow(projectWindowInfo);
803
                }
804
805 31496 jjdelcerro
        }
806
807
        public void saveToState(PersistentState state) throws PersistenceException {
808 31547 jjdelcerro
                state.set("version", VERSION);
809 31496 jjdelcerro
                state.set("comments", getComments());
810
                state.set("creationDate", this.getCreationDate());
811
812 34300 fdiaz
                state.set("modificationDate", this.getModificationDate());
813 31496 jjdelcerro
                state.set("name", this.getName());
814
                state.set("owner", this.getOwner());
815
                state.set("selectionColor", this.getSelectionColor());
816
817 34300 fdiaz
                state.set("projection", this.getProjection());
818
819 31547 jjdelcerro
                state.set("extents", this.extents);
820 31496 jjdelcerro
                state.set("documents", this.getDocuments());
821
822 34833 fdiaz
                List<DocumentWindowInfo> persistentWindows = new ArrayList<DocumentWindowInfo>();
823 36473 fdiaz
                MDIManager mdiMan = PluginServices.getMDIManager();
824
                IWindow[] windows = mdiMan.getOrderedWindows();
825 31496 jjdelcerro
                for (int i = windows.length - 1; i >= 0; i--) {
826
                        IWindow window = windows[i];
827 34833 fdiaz
                        if (window instanceof IDocumentWindow){
828 36473 fdiaz
                                WindowInfo wi =  mdiMan.getWindowInfo(window);
829 34833 fdiaz
                                DocumentWindowInfo dwi = new DocumentWindowInfo(
830 36473 fdiaz
                                                wi,
831 34833 fdiaz
                                                ((IDocumentWindow) window).getDocument().getTypeName(),
832
                                                ((IDocumentWindow) window).getDocument().getName());
833
                                persistentWindows.add(dwi);
834
                        } else if (window instanceof ProjectWindow){
835 36473 fdiaz
                                state.set("projectWindowInfo", mdiMan.getWindowInfo(window));
836 31496 jjdelcerro
                        }
837
                }
838 34833 fdiaz
                state.set("documentWindowsInformation", persistentWindows);
839 34300 fdiaz
840 31496 jjdelcerro
        }
841 31547 jjdelcerro
842 34833 fdiaz
        public static class DocumentWindowInfo implements Persistent {
843
844
                public static final String PERSISTENCE_DEFINITION_NAME = "DocumentWindowInfo";
845
846
                private WindowInfo windowInfo;
847
                private String documentType;
848
                private String documentName;
849
850
                public DocumentWindowInfo(){
851
                }
852
853
                DocumentWindowInfo(WindowInfo wi, String docType, String docName){
854
                        windowInfo = wi;
855
                        documentType = docType;
856
                        documentName = docName;
857
                }
858
859
                public WindowInfo getWindowInfo() {
860
                        return windowInfo;
861
                }
862
863
                public String getDocumentType() {
864
                        return documentType;
865
                }
866
867
                public String getDocumentName() {
868
                        return documentName;
869
                }
870
871
                public void saveToState(PersistentState state)
872
                                throws PersistenceException {
873
                        state.set("windowInfo", this.windowInfo);
874
                        state.set("documentType", this.documentType);
875
                        state.set("documentName", this.documentName);
876
                }
877
878
                public void loadFromState(PersistentState state)
879
                                throws PersistenceException {
880
                        this.windowInfo = (WindowInfo) state.get("windowInfo");
881
                        this.documentType = state.getString("documentType");
882
                        this.documentName = state.getString("documentName");
883
                }
884
885
                public static void registerPersistent() {
886
                        PersistenceManager manager = ToolsLocator.getPersistenceManager();
887
                        DynStruct definition = manager.getDefinition(PERSISTENCE_DEFINITION_NAME);
888
                        if ( definition == null ){
889
                                definition = manager.addDefinition(
890
                                                DocumentWindowInfo.class,
891
                                                PERSISTENCE_DEFINITION_NAME,
892
                                                "DocumentWindowInfo persistence definition",
893
                                                null,
894
                                                null
895
                                );
896
                                definition.addDynFieldObject("windowInfo").setMandatory(true).setClassOfValue(WindowInfo.class);
897
                                definition.addDynFieldString("documentType").setMandatory(true);
898
                                definition.addDynFieldString("documentName").setMandatory(true);
899
                        }
900
901
                }
902
        }
903
904 31547 jjdelcerro
        public static void registerPersistent() {
905 34833 fdiaz
                AbstractDocument.registerPersistent();
906
                DocumentWindowInfo.registerPersistent();
907
908 32880 jjdelcerro
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
909 34300 fdiaz
                DynStruct definition = manager.addDefinition(DefaultProject.class,
910
                                "Project", "Project Persistence definition", null, null);
911 32880 jjdelcerro
                definition.addDynFieldString("version").setMandatory(true);
912
                definition.addDynFieldString("comments").setMandatory(true);
913
                definition.addDynFieldString("creationDate").setMandatory(true);
914
                definition.addDynFieldString("modificationDate").setMandatory(true);
915
                definition.addDynFieldString("name").setMandatory(true);
916
                definition.addDynFieldString("owner").setMandatory(true);
917 31547 jjdelcerro
918 34300 fdiaz
                definition.addDynFieldObject("selectionColor")
919
                                .setClassOfValue(Color.class).setMandatory(true);
920
                definition.addDynFieldObject("projection")
921
                                .setClassOfValue(IProjection.class).setMandatory(true);
922 31547 jjdelcerro
923 34300 fdiaz
                definition.addDynFieldList("extents")
924
                                .setClassOfItems(ProjectExtent.class).setMandatory(true);
925 31547 jjdelcerro
926 34300 fdiaz
                definition.addDynFieldList("documents").setClassOfItems(Document.class)
927
                                .setMandatory(true);
928
929 34833 fdiaz
                definition.addDynFieldObject("projectWindowInfo").setClassOfValue(WindowInfo.class).setMandatory(false);
930
931
                definition.addDynFieldList("documentWindowsInformation").setClassOfItems(WindowInfo.class).setMandatory(false);
932
933 31547 jjdelcerro
        }
934
935 31496 jjdelcerro
        /**
936
         * @deprecated use getPreferences().setDefaultSelectionColor()
937
         */
938
        public static void setDefaultSelectionColor(Color color) {
939
                getPreferences().setDefaultSelectionColor(color);
940
        }
941
942
        /**
943
         * @deprecated use getPreferences().getDefaultSelectionColor()
944
         */
945 34300 fdiaz
946 31496 jjdelcerro
        public static Color getDefaultSelectionColor() {
947
                return getPreferences().getDefaultSelectionColor();
948
        }
949
950
        /**
951
         * @deprecated use getPreferences().getDefaultMapUnits()
952
         */
953
        public static int getDefaultMapUnits() {
954
                return getPreferences().getDefaultMapUnits();
955
        }
956
957
        /**
958
         * @deprecated use getPreferences().getDefaultDistanceUnits()
959
         */
960
        public static int getDefaultDistanceUnits() {
961
                return getPreferences().getDefaultDistanceUnits();
962
        }
963 34300 fdiaz
964 31496 jjdelcerro
        /**
965
         * @deprecated use getPreferences().getDefaultDistanceArea()
966
         */
967
        public static int getDefaultDistanceArea() {
968
                return getPreferences().getDefaultDistanceArea();
969
        }
970 34300 fdiaz
971 31496 jjdelcerro
        /**
972
         * @deprecated use getPreferences().setDefaultMapUnits()
973
         */
974
        public static void setDefaultMapUnits(int mapUnits) {
975
                getPreferences().setDefaultMapUnits(mapUnits);
976
        }
977
978
        /**
979
         * @deprecated use getPreferences().setDefaultDistanceUnits()
980
         */
981
        public static void setDefaultDistanceUnits(int distanceUnits) {
982
                getPreferences().setDefaultDistanceUnits(distanceUnits);
983
        }
984 34300 fdiaz
985 31496 jjdelcerro
        /**
986
         * @deprecated use getPreferences().setDefaultDistanceArea()
987
         */
988
        public static void setDefaultDistanceArea(int distanceArea) {
989
                getPreferences().setDefaultDistanceArea(distanceArea);
990
        }
991
992
        /**
993
         * @deprecated use getPreferences().setDefaultProjection()
994
         */
995
        public static void setDefaultProjection(IProjection defaultProjection) {
996
                getPreferences().setDefaultProjection(defaultProjection);
997
        }
998
999
        /**
1000
         * @deprecated use getPreferences().getDefaultProjection()
1001
         */
1002
        public static IProjection getDefaultProjection() {
1003
                return getPreferences().getDefaultProjection();
1004
        }
1005
1006
        /**
1007 34300 fdiaz
         * @deprecated see {@link #setSelectionColor(String)}, to be remove in gvSIG
1008
         *             2.1.0
1009 31496 jjdelcerro
         */
1010
        public void setColor(String color) {
1011
                this.setSelectionColor(StringUtilities.string2Color(color));
1012
        }
1013
1014
        /**
1015 34300 fdiaz
         * Return the selection color
1016
         *
1017 31496 jjdelcerro
         * @return selection color as string
1018
         * @deprecated use {@link #getSelectionColor()}
1019
         */
1020
        public String getColor() {
1021
                return StringUtilities.color2String(selectionColor);
1022
        }
1023
1024
        /**
1025
         * Return the list of views of the project
1026 34300 fdiaz
         *
1027 31496 jjdelcerro
         * @return views as ArrayList of ProjectDocument
1028
         *
1029
         * @deprecated see {@link #getDocumentsByType(String)}
1030
         */
1031
        public List<Document> getViews() {
1032
                return getDocuments(ViewManager.TYPENAME);
1033
        }
1034
1035
        /**
1036 34300 fdiaz
         * Add a view to the project
1037
         *
1038 31496 jjdelcerro
         * @deprecated see {@link #add(AbstractDocument)}
1039
         */
1040
        public void addView(DefaultViewDocument v) {
1041
                add(v);
1042
        }
1043
1044
        /**
1045
         * Remove a view of the project
1046
         *
1047 34300 fdiaz
         * @param index
1048
         *            of the view as integer
1049
         *
1050 31496 jjdelcerro
         * @deprecated see {@link #remove(AbstractDocument)}
1051
         */
1052
        public void delView(int i) {
1053
                List<Document> list = getDocuments(ViewManager.TYPENAME);
1054
                remove(list.get(i));
1055
        }
1056
1057
        /**
1058 34300 fdiaz
         * @deprecated see {@link #getDocument(String, String)}
1059 31496 jjdelcerro
         */
1060
        public Document getProjectDocumentByName(String name, String type) {
1061
                return this.getDocument(name, type);
1062
        }
1063
1064
        /**
1065 34300 fdiaz
         * @deprecated see {@link #getDocuments(String)}
1066 31496 jjdelcerro
         */
1067
        public List<Document> getDocumentsByType(String type) {
1068
                return this.getDocuments(type);
1069
        }
1070
1071
        /**
1072 34300 fdiaz
         * @deprecated aun por decidir que API darle al copy/paste
1073 31496 jjdelcerro
         */
1074 34300 fdiaz
        public String exportToXML(AbstractDocument[] selectedItems)
1075
                        throws SaveException {
1076 31496 jjdelcerro
                // FIXME jjdc:hay que decirdir que API darle al copy/paste
1077
                throw new UnsupportedOperationException("This method is not supported");
1078
        }
1079
1080
        /**
1081 34300 fdiaz
         * @deprecated aun por decidir que API darle al copy/paste
1082 31496 jjdelcerro
         */
1083
        public void importFromXML(String sourceString, String docType) {
1084
                // FIXME jjdc:hay que decirdir que API darle al copy/paste
1085
                throw new UnsupportedOperationException("This method is not supported");
1086
        }
1087
1088
        /**
1089 34300 fdiaz
         * @deprecated aun por decidir que API darle al copy/paste
1090 31496 jjdelcerro
         */
1091
        public boolean isValidXMLForImport(String sourceString, String docType) {
1092
                // FIXME jjdc:hay que decirdir que API darle al copy/paste
1093
                throw new UnsupportedOperationException("This method is not supported");
1094
        }
1095
1096
        public boolean canImportDocuments(String data, String doctype) {
1097
                // TODO Auto-generated method stub
1098
                return false;
1099
        }
1100
1101
        public String exportDocumentsAsText(List<Document> documents) {
1102
                // TODO Auto-generated method stub
1103
                return null;
1104
        }
1105
1106
        public void importDocuments(String data, String doctype) {
1107
                // TODO Auto-generated method stub
1108 34300 fdiaz
1109 31496 jjdelcerro
        }
1110
1111
        public Document getActiveDocument() {
1112 36184 jjdelcerro
                ApplicationManager application = ApplicationLocator.getManager();
1113
1114
                Document document = null;
1115
                IWindow[] windows = application.getUIManager().getOrderedWindows();
1116
                IWindow window = null;
1117
                for (int i = 0; i < windows.length; i++) {
1118 36195 nfrancisco
                    window = windows[i];
1119 36184 jjdelcerro
                        if (window instanceof SingletonWindow) {
1120
                                // Cogemos no la primera ventana, si no la primera
1121
                                // ventana de tipo documento (SingletonWindow).
1122
                                // Y por si las mosca no es un documento, atrapamos
1123
                                // los errores y continuamos si no puede hacer un cast
1124
                                // del Model a Document
1125
                                try {
1126
                                        document = (Document) ((SingletonWindow) window).getWindowModel();
1127
                                        return document;
1128
                                } catch (ClassCastException e) {
1129
                                        // Do nothing, skip this window
1130
                                }
1131
                        }
1132 31496 jjdelcerro
                }
1133 36184 jjdelcerro
                return null;
1134
        }
1135 31496 jjdelcerro
}