Statistics
| Revision:

gvsig-gdal / trunk / org.gvsig.gdal2 / org.gvsig.gdal2.prov / org.gvsig.gdal2.prov.ogr / src / main / java / org / gvsig / gdal / prov / ogr / OGRDataExplorer.java @ 368

History | View | Annotate | Download (17 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2016 gvSIG Association
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.gdal.prov.ogr;
25

    
26
import java.io.File;
27
import java.util.ArrayList;
28
import java.util.List;
29

    
30
import org.apache.commons.lang3.StringUtils;
31
import org.cresques.cts.ICRSFactory;
32
import org.cresques.cts.IProjection;
33
import org.gdal.ogr.DataSource;
34
import org.gdal.ogr.FieldDefn;
35
import org.gdal.ogr.GeomFieldDefn;
36
import org.gdal.ogr.Layer;
37
import org.gdal.ogr.ogr;
38
import org.gdal.ogr.ogrConstants;
39
import org.gdal.osr.SpatialReference;
40
import org.gvsig.fmap.dal.DALLocator;
41
import org.gvsig.fmap.dal.DataManager;
42
import org.gvsig.fmap.dal.DataServerExplorerParameters;
43
import org.gvsig.fmap.dal.DataStoreParameters;
44
import org.gvsig.fmap.dal.NewDataStoreParameters;
45
import org.gvsig.fmap.dal.exception.DataException;
46
import org.gvsig.fmap.dal.exception.InitializeException;
47
import org.gvsig.fmap.dal.exception.ReadRuntimeException;
48
import org.gvsig.fmap.dal.feature.EditableFeatureType;
49
import org.gvsig.fmap.dal.resource.ResourceAction;
50
import org.gvsig.fmap.dal.resource.file.FileResource;
51
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
52
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
53
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
54
import org.gvsig.fmap.dal.spi.AbstractDataServerExplorer;
55
import org.gvsig.fmap.dal.spi.DataServerExplorerProvider;
56
import org.gvsig.fmap.dal.spi.DataServerExplorerProviderServices;
57
import org.gvsig.tools.dynobject.DynField;
58
import org.slf4j.Logger;
59
import org.slf4j.LoggerFactory;
60

    
61
/**
62
 * 
63
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
64
 *
65
 */
66
public class OGRDataExplorer extends AbstractDataServerExplorer implements DataServerExplorerProvider, ResourceConsumer {
67

    
68
    private static final Logger LOG = LoggerFactory.getLogger(OGRDataExplorer.class);
69

    
70
    /**
71
     * 
72
     */
73
    public static final String NAME = "OGRDataExplorer";
74

    
75
    private DataServerExplorerProviderServices providerServives;
76
    protected OGRDataExplorerParameters parameters;
77

    
78
    private ResourceProvider resourceProvider;
79

    
80
    protected DataSource dataSource;
81

    
82
    protected Boolean updateSupport;
83

    
84
    private List<Layer> layerList;
85

    
86
    /**
87
     * @param parameters
88
     *            Parameters to open data explorer.
89
     * @param providerServices
90
     *            Available services
91
     * @throws InitializeException
92
     *             If there is some error initializing this store provider
93
     */
94
    public OGRDataExplorer(OGRDataExplorerParameters parameters,
95
        DataServerExplorerProviderServices providerServices) throws InitializeException {
96
        super(parameters, providerServices);
97
        this.providerServives = providerServices;
98
        this.parameters = parameters;
99

    
100
        getResourceProvider().addConsumer(this);
101
    }
102

    
103
    private ResourceProvider getResourceProvider() {
104
        if (this.resourceProvider == null) {
105
            ResourceManagerProviderServices manager =
106
                (ResourceManagerProviderServices) DALLocator.getResourceManager();
107

    
108
            if (StringUtils.isBlank(parameters.getConnectionString())) {
109
                try {
110
                    this.resourceProvider =
111
                        (FileResource) manager.createAddResource(FileResource.NAME,
112
                            new Object[] { this.parameters.getFile().getAbsolutePath() });
113
                } catch (InitializeException e) {
114
                    throw new ReadRuntimeException(getProviderName(), e);
115
                }
116
            } else {
117
                try {
118
                    this.resourceProvider =
119
                        (OGRResource) manager.createAddResource(OGRResource.NAME,
120
                            new Object[] { this.parameters.getConnectionString() });
121
                } catch (InitializeException e) {
122
                    throw new ReadRuntimeException(getProviderName(), e);
123
                }
124
            }
125
        }
126
        return this.resourceProvider;
127
    }
128

    
129
    protected synchronized DataSource getDataSource() throws OGRUnsupportedFormatException {
130
        if (this.dataSource == null) {
131
            // Prioritize connection string over file
132
            if (StringUtils.isNotBlank(this.parameters.getConnectionString())) {
133
                // Trying to open in update mode
134
                this.dataSource = ogr.Open(this.parameters.getConnectionString(), 1);
135

    
136
                if (this.dataSource == null) {
137
                    this.dataSource = ogr.Open(this.parameters.getConnectionString());
138
                    updateSupport = false;
139
                } else {
140
                    updateSupport = true;
141
                }
142

    
143
            } else if (this.parameters.getFile() != null && this.parameters.getFile().exists()) {
144

    
145
                // Trying to open in update mode
146
                this.dataSource = ogr.Open(this.parameters.getFile().getAbsolutePath(), 1);
147

    
148
                if (this.dataSource == null) {
149
                    this.dataSource = ogr.Open(this.parameters.getFile().getAbsolutePath());
150
                    updateSupport = false;
151
                } else {
152
                    updateSupport = true;
153
                }
154

    
155
            } else {
156
                throw new IllegalStateException(
157
                    "Invalid parameters. Connection string must not be blank or file must exists");
158
            }
159
        }
160

    
161
        if (this.dataSource == null) {
162

    
163
            if (StringUtils.isNotBlank(this.parameters.getConnectionString())) {
164
                throw new OGRUnsupportedFormatException(this.parameters.getConnectionString());
165
            }
166
        }
167

    
168
        return this.dataSource;
169
    }
170

    
171
    @SuppressWarnings("unchecked")
172
    protected List<Layer> getLayerList() {
173
        if (this.layerList == null) {
174
            this.layerList = (List<Layer>) getResourceProvider().execute(new ResourceAction() {
175

    
176
                @Override
177
                public Object run() throws Exception {
178
                    List<Layer> layers = new ArrayList<Layer>();
179

    
180
                    for (int i = 0; i < getDataSource().GetLayerCount(); i++) {
181
                        layers.add(getDataSource().GetLayer(i));
182
                    }
183

    
184
                    return layers;
185
                }
186
            });
187
        }
188
        return this.layerList;
189
    }
190

    
191
    private Boolean hasUpdateSupport() throws OGRUnsupportedFormatException {
192
        if (this.updateSupport == null) {
193
            // Open data source to check update support of driver
194
            getDataSource();
195
        }
196
        return this.updateSupport;
197
    }
198

    
199
    @Override
200
    public String getProviderName() {
201
        return NAME;
202
    }
203

    
204
    @Override
205
    public boolean canAdd() {
206

    
207
        return (boolean) getResourceProvider().execute(new ResourceAction() {
208

    
209
            @Override
210
            public Object run() throws Exception {
211
                return getDataSource().TestCapability(ogrConstants.ODsCCreateLayer)
212
                    && getDataSource().TestCapability(ogrConstants.ODsCDeleteLayer)
213
                    && hasUpdateSupport();
214
            }
215
        });
216
    }
217

    
218
    @Override
219
    public boolean canAdd(String storeName) throws DataException {
220
        return getDataStoreProviderNames().contains(storeName) && canAdd();
221
    }
222

    
223
    @SuppressWarnings("rawtypes")
224
    @Override
225
    public List list() throws DataException {
226
        return list(MODE_ALL);
227
    }
228

    
229
    @SuppressWarnings("rawtypes")
230
    @Override
231
    public List list(int mode) throws DataException {
232
        List<Layer> layerList = getLayerList();
233
        DataManager dataManager = DALLocator.getDataManager();
234
        
235
        List<OGRDataStoreParameters> parametersList = new ArrayList<OGRDataStoreParameters>();
236
        for (Layer layer : layerList) {
237
            
238
            OGRDataStoreParameters storeParameters =
239
                (OGRDataStoreParameters) dataManager.createStoreParameters(OGRDataStoreProvider.NAME);
240
            String connectionString = this.parameters.getConnectionString();
241
            File file = this.parameters.getFile();
242
            storeParameters.setConnectionString(connectionString);
243
            storeParameters.setFile(file);
244
            storeParameters.setLayerName(layer.GetName());
245
            parametersList.add(storeParameters);
246
        }
247
        return parametersList;
248
    }
249

    
250
    @Override
251
    public boolean add(String provider, final NewDataStoreParameters parameters,
252
        final boolean overwrite) throws DataException {
253

    
254
        if (canAdd()) {
255

    
256
            return (boolean) getResourceProvider().execute(new ResourceAction() {
257

    
258
                @Override
259
                public Object run() throws Exception {
260

    
261
                    if (parameters instanceof OGRNewDataStoreParameters) {
262
                        OGRNewDataStoreParameters ogrParameters =
263
                            (OGRNewDataStoreParameters) parameters;
264

    
265
                        String layerName = ogrParameters.getLayerName();
266
                        if (overwrite) {
267
                            for (int i = 0; i < getLayerList().size(); i++) {
268
                                if (getLayerList().get(i).GetName().equals(layerName)) {
269
                                    getDataSource().DeleteLayer(i);
270
                                }
271
                            }
272
                        } else {
273
                            for (Layer layer : getLayerList()) {
274
                                if (layer.GetName().equals(layerName)) {
275
                                    return false;
276
                                }
277
                            }
278
                        }
279

    
280
                        EditableFeatureType editableFeatureType =
281
                            ogrParameters.getDefaultFeatureType();
282

    
283
                        OGRConverter converter = new OGRConverter();
284

    
285
                        // If SRS is defined convert it to spatial reference
286
                        IProjection projection = editableFeatureType.getDefaultSRS();
287
                        SpatialReference srs = null;
288
                        if (projection != null) {
289
                            srs = new SpatialReference(projection.export(ICRSFactory.FORMAT_PROJ4));
290
                        }
291

    
292
                        // Convert to geometry type to OGR Geometry type
293
                        Integer ogrGeometryType = null;
294
                        if (editableFeatureType.getDefaultGeometryAttribute() != null) {
295
                            int geomType =
296
                                editableFeatureType.getDefaultGeometryAttribute().getGeomType()
297
                                    .getType();
298
                            ogrGeometryType = converter.convertToOGRGeomType(geomType);
299
                        }
300

    
301
                        // Create layer
302
                        Layer newlayer = null;
303
                        if (srs == null) {
304
                            newlayer = getDataSource().CreateLayer(layerName);
305
                        } else if (ogrGeometryType == null && srs != null) {
306
                            newlayer = getDataSource().CreateLayer(layerName, srs);
307
                        } else if (ogrGeometryType != null && srs != null) {
308
                            newlayer = getDataSource().CreateLayer(layerName, srs, ogrGeometryType);
309
                        }
310

    
311
                        List<FieldDefn> fields =
312
                            converter.convertFields(editableFeatureType.getNotEditableCopy());
313
                        for (FieldDefn fieldDefn : fields) {
314
                            newlayer.CreateField(fieldDefn);
315
                        }
316

    
317
                        List<GeomFieldDefn> geometryFields =
318
                            converter.convertGeometryFields(
319
                                editableFeatureType.getNotEditableCopy(), false);
320
                        for (GeomFieldDefn geomFieldDefn : geometryFields) {
321
                            newlayer.CreateGeomField(geomFieldDefn);
322
                        }
323
                        return true;
324
                    }
325
                    return false;
326
                }
327
            });
328
        }
329
        return false;
330
    }
331

    
332
    @Override
333
    public void remove(final DataStoreParameters parameters) throws DataException {
334

    
335
        if (canAdd()) {
336

    
337
            getResourceProvider().execute(new ResourceAction() {
338

    
339
                @Override
340
                public Object run() throws Exception {
341
                    if (parameters instanceof OGRNewDataStoreParameters) {
342
                        OGRNewDataStoreParameters ogrParameters =
343
                            (OGRNewDataStoreParameters) parameters;
344

    
345
                        String layerName = ogrParameters.getLayerName();
346
                        for (int i = 0; i < getLayerList().size(); i++) {
347
                            if (getLayerList().get(i).GetName().equals(layerName)) {
348
                                getDataSource().DeleteLayer(i);
349
                                return true;
350
                            }
351
                        }
352
                    }
353
                    return false;
354
                }
355
            });
356
        }
357
    }
358

    
359
    @Override
360
    public NewDataStoreParameters getAddParameters(String storeName) throws DataException {
361

    
362
        if (getDataStoreProviderNames().contains(storeName)) {
363
            OGRNewDataStoreParameters newParameters = new OGRNewDataStoreParameters();
364
            newParameters.setFile(this.parameters.getFile());
365
            newParameters.setConnectionString(this.parameters.getConnectionString());
366
            return newParameters;
367
        }
368

    
369
        return null;
370
    }
371

    
372
    @Override
373
    public DataServerExplorerParameters getParameters() {
374
        return parameters;
375
    }
376

    
377
    @SuppressWarnings("rawtypes")
378
    @Override
379
    public List getDataStoreProviderNames() {
380
        List<String> providerNames = new ArrayList<String>();
381
        providerNames.add(OGRDataStoreProvider.NAME);
382
        return providerNames;
383
    }
384

    
385
    @Override
386
    public void doDispose() {
387

    
388
        try {
389
            getDataSource().SyncToDisk();
390
            getDataSource().delete();
391
        } catch (OGRUnsupportedFormatException e) {
392
            LOG.warn("Can not dispose OGRDataExplorer", e);
393
        }
394

    
395
        this.dataSource = null;
396
        this.layerList = null;
397

    
398
        getResourceProvider().removeConsumer(this);
399
        this.resourceProvider = null;
400
    }
401

    
402
    @Override
403
    public DataServerExplorerProviderServices getServerExplorerProviderServices() {
404
        return providerServives;
405
    }
406

    
407
    @Override
408
    public boolean closeResourceRequested(ResourceProvider resource) {
409

    
410
        try {
411
            getDataSource().SyncToDisk();
412
            getDataSource().delete();
413
        } catch (OGRUnsupportedFormatException e) {
414
            LOG.warn(String.format("Can not close requested resource %1s", resource), e);
415
        }
416

    
417
        this.dataSource = null;
418
        this.layerList = null;
419
        return true;
420
    }
421

    
422
    @Override
423
    public void resourceChanged(ResourceProvider resource) {
424

    
425
        try {
426
            getDataSource().SyncToDisk();
427
            getDataSource().delete();
428
        } catch (OGRUnsupportedFormatException e) {
429
            LOG.warn("Can not sync to disk or release native resources to reopen data source", e);
430
        }
431

    
432
        this.dataSource = null;
433
        this.layerList = null;
434
    }
435

    
436
    @Override
437
    public DataStoreParameters get(String name) throws DataException {
438
        // "name" es un nombre de fichero sin path.
439
        
440
        // No tengo nada clara esta implementacion
441
        OGRDataStoreParameters params = new OGRDataStoreParameters();
442
        //
443
        // Copiamos los paramametros que se llamen igual entre el explorer y
444
        // el DataStoreParametes
445
        for( DynField field : params.getDynClass().getDynFields() ) {
446
            String fieldName = field.getName();
447
            if( parameters.hasDynValue(fieldName) ) {
448
                params.setDynValue(fieldName, parameters.getDynValue(fieldName));
449
            }
450
        }
451
        // Si el file es una carpeta asignamos como file el fichero name que haya
452
        // en ella
453
        // Si el file es un fichero cogemos el fichero name que se encuentre en
454
        // su misma carpeta.
455
        if( parameters.getFile().isDirectory() ) {
456
            params.setFile(new File(parameters.getFile(),name));
457
        } else {
458
            params.setFile(new File(parameters.getFile().getParentFile(),name));
459
        }
460
        // Usamos como layer el nombre del fichero pasado como parametro.
461
        params.setLayerName(name);
462
        return params;
463
    }
464
}