Statistics
| Revision:

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

History | View | Annotate | Download (14.1 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.Arrays;
32
import java.util.Iterator;
33
import java.util.List;
34

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

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

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

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

    
71
        private FeatureStore store;
72

    
73
        private String featureTypeId;
74

    
75
        private String[] attributeNames;
76

    
77
        private List<TableLink> linkTable;
78

    
79
        private FLyrVect associatedLayer;
80

    
81
        private FeatureQuery query;
82

    
83
        private Evaluator baseFilter;
84

    
85
        private FeatureQueryOrder baseOrder;
86

    
87
        private ConfigurableFeatureTableModel tableModel;
88

    
89
        private Object lock = new Object();
90

    
91
        public TableDocument(DocumentManager factory) {
92
                super(factory);
93
                this.store = null;
94
                this.query = null;
95
                this.featureTypeId = null;
96
                this.baseFilter = null;
97
                this.baseOrder = null;
98
                this.linkTable = new ArrayList<TableLink>();
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 (DataException 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
         * Devuelve el identificador de la tabla que contiene el link.
218
         * 
219
         * @return identificador ?nico de la tabla.
220
         * @deprecated see {{@link #getLinks()}
221
         */
222
        public String getLinkTable() {
223
                if (linkTable.isEmpty()) {
224
                        return null;
225
                }
226
                return linkTable.get(0).getTargetTable().getName();
227
        }
228

    
229
        /**
230
         * Devuelve el nombre del campo de la tabla a enlazar.
231
         * 
232
         * @return Nombre del campo de la tabla a enlazar.
233
         * @deprecated see {{@link #getLink()}
234
         */
235
        public String getField1() {
236
                if (linkTable.isEmpty()) {
237
                        return null;
238
                }
239
                return this.linkTable.get(0).getSourceFieldName();
240
        }
241

    
242
        /**
243
         * Devuelve el nombre del campo de la tabla enlazada.
244
         * 
245
         * @return Nombre del campo de la tabla enlazada.
246
         * @deprecated see {{@link #getLink()}
247
         */
248
        public String getField2() {
249
                if (linkTable.isEmpty()) {
250
                        return null;
251
                }
252
                return this.linkTable.get(0).getTargetFieldName();
253
        }
254

    
255
        /**
256
         * Enlaza la seleccion de esta tabla con la de la tabla indicada
257
         * 
258
         * @deprecated see {@link #addLinkTable(String, String, String)}
259
         */
260
        public void setLinkTable(String targetTable, String fieldSource,
261
                        String fieldTarget) {
262
                this.addLinkTable(targetTable, fieldSource, fieldTarget);
263
        }
264

    
265
        /**
266
         * Add a table link to this document.
267
         * 
268
         * @param targetTable
269
         * @param fieldSource
270
         * @param fieldTarget
271
         */
272
        public void addLinkTable(String targetTable, String fieldSource,
273
                        String fieldTarget) {
274
                TableDocument target =
275
                                (TableDocument) ProjectManager.getInstance()
276
                                                .getCurrentProject()
277
                                                .getDocument(targetTable, TableManager.TYPENAME);
278
                TableLink link = new TableLink(this, target, fieldSource, fieldTarget);
279
                link.setEnabled(true);
280
                this.linkTable.add(link);
281
        }
282

    
283
        /**
284
         * remove the last link to table added.
285
         * 
286
         */
287
        public void removeLinkTable() {
288
                if (linkTable.isEmpty()) {
289
                        return;
290
                }
291
                TableLink link = this.linkTable.remove(this.linkTable.size() - 1);
292
                link.setEnabled(false);
293
                this.linkTable = null;
294
        }
295

    
296
        /**
297
         * Remove the link to the table document.
298
         * 
299
         * @param name
300
         *            of table document to remove.
301
         */
302
        public void removeLinkTable(String name) {
303
                for (TableLink link : this.linkTable) {
304
                        if (name.equals(link.target.getName())) {
305
                                link.setEnabled(false);
306
                                this.linkTable.remove(link);
307
                        }
308
                }
309
        }
310

    
311
        public FLyrVect getAssociatedLayer() {
312
                return associatedLayer;
313
        }
314

    
315
        public void setAssociatedLayer(FLyrVect associatedLayer) {
316
                this.associatedLayer = associatedLayer;
317
        }
318

    
319
        public void update(Observable arg0, Object arg1) {
320
                if (this.store.equals(arg0)) {
321
                        if (arg1 instanceof FeatureStoreNotification) {
322
                                FeatureStoreNotification event =
323
                                                (FeatureStoreNotification) arg1;
324
                                if (event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE
325
                                                || event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
326
                                        this.query = null;
327
                                }
328
                        }
329

    
330
                }
331

    
332
        }
333

    
334
        @SuppressWarnings("unchecked")
335
        public void loadFromState(PersistentState state)
336
                        throws PersistenceException {
337
                this.store = (FeatureStore) state.get("store");
338

    
339
                this.featureTypeId = state.getString("featureTypeId");
340
                this.attributeNames =
341
                                (String[]) ((List) state.get("attributeNames")).toArray(new String[0]);
342
                this.linkTable =
343
                                new ArrayList<TableLink>((List) state.get("linkTable"));
344
                this.associatedLayer = (FLyrVect) state.get("associatedLayer");
345
                this.query = (FeatureQuery) state.get("query");
346
                this.baseFilter = (Evaluator) state.get(" baseFilter");
347
                this.baseOrder = (FeatureQueryOrder) state.get("baseOrder");
348
        }
349

    
350
        public void saveToState(PersistentState state) throws PersistenceException {
351
                state.set("store", store);
352
                state.set("featureTypeId", featureTypeId);
353
                state.set("attributeNames", Arrays.asList(attributeNames));
354
                state.set("linkTable", linkTable);
355
                state.set("associatedLayer", associatedLayer);
356
                state.set("query", query);
357
                state.set("baseFilter", baseFilter);
358
                state.set("baseOrder", baseOrder);
359
        }
360

    
361
        public static class TableLink implements Observer, Persistent {
362
                private TableDocument source;
363
                private FeatureStore storeSource;
364
                private int fieldSource;
365

    
366
                private TableDocument target;
367
                private FeatureStore storeTarget;
368
                private int fieldTarget;
369

    
370
                private boolean enabled;
371

    
372
                TableLink() {
373
                        this.source = null;
374
                        this.target = null;
375
                        this.fieldSource = -1;
376
                        this.fieldTarget = -1;
377
                        this.storeSource = null;
378
                        this.storeTarget = null;
379
                        this.enabled = false;
380
                }
381

    
382
                public TableLink(TableDocument source, TableDocument target,
383
                                String fieldSource, String fieldTarget) {
384
                        this();
385
                        this.initialize(source, target, fieldSource, fieldTarget);
386
                }
387

    
388
                private void initialize(TableDocument source, TableDocument target,
389
                                String fieldSource, String fieldTarget) {
390
                        this.source = source;
391
                        this.target = target;
392

    
393
                        this.storeSource = this.source.getStore();
394
                        this.storeTarget = this.target.getStore();
395
                        try {
396
                                this.fieldSource =
397
                                                storeSource.getDefaultFeatureType().getIndex(
398
                                                                fieldSource);
399
                                this.fieldTarget =
400
                                                storeTarget.getDefaultFeatureType().getIndex(
401
                                                                fieldTarget);
402
                        } catch (DataException ex) {
403
                                logger.error("Can't initialize TableLink", ex);
404
                                throw new RuntimeException("Can't initialize TableLink", ex);
405
                        }
406
                }
407

    
408
                public void setEnabled(boolean enabled) {
409
                        if (enabled) {
410
                                this.storeSource.addObserver(this);
411
                        } else {
412
                                this.storeSource.deleteObserver(this);
413
                        }
414
                        this.enabled = enabled;
415
                }
416

    
417
                public boolean getEnabled() {
418
                        return this.enabled;
419
                }
420

    
421
                public TableDocument getTargetTable() {
422
                        return this.target;
423
                }
424

    
425
                public TableDocument getSourceTable() {
426
                        return this.source;
427
                }
428

    
429
                public String getSourceFieldName() {
430
                        try {
431
                                return ((FeatureAttributeDescriptor) this.storeSource.getDefaultFeatureType()
432
                                                .get(this.fieldSource)).getName();
433
                        } catch (DataException e) {
434
                                logger.warn("Can't get source field name.", e);
435
                                return null;
436
                        }
437
                }
438

    
439
                public String getTargetFieldName() {
440
                        try {
441
                                return ((FeatureAttributeDescriptor) this.storeTarget.getDefaultFeatureType()
442
                                                .get(this.fieldTarget)).getName();
443
                        } catch (DataException e) {
444
                                logger.warn("Can't get target field name.", e);
445
                                return null;
446
                        }
447
                }
448

    
449
                public void update(Observable arg0, Object arg1) {
450
                        try {
451
                                FeatureSet fCollection1 =
452
                                                (FeatureSet) storeSource.getSelection();
453
                                FeatureSelection fCollection2 =
454
                                                (FeatureSelection) storeTarget.createSelection();
455
                                List<Object> idx = new ArrayList<Object>();
456

    
457
                                // Construimos el ?ndice
458
                                DisposableIterator iterator1 = null;
459
                                try {
460
                                        iterator1 = fCollection1.iterator();
461
                                        while (iterator1.hasNext()) {
462
                                                Feature feature = (Feature) iterator1.next();
463
                                                Object obj = feature.get(fieldSource);
464
                                                if (!idx.contains(obj)) {
465
                                                        idx.add(obj);
466
                                                }
467
                                        }
468
                                } finally {
469
                                        if (iterator1 != null) {
470
                                                iterator1.dispose();
471
                                        }
472
                                }
473
                                FeatureSet set = null;
474
                                DisposableIterator iterator2 = null;
475

    
476
                                try {
477
                                        set = storeTarget.getFeatureSet();
478
                                        iterator2 = set.iterator();
479
                                        while (iterator2.hasNext()) {
480
                                                Feature feature = (Feature) iterator2.next();
481
                                                Object obj = feature.get(fieldTarget);
482
                                                if (idx.contains(obj)) {
483
                                                        fCollection2.select(feature);
484
                                                }
485
                                        }
486
                                } catch (DataException e1) {
487
                                        NotificationManager.addError(e1);
488
                                        return;
489
                                } finally {
490
                                        if (iterator2 != null) {
491
                                                iterator2.dispose();
492
                                        }
493
                                        if (set != null) {
494
                                                set.dispose();
495
                                        }
496
                                }
497

    
498
                                // this applies the selection to the linked table
499
                                if (storeSource != storeTarget) {
500
                                        storeTarget.setSelection(fCollection2);
501
                                }
502
                        } catch (DataException e2) {
503
                                NotificationManager.addError(e2);
504
                                return;
505
                        }
506
                }
507

    
508
                public void loadFromState(PersistentState state)
509
                                throws PersistenceException {
510
                        this.initialize((TableDocument) state.get("source"),
511
                                        (TableDocument) state.get("target"),
512
                                        state.getString("fieldSource"),
513
                                        state.getString("fieldTarget"));
514
                        this.setEnabled(state.getBoolean("enabled"));
515
                }
516

    
517
                public void saveToState(PersistentState state)
518
                                throws PersistenceException {
519
                        state.set("source", this.source);
520
                        state.set("target", this.target);
521
                        state.set("fieldSource", this.getSourceFieldName());
522
                        state.set("fieldTarget", this.getTargetFieldName());
523
                        state.set("enabled", this.getEnabled());
524
                }
525

    
526
        }
527

    
528
}