Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.h2 / src / main / java / org / gvsig / fmap / dal / store / h2 / H2StoreProvider.java @ 41719

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

    
28
package org.gvsig.fmap.dal.store.h2;
29

    
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.Properties;
33
import java.util.regex.Matcher;
34
import java.util.regex.Pattern;
35

    
36
import org.gvsig.fmap.dal.DALLocator;
37
import org.gvsig.fmap.dal.DataManager;
38
import org.gvsig.fmap.dal.DataServerExplorer;
39
import org.gvsig.fmap.dal.DataTypes;
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.exception.InitializeException;
42
import org.gvsig.fmap.dal.exception.ReadException;
43
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
44
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
45
import org.gvsig.fmap.dal.feature.FeatureQuery;
46
import org.gvsig.fmap.dal.feature.FeatureType;
47
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
48
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
49
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
50
import org.gvsig.fmap.dal.store.db.DBHelper;
51
import org.gvsig.fmap.dal.store.jdbc.JDBCHelper;
52
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreProviderWriter;
53
import org.gvsig.fmap.geom.Geometry;
54
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
56

    
57
public class H2StoreProvider extends JDBCStoreProviderWriter {
58

    
59
        public final static Logger logger = LoggerFactory
60
                        .getLogger(H2StoreProvider.class);
61

    
62
        public static final String NAME = "H2";
63
        public static final String DESCRIPTION = "H2 source";
64

    
65
        public static final String METADATA_DEFINITION_NAME = NAME;
66
        
67
        public H2StoreProvider(H2StoreParameters params,
68
                        DataStoreProviderServices storeServices)
69
                        throws InitializeException {
70
                super(params, storeServices, DBHelper.newMetadataContainer(METADATA_DEFINITION_NAME));
71
        }
72

    
73
        private H2StoreParameters getPGParameters() {
74
                return (H2StoreParameters) this.getParameters();
75
        }
76

    
77
        protected JDBCHelper createHelper() throws InitializeException {
78
            JDBCHelper resp = new H2Helper(this, getPGParameters());
79
            
80
            return resp;
81
        }
82

    
83

    
84

    
85
        protected String fixFilter(String _filter) {
86
                if (_filter == null) {
87
                        return null;
88
                }
89
                
90
                String filter = fixFunctionNames(_filter);
91

    
92
                // Transform SRS to code
93
                // GeomFromText\s*\(\s*'[^']*'\s*,\s*('[^']*')\s*\)
94
                
95
                String geom_from_text = this.getFunctionName("ST_GeomFromText");
96
                Pattern pattern = Pattern
97
                                .compile(geom_from_text + "\\s*\\(\\s*'[^']*'\\s*,\\s*'([^']*)'\\s*\\)");
98
                Matcher matcher = pattern.matcher(filter);
99
                StringBuilder strb = new StringBuilder();
100
                int pos = 0;
101
                String srsCode;
102
                while (matcher.find(pos)) {
103
                        strb.append(filter.substring(pos, matcher.start(1)));
104
                        srsCode = matcher.group(1).trim();
105
                        if (srsCode.startsWith("'")) {
106
                                srsCode = srsCode.substring(1);
107
                        }
108
                        if (srsCode.endsWith("'")) {
109
                                srsCode = srsCode.substring(0, srsCode.length() - 1);
110
                        }
111
                        strb.append(helper.getProviderSRID(srsCode));
112
                        strb.append(filter.substring(matcher.end(1), matcher.end()));
113
                        pos = matcher.end();
114

    
115
                }
116
                strb.append(filter.substring(pos));
117

    
118
                return strb.toString();
119
        }
120

    
121

    
122
    public String getName() {
123
                return NAME;
124
        }
125

    
126
        public FeatureSetProvider createSet(FeatureQuery query,
127
                        FeatureType featureType) throws DataException {
128

    
129
                return new H2SetProvider(this, query, featureType);
130
        }
131

    
132

    
133
        public DataServerExplorer getExplorer() throws ReadException {
134
                DataManager manager = DALLocator.getDataManager();
135
                H2ServerExplorerParameters exParams;
136
                H2StoreParameters params = getPGParameters();
137
                try {
138
                        exParams = (H2ServerExplorerParameters) manager
139
                                        .createServerExplorerParameters(H2ServerExplorer.NAME);
140
                        exParams.setUrl(params.getUrl());
141
                        exParams.setHost(params.getHost());
142
                        exParams.setPort(params.getPort());
143
                        exParams.setDBName(params.getDBName());
144
                        exParams.setUser(params.getUser());
145
                        exParams.setPassword(params.getPassword());
146
                        exParams.setCatalog(params.getCatalog());
147
                        exParams.setSchema(params.getSchema());
148
                        exParams.setJDBCDriverClassName(params.getJDBCDriverClassName());
149
                        exParams.setUseSSL(params.getUseSSL());
150

    
151
                        return manager.openServerExplorer(H2ServerExplorer.NAME, exParams);
152
                } catch (DataException e) {
153
                        throw new ReadException(this.getName(), e);
154
                } catch (ValidateDataParametersException e) {
155
                        throw new ReadException(this.getName(), e);
156
                }
157
        }
158

    
159
        public boolean allowAutomaticValues() {
160
                return true;
161
        }
162

    
163

    
164
        public boolean hasGeometrySupport() {
165
                return true;
166
        }
167

    
168

    
169
        protected H2Helper getPgHelper() {
170
                return (H2Helper) getHelper();
171
        }
172

    
173

    
174

    
175
        public boolean canWriteGeometry(int geometryType, int geometrySubtype)
176
                        throws DataException {
177
                FeatureType type = getFeatureStore().getDefaultFeatureType();
178
                FeatureAttributeDescriptor geomAttr = type.getAttributeDescriptor(type
179
                                                                .getDefaultGeometryAttributeName());
180
                if (geomAttr == null) {
181
                        return false;
182
                }
183
                if (geometrySubtype != geomAttr.getGeometrySubType()) {
184
                        return false;
185
                }
186
                switch (geomAttr.getGeometryType()) {
187
                case Geometry.TYPES.GEOMETRY:
188
                        return true;
189

    
190
                case Geometry.TYPES.MULTISURFACE:
191
                        return geometryType == Geometry.TYPES.MULTISURFACE
192
                                        || geometryType == Geometry.TYPES.SURFACE;
193

    
194
                case Geometry.TYPES.MULTIPOINT:
195
                        return geometryType == Geometry.TYPES.MULTIPOINT
196
                                        || geometryType == Geometry.TYPES.POINT;
197

    
198
                case Geometry.TYPES.MULTICURVE:
199
                        return geometryType == Geometry.TYPES.MULTICURVE
200
                                        || geometryType == Geometry.TYPES.CURVE;
201

    
202
                case Geometry.TYPES.MULTISOLID:
203
                        return geometryType == Geometry.TYPES.MULTISOLID
204
                                        || geometryType == Geometry.TYPES.SOLID;
205

    
206
                default:
207
                        return geometryType == geomAttr.getGeometryType();
208
                }
209

    
210
        }
211

    
212

    
213
        protected void addToListFeatureValues(FeatureProvider featureProvider,
214
                        FeatureAttributeDescriptor attrOfList,
215
                        FeatureAttributeDescriptor attr,
216
                        List<Object> values) throws DataException {
217

    
218
                super.addToListFeatureValues(featureProvider, attrOfList, attr, values);
219
                if (attr.getType() == DataTypes.GEOMETRY) {
220
                        values.add(helper.getProviderSRID(attr.getSRS()));
221
                }
222
        }
223

    
224
        protected void prepareAttributeForInsert(
225
                        FeatureAttributeDescriptor attr, List<String> fields, List<String> values) {
226

    
227
                if (attr.getType() == DataTypes.GEOMETRY) {
228
                        fields.add(helper.escapeFieldName(attr.getName()));
229
                        values.add(getFunctionName("ST_GeomFromWKB") + "(?,?)");
230
                } else {
231
                        super.prepareAttributeForInsert(attr, fields, values);
232
                }
233

    
234
        }
235

    
236
        protected void prepareAttributeForUpdate(FeatureAttributeDescriptor attr,
237
                        List<String> values) {
238
                if (attr.getType() == DataTypes.GEOMETRY) {
239
                        values.add(helper.escapeFieldName(attr.getName())
240
                                        + " = " + getFunctionName("ST_GeomFromWKB") + "(?,?)");
241
                } else {
242
                        super.prepareAttributeForUpdate(attr, values);
243
                }
244
        }
245

    
246
        protected String getSqlStatementAddField(FeatureAttributeDescriptor attr,
247
                        List<String> additionalStatement) throws DataException {
248
                if (attr.getType() == DataTypes.GEOMETRY) {
249
                        H2StoreParameters params = getPGParameters();
250
                        additionalStatement.addAll(        ((H2Helper) helper)
251
                                        .getSqlGeometyFieldAdd(attr, params.getTable(), params
252
                                                        .getSchema()));
253

    
254
                }
255
                return super.getSqlStatementAddField(attr, additionalStatement);
256

    
257
        }
258
        private String getSqlGeometyFieldDrop(FeatureAttributeDescriptor attr) {
259
                StringBuilder strb = new StringBuilder();
260
                H2StoreParameters params = getPGParameters();
261
                strb.append("Delete from geometry_columns where f_geometry_column = '");
262
                strb.append(attr.getName());
263
                strb.append("' and f_table_nam = '");
264
                strb.append(params.getTable());
265
                strb.append("' and f_table_schema = ");
266
                if (params.getSchema() == null || params.getSchema().length() == 0) {
267
                        strb.append("current_schema()");
268
                } else {
269
                        strb.append("'");
270
                        strb.append(params.getSchema());
271
                        strb.append("'");
272
                }
273
                if (params.getCatalog() != null && params.getCatalog().length() > 0) {
274
                        strb.append(" and f_table_catalog = '");
275
                        strb.append(params.getCatalog());
276
                        strb.append("'");
277
                }
278
                return strb.toString();
279
        }
280

    
281
        protected String getSqlStatementDropField(FeatureAttributeDescriptor attr,
282
                        List<String> additionalStatement) {
283
                String result = super.getSqlStatementDropField(attr,
284
                                additionalStatement);
285
                if (attr.getType() == DataTypes.GEOMETRY) {
286
                        additionalStatement.add(getSqlGeometyFieldDrop(attr));
287
                }
288
                return result;
289
        }
290

    
291
        protected List<String> getSqlStatementAlterField(
292
                        FeatureAttributeDescriptor attrOrg,
293
                        FeatureAttributeDescriptor attrTrg, List<String> additionalStatement)
294
                        throws DataException {
295
                //
296
                List<String> actions = super.getSqlStatementAlterField(attrOrg, attrTrg,
297
                                additionalStatement);
298
                H2StoreParameters params = getPGParameters();
299
                if (attrOrg.getDataType() != attrTrg.getDataType()) {
300
                        if (attrOrg.getType() == DataTypes.GEOMETRY) {
301
                                additionalStatement.add(getSqlGeometyFieldDrop(attrOrg));
302
                        }
303
                        if (attrTrg.getType() == DataTypes.GEOMETRY) {
304
                                additionalStatement.addAll(((H2Helper) helper)
305
                                                .getSqlGeometyFieldAdd(attrTrg, params.getTable(),
306
                                                                params.getSchema()));
307
                        }
308
                }
309
                if (attrOrg.getDataType() == attrTrg.getDataType()
310
                                && attrTrg.getType() == DataTypes.GEOMETRY) {
311
                        // TODO Checks SRS and GeomType/Subtype
312
                }
313

    
314
                return actions;
315
        }
316
        
317

    
318
        private String getFunctionName(String newFunctionName) {
319
        
320
        H2Helper hpr = getPgHelper();
321
        if (hpr == null) {
322
            logger.info("Unable to get PG helper.", new Exception("Helper is null"));
323
            return newFunctionName;
324
        } else {
325
            return hpr.getFunctionName(newFunctionName);
326
        }
327
    }
328
        
329
    private String fixFunctionNames(String _filter) {
330
        
331
        Properties props = this.getPgHelper().getBeforePostgis13Properties();
332
        Iterator iter = props.keySet().iterator();
333
        String kstr = null;
334
        String vstr = null;
335
        
336
        String resp = _filter;
337
        
338
        while (iter.hasNext()) {
339
            kstr = (String) iter.next();
340
            vstr = getPgHelper().getFunctionName(kstr);
341
            resp = replace(resp, kstr, vstr);
342
        }
343
        return resp;
344
    }
345

    
346
    private String replace(String str, String oldstr, String newstr) {
347
        
348
        if (oldstr == null || newstr == null ||
349
            oldstr.length() == 0 || oldstr.equals(newstr)) {
350
            return str;
351
        }
352
        
353
        String lowerstr = str.toLowerCase();
354
        String lowerold = oldstr.toLowerCase();
355
        
356
        if (lowerstr.indexOf(lowerold) == -1) {
357
            // nothing to do
358
            return str;
359
        }
360
        
361
        Pattern p = Pattern.compile(lowerold, Pattern.LITERAL);
362
        String[] parts = p.split(lowerstr); 
363
        
364
        StringBuffer resp = new StringBuffer();
365
        int auxind = 0;
366
        resp.append(str.subSequence(0, parts[0].length()));
367
        for (int i=1; i<parts.length; i++) {
368
            resp.append(newstr);
369
            auxind = getIndex(parts, i-1, oldstr.length());
370
            resp.append(str.subSequence(auxind, auxind + parts[i].length()));
371
        }
372
        return resp.toString();
373
    }
374

    
375
    /**
376
     * This method gets the index where the n-th part (0-based)
377
     * starts in the original string
378
     * 
379
     * @param parts
380
     * @param n
381
     * @param length
382
     * @return
383
     */
384
    private int getIndex(String[] parts, int till_n, int length) {
385
        
386
        int resp = 0;
387
        for (int i=0; i<(till_n+1); i++) {
388
            resp = resp + parts[i].length();
389
            resp = resp + length;
390
        }
391
        return resp;
392
    }
393

    
394
    
395
}