Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / applications / appgvSIG / src / org / gvsig / app / project / DefaultProject.java @ 36443

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