Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extWFS2 / src / org / gvsig / fmap / dal / store / wfs / WFSStoreProvider.java @ 32880

History | View | Annotate | Download (13.4 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.wfs;
29

    
30
import java.io.IOException;
31
import java.util.List;
32
import java.util.Vector;
33

    
34
import org.cresques.cts.ICoordTrans;
35
import org.cresques.cts.IProjection;
36
import org.gvsig.fmap.crs.CRSFactory;
37
import org.gvsig.fmap.dal.DALLocator;
38
import org.gvsig.fmap.dal.DataManager;
39
import org.gvsig.fmap.dal.DataServerExplorer;
40
import org.gvsig.fmap.dal.DataStoreParameters;
41
import org.gvsig.fmap.dal.exception.DataException;
42
import org.gvsig.fmap.dal.exception.InitializeException;
43
import org.gvsig.fmap.dal.exception.OpenException;
44
import org.gvsig.fmap.dal.exception.ReadException;
45
import org.gvsig.fmap.dal.feature.FeatureQuery;
46
import org.gvsig.fmap.dal.feature.FeatureStore;
47
import org.gvsig.fmap.dal.feature.FeatureType;
48
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
49
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
50
import org.gvsig.fmap.dal.serverexplorer.wfs.WFSServerExplorer;
51
import org.gvsig.fmap.dal.serverexplorer.wfs.WFSServerExplorerParameters;
52
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
53
import org.gvsig.fmap.dal.store.gpe.GPEStoreProvider;
54
import org.gvsig.fmap.geom.Geometry;
55
import org.gvsig.fmap.geom.GeometryLocator;
56
import org.gvsig.fmap.geom.GeometryManager;
57
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
58
import org.gvsig.fmap.geom.Geometry.TYPES;
59
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
60
import org.gvsig.fmap.geom.primitive.Envelope;
61
import org.gvsig.remoteclient.ogc.OGCClientOperation;
62
import org.gvsig.remoteclient.utils.BoundaryBox;
63
import org.gvsig.remoteclient.wfs.WFSClient;
64
import org.gvsig.remoteclient.wfs.WFSFeature;
65
import org.gvsig.remoteclient.wfs.WFSStatus;
66
import org.gvsig.remoteclient.wfs.exceptions.WFSException;
67
import org.gvsig.remoteclient.wfs.filters.filterencoding.FilterEncoding;
68
import org.gvsig.remoteclient.wfs.schema.XMLElement;
69
import org.gvsig.tools.ToolsLocator;
70
import org.gvsig.tools.dynobject.DynClass;
71
import org.gvsig.tools.dynobject.DynObjectManager;
72
import org.gvsig.tools.evaluator.EvaluatorFieldValue;
73
import org.gvsig.tools.evaluator.EvaluatorFieldValueMatch;
74
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
75
import org.slf4j.Logger;
76
import org.slf4j.LoggerFactory;
77

    
78

    
79
/**
80
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
81
 */
82
public class WFSStoreProvider extends GPEStoreProvider implements
83
ResourceConsumer {
84
        private static final Logger logger = LoggerFactory.getLogger(WFSStoreProvider.class);
85
        public static String NAME = "WFSStore";
86
        public static String DESCRIPTION = "WFS store to load WFS resources";
87
        private static final String METADATA_DEFINITION_NAME = "WFSStore";
88
        protected static DynClass DYNCLASS = null;
89
        private IProjection projection;        
90

    
91
        boolean isFilterByAreaSupported = true;
92

    
93
        //WFS Parameters
94
        private WFSClient wfsClient;
95
        private WFSStatus wfsStatus;
96

    
97
        public WFSStoreProvider(DataStoreParameters params,
98
                        DataStoreProviderServices storeServices)
99
        throws InitializeException {
100
                super(params, storeServices, ToolsLocator.getDynObjectManager()
101
                                .createDynObject(DYNCLASS));                
102
        }
103

    
104
        protected void retrieveFile() throws InitializeException{
105
                try {
106
                        WFSStoreParameters wfsParameters = getWFSParameters();
107
                        try {
108
                                if (wfsParameters.getVersion() == null){
109
                                        wfsClient = new WFSClient(wfsParameters.getUrl());
110
                                        wfsParameters.setVersion(wfsClient.getVersion());
111
                                }else{
112
                                        wfsClient = new WFSClient(wfsParameters.getUrl(), wfsParameters.getVersion());
113
                                }
114
                        } catch (IOException e) {
115
                                throw new InitializeException(e);
116
                        }
117
                        wfsStatus = new WFSStatus( wfsParameters.getFeatureType(),
118
                                        wfsParameters.getFeaturePrefix());
119
                        wfsStatus.setNamespace(wfsParameters.getFeatureNamespace());
120
                        wfsStatus.setFields(wfsParameters.getFields());
121
                        //wfsStatus.setFilterQuery(wfsParameters.getFilterEncoding());
122
                        wfsStatus.setTimeout(wfsParameters.getTimeOut());
123
                        wfsStatus.setBuffer(wfsParameters.getMaxFeatures());
124
                        wfsStatus.setUserName(wfsParameters.getUser());
125
                        wfsStatus.setPassword(wfsParameters.getPassword());
126

    
127
                        //Setting the envelope for the layer
128
                        wfsClient.getCapabilities(wfsStatus, false, null);
129

    
130
                        Envelope envelope = calculateFullEnvelope();
131
                        if (envelope != null){
132
                                this.setDynValue("Envelope", envelope);
133
                        }
134

    
135
                        m_Fich = wfsClient.getFeature(wfsStatus, true, null);
136
                } catch (WFSException e) {
137
                        throw new InitializeException("Impossible to retrieve the file", e);
138
                }
139
        }
140

    
141
        private Envelope calculateFullEnvelope() {
142
                GeometryManager geometryManager = GeometryLocator.getGeometryManager();
143
        
144
                Object obj = wfsClient.getFeatures().get(wfsStatus.getFeatureName());
145
                try{
146
                        if (obj != null){
147
                                WFSFeature feature = (WFSFeature)obj;
148
                                if (feature.getSrs().size() > 0){
149
                                        String srs = (String)feature.getSrs().get(0);
150
                                        BoundaryBox boundaryBox = feature.getBbox("srs");
151
                                        if (boundaryBox == null)
152
                                        {
153
                                                boundaryBox = feature.getBbox(getEPSGCode("srs"));
154
                                        }        
155
                                        //The projection is found
156
                                        if (boundaryBox != null){
157
                                                return geometryManager.createEnvelope(boundaryBox.getXmin(),
158
                                                                boundaryBox.getYmin(), boundaryBox.getXmax(), boundaryBox.getYmax(), SUBTYPES.GEOM2D);
159
                                        }
160
                                        //Check if there is a latlon envelope
161
                                        boundaryBox = feature.getLatLonBbox();
162
                                        if (boundaryBox != null){
163
                                                Envelope envelope = geometryManager.createEnvelope(boundaryBox.getXmin(),
164
                                                                boundaryBox.getYmin(), boundaryBox.getXmax(), boundaryBox.getYmax(), SUBTYPES.GEOM2D);
165
                                                IProjection projection = CRSFactory.getCRS(getEPSGCode(srs));
166
                                                if (projection != null){
167
                                                        ICoordTrans coordTrans = projection.getCT(CRSFactory.getCRS(getEPSGCode("EPSG:4326")));
168
                                                        return envelope.convert(coordTrans);
169
                                                }                                        
170
                                        }
171
                                }
172
                        }
173
                }catch(CreateEnvelopeException e){
174
                        logger.error("Impossible to create an envelope", e);
175
                }
176
                return null;
177
        }
178

    
179
        private WFSStoreParameters getWFSParameters() {
180
                return (WFSStoreParameters) getParameters();
181
        }
182

    
183
        /* (non-Javadoc)
184
         * @see org.gvsig.fmap.dal.store.gpe.GPEStoreProvider#open()
185
         */
186
        public void open() throws OpenException {
187
                super.open();
188
                try {
189
                        List featureTypes = this.getFeatureStore().getFeatureTypes();
190
                        for (int i=0 ; i<featureTypes.size() ; i++){
191
                                FeatureType featureType = (FeatureType)featureTypes.get(i);
192

    
193
                        }
194
                } catch (DataException e) {
195
                        throw new OpenException("Reading the geometry type", e);
196
                }
197
        }
198

    
199
        protected static void registerMetadataDefinition() {
200
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
201
                DynClass dynClass;
202
                if (DYNCLASS == null) {
203

    
204
                        dynClass = dynman.add(METADATA_DEFINITION_NAME);
205
                        dynClass.extend(dynman.get(FeatureStore.METADATA_DEFINITION_NAME));
206

    
207
                        DYNCLASS = dynClass;
208
                }
209

    
210
        }
211

    
212

    
213
        /* (non-Javadoc)
214
         * @see org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider#getExplorer()
215
         */
216
        public DataServerExplorer getExplorer() throws ReadException {
217
                DataManager manager = DALLocator.getDataManager();
218
                WFSServerExplorerParameters params;
219
                try {
220
                        params = (WFSServerExplorerParameters) manager
221
                        .createServerExplorerParameters(WFSServerExplorer.NAME);
222
                        params.setUrl(wfsClient.getHost());
223
                        return manager.openServerExplorer(WFSServerExplorer.NAME,params);
224
                } catch (Exception e) {
225
                        throw new ReadException(this.getName(), e);
226
                }
227
        }
228

    
229

    
230
        /* (non-Javadoc)
231
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getName()
232
         */
233
        public String getName() {
234
                return NAME;
235
        }
236

    
237
        /* (non-Javadoc)
238
         * @see org.gvsig.fmap.dal.store.gpe.GPEStoreProvider#createSet(org.gvsig.fmap.dal.feature.FeatureQuery)
239
         */
240
        @Override
241
        public FeatureSetProvider createSet(FeatureQuery query)
242
        throws DataException {
243
                return createSet(query, null);
244
        }
245

    
246
        /* (non-Javadoc)
247
         * @see org.gvsig.fmap.dal.store.gpe.GPEStoreProvider#createSet(org.gvsig.fmap.dal.feature.FeatureQuery, org.gvsig.fmap.dal.feature.FeatureType)
248
         */
249
        @Override
250
        public FeatureSetProvider createSet(FeatureQuery query,
251
                        FeatureType featureType) throws DataException {
252
                //If it is possible to execute a spatial query...
253
                if (query.getFilter() != null){
254
                        executeSpatialQuery(query);
255
                }else{
256
                        executeQuery();   
257
                }
258
                isOpen = false;
259
                open();
260
                return super.createSet(query, featureType);
261
        }
262

    
263
        /**
264
         * It executes a wfs Query without spatial filter
265
         * @throws DataException
266
         */
267
        private void executeQuery() throws DataException{
268
                try{
269
                        wfsStatus.setResultType(WFSStatus.RESULTYPE_RESULTS);
270
                        m_Fich = wfsClient.getFeature(wfsStatus, true, null);
271
                } catch (WFSException e) {
272
                        throw new InitializeException("Impossible to retrieve the file", e);
273
                }
274
        }
275

    
276
        /**
277
         * Executes a new query sending the FilterEncoding request to the server
278
         * @param query
279
         * The Query to send
280
         * @throws InitializeException
281
         * If there is a problem with the request or the parsing process
282
         */
283
        private boolean executeSpatialQuery(FeatureQuery query) throws DataException{
284
                EvaluatorFieldsInfo fieldsInfo = query.getFilter().getFieldsInfo();
285
                String[] fields = fieldsInfo.getFieldNames();
286
                for (int i=0 ; i<fields.length ; i++){
287
                        EvaluatorFieldValue[] evaluatorFieldValues = fieldsInfo.getFieldValues(fields[i]);
288
                        for (int j=0 ; j<evaluatorFieldValues.length ; j++){                                
289
                                if (EvaluatorFieldValue.MATCH == evaluatorFieldValues[j].getType()){
290
                                        EvaluatorFieldValueMatch evaluatorFieldValueMatch = (EvaluatorFieldValueMatch)evaluatorFieldValues[j];
291
                                        Object area = evaluatorFieldValueMatch.getValue();
292
                                        if (area instanceof Envelope){
293
                                                executeSpatialQueryFromEnvelope(evaluatorFieldValueMatch.getFieldName(),
294
                                                                (Envelope)area);
295
                                                return true;
296
                                        }else if (area instanceof Geometry){
297
                                                executeSpatialQueryFromGeometry(evaluatorFieldValueMatch.getFieldName(),
298
                                                                (Geometry)area);
299
                                                return true;
300
                                        }
301
                                }
302
                        }                        
303
                }
304
                return false;
305
        }
306

    
307
        private void executeSpatialQueryFromGeometry(String the_geom, Geometry geometry) throws DataException{
308
                wfsStatus.setFilterByArea(geometry, the_geom, projection.getAbrev(), 
309
                                FilterEncoding.GEOMETRIC_OPERATOR_CONTAINS);
310
                executeSpatialQuery();
311
        }
312

    
313
        private void executeSpatialQueryFromEnvelope(String the_geom, Envelope envelope) throws DataException{
314
                wfsStatus.setFilterByArea(envelope, the_geom, projection.getAbrev(), 
315
                                FilterEncoding.GEOMETRIC_OPERATOR_CONTAINS);                
316
                executeSpatialQuery();
317
        }
318

    
319
        private void executeSpatialQuery() throws DataException{
320
                try {
321
                        wfsStatus.setProtocol(OGCClientOperation.PROTOCOL_POST);
322
                        //If it is not possible to calculate the 
323
                        wfsStatus.setResultType(WFSStatus.RESULTYPE_RESULTS);
324
                        m_Fich = wfsClient.getFeature(wfsStatus, true, null);
325
                } catch (WFSException e) {
326
                        throw new InitializeException("Impossible to retrieve the file", e);
327
                }
328
        }                
329

    
330
        public Object getSourceId() {
331
                StringBuffer sourceID = new StringBuffer(getWFSParameters().getUrl());
332
                sourceID.append("_" + getWFSParameters().getFeatureType());
333
                int hash = sourceID.hashCode();
334
                if (sourceID.length() > 60){
335
                        return sourceID.substring(0, 60) + "_" + hash;
336
                }else{
337
                        return sourceID.toString() + "_" + hash;
338
                }
339
        }
340

    
341
        protected IProjection getSRS(){
342
                if (projection == null){
343
                        try {
344
                                wfsClient.getCapabilities(wfsStatus, false, null);
345
                                wfsClient.describeFeatureType(wfsStatus, false, null);
346
                                WFSFeature feature = (WFSFeature) wfsClient.getFeatures().get(wfsStatus.getFeatureName());        
347
                                if (feature.getSrs().size() > 0){
348
                                        projection = CRSFactory.getCRS(getEPSGCode((String)feature.getSrs().get(0)));
349
                                }                
350
                        } catch (WFSException e) {                        
351
                                logger.error("Error retrieving the feature type");
352
                        }        
353
                }
354
                return projection;
355
        }
356

    
357
        private String getEPSGCode(String srs){
358
                if (srs == null){
359
                        return null;
360
                }
361
                if (srs.startsWith("urn:x-ogc:def:crs:")){
362
                        String newString = srs.substring(srs.lastIndexOf(":") + 1, srs.length());
363
                        if (srs.indexOf("EPSG") > 0){
364
                                if (newString.indexOf("EPSG") < 0){
365
                                        newString = "EPSG:" + newString;
366
                                }
367
                        }
368
                        return newString;                        
369
                }
370
                if (srs.toLowerCase().startsWith("crs:")){
371
                        return srs.substring(4, srs.length());
372
                }
373
                return srs;
374
        }                
375

    
376
        protected int getGeometryType() {
377
                WFSFeature feature = (WFSFeature) wfsClient.getFeatures().get(wfsStatus.getFeatureName());        
378
                Vector field = feature.getFields();
379
                if (field.size() > 0){
380
                        XMLElement rootElement = (XMLElement)field.get(0);
381
                        Vector children = rootElement.getChildren();
382
                        for (int i=0 ; i<children.size() ; i++){
383
                                XMLElement child = (XMLElement)children.get(i);
384
                                String type = child.getEntityType().getName();
385
                                if (type != null){
386
                                        int index = type.indexOf(":");
387
                                        if (index > -1){
388
                                                type = type.substring(index+1);
389
                                        }
390
                                        Object obj = xmlSchemaManager.getApplicationGeometryTypeByFormat("gml", type);
391
                                        if (obj != null){
392
                                                return (Integer)obj;
393
                                        }        
394
                                }
395
                        }
396
                }
397
                return TYPES.GEOMETRY;
398
        }
399
}
400