Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2020 / libraries / libRemoteServices / src / org / gvsig / remoteclient / wfs / WFSProtocolHandler.java @ 33910

History | View | Annotate | Download (14.5 KB)

1 29650 jpiera
package org.gvsig.remoteclient.wfs;
2 4887 jorpiell
3
import java.io.File;
4
import java.net.URL;
5 31835 jpiera
import java.util.ArrayList;
6 4887 jorpiell
import java.util.Hashtable;
7 5368 jorpiell
import java.util.Set;
8 17849 jmvivo
import java.util.StringTokenizer;
9 4887 jorpiell
import java.util.Vector;
10
11 33738 jpiera
import org.kxml2.io.KXmlParser;
12
13
import org.gvsig.compat.net.ICancellable;
14 29650 jpiera
import org.gvsig.remoteclient.ogc.OGCProtocolHandler;
15
import org.gvsig.remoteclient.ogc.OGCServiceInformation;
16
import org.gvsig.remoteclient.utils.CapabilitiesTags;
17
import org.gvsig.remoteclient.wfs.edition.WFSTTransaction;
18
import org.gvsig.remoteclient.wfs.exceptions.WFSException;
19
import org.gvsig.remoteclient.wfs.request.WFSDescribeFeatureTypeRequest;
20
import org.gvsig.remoteclient.wfs.request.WFSGetFeatureRequest;
21
import org.gvsig.remoteclient.wfs.request.WFSTLockFeatureRequest;
22
import org.gvsig.remoteclient.wfs.schema.GMLTags;
23 4887 jorpiell
24
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
25
 *
26
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
27
 *
28
 * This program is free software; you can redistribute it and/or
29
 * modify it under the terms of the GNU General Public License
30
 * as published by the Free Software Foundation; either version 2
31
 * of the License, or (at your option) any later version.
32
 *
33
 * This program is distributed in the hope that it will be useful,
34
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36
 * GNU General Public License for more details.
37
 *
38
 * You should have received a copy of the GNU General Public License
39
 * along with this program; if not, write to the Free Software
40
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
41
 *
42
 * For more information, contact:
43
 *
44
 *  Generalitat Valenciana
45
 *   Conselleria d'Infraestructures i Transport
46
 *   Av. Blasco Ib??ez, 50
47
 *   46010 VALENCIA
48
 *   SPAIN
49
 *
50
 *      +34 963862235
51
 *   gvsig@gva.es
52
 *      www.gvsig.gva.es
53
 *
54
 *    or
55
 *
56
 *   IVER T.I. S.A
57
 *   Salamanca 50
58
 *   46005 Valencia
59
 *   Spain
60
 *
61
 *   +34 963163400
62
 *   dac@iver.es
63
 */
64
/* CVS MESSAGES:
65
 *
66
 * $Id$
67
 * $Log$
68 13912 jaume
 * Revision 1.11  2007-09-20 09:30:12  jaume
69
 * removed unnecessary imports
70
 *
71
 * Revision 1.10  2007/02/09 14:11:01  jorpiell
72 10246 jorpiell
 * Primer piloto del soporte para WFS 1.1 y para WFS-T
73
 *
74
 * Revision 1.9  2007/01/12 13:09:42  jorpiell
75 9709 jorpiell
 * added searches by area
76
 *
77
 * Revision 1.8  2006/10/10 12:52:28  jorpiell
78 8017 jorpiell
 * Soporte para features complejas.
79
 *
80
 * Revision 1.7  2006/06/21 12:53:03  jorpiell
81 5950 jorpiell
 * Se tienen en cuanta el n?mero de features
82
 *
83
 * Revision 1.6  2006/06/14 08:46:07  jorpiell
84 5830 jorpiell
 * Se tiene en cuanta la opcion para refrescar las capabilities
85
 *
86
 * Revision 1.5  2006/06/14 07:54:18  jorpiell
87 5821 jorpiell
 * Se parsea el online resource que antes se ignoraba
88
 *
89
 * Revision 1.4  2006/05/30 13:58:03  jaume
90 5536 jaume
 * cancelable downloads
91
 *
92
 * Revision 1.3  2006/05/23 13:23:13  jorpiell
93 5368 jorpiell
 * Se ha cambiado el final del bucle de parseado y se tiene en cuenta el online resource
94
 *
95
 * Revision 1.2  2006/04/20 16:39:16  jorpiell
96 4912 jorpiell
 * A?adida la operacion de describeFeatureType y el parser correspondiente.
97
 *
98
 * Revision 1.1  2006/04/19 12:51:35  jorpiell
99 4887 jorpiell
 * A?adidas algunas de las clases del servicio WFS
100
 *
101
 *
102
 */
103
/**
104
 * @author Jorge Piera Llodr? (piera_jor@gva.es)
105
 */
106
public abstract class WFSProtocolHandler extends OGCProtocolHandler {
107
        /**
108 18271 jpiera
         * WFS metadata
109 4887 jorpiell
         */
110 18271 jpiera
        protected WFSServiceInformation serviceInfo = new WFSServiceInformation();
111 4912 jorpiell
        protected Hashtable features = new Hashtable();
112
        protected String currentFeature = null;
113 10246 jorpiell
        private int numberOfErrors = 0;
114 17849 jmvivo
115 18271 jpiera
        /**
116 31835 jpiera
         * This class contains all the data that the library is able
117
         * to retrieve of the server for all the requests.
118
         */
119
        protected ArrayList wfsRequestInformations = new ArrayList();
120
121
        /**
122 18271 jpiera
         * Clear the connection
123 17849 jmvivo
         */
124 18271 jpiera
        private void clear() {
125
                features.clear();
126
                serviceInfo.clear();
127 17849 jmvivo
        }
128
129 4887 jorpiell
        /**
130 18271 jpiera
         * <p>Builds a GetCapabilities request that is sent to the WFS
131
         * the response will be parse to extract the data needed by the
132
         * WFS client</p>
133
         */
134
        public void getCapabilities(WFSStatus status,boolean override, ICancellable cancel) throws WFSException {
135
                URL request = null;
136
                try {
137
                        request = new URL(buildCapabilitiesRequest(status));
138
                        if (override){
139 33738 jpiera
                            downloader.removeURL(request);
140 18271 jpiera
                        }
141 33738 jpiera
                        File f = downloader.downloadFile(request,"wfs_capabilities.xml", cancel);
142 18271 jpiera
                        if (f == null)
143
                                return;
144
                        clear();
145
                        parseCapabilities(f);
146
                } catch (Exception e){
147
                        throw new WFSException(e);
148
                }
149
        }
150 5830 jorpiell
151 18271 jpiera
        /**
152
         * @return
153
         */
154
        private String buildCapabilitiesRequest(WFSStatus status) {
155
                StringBuffer req = new StringBuffer();
156 4887 jorpiell
                String symbol = null;
157 18271 jpiera
158 4887 jorpiell
                String onlineResource;
159
                if (status == null || status.getOnlineResource() == null)
160
                        onlineResource = getHost();
161
                else
162
                        onlineResource = status.getOnlineResource();
163
                symbol = getSymbol(onlineResource);
164 18271 jpiera
165 4887 jorpiell
                req.append(onlineResource).append(symbol).append("REQUEST=GetCapabilities&SERVICE=WFS&");
166
                req.append("VERSION=").append(getVersion()).append("&EXCEPTIONS=XML");
167
                return req.toString();
168 18271 jpiera
        }
169
170
        /**
171
         * Builds the GetCapabilitiesRequest according to the OGC WFS Specifications
172
         * without a VERSION, to get the highest version than a WFS supports.
173
         */
174
        public static String buildCapabilitiesSuitableVersionRequest(String _host, String _version)
175
        {
176 31835 jpiera
                int index = _host.indexOf('?');
177
178 17849 jmvivo
                if (index > -1) {
179
                        String host = _host.substring(0, index + 1);
180
                        String query = _host.substring(index + 1, _host.length());
181 31835 jpiera
182 17849 jmvivo
                        StringTokenizer tokens = new StringTokenizer(query, "&");
183
                        String newQuery = "", token;
184
185
                        // If there is a field or a value with spaces, (and then it's on different tokens) -> unify them
186
                        while (tokens.hasMoreTokens()) {
187
                                token = tokens.nextToken().trim();
188
189
                                if (token.toUpperCase().compareTo("REQUEST=GETCAPABILITIES") == 0)
190
                                        continue;
191
192
                                if (token.toUpperCase().compareTo("SERVICE=WFS") == 0)
193
                                        continue;
194
195
                                if ((_version != null) && (_version.length() > 0)) {
196 31835 jpiera
                                        if (token.toUpperCase().compareTo("VERSION=" + _version) == 0)
197
                                                continue;
198 17849 jmvivo
                                }
199
200
                                if (token.toUpperCase().compareTo("EXCEPTIONS=XML") == 0)
201
                                        continue;
202
203
                                newQuery += token + "&";
204
                        }
205
206 31835 jpiera
                        _host = host + newQuery;
207 17849 jmvivo
                }
208
                else {
209
                        _host += "?";
210
                }
211
212 31835 jpiera
                if ((_version != null) && (_version.compareTo("") != 0))
213
                        _host += "REQUEST=GetCapabilities&SERVICE=WFS&VERSION=" + _version + "&EXCEPTIONS=XML";
214
                else
215
                        _host += "REQUEST=GetCapabilities&SERVICE=WFS&EXCEPTIONS=XML";
216 17849 jmvivo
217 31835 jpiera
                return _host;
218 18271 jpiera
        }
219
220 5368 jorpiell
        /**
221 18271 jpiera
         * <p>Builds a describeFeatureType request that is sent to the WFS
222
         * the response will be parse to extract the data needed by the
223
         * WFS client</p>
224
         * @param status
225 5368 jorpiell
         * WFS client status. Contains all the information to create
226
         * the query. In this case, the only the feature name is needed.
227 18271 jpiera
         */
228 27881 jpiera
        public void describeFeatureType(WFSStatus status,boolean override, ICancellable cancel)throws WFSException {
229 18271 jpiera
                this.currentFeature = status.getFeatureName();
230
                //sets the namespace URI and the namespace prefix
231
                int index = currentFeature.indexOf(":");
232
                if (index > 0){
233
                        String namespacePrefix = currentFeature.substring(0, index);
234
                        String namespaceURI = serviceInfo.getNamespace(namespacePrefix);
235
                        if (namespaceURI != null){
236
                                status.setNamespace(namespaceURI);
237
                                status.setNamespacePrefix(namespacePrefix);
238
                        }
239
                }
240
                try {
241 27881 jpiera
                        WFSDescribeFeatureTypeRequest request = createDescribeFeatureTypeRequest(status);
242
                        File f = request.sendRequest();
243 18271 jpiera
                        parseDescribeFeatureType(f,status.getNamespacePrefix());
244
                } catch (Exception e){
245
                        throw new WFSException(e);
246
                }
247 27881 jpiera
        }
248 18271 jpiera
249
        /**
250
         * parses the data retrieved by the DescribeCoverage XML document
251
         */
252
        protected abstract boolean parseDescribeFeatureType(File f,String nameSpace);
253
254
        /**
255
         * <p>Builds a getFeature request that is sent to the WFS
256
         * the response will be parse to extract the data needed by the
257
         * WFS client</p>
258
         * @param status
259 5368 jorpiell
         * WFS client status. Contains all the information to create
260
         * the query.
261
         * @return File
262
         * GML file
263 18271 jpiera
         */
264 27881 jpiera
        public File getFeature(WFSStatus status,boolean override, ICancellable cancel) throws WFSException{
265 18271 jpiera
                try{
266 27881 jpiera
                        WFSGetFeatureRequest request = createGetFeatureRequest(status);
267 31835 jpiera
                        File f = request.sendRequest();
268
                        parseGetFeature(f, status.getNamespacePrefix());
269 18271 jpiera
                        return f;
270
                } catch (Exception e){
271
                        throw new WFSException(e);
272
                }
273
        }
274
275 5368 jorpiell
        /**
276 18271 jpiera
         * parses the data retrieved by the GetFeature XML document. It is
277
         * used just to find errors
278
         */
279
        protected abstract boolean parseGetFeature(File f,String nameSpace) throws WFSException;
280
281 31835 jpiera
282 18271 jpiera
        /**
283
         * <p>Builds a transaction request that is sent to the WFS
284
         * the response will be parse to extract the data needed by the
285
         * WFS client</p>
286
         * @param status
287 10246 jorpiell
         * WFS client status. Contains all the information to create
288
         * the query.
289 18271 jpiera
         */
290 27881 jpiera
        public void transaction(WFSStatus status,boolean override, ICancellable cancel) throws WFSException {
291 18271 jpiera
                URL request = null;
292
                try {
293
                        request = new URL(buildTransactionRequest(status));
294
                        for (int i=0 ; i<status.getTransactionsSize() ; i++){
295
                                WFSTTransaction transaction = status.getTransactionAt(i);
296
                                if (transaction.getStatus() == WFSTTransaction.STATUS_NO_EXECUTED){
297
                                        System.out.println(transaction.getWFSTRequest());
298 33738 jpiera
                                        File f = downloader.downloadFile(request,
299 18271 jpiera
                                                        transaction.getWFSTRequest(),
300
                                                        "wfs_transaction.xml", null);
301
                                        parseTransaction(f,status.getNamespacePrefix(),transaction);
302
                                        //If the transaction has been executed with success,
303
                                        //it is necessary to remove the getFeature file from the
304
                                        //downloader manager.
305
                                        if (transaction.getStatus() == WFSTTransaction.STATUS_SUCCESS){
306 27881 jpiera
                                                WFSGetFeatureRequest requestAux = createGetFeatureRequest(status);
307
                                                requestAux.setDeleted(true);
308
                                                requestAux.sendRequest();
309 18271 jpiera
                                        }
310
                                }
311
                        }
312
                } catch (Exception e){
313
                        throw new WFSException(e);
314
                }
315
        }
316
317
        /**
318
         * <p>Builds a transaction request that is sent to the WFS
319
         * the response will be parse to extract the data needed by the
320
         * WFS client</p>
321
         * @param status
322 10246 jorpiell
         * WFS client status. Contains all the information to create
323
         * the query.
324 18271 jpiera
         */
325
        private String buildTransactionRequest(WFSStatus status){
326
                StringBuffer req = new StringBuffer();
327
                String symbol = null;
328
329
                String onlineResource;
330 27881 jpiera
                if(serviceInfo.getOnlineResource(CapabilitiesTags.WFS_TRANSACTION) != null){
331
                        onlineResource = serviceInfo.getOnlineResource(CapabilitiesTags.WFS_TRANSACTION);
332 18271 jpiera
                }else {
333
                        onlineResource = getHost();
334
                }
335
                symbol = getSymbol(onlineResource);
336
337
                req.append(onlineResource);
338
                return req.toString();
339
        }
340
341
        /**
342
         * parses the data retrieved by the transaction operation
343
         * @param f
344
         * The retrieved file
345
         * @param nameSpace
346
         * The namespace
347
         * @param transaction
348
         * The current WFSTransaction
349
         */
350
        protected abstract boolean parseTransaction(File f,String nameSpace, WFSTTransaction transaction) throws WFSException;
351
352
        /**
353
         * <p>Builds a lockFeature request that is sent to the WFS
354
         * the response will be parse to extract the data needed by the
355
         * WFS client</p>
356
         * @param status
357 10246 jorpiell
         * WFS client status. Contains all the information to create
358
         * the query.
359 18271 jpiera
         */
360 27881 jpiera
        public void lockFeature(WFSStatus status,boolean override, ICancellable cancel) throws WFSException {
361 18271 jpiera
                try {
362 27881 jpiera
                        WFSTLockFeatureRequest request = createLockFeatureRequest(status);
363 18271 jpiera
                        File f = request.sendRequest();
364
                        parseLockFeature(f,status.getNamespacePrefix(),status);
365
                } catch(WFSException e) {
366
                        throw e;
367
                } catch (Exception e){
368
                        throw new WFSException(e);
369
                }
370
        }
371
372
        /**
373
         * parses the data retrieved by the LockFeature operation
374
         */
375
        protected abstract boolean parseLockFeature(File f,String nameSpace, WFSStatus status) throws WFSException;
376
377
        /**
378 5821 jorpiell
         * @return Returns the features.
379
         */
380
        public Hashtable getFeatures() {
381
                return features;
382
        }
383
384
        /**
385
         * @return Returns the currentFeature.
386
         */
387
        public String getCurrentFeature() {
388
                return currentFeature;
389
        }
390 18271 jpiera
391 5821 jorpiell
        /**
392
         * Sets the fields of the current feature
393
         * @param fields
394
         */
395
        public void setFields(Vector fields){
396
                WFSFeature feature = (WFSFeature) features.get(currentFeature);
397
                feature.setFields(fields);
398
                features.put(feature.getName(),feature);
399
        }
400 18271 jpiera
401 5821 jorpiell
        /**
402
         * Sets the fields of the current feature
403
         * @param fields
404
         */
405
        public void setFields(Hashtable fields){
406
                WFSFeature feature = (WFSFeature) features.get(currentFeature);
407
                Vector vFields = new Vector();
408
                Set keys = fields.keySet();
409
                for (int i=0 ; i<keys.size() ; i++){
410
                        vFields.add(fields.get(keys.toArray()[i]));
411
                }
412
                feature.setFields(vFields);
413
                features.put(feature.getName(),feature);
414
        }
415
416 18271 jpiera
417 5821 jorpiell
        /**
418
         * @param currentFeature The currentFeature to set.
419
         */
420
        public void setCurrentFeature(String currentFeature) {
421
                this.currentFeature = currentFeature;
422 27881 jpiera
        }
423 31835 jpiera
424 27504 jpiera
        /**
425
         * It parses the attributes of the current KXMLParser
426
         * and add the new namespaces to the service information
427
         * @param parser
428
         * The KXML parser
429
         */
430
        protected void parseNamespaces(KXmlParser parser){
431
                for (int i=0 ; i<parser.getAttributeCount() ; i++){
432
                        String attName = parser.getAttributeName(i);
433
                        if (attName.startsWith(GMLTags.XML_NAMESPACE)){
434
                                int index = attName.indexOf(":");
435
                                if (index > 0){
436
                                        serviceInfo.addNamespace(attName.substring(index+1, attName.length()),
437
                                                        parser.getAttributeValue(i));
438
                                }
439
                        }
440
                }
441
        }
442 31835 jpiera
443 27881 jpiera
        /* (non-Javadoc)
444
         * @see org.gvsig.remoteClient.ogc.OGCProtocolHandler#getServiceInformation()
445
         */
446
        public OGCServiceInformation getServiceInformation() {
447
                return serviceInfo;
448
        }
449
450
        /**
451
         * @param status
452
         * The WFS status
453
         * @param protocolHandler
454
         * The handler to parse the requests
455
         * @return an object to send the DescribeFeatureType requests
456
         */
457
        protected abstract WFSDescribeFeatureTypeRequest createDescribeFeatureTypeRequest(WFSStatus status);
458
459
        /**
460
         * @param status
461
         * The WFS status
462
         * @param protocolHandler
463
         * The handler to parse the requests
464
         * @return an object to send the GetFeature requests
465
         */
466
        protected abstract WFSGetFeatureRequest createGetFeatureRequest(WFSStatus status);
467
468
        /**
469
         * @param status
470
         * The WFS status
471
         * @param protocolHandler
472
         * The handler to parse the requests
473
         * @return an object to send the LockFeature requests
474
         */
475
        protected abstract WFSTLockFeatureRequest createLockFeatureRequest(WFSStatus status);
476 31835 jpiera
477
        /**
478
         * @return the wfsRequestInformations
479
         */
480
        ArrayList getWfsRequestInformations() {
481
                return wfsRequestInformations;
482
        }
483
484
        /**
485
         * Adds a new WFSRequestInformation
486
         * @param wfsRequestInformation
487
         */
488
        public void addLastWfsRequestInformation(
489
                        WFSRequestInformation wfsRequestInformation) {
490
                wfsRequestInformations.add(wfsRequestInformation);
491
        }
492
493
        /**
494
         * @return the lastWfsRequestInformation
495
         */
496
        public WFSRequestInformation getLastWfsRequestInformation() {
497
                if (wfsRequestInformations.size() > 0){
498
                        return (WFSRequestInformation)wfsRequestInformations.get(wfsRequestInformations.size() - 1);
499
                }
500
                return null;
501
        }
502 4887 jorpiell
}