Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_data / src / org / gvsig / fmap / data / feature / joinstore / JoinFeatureStore.java @ 23688

History | View | Annotate | Download (12.7 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 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.data.feature.joinstore;
32

    
33
import java.lang.ref.WeakReference;
34
import java.util.ArrayList;
35
import java.util.ConcurrentModificationException;
36
import java.util.HashMap;
37
import java.util.Iterator;
38
import java.util.Map;
39

    
40
import org.gvsig.fmap.data.CloseException;
41
import org.gvsig.fmap.data.DataCollection;
42
import org.gvsig.fmap.data.DataException;
43
import org.gvsig.fmap.data.DataExplorer;
44
import org.gvsig.fmap.data.DataManager;
45
import org.gvsig.fmap.data.DataStoreParameters;
46
import org.gvsig.fmap.data.InitializeException;
47
import org.gvsig.fmap.data.OpenException;
48
import org.gvsig.fmap.data.ReadException;
49
import org.gvsig.fmap.data.WriteException;
50
import org.gvsig.fmap.data.feature.AbstractFeatureStore;
51
import org.gvsig.fmap.data.feature.Feature;
52
import org.gvsig.fmap.data.feature.FeatureCollection;
53
import org.gvsig.fmap.data.feature.FeatureID;
54
import org.gvsig.fmap.data.feature.FeatureStore;
55
import org.gvsig.fmap.data.feature.FeatureType;
56
import org.gvsig.fmap.data.feature.IsNotAttributeSettingException;
57
import org.gvsig.fmap.data.index.Index;
58
import org.gvsig.fmap.data.index.IndexException;
59
import org.gvsig.metadata.IMetadata;
60
import org.gvsig.tools.exception.BaseException;
61
import org.gvsig.tools.observer.Observable;
62
import org.gvsig.tools.observer.Observer;
63

    
64
/**
65
 * @author jmvivo
66
 *
67
 */
68
public class JoinFeatureStore extends AbstractFeatureStore{
69
        public static String DATASTORE_NAME="JoinFeatureStore";
70
        private FeatureStore storePrimary;
71
        private FeatureStore storeSecondary;
72
        //        private String linkFieldSecondary=null;
73
//        private List featuresList = null;
74

    
75
        private boolean changed = false;
76

    
77
        private Map mapValues = null;
78

    
79
        protected JoinFeatureStoreParameters getJoinParameters(){
80
                return (JoinFeatureStoreParameters)this.parameters;
81
        }
82

    
83
        /* (non-Javadoc)
84
         * @see org.gvsig.fmap.data.feature.FeatureStore#canAlterFeatureType()
85
         */
86
        public boolean canAlterFeatureType() {
87
                return false;
88
        }
89

    
90
        /* (non-Javadoc)
91
         * @see org.gvsig.fmap.data.feature.AbstractFeatureStore#doFinishEdition()
92
         */
93
        protected void doFinishEdition() throws WriteException, ReadException {
94
                throw new WriteException("UnsupportedOperation", "JoinFeatureStore");
95
        }
96

    
97
        /* (non-Javadoc)
98
         * @see org.gvsig.fmap.data.feature.FeatureStore#getDataCollection(org.gvsig.fmap.data.feature.FeatureType, java.lang.String, java.lang.String)
99
         */
100
        public DataCollection getDataCollection(FeatureType type, String filter, String order) throws ReadException {
101
                //                JoinFeatureCollection complexDataCollection=new JoinFeatureCollection(this,type,filter,order);
102
                //                return complexDataCollection;
103
                this.checkChanged();
104

    
105
                try {
106
                        type = this.checkFeatureTypeForCollection(type);
107
                } catch (DataException e) {
108
                        throw new ReadException(this.getName(), e);
109
                }
110

    
111
                if (!(type instanceof JoinFeatureType)) {
112
                        throw new ReadException("incompatible types", this.getName());
113
                }
114

    
115
                FeatureCollection coll;
116
                if (filter != null || order != null) {
117
                        coll = new JoinFeatureCollectionWithFeatureID(this, type, filter,
118
                                        order);
119
                } else {
120
                        coll = new JoinFeatureCollection(this, type);
121
                }
122

    
123
                this.addObserver(new WeakReference(coll));
124
                return coll;
125

    
126
        }
127

    
128
        /* (non-Javadoc)
129
         * @see org.gvsig.fmap.data.feature.FeatureStore#getFeatureByID(org.gvsig.fmap.data.feature.FeatureID)
130
         */
131
        public Feature getFeatureByID(FeatureID id,FeatureType featureType) throws ReadException {
132
                this.checkChanged();
133
                return id.getFeature(featureType);
134
        }
135

    
136
        /* (non-Javadoc)
137
         * @see org.gvsig.fmap.data.FeatureStore#doClose()
138
         */
139
        protected void doClose() throws CloseException {
140
                ((AbstractFeatureStore)this.storePrimary).close();
141
                ((AbstractFeatureStore)this.storeSecondary).close();
142
        }
143

    
144
        /* (non-Javadoc)
145
         * @see org.gvsig.fmap.data.FeatureStore#doDispose()
146
         */
147
        protected void doDispose() throws CloseException {
148
                super.doDispose();
149
                this.storePrimary.dispose();
150
                this.storeSecondary.dispose();
151
        }
152

    
153
        /* (non-Javadoc)
154
         * @see org.gvsig.fmap.data.DataStore#getExplorer()
155
         */
156
        public DataExplorer getExplorer() throws ReadException {
157
                return null;
158
        }
159

    
160
        /* (non-Javadoc)
161
         * @see org.gvsig.fmap.data.DataStore#getName()
162
         */
163
        public String getName() {
164
                return DATASTORE_NAME;
165
        }
166

    
167
        /* (non-Javadoc)
168
         * @see org.gvsig.fmap.data.DataStore#isEditable()
169
         */
170
        public boolean isEditable() {
171
                return false;
172
        }
173

    
174
        /* (non-Javadoc)
175
         * @see org.gvsig.fmap.data.FeatureStore#doOpen()
176
         */
177
        protected void doOpen() throws OpenException {
178
                ((AbstractFeatureStore)this.storePrimary).open();
179
                ((AbstractFeatureStore)this.storeSecondary).open();
180

    
181
        }
182

    
183
        /* (non-Javadoc)
184
         * @see org.gvsig.metadata.IMetadatable#getMetadata()
185
         */
186
        public IMetadata getMetadata() throws BaseException {
187
                IMetadata md=getPrimaryStore().getMetadata();
188
                JoinAttributeDescriptor geomAttr = ((JoinFeatureType) this
189
                                .getDefaultFeatureType()).getDefaultGeometryAttribute();
190

    
191
                if (geomAttr != null) {
192

    
193
                        FeatureStore geomStore;
194
                        if (geomAttr.isFromSecondarySource()) {
195
                                geomStore = this.getSecondaryStore();
196
                        } else {
197
                                geomStore = this.getPrimaryStore();
198
                        }
199
                        if (geomStore.getDefaultFeatureType().getDefaultGeometry().equals(
200
                                        geomAttr.getOriginalName())) {
201
                                IMetadata omd = geomStore.getMetadata();
202
                                md.set("extent", omd.get("extent"));
203
                                md.set("srs", omd.get("srs"));
204
                        } else {
205
                                //TODO
206
                        }
207
                        md.set("primaryStoreMetada", this.getPrimaryStore().getMetadata());
208
                        md.set("secondaryStoreMetada", this.getSecondaryStore()
209
                                        .getMetadata());
210

    
211
                }
212
                return md;
213
        }
214

    
215
        protected void initFeatureType() throws InitializeException {
216

    
217
                JoinFeatureStoreParameters jParams = this.getJoinParameters();
218
                JoinFeatureType fType = new JoinFeatureType();
219

    
220
                if (jParams.getFieldsStorePrimary() != null
221
                                && jParams.getFieldsStorePrimary().length > 0) {
222
                        try {
223
                                fType.loadPrimaryStoreFeatureType(
224
                                                this.storePrimary.getDefaultFeatureType().getSubFeatureType(
225
                                                                jParams.getFieldsStorePrimary()));
226
                        } catch (DataException e) {
227
                                throw new InitializeException(this.getName(), e);
228
                        }
229
                } else {
230
                        try {
231
                                fType.loadPrimaryStoreFeatureType(this.storePrimary
232
                                                .getDefaultFeatureType());
233
                        } catch (IsNotAttributeSettingException e) {
234
                                throw new InitializeException(this.getName(), e);
235
                        }
236
                }
237

    
238
                String prefix = jParams.getFieldNamePrefix();
239
                if (jParams.getFieldsStoreSecondary() != null
240
                                && jParams.getFieldsStoreSecondary().length > 0) {
241
                        try {
242
                                fType.loadSecondaryStoreFeatureType(
243
                                                this.storeSecondary
244
                                                .getDefaultFeatureType().getSubFeatureType(
245
                                                                jParams.getFieldsStoreSecondary()),
246
                                                prefix);
247
                        } catch (DataException e) {
248
                                throw new InitializeException(this.getName(), e);
249
                        }
250
                } else {
251
                        try {
252
                                fType.loadSecondaryStoreFeatureType(this.storeSecondary
253
                                                .getDefaultFeatureType(), prefix);
254
                        } catch (IsNotAttributeSettingException e) {
255
                                throw new InitializeException(this.getName(), e);
256
                        }
257
                }
258

    
259
                if (this.storePrimary.getDefaultFeatureType().getFieldIndex(
260
                                jParams.getLinkFieldPrimary()) < 0) {
261
                        throw new InitializeException("Primary link field not found: " +jParams.getLinkFieldPrimary(),this.getName());
262
                }
263

    
264
                if (this.storeSecondary.getDefaultFeatureType().getFieldIndex(
265
                                jParams.getLinkFieldSecondary()) < 0) {
266
                        throw new InitializeException("Secondary link field not found: " +jParams.getLinkFieldSecondary(),this.getName());
267
                }
268

    
269
                String defGeometry = jParams.getDefaultGeometry();
270
                if (defGeometry != null && defGeometry.length() > 0) {
271
                        if (fType.getFieldIndex(defGeometry) >= 0) {
272
                                fType.setDefaultGeometry(defGeometry);
273
                                fType
274
                                                .setDefaultGeometryAttribute((JoinAttributeDescriptor) fType
275
                                                                .get(defGeometry));
276
                        } else if (fType.getFieldIndex(prefix + defGeometry) >= 0) {
277
                                fType.setDefaultGeometry(prefix + defGeometry);
278
                                fType
279
                                                .setDefaultGeometryAttribute((JoinAttributeDescriptor) fType
280
                                                                .get(prefix + defGeometry));
281
                        } else {
282
                                throw new InitializeException("Default geometry field not found: " +defGeometry,this.getName());
283
                        }
284
                }
285
                this.defaultFeatureType = fType;
286
                this.featureTypes = new ArrayList();
287
                this.featureTypes.add(defaultFeatureType);
288

    
289
        }
290

    
291
        public void init(DataStoreParameters parameters) throws InitializeException {
292
                super.init(parameters);
293
                if (!(this.parameters instanceof JoinFeatureStoreParameters)) {
294
                        throw new InitializeException("Wrong parameters", this.getName());
295
                }
296
                JoinFeatureStoreParameters jParams = this.getJoinParameters();
297
                DataManager dataManager = DataManager.getManager();
298
                this.storePrimary = (FeatureStore) dataManager.createDataStore(jParams
299
                                .getStorePrimary());
300
                this.storeSecondary = (FeatureStore) dataManager
301
                                .createDataStore(jParams.getStoreSecondary());
302

    
303
                this.observeStore(this.storePrimary);
304
                this.observeStore(this.storeSecondary);
305

    
306
                this.initFeatureType();
307
                this.changed = false;
308
        }
309

    
310
        /* (non-Javadoc)
311
         * @see org.gvsig.fmap.data.DataStore#refresh()
312
         */
313
        protected void doRefresh() throws OpenException,InitializeException {
314
                this.clearResourceObservers();
315
                this.storePrimary.refresh();
316
                this.storeSecondary.refresh();
317

    
318
                this.mapValues = null;
319

    
320
                this.observeStore(this.storePrimary);
321
                this.observeStore(this.storeSecondary);
322

    
323
                this.initFeatureType();
324
                this.changed = false;
325
        }
326
        /**
327
         * @deprecated
328
         */
329
        public boolean canWriteGeometry(int gvSIGgeometryType) {
330
                return false;
331
        }
332

    
333
        protected FeatureStore getPrimaryStore() {
334
                return storePrimary;
335
        }
336

    
337
        protected FeatureStore getSecondaryStore() {
338
                return storeSecondary;
339
        }
340

    
341
        protected final void observeStore(FeatureStore store) {
342
                StoreResourceChangedObserver observer = new StoreResourceChangedObserver(
343
                                this);
344
                store.addObserver(observer);
345
                this.resouceObservers.add(observer);
346
        }
347
        private class StoreResourceChangedObserver implements Observer {
348

    
349
                private JoinFeatureStore joinFeatureStore = null;
350
                public StoreResourceChangedObserver(JoinFeatureStore joinFeatureStore) {
351
                        this.joinFeatureStore = joinFeatureStore;
352
                }
353

    
354
                public void update(Observable observable, Object notification) {
355
                        this.joinFeatureStore.changed = true;
356
                }
357

    
358
        }
359

    
360
        protected void checkChanged() {
361
                if (this.changed) {
362
                        throw new ConcurrentModificationException(
363
                                        "Source Stores was changed");
364
                }
365
        }
366

    
367
        public Index createIndex(FeatureType type, String colName)
368
                        throws IndexException {
369
                throw new UnsupportedOperationException();
370

    
371
        }
372

    
373
        protected Feature getFeatureFromPrimary(Feature primaryFeature,
374
                        FeatureType fType)
375
                        throws ReadException {
376
                if (fType == null) {
377
                        fType = this.getDefaultFeatureType();
378
                } else {
379
                        if (!fType.isSubtypeOf(this.defaultFeatureType)) {
380
                                throw new ReadException("type error", this.getName());
381
                        } else if (!(fType instanceof JoinFeatureType)) {
382
                                throw new ReadException("type error", this.getName());
383
                        }
384
                }
385

    
386
                JoinFeatureStoreParameters jparams = this.getJoinParameters();
387
                Object key = primaryFeature.get(jparams.getLinkFieldPrimary());
388

    
389
                Feature secondaryFeature = (Feature) this.getMapOfSecondaryValues()
390
                                .get(key);
391

    
392
                return new JoinFeature(this, (JoinFeatureType) fType, primaryFeature,
393
                                secondaryFeature);
394

    
395

    
396

    
397
        }
398

    
399
        private Map getMapOfSecondaryValues() throws ReadException {
400
                if (this.mapValues == null) {
401

    
402
                        JoinFeatureStoreParameters jParams = this.getJoinParameters();
403
                        Map mapValues = new HashMap();
404
                        FeatureType sFType =((JoinFeatureType)this.defaultFeatureType).getSecondaryFeatureType();
405
                        int keyIndex = sFType
406
                                        .getFieldIndex(jParams.getLinkFieldSecondary());
407
                        FeatureCollection fc = (FeatureCollection) this.getSecondaryStore().getDataCollection(
408
                                        sFType, null, null);
409
                        Iterator iter = fc.iterator();
410
                        Object key;
411
                        Feature feature;
412
                        while (iter.hasNext()) {
413
                                feature = (Feature) iter.next();
414
                                key = feature.get(keyIndex);
415
                                if (!mapValues.containsKey(key)) {
416
                                        mapValues.put(key, feature);
417
                                }
418

    
419
                        }
420

    
421
                        fc.dispose();
422
                        fc = null;
423

    
424
                        this.mapValues = mapValues;
425

    
426
                }
427
                return this.mapValues;
428
        }
429
        //        public DataCollection getSelection() {
430
        //                this.selection = createSelection();
431
        //                this.setSelectionObserver();
432
        //                return selection;
433
        //        }
434
}
435