Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / data / feature / db / jdbc / JDBCStore.java @ 24491

History | View | Annotate | Download (12.1 KB)

1
package org.gvsig.fmap.data.feature.db.jdbc;
2

    
3

    
4
import java.security.KeyException;
5
import java.sql.Connection;
6
import java.sql.ResultSet;
7
import java.sql.Statement;
8
import java.util.HashMap;
9
import java.util.Iterator;
10

    
11
import org.gvsig.fmap.data.DataExplorer;
12
import org.gvsig.fmap.data.DataStoreParameters;
13
import org.gvsig.fmap.data.exceptions.CloseException;
14
import org.gvsig.fmap.data.exceptions.DataException;
15
import org.gvsig.fmap.data.exceptions.InitializeException;
16
import org.gvsig.fmap.data.exceptions.OpenException;
17
import org.gvsig.fmap.data.exceptions.ReadException;
18
import org.gvsig.fmap.data.exceptions.WriteException;
19
import org.gvsig.fmap.data.feature.AttributeDescriptor;
20
import org.gvsig.fmap.data.feature.CreatedFeature;
21
import org.gvsig.fmap.data.feature.Feature;
22
import org.gvsig.fmap.data.feature.FeatureAttributeDescriptor;
23
import org.gvsig.fmap.data.feature.FeatureReference;
24
import org.gvsig.fmap.data.feature.FeatureType;
25
import org.gvsig.fmap.data.feature.db.DBFeatureID;
26
import org.gvsig.fmap.data.feature.db.DBFeatureType;
27
import org.gvsig.fmap.data.feature.db.DBResource;
28
import org.gvsig.fmap.data.feature.db.DBStore;
29
import org.gvsig.fmap.data.feature.exceptions.InitializeWriterException;
30
import org.gvsig.fmap.data.feature.impl.commands.implementation.AttributeCommand;
31
import org.gvsig.fmap.data.feature.impl.commands.implementation.FeatureCommand;
32
import org.gvsig.fmap.data.feature.impl.commands.implementation.UpdateAttributeCommand
33
import org.gvsig.fmap.data.feature.impl.commands.implementation.FeatureUpdateCommand;
34

    
35
import org.gvsig.fmap.data.feature.impl.commands.implementation.FeatureCommandUpdate;
36
import org.gvsig.fmap.data.resource.ResourceManager;
37
import org.gvsig.fmap.data.resource.impl.DefaultResourceManager;
38
import org.gvsig.fmap.data.resource.spi.AbstractResource;
39
import org.gvsig.metadata.Metadata;
40
import org.gvsig.metadata.MetadataManager;
41
import org.gvsig.metadata.DefaultMetadataManager;
42
import org.gvsig.tools.exception.BaseException;
43

    
44
public abstract class JDBCStore extends DBStore {
45

    
46
        protected JDBCResource resource = null;
47
        protected String sqlSelectPart;
48
        protected String baseWhereClause = null;
49
        protected String baseOrder = null;
50
        protected String sqlSource = null;
51
        protected boolean useSqlSource = false;
52
        protected Metadata metadata;
53

    
54

    
55
        public void init(DataStoreParameters parameters) throws InitializeException {
56

    
57
                DBResource tmpResource = this.createResource((JDBCStoreParameters)parameters);
58
                DefaultResourceManager resMan = DefaultResourceManager.getResourceManager();
59

    
60
                try {
61
                        this.resource = (JDBCResource) resMan
62
                                        .addResource(tmpResource, this);
63
                } catch (DataException e1) {
64
                        throw new InitializeException(this.getName(),e1);
65
                }
66

    
67
                super.init(parameters,this.resource);
68

    
69

    
70
                this.initFeatureType();
71
                this.initSqlProperties();
72
        }
73

    
74

    
75
        protected abstract DBResource createResource(JDBCStoreParameters params);
76
        protected abstract void initFeatureType() throws InitializeException;
77
        protected abstract void initSqlProperties() throws InitializeException;
78

    
79

    
80
        /* (non-Javadoc)
81
         * @see org.gvsig.fmap.dal.feature.FeatureStore#doClose()
82
         */
83
        protected void doClose() throws CloseException {
84
                this.resource.close();
85

    
86
        }
87

    
88
        /* (non-Javadoc)
89
         * @see org.gvsig.fmap.dal.feature.FeatureStore#doDispose()
90
         */
91
        protected void doDispose() throws CloseException {
92
                ResourceManager resMan = DefaultResourceManager.getResourceManager();
93

    
94
            try {
95
                        resMan.remove(this.resource, this);
96
                } catch (DataException e1) {
97
                        throw new CloseException(this.getName(),e1);
98
                } catch (KeyException e) {
99
                        // TODO Auto-generated catch block
100
                        throw new CloseException(this.getName(),e);
101
                }
102
                this.metadata = null;
103
                super.doDispose();
104
        }
105

    
106
        /* (non-Javadoc)
107
         * @see org.gvsig.fmap.dal.feature.FeatureStore#doOpen()
108
         */
109
        protected void doOpen() throws OpenException {
110
                //No Operation
111

    
112
        }
113

    
114

    
115
        /* (non-Javadoc)
116
         * @see org.gvsig.fmap.dal.feature.FeatureStore#canAlterFeatureType()
117
         */
118
        public boolean canAlterFeatureType() {
119
                return false;
120
        }
121

    
122
        /* (non-Javadoc)
123
         * @see org.gvsig.fmap.dal.DataStore#getExplorer()
124
         */
125
        public DataExplorer getExplorer() throws ReadException {
126
                return null;
127
        }
128

    
129

    
130
        /* (non-Javadoc)
131
         * @see org.gvsig.fmap.dal.feature.FeatureStore#init(org.gvsig.fmap.dal.DataStoreParameters, org.gvsig.fmap.dal.Resource)
132
         */
133
        public void init(DataStoreParameters parameters, AbstractResource resource) throws InitializeException {
134
                super.init(parameters, resource);
135
                this.resource=(JDBCResource)resource;
136
        }
137

    
138
        protected Connection getConnection() throws ReadException{
139
                return this.resource.getConnection();
140
        }
141

    
142
        protected Connection getWriterConnection() throws ReadException{
143
                return this.resource.getWriterConnection();
144
        }
145

    
146
        public boolean allowWrite() {
147
                return super.allowWrite() && !this.useSqlSource;
148
        }
149

    
150

    
151
        public String getSqlSelectPart() {
152
                return sqlSelectPart;
153
        }
154

    
155
        public String getBaseOrder() {
156
                return this.baseOrder;
157
        }
158

    
159
        public String getBaseWhereClause() {
160
                return baseWhereClause;
161
        }
162

    
163
        public boolean isUseSqlSource() {
164
                return this.useSqlSource;
165
        }
166

    
167
        public String getSqlSource() {
168
                return this.sqlSource;
169
        }
170

    
171
        protected abstract JDBCFeaturesWriter getFeaturesWriter() throws InitializeWriterException;
172

    
173
        protected void doFinishEdition() throws WriteException, ReadException {
174
                Iterator commandsfeatures = null;
175
            JDBCFeaturesWriter selectiveWriter = getFeaturesWriter();
176
            FeatureType type = getDefaultFeatureType();
177
            boolean needRefresh=false;
178

    
179
                Feature feature;
180
                Object obj;
181
                FeatureReference featureId;
182

    
183

    
184
                selectiveWriter.updateFeatureType(type);
185
                selectiveWriter.preProcess();
186

    
187
                try{
188
                    commandsfeatures = commands.getCommandsAttributeDeleted().iterator();
189
                        while( commandsfeatures.hasNext() ) {
190
                                obj=commandsfeatures.next();
191
                                if (obj instanceof AttributeCommand){
192
                                        FeatureAttributeDescriptor attribute = ((AttributeCommand)obj).getAttributeDescriptor();
193
                                        selectiveWriter.deleteAttribute(attribute);
194
                                        needRefresh=true;
195
                                }
196
                        }
197
                        commandsfeatures = commands.getCommandsAttributeUpdated().iterator();
198
                        while( commandsfeatures.hasNext() ) {
199
                                obj=commandsfeatures.next();
200
                                if (obj instanceof AttributeCommand){
201
                                        FeatureAttributeDescriptor oldAttribute = ((UpdateAttributeCommand)obj).getOldAttributeDescriptor();
202
                                        FeatureAttributeDescriptor attribute = ((UpdateAttributeCommand)obj).getAttributeDescriptor();
203
                                        selectiveWriter.updateAttribute(oldAttribute,attribute);
204
                                        needRefresh=true;
205
                                }
206
                        }
207
                        commandsfeatures = commands.getCommandsAttributeInserted().iterator();
208
                        while( commandsfeatures.hasNext() ) {
209
                                obj=commandsfeatures.next();
210
                                if (obj instanceof AttributeCommand){
211
                                        FeatureAttributeDescriptor attribute = ((AttributeCommand)obj).getAttributeDescriptor();
212
                                        selectiveWriter.insertAttribute(attribute);
213
                                        needRefresh=true;
214
                                }
215
                        }
216

    
217

    
218
                        commandsfeatures = commands.getCommandsFeatureDeleted().iterator();
219
                        while( commandsfeatures.hasNext() ) {
220
                                obj=commandsfeatures.next();
221
                                if (obj instanceof FeatureCommand){
222
                                        feature = ((FeatureCommand)obj).getFeature();
223
                                        if (feature instanceof CreatedFeature) {
224
                                                continue;
225
                                        }
226

    
227
                                        selectiveWriter.delete(feature);
228
                                }
229
                        }
230

    
231
                        commandsfeatures = commands.getCommandsFeatureInserted().iterator();
232
                        while( commandsfeatures.hasNext() ) {
233
                                obj=commandsfeatures.next();
234
                                if (obj instanceof FeatureCommand){
235
                                        feature = ((FeatureCommand)obj).getFeature();
236
                                        if (featureManager.isDeleted(feature)){
237
                                                continue;
238
                                        }
239
                                        selectiveWriter.insertFeature(feature);
240
                                }
241
                        }
242

    
243
                        commandsfeatures = commands.getCommandsFeatureUpdated().iterator();
244
                        HashMap toUpdate = new HashMap();
245
                        while( commandsfeatures.hasNext() ) {
246
                                obj=commandsfeatures.next();
247
                                if (obj instanceof FeatureCommand){
248
//                                        Feature oldFeature = ((UpdateFeatureCommand)obj).getOldFeature();
249
                                        feature = ((FeatureUpdateCommand)obj).getFeature();
250
                                        feature = ((FeatureCommandUpdate)obj).getFeature();
251
                                        featureId =feature.getReference();
252
                                        feature = featureManager.get(featureId, this,null);
253
                                        if (feature != null){
254
                                                toUpdate.put(featureId, feature);
255
                                        }
256
                                }
257
                        }
258
                        Iterator toUpdateIter = toUpdate.values().iterator();
259
                        while (toUpdateIter.hasNext()){
260
                                feature = (Feature) toUpdateIter.next();
261
                                selectiveWriter.updateFeature(feature);
262
                        }
263

    
264

    
265
                        selectiveWriter.postProcess();
266
                        this.resource.changed(this);
267
                        if (needRefresh){
268
                                this.refresh();
269
                        }
270

    
271

    
272
                }catch (ReadException e) {
273
                        selectiveWriter.cancelProcess();
274
                        throw e;
275
                } catch (WriteException e){
276
                        selectiveWriter.cancelProcess();
277
                        throw e;
278
                } catch (Exception e){
279
                        selectiveWriter.cancelProcess();
280
                        throw new WriteException(this.getName(),e);
281
                }
282
        }
283

    
284
        public String getFilterForID(DBFeatureType fType, Object[] featureKey) {
285
                if (fType.getFieldsId().length != 1) {
286
                        throw new UnsupportedOperationException("ID fields > 1");
287
                }
288
                String id =fType.getFieldsId()[0];
289
                return id + " = " + objectToSqlString(featureKey[0]);
290
        }
291

    
292
        protected String objectToSqlString(Object obj) {
293
                if (obj instanceof String){
294
                        return "'"+ scapeString((String)obj) +"'";
295
                } else if (obj == null){
296
                        return "null";
297
                }else{
298
                        // OJO con otros tipos!!
299
                        return obj.toString();
300
                }
301

    
302
        }
303

    
304
        protected String scapeString(String str) {
305
                return str.replace("'", "''");
306
        }
307

    
308
        public Feature getFeatureByID(FeatureReference id,FeatureType featureType) throws ReadException{
309
                return getFeatureByID(featureType,((DBFeatureID)id).getKey());
310
        }
311

    
312
        public Metadata getMetadata() throws BaseException {
313
                if (metadata==null){
314
                        MetadataManager manager=DefaultMetadataManager.getManager();
315
                        metadata=manager.create(this.getName());
316

    
317
                        DBFeatureType fType = (DBFeatureType) this.getDefaultFeatureType();
318
                        metadata.set("srs",fType.getDefaultSRS());
319
                }
320
                return metadata;
321
        }
322

    
323

    
324
        public Feature getFeatureByID(FeatureType featureType, Object[] featureKey) throws ReadException{
325
                //TODO: Tener en cuenta el FeatureType por si es distinto
326
                if (useSqlSource){
327
                        throw new ReadException("Unsuported featureByID in sqlSource mode",this.getName());
328
                }
329
                if (featureType==null){
330
                        featureType=getDefaultFeatureType();
331
                }else{
332
                        if (!featureType.isSubtypeOf(this.getDefaultFeatureType())){
333
                                throw new ReadException("invalid type",this.getName());
334
                        }
335
                }
336
                ResultSet rs=null;
337
                try{
338
                        this.open();
339
                        Statement st=this.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
340
                        String sql = this.getSqlSelectPart() + " WHERE "+ this.getFilterForID((DBFeatureType)this.getDefaultFeatureType(), featureKey);
341
                        rs=st.executeQuery(sql);
342
                        if(rs.next()){
343
                                return createFeatureFromResulset(rs, (DBFeatureType)featureType);
344
                        }
345

    
346
                } catch (java.sql.SQLException e) {
347
                        e.printStackTrace();
348
                        throw new ReadException(this.getName(), e);
349
                } finally{
350
                        if (rs != null){
351
                                try {
352
                                        rs.close();
353
                                } catch (java.sql.SQLException e) {
354
                                        throw new ReadException(this.getName(),e);
355
                                }
356
                        }
357
                }
358
                return null;
359
        }
360

    
361

    
362
        protected abstract Feature createFeatureFromResulset(ResultSet rs, DBFeatureType featureType2) throws ReadException;
363

    
364

    
365
        protected FeatureType checkFeatureTypeForCollection(FeatureType fType)
366
                        throws DataException {
367
                if (!this.useSqlSource) {
368
                        return super.checkFeatureTypeForCollection(fType);
369
                }
370
                FeatureType defType = this.getDefaultFeatureType();
371
                if (fType == null || fType.equals(defType)) {
372
                        return defType.getSubFeatureType(null);
373
                }
374
                if (!fType.isSubtypeOf(defType)) {
375
                        throw new ReadException("invalid type", this.getName());
376
                }
377
                Iterator iterDef = defType.iterator();
378
                Iterator iterType = fType.iterator();
379

    
380
                AttributeDescriptor defAttr;
381
                AttributeDescriptor attr;
382

    
383
                while (iterDef.hasNext()) {
384
                        defAttr = (AttributeDescriptor) iterDef.next();
385
                        attr = (AttributeDescriptor) iterType.next();
386
                        if (!(
387
                                        defAttr.getName().equals(attr.getName())
388
                                        && defAttr.getDataType().equals(attr.getDataType())
389
                                        && defAttr.getSize() == attr.getSize()
390
                                        && defAttr.isReadOnly() == attr.isReadOnly()
391
                                        && defAttr.isEvaluated() == attr.isEvaluated()
392
                                        )) {
393
                                throw new ReadException("invalid type", this.getName());
394
                        }
395
                }
396
                while (iterType.hasNext()) {
397
                        attr = (AttributeDescriptor) iterType.next();
398
                        if (!attr.isEvaluated()) {
399
                                throw new ReadException("invalid type", this.getName());
400
                        }
401
                }
402

    
403
                return fType;
404
        }
405

    
406
}