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 / OGRFilesystemServerProvider.java @ 368

History | View | Annotate | Download (15 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.List;
28
import java.util.Vector;
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.Driver;
35
import org.gdal.ogr.FieldDefn;
36
import org.gdal.ogr.GeomFieldDefn;
37
import org.gdal.ogr.Layer;
38
import org.gdal.ogr.ogr;
39
import org.gdal.ogr.ogrConstants;
40
import org.gdal.osr.SpatialReference;
41
import org.gvsig.fmap.dal.DALLocator;
42
import org.gvsig.fmap.dal.DataStoreParameters;
43
import org.gvsig.fmap.dal.NewDataStoreParameters;
44
import org.gvsig.fmap.dal.exception.CreateException;
45
import org.gvsig.fmap.dal.exception.DataException;
46
import org.gvsig.fmap.dal.exception.InitializeException;
47
import org.gvsig.fmap.dal.exception.RemoveException;
48
import org.gvsig.fmap.dal.feature.EditableFeatureType;
49
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
50
import org.gvsig.fmap.dal.resource.ResourceAction;
51
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
52
import org.gvsig.fmap.dal.resource.file.FileResource;
53
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
54
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
55
import org.gvsig.fmap.dal.serverexplorer.filesystem.impl.AbstractFilesystemServerExplorerProvider;
56
import org.gvsig.fmap.dal.serverexplorer.filesystem.spi.FilesystemServerExplorerProvider;
57
import org.gvsig.fmap.dal.serverexplorer.filesystem.spi.FilesystemServerExplorerProviderServices;
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 OGRFilesystemServerProvider extends AbstractFilesystemServerExplorerProvider implements
67
    FilesystemServerExplorerProvider, ResourceConsumer {
68

    
69
    private static final Logger LOG = LoggerFactory.getLogger(OGRFilesystemServerProvider.class);
70

    
71
    private FilesystemServerExplorerProviderServices serverExplorer;
72

    
73
    @Override
74
    public String getDataStoreProviderName() {
75
        return OGRDataStoreProvider.NAME;
76
    }
77

    
78
    @Override
79
    public String getDescription() {
80
        return OGRDataStoreProvider.DESCRIPTION;
81
    }
82

    
83
    @Override
84
    public boolean accept(File pathname) {
85
        if (pathname.isFile() && ogr.Open(pathname.getAbsolutePath(), 1)!=null){
86
            return true;
87
        }
88
        return false;
89
    }
90

    
91
    @Override
92
    public boolean closeResourceRequested(ResourceProvider resource) {
93
        // Do nothing
94
        return true;
95
    }
96

    
97
    @Override
98
    public void resourceChanged(ResourceProvider resource) {
99
        // Do nothing
100
    }
101

    
102
    @Override
103
    public void initialize(FilesystemServerExplorerProviderServices serverExplorer) {
104
        this.serverExplorer = serverExplorer;
105
    }
106

    
107
    @Override
108
    public boolean canCreate() {
109
        throw new UnsupportedOperationException();
110
    }
111

    
112
    @Override
113
    public void create(NewDataStoreParameters parameters, boolean overwrite) throws CreateException {
114

    
115
        if (parameters instanceof OGRNewDataStoreParameters) {
116

    
117
            final OGRNewDataStoreParameters newOGRDataStoreParameters =
118
                (OGRNewDataStoreParameters) parameters;
119

    
120
            final File file = newOGRDataStoreParameters.getFile();
121

    
122
            if (file.isFile() && file.exists()) {
123
                if (overwrite) {
124
                    // Deleting existing file
125
                    try {
126
                        this.remove(newOGRDataStoreParameters);
127
                    } catch (RemoveException e) {
128
                        throw new CreateException("Can not overwrite file", e);
129
                    }
130
                } else {
131
                    throw new CreateException(file.getAbsolutePath(), new IllegalArgumentException(
132
                        String.format("%1s exists and overwrite option is false",
133
                            file.getAbsolutePath())));
134
                }
135
            }
136

    
137
            try {
138
                final FileResource resource =
139
                    (FileResource) serverExplorer.getServerExplorerProviderServices()
140
                        .createResource(FileResource.NAME, new Object[] { file.getAbsolutePath() });
141

    
142
                resource.addConsumer(this);
143
                resource.execute(new ResourceAction() {
144

    
145
                    @Override
146
                    public Object run() throws Exception {
147

    
148
                        String driverName = newOGRDataStoreParameters.getDriverName();
149
                        Driver driver = ogr.GetDriverByName(driverName);
150
                        if (driver == null || StringUtils.isBlank(driverName)) {
151
                            throw new IllegalArgumentException(
152
                                "Driver name can not be blank and driver must exist.");
153
                        }
154

    
155
                        List options = newOGRDataStoreParameters.getDatasetCreationOptions();
156
                        DataSource dataSource = null;
157
                        if (options == null) {
158
                            dataSource =
159
                                driver.CreateDataSource(resource.getFile().getAbsolutePath());
160
                        } else {
161
                            dataSource =
162
                                driver.CreateDataSource(resource.getFile().getAbsolutePath(),
163
                                    new Vector<String>(options));
164
                        }
165

    
166
                        if (dataSource == null) {
167
                            LOG.error("Can not open datasource from {} and {} options", resource
168
                                .getFile().getAbsoluteFile(), options);
169
                            throw new ResourceExecuteException(resource, null);
170
                        }
171

    
172
                        String layerName = newOGRDataStoreParameters.getLayerName();
173
                        if (StringUtils.isBlank(layerName)) {
174
                            layerName = file.getName();
175
                        }
176

    
177
                        // Check if layer already exist at dataSource
178
                        Layer existingLayer = dataSource.GetLayerByName(layerName);
179
                        if (existingLayer != null) {
180
                            for (int i = 0; i < dataSource.GetLayerCount(); i++) {
181
                                if (dataSource.GetLayerByIndex(i).GetName()
182
                                    .equals(existingLayer.GetName())) {
183
                                    dataSource.DeleteLayer(i); // Delete it if
184
                                                               // exist
185
                                    break;
186
                                }
187
                            }
188
                        }
189

    
190
                        OGRConverter converter = new OGRConverter();
191

    
192
                        FeatureAttributeDescriptor geometryAttribute =
193
                            newOGRDataStoreParameters.getDefaultFeatureType()
194
                                .getDefaultGeometryAttribute();
195
                        Integer ogrType = null;
196
                        SpatialReference srs = null;
197

    
198
                        // Determinate if featureType has SRS and geometry type
199
                        // defined
200
                        if (geometryAttribute != null) {
201
                            int type = geometryAttribute.getGeomType().getType();
202
                            ogrType = converter.convertToOGRGeomType(type);
203

    
204
                            IProjection projection = geometryAttribute.getSRS();
205
                            if (projection == null && newOGRDataStoreParameters.getCRS() != null) {
206
                                projection = newOGRDataStoreParameters.getCRS();
207
                                srs =
208
                                    new SpatialReference(projection.export(ICRSFactory.FORMAT_WKT));
209
                            }
210
                        }
211

    
212
                        Layer layer = null;
213
                        if (srs == null) {
214
                            layer = dataSource.CreateLayer(layerName);
215
                        } else if (ogrType == null) {
216
                            layer = dataSource.CreateLayer(layerName, srs);
217
                        } else {
218
                            layer = dataSource.CreateLayer(layerName, srs, ogrType);
219
                        }
220

    
221
                        // Creating fields
222
                        if (layer.TestCapability(ogrConstants.OLCCreateField)) {
223
                            List<FieldDefn> fields =
224
                                converter.convertFields(newOGRDataStoreParameters
225
                                    .getDefaultFeatureType());
226
                            for (FieldDefn fieldDefn : fields) {
227
                                layer.CreateField(fieldDefn);
228
                            }
229
                        } else {
230
                            LOG.warn("{} driver does not support creation of fields",
231
                                driver.getName());
232
                        }
233

    
234
                        // Creating additional geometry fields, skipping default
235
                        // geometry column.
236
                        // When a OGR Layer is created, if feature type has
237
                        // default geometry column
238
                        // it will be set when layer is created
239
                        if (layer.TestCapability(ogrConstants.OLCCreateGeomField)) {
240
                            List<GeomFieldDefn> geomFields =
241
                                converter.convertGeometryFields(
242
                                    newOGRDataStoreParameters.getDefaultFeatureType(), false);
243
                            for (GeomFieldDefn geomFieldDefn : geomFields) {
244
                                layer.CreateGeomField(geomFieldDefn);
245
                            }
246
                        } else {
247
                            LOG.warn(
248
                                "{} driver does not support creation of geometry fields, only default"
249
                                    + " OGR geometry field has been created", driver.getName());
250
                        }
251

    
252
                        // Release native resource to close file
253
                        dataSource.delete();
254
                        return null;
255
                    }
256
                });
257
            } catch (InitializeException e) {
258
                throw new CreateException("Can not create file resource to create it", e);
259
            }
260
        }
261

    
262
    }
263

    
264
    @Override
265
    public NewDataStoreParameters getCreateParameters() throws DataException {
266
        OGRNewDataStoreParameters newParameters = new OGRNewDataStoreParameters();
267
        EditableFeatureType editableFeatureType = DALLocator.getDataManager().createFeatureType();
268
        newParameters.setDefaultFeatureType(editableFeatureType);
269
        return newParameters;
270
    }
271

    
272
    @Override
273
    public void remove(DataStoreParameters parameters) throws RemoveException {
274

    
275
        if (parameters instanceof OGRNewDataStoreParameters) {
276

    
277
            final OGRNewDataStoreParameters newOGRDataStoreParameters =
278
                (OGRNewDataStoreParameters) parameters;
279

    
280
            File file = newOGRDataStoreParameters.getFile();
281

    
282
            if (!file.exists() && !file.canWrite()) {
283
                throw new RemoveException(file.getAbsolutePath(), new IllegalArgumentException(
284
                    String.format("%1s does not exist", file.getAbsolutePath())));
285
            }
286

    
287
            try {
288
                final FileResource resource =
289
                    (FileResource) serverExplorer.getServerExplorerProviderServices()
290
                        .createResource(FileResource.NAME, new Object[] { file.getAbsolutePath() });
291

    
292
                resource.addConsumer(this);
293
                resource.execute(new ResourceAction() {
294

    
295
                    @Override
296
                    public Object run() throws Exception {
297
                        resource.closeRequest();
298
                        String driverName = newOGRDataStoreParameters.getDriverName();
299
                        Driver driver = ogr.GetDriverByName(driverName);
300
                        if (driver == null || StringUtils.isBlank(driverName)) {
301
                            LOG.warn("Driver name is blank or driver null, trying to get it opening datasource of resource");
302
                            DataSource dataSource = ogr.Open(resource.getFile().getAbsolutePath());
303
                            if (dataSource == null) {
304
                                LOG.error("Can not determiante driver to remove resource");
305
                                throw new RemoveException(resource.getName(), null);
306
                            }
307
                            driver = dataSource.GetDriver();
308
                        }
309

    
310
                        if (driver.TestCapability(ogrConstants.ODrCDeleteDataSource)) {
311
                            driver.DeleteDataSource(resource.getFile().getAbsolutePath());
312
                        } else {
313
                            LOG.error("{} driver does not support delete data source",
314
                                driver.getName());
315
                            throw new RemoveException(resource.getFile().getAbsolutePath(), null);
316
                        }
317
                        return null;
318
                    }
319
                });
320
                resource.addConsumer(this);
321
            } catch (InitializeException e) {
322
                throw new RemoveException("Can not create file resource to remove it", e);
323
            }
324
        }
325
    }
326

    
327
    @Override
328
    public boolean canCreate(NewDataStoreParameters parameters) {
329
        if (parameters instanceof OGRNewDataStoreParameters) {
330

    
331
            OGRNewDataStoreParameters newOGRDataStoreParameters =
332
                (OGRNewDataStoreParameters) parameters;
333

    
334
            String driverName = newOGRDataStoreParameters.getDriverName();
335
            Driver driver = null;
336
            if (StringUtils.isNotBlank(driverName)) {
337
                driver = ogr.GetDriverByName(driverName);
338
            } else {
339
                return false;
340
            }
341

    
342
            if (driver.TestCapability(ogrConstants.ODrCCreateDataSource)
343
                && driver.TestCapability(ogrConstants.OLCCreateField)) {
344

    
345
                File file = newOGRDataStoreParameters.getFile();
346
                if (file != null && file.canWrite()) {
347
                    return true;
348
                }
349
            }
350
        }
351
        return false;
352
    }
353
}