Statistics
| Revision:

root / branches / v2_0_0_prep / applications / appgvSIG / src / org / gvsig / app / project / documents / table / TableDocument.java @ 36404

History | View | Annotate | Download (14.5 KB)

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

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2008 {DiSiD Technologies}  {TableDocument implementation based on the gvSIG DAL API}
26
 */
27
package org.gvsig.app.project.documents.table;
28

    
29
import java.text.MessageFormat;
30
import java.util.ArrayList;
31
import java.util.Iterator;
32
import java.util.List;
33

    
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36

    
37
import org.gvsig.andami.messages.NotificationManager;
38
import org.gvsig.app.project.ProjectManager;
39
import org.gvsig.app.project.documents.AbstractDocument;
40
import org.gvsig.app.project.documents.DocumentManager;
41
import org.gvsig.fmap.dal.exception.DataException;
42
import org.gvsig.fmap.dal.feature.Feature;
43
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
44
import org.gvsig.fmap.dal.feature.FeatureQuery;
45
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
46
import org.gvsig.fmap.dal.feature.FeatureSelection;
47
import org.gvsig.fmap.dal.feature.FeatureSet;
48
import org.gvsig.fmap.dal.feature.FeatureStore;
49
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
50
import org.gvsig.fmap.dal.feature.FeatureType;
51
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
52
import org.gvsig.fmap.mapcontrol.dal.feature.swing.table.ConfigurableFeatureTableModel;
53
import org.gvsig.tools.dispose.DisposableIterator;
54
import org.gvsig.tools.evaluator.Evaluator;
55
import org.gvsig.tools.exception.BaseException;
56
import org.gvsig.tools.observer.Observable;
57
import org.gvsig.tools.observer.Observer;
58
import org.gvsig.tools.persistence.Persistent;
59
import org.gvsig.tools.persistence.PersistentState;
60
import org.gvsig.tools.persistence.exception.PersistenceException;
61

    
62
/**
63
 * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
64
 */
65
public class TableDocument extends AbstractDocument implements Observer {
66

    
67
        private static final long serialVersionUID = -1842181135614158881L;
68

    
69
        final static private Logger logger =
70
                        LoggerFactory.getLogger(TableDocument.class);
71

    
72
        private FeatureStore store;
73

    
74
        private String featureTypeId;
75

    
76
        private String[] attributeNames;
77

    
78
        private List<TableLink> linkTable;
79

    
80
        private FLyrVect associatedLayer;
81

    
82
        private FeatureQuery query;
83

    
84
        private Evaluator baseFilter;
85

    
86
        private FeatureQueryOrder baseOrder;
87

    
88
        private ConfigurableFeatureTableModel tableModel;
89

    
90
        private Object lock = new Object();
91

    
92
        public TableDocument(DocumentManager factory) {
93
                super(factory);
94
                this.store = null;
95
                this.query = null;
96
                this.featureTypeId = null;
97
                this.baseFilter = null;
98
                this.baseOrder = null;
99
        }
100

    
101
        public TableDocument() {
102
                this(null);
103
        }
104

    
105
        public TableDocument(DocumentManager factory, FeatureStore store) {
106
                this(factory);
107
                setStore(store);
108
        }
109

    
110
        public ConfigurableFeatureTableModel getTableModel() {
111
                synchronized (lock) {
112
                        if (this.tableModel == null) {
113
                                try {
114
                                        this.tableModel =
115
                                                        new ConfigurableFeatureTableModel(getStore(),
116
                                                                        getQuery());
117
                } catch (BaseException e) {
118
                                        NotificationManager.addError(e);
119
                                }
120
                        }
121
                }
122
                return this.tableModel;
123
        }
124

    
125
        public void setStore(FeatureStore store) {
126
                if (this.store != null) {
127
                        throw new UnsupportedOperationException(
128
                                        "can't set store. store already set.");
129
                }
130
                this.store = store;
131
                this.store.addObserver(this);
132
                this.query = null; // setQuery(store.createFeatureQuery());
133
        }
134

    
135
        // private void setQuery(FeatureQuery query) {
136
        // this.query = query;
137
        // this.featureTypeId = query.getFeatureTypeId();
138
        // this.baseFilter = query.getFilter();
139
        // this.baseOrder = query.getOrder();
140
        // }
141

    
142
        @SuppressWarnings("unchecked")
143
        public FeatureQuery getQuery() {
144
                if (this.query == null) {
145
                        try {
146
                                FeatureType fType = null;
147
                                this.query = this.store.createFeatureQuery();
148
                                if (this.featureTypeId != null) {
149
                                        Iterator<FeatureType> iter;
150
                                        iter = this.store.getFeatureTypes().iterator();
151
                                        while (iter.hasNext()) {
152
                                                fType = iter.next();
153
                                                if (this.featureTypeId.equals(fType.getId())) {
154
                                                        this.query.setFeatureType(fType);
155
                                                        break;
156
                                                }
157
                                        }
158
                                        if (fType == null) {
159
                                                throw new RuntimeException(MessageFormat.format(
160
                                                                "frature type {1} not found.",
161
                                                                this.featureTypeId));
162
                                        }
163

    
164
                                } else {
165
                                        fType = store.getDefaultFeatureType();
166
                                }
167

    
168
                                if (this.attributeNames != null) {
169
                                        ArrayList<String> newNames = new ArrayList<String>();
170
                                        for (String name : this.attributeNames) {
171
                                                if (fType.getIndex(name) > -1) {
172
                                                        newNames.add(name);
173
                                                }
174
                                        }
175
                                        if (newNames.size() > 0) {
176
                                                this.query.setAttributeNames(newNames.toArray(this.attributeNames));
177
                                        }
178
                                }
179

    
180
                                this.query.setFilter(this.baseFilter); // TODO check is valid
181
                                this.query.setOrder(this.baseOrder);
182

    
183
                        } catch (DataException e) {
184
                                NotificationManager.addError(e);
185
                                return null;
186
                        }
187

    
188
                }
189
                return this.query;
190
        }
191

    
192
        /**
193
         * @return the store
194
         */
195
        public FeatureStore getStore() {
196
                return store;
197
        }
198

    
199
        // public void importFromXML(XMLEntity root, XMLEntity typeRoot,
200
        // int elementIndex, Project project, boolean removeDocumentsFromRoot)
201
        // throws XMLException, OpenException,
202
        // org.gvsig.fmap.dal.exception.ReadException {
203
        //
204
        // }
205
        //
206

    
207
        /**
208
         * Return information about the table links.
209
         * 
210
         * @return List of TableLink information.
211
         */
212
        public List<TableLink> getLinks() {
213
                return this.linkTable;
214
        }
215

    
216
    /**
217
     * Returns if this table document has links with other tables.
218
     * 
219
     * @return if this table document has links with other tables
220
     */
221
    public boolean hasLinks() {
222
        return this.linkTable != null && this.linkTable.size() > 0;
223
    }
224

    
225
        /**
226
         * Devuelve el identificador de la tabla que contiene el link.
227
         * 
228
         * @return identificador ?nico de la tabla.
229
         * @deprecated see {{@link #getLinks()}
230
         */
231
        public String getLinkTable() {
232
        if (linkTable == null || linkTable.isEmpty()) {
233
                        return null;
234
                }
235
                return linkTable.get(0).getTargetTable().getName();
236
        }
237

    
238
        /**
239
         * Devuelve el nombre del campo de la tabla a enlazar.
240
         * 
241
         * @return Nombre del campo de la tabla a enlazar.
242
         * @deprecated see {{@link #getLink()}
243
         */
244
        public String getField1() {
245
                if (linkTable.isEmpty()) {
246
                        return null;
247
                }
248
                return this.linkTable.get(0).getSourceFieldName();
249
        }
250

    
251
        /**
252
         * Devuelve el nombre del campo de la tabla enlazada.
253
         * 
254
         * @return Nombre del campo de la tabla enlazada.
255
         * @deprecated see {{@link #getLink()}
256
         */
257
        public String getField2() {
258
                if (linkTable.isEmpty()) {
259
                        return null;
260
                }
261
                return this.linkTable.get(0).getTargetFieldName();
262
        }
263

    
264
        /**
265
         * Enlaza la seleccion de esta tabla con la de la tabla indicada
266
         * 
267
         * @deprecated see {@link #addLinkTable(String, String, String)}
268
         */
269
        public void setLinkTable(String targetTable, String fieldSource,
270
                        String fieldTarget) {
271
                this.addLinkTable(targetTable, fieldSource, fieldTarget);
272
        }
273

    
274
        /**
275
         * Add a table link to this document.
276
         * 
277
         * @param targetTable
278
         * @param fieldSource
279
         * @param fieldTarget
280
         */
281
        public void addLinkTable(String targetTable, String fieldSource,
282
                        String fieldTarget) {
283
                TableDocument target =
284
                                (TableDocument) ProjectManager.getInstance()
285
                                                .getCurrentProject()
286
                                                .getDocument(targetTable, TableManager.TYPENAME);
287
                TableLink link = new TableLink(this, target, fieldSource, fieldTarget);
288
                link.setEnabled(true);
289
        if (this.linkTable == null) {
290
            this.linkTable = new ArrayList<TableLink>();
291
        }
292
                this.linkTable.add(link);
293
        }
294

    
295
        /**
296
         * remove the last link to table added.
297
         * 
298
         */
299
        public void removeLinkTable() {
300
                if (linkTable.isEmpty()) {
301
                        return;
302
                }
303
                TableLink link = this.linkTable.remove(this.linkTable.size() - 1);
304
                link.setEnabled(false);
305
                this.linkTable = null;
306
        }
307

    
308
        /**
309
         * Remove the link to the table document.
310
         * 
311
         * @param name
312
         *            of table document to remove.
313
         */
314
        public void removeLinkTable(String name) {
315
                for (TableLink link : this.linkTable) {
316
                        if (name.equals(link.target.getName())) {
317
                                link.setEnabled(false);
318
                                this.linkTable.remove(link);
319
                        }
320
                }
321
        }
322

    
323
        public FLyrVect getAssociatedLayer() {
324
                return associatedLayer;
325
        }
326

    
327
        public void setAssociatedLayer(FLyrVect associatedLayer) {
328
                this.associatedLayer = associatedLayer;
329
        }
330

    
331
        public void update(Observable arg0, Object arg1) {
332
                if (this.store.equals(arg0)) {
333
                        if (arg1 instanceof FeatureStoreNotification) {
334
                                FeatureStoreNotification event =
335
                                                (FeatureStoreNotification) arg1;
336
                                if (event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE
337
                                                || event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
338
                                        this.query = null;
339
                                }
340
                        }
341

    
342
                }
343

    
344
        }
345

    
346
        @SuppressWarnings("unchecked")
347
        public void loadFromState(PersistentState state)
348
                        throws PersistenceException {
349
                super.loadFromState(state);
350
                
351
                this.store = (FeatureStore) state.get("store");
352
                this.featureTypeId = state.getString("featureTypeId");
353
                this.attributeNames = (String[]) state.getArray("attributeNames", String.class);
354
                this.linkTable = state.getList("linkTable");
355
                this.associatedLayer = (FLyrVect) state.get("associatedLayer");
356
                this.query = (FeatureQuery) state.get("query");
357
                this.baseFilter = (Evaluator) state.get("baseFilter");
358
                this.baseOrder = (FeatureQueryOrder) state.get("baseOrder");
359
        }
360

    
361
        public void saveToState(PersistentState state) throws PersistenceException {
362
                super.saveToState(state);
363
                
364
                state.set("store", store);
365
                state.set("featureTypeId", featureTypeId);
366
                state.set("attributeNames", attributeNames);
367
                state.set("linkTable", linkTable);
368
                state.set("associatedLayer", associatedLayer);
369
                state.set("query", query);
370
//                state.set("baseFilter", baseFilter);
371
                state.set("baseOrder", baseOrder);
372
        }
373

    
374
        public static class TableLink implements Observer, Persistent {
375
                private TableDocument source;
376
                private FeatureStore storeSource;
377
                private int fieldSource;
378

    
379
                private TableDocument target;
380
                private FeatureStore storeTarget;
381
                private int fieldTarget;
382

    
383
                private boolean enabled;
384

    
385
                TableLink() {
386
                        this.source = null;
387
                        this.target = null;
388
                        this.fieldSource = -1;
389
                        this.fieldTarget = -1;
390
                        this.storeSource = null;
391
                        this.storeTarget = null;
392
                        this.enabled = false;
393
                }
394

    
395
                public TableLink(TableDocument source, TableDocument target,
396
                                String fieldSource, String fieldTarget) {
397
                        this();
398
                        this.initialize(source, target, fieldSource, fieldTarget);
399
                }
400

    
401
                private void initialize(TableDocument source, TableDocument target,
402
                                String fieldSource, String fieldTarget) {
403
                        this.source = source;
404
                        this.target = target;
405

    
406
                        this.storeSource = this.source.getStore();
407
                        this.storeTarget = this.target.getStore();
408
                        try {
409
                                this.fieldSource =
410
                                                storeSource.getDefaultFeatureType().getIndex(
411
                                                                fieldSource);
412
                                this.fieldTarget =
413
                                                storeTarget.getDefaultFeatureType().getIndex(
414
                                                                fieldTarget);
415
                        } catch (DataException ex) {
416
                                logger.error("Can't initialize TableLink", ex);
417
                                throw new RuntimeException("Can't initialize TableLink", ex);
418
                        }
419
                }
420

    
421
                public void setEnabled(boolean enabled) {
422
                        if (enabled) {
423
                                this.storeSource.addObserver(this);
424
                        } else {
425
                                this.storeSource.deleteObserver(this);
426
                        }
427
                        this.enabled = enabled;
428
                }
429

    
430
                public boolean getEnabled() {
431
                        return this.enabled;
432
                }
433

    
434
                public TableDocument getTargetTable() {
435
                        return this.target;
436
                }
437

    
438
                public TableDocument getSourceTable() {
439
                        return this.source;
440
                }
441

    
442
                public String getSourceFieldName() {
443
                        try {
444
                                return ((FeatureAttributeDescriptor) this.storeSource.getDefaultFeatureType()
445
                                                .get(this.fieldSource)).getName();
446
                        } catch (DataException e) {
447
                                logger.warn("Can't get source field name.", e);
448
                                return null;
449
                        }
450
                }
451

    
452
                public String getTargetFieldName() {
453
                        try {
454
                                return ((FeatureAttributeDescriptor) this.storeTarget.getDefaultFeatureType()
455
                                                .get(this.fieldTarget)).getName();
456
                        } catch (DataException e) {
457
                                logger.warn("Can't get target field name.", e);
458
                                return null;
459
                        }
460
                }
461

    
462
                public void update(Observable arg0, Object arg1) {
463
                        try {
464
                                FeatureSet fCollection1 =
465
                                                (FeatureSet) storeSource.getSelection();
466
                                FeatureSelection fCollection2 =
467
                                                (FeatureSelection) storeTarget.createSelection();
468
                                List<Object> idx = new ArrayList<Object>();
469

    
470
                                // Construimos el ?ndice
471
                                DisposableIterator iterator1 = null;
472
                                try {
473
                                        iterator1 = fCollection1.iterator();
474
                                        while (iterator1.hasNext()) {
475
                                                Feature feature = (Feature) iterator1.next();
476
                                                Object obj = feature.get(fieldSource);
477
                                                if (!idx.contains(obj)) {
478
                                                        idx.add(obj);
479
                                                }
480
                                        }
481
                                } finally {
482
                                        if (iterator1 != null) {
483
                                                iterator1.dispose();
484
                                        }
485
                                }
486
                                FeatureSet set = null;
487
                                DisposableIterator iterator2 = null;
488

    
489
                                try {
490
                                        set = storeTarget.getFeatureSet();
491
                                        iterator2 = set.iterator();
492
                                        while (iterator2.hasNext()) {
493
                                                Feature feature = (Feature) iterator2.next();
494
                                                Object obj = feature.get(fieldTarget);
495
                                                if (idx.contains(obj)) {
496
                                                        fCollection2.select(feature);
497
                                                }
498
                                        }
499
                                } catch (DataException e1) {
500
                                        NotificationManager.addError(e1);
501
                                        return;
502
                                } finally {
503
                                        if (iterator2 != null) {
504
                                                iterator2.dispose();
505
                                        }
506
                                        if (set != null) {
507
                                                set.dispose();
508
                                        }
509
                                }
510

    
511
                                // this applies the selection to the linked table
512
                                if (storeSource != storeTarget) {
513
                                        storeTarget.setSelection(fCollection2);
514
                                }
515
                        } catch (DataException e2) {
516
                                NotificationManager.addError(e2);
517
                                return;
518
                        }
519
                }
520

    
521
                public void loadFromState(PersistentState state)
522
                                throws PersistenceException {
523
                        this.initialize((TableDocument) state.get("source"),
524
                                        (TableDocument) state.get("target"),
525
                                        state.getString("fieldSource"),
526
                                        state.getString("fieldTarget"));
527
                        this.setEnabled(state.getBoolean("enabled"));
528
                }
529

    
530
                public void saveToState(PersistentState state)
531
                                throws PersistenceException {
532
                        state.set("source", this.source);
533
                        state.set("target", this.target);
534
                        state.set("fieldSource", this.getSourceFieldName());
535
                        state.set("fieldTarget", this.getTargetFieldName());
536
                        state.set("enabled", this.getEnabled());
537
                }
538

    
539
        }
540

    
541
}