Statistics
| Revision:

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

History | View | Annotate | Download (12 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.ResourceManager;
14
import org.gvsig.fmap.data.exceptions.CloseException;
15
import org.gvsig.fmap.data.exceptions.DataException;
16
import org.gvsig.fmap.data.exceptions.InitializeException;
17
import org.gvsig.fmap.data.exceptions.OpenException;
18
import org.gvsig.fmap.data.exceptions.ReadException;
19
import org.gvsig.fmap.data.exceptions.WriteException;
20
import org.gvsig.fmap.data.feature.AttributeDescriptor;
21
import org.gvsig.fmap.data.feature.CreatedFeature;
22
import org.gvsig.fmap.data.feature.Feature;
23
import org.gvsig.fmap.data.feature.FeatureAttributeDescriptor;
24
import org.gvsig.fmap.data.feature.FeatureReference;
25
import org.gvsig.fmap.data.feature.FeatureType;
26
import org.gvsig.fmap.data.feature.db.DBFeatureID;
27
import org.gvsig.fmap.data.feature.db.DBFeatureType;
28
import org.gvsig.fmap.data.feature.db.DBResource;
29
import org.gvsig.fmap.data.feature.db.DBStore;
30
import org.gvsig.fmap.data.feature.exceptions.InitializeWriterException;
31
import org.gvsig.fmap.data.feature.impl.commands.implementation.AttributeCommand;
32
import org.gvsig.fmap.data.feature.impl.commands.implementation.FeatureCommand;
33
import org.gvsig.fmap.data.feature.impl.commands.implementation.UpdateAttributeCommand;
34
import org.gvsig.fmap.data.feature.impl.commands.implementation.UpdateFeatureCommand;
35
import org.gvsig.fmap.data.impl.DefaultResourceManager;
36
import org.gvsig.fmap.data.spi.AbstractResource;
37
import org.gvsig.metadata.Metadata;
38
import org.gvsig.metadata.MetadataManager;
39
import org.gvsig.metadata.DefaultMetadataManager;
40
import org.gvsig.tools.exception.BaseException;
41

    
42
public abstract class JDBCStore extends DBStore {
43

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

    
52

    
53
        public void init(DataStoreParameters parameters) throws InitializeException {
54

    
55
                DBResource tmpResource = this.createResource((JDBCStoreParameters)parameters);
56
                DefaultResourceManager resMan = DefaultResourceManager.getResourceManager();
57

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

    
65
                super.init(parameters,this.resource);
66

    
67

    
68
                this.initFeatureType();
69
                this.initSqlProperties();
70
        }
71

    
72

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

    
77

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

    
84
        }
85

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

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

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

    
110
        }
111

    
112

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

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

    
127

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

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

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

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

    
148

    
149
        public String getSqlSelectPart() {
150
                return sqlSelectPart;
151
        }
152

    
153
        public String getBaseOrder() {
154
                return this.baseOrder;
155
        }
156

    
157
        public String getBaseWhereClause() {
158
                return baseWhereClause;
159
        }
160

    
161
        public boolean isUseSqlSource() {
162
                return this.useSqlSource;
163
        }
164

    
165
        public String getSqlSource() {
166
                return this.sqlSource;
167
        }
168

    
169
        protected abstract JDBCFeaturesWriter getFeaturesWriter() throws InitializeWriterException;
170

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

    
177
                Feature feature;
178
                Object obj;
179
                FeatureReference featureId;
180

    
181

    
182
                selectiveWriter.updateFeatureType(type);
183
                selectiveWriter.preProcess();
184

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

    
215

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

    
225
                                        selectiveWriter.deleteFeature(feature);
226
                                }
227
                        }
228

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

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

    
261

    
262
                        selectiveWriter.postProcess();
263
                        this.resource.changed(this);
264
                        if (needRefresh){
265
                                this.refresh();
266
                        }
267

    
268

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

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

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

    
299
        }
300

    
301
        protected String scapeString(String str) {
302
                return str.replace("'", "''");
303
        }
304

    
305
        public Feature getFeatureByID(FeatureReference id,FeatureType featureType) throws ReadException{
306
                return getFeatureByID(featureType,((DBFeatureID)id).getKey());
307
        }
308

    
309
        public Metadata getMetadata() throws BaseException {
310
                if (metadata==null){
311
                        MetadataManager manager=DefaultMetadataManager.getManager();
312
                        metadata=manager.create(this.getName());
313

    
314
                        DBFeatureType fType = (DBFeatureType) this.getDefaultFeatureType();
315
                        metadata.set("srs",fType.getDefaultSRS());
316
                }
317
                return metadata;
318
        }
319

    
320

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

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

    
358

    
359
        protected abstract Feature createFeatureFromResulset(ResultSet rs, DBFeatureType featureType2) throws ReadException;
360

    
361

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

    
377
                AttributeDescriptor defAttr;
378
                AttributeDescriptor attr;
379

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

    
400
                return fType;
401
        }
402

    
403
}