Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.remoteclient / src / main / java / org / gvsig / remoteclient / wfs / WFSProtocolHandlerFactory.java @ 40559

History | View | Annotate | Download (9.73 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 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 3
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.remoteclient.wfs;
25

    
26
import java.io.File;
27
import java.io.FileReader;
28
import java.io.IOException;
29
import java.io.Reader;
30
import java.net.ConnectException;
31
import java.net.URL;
32
import java.util.ArrayList;
33
import java.util.Iterator;
34
import java.util.List;
35

    
36
import org.kxml2.io.KXmlParser;
37
import org.xmlpull.v1.XmlPullParserException;
38

    
39
import org.gvsig.compat.CompatLocator;
40
import org.gvsig.compat.lang.StringUtils;
41
import org.gvsig.remoteclient.utils.CapabilitiesTags;
42
import org.gvsig.remoteclient.utils.EncodingXMLParser;
43
import org.gvsig.remoteclient.utils.Utilities;
44

    
45
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
46
 *
47
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
48
 *
49
 * This program is free software; you can redistribute it and/or
50
 * modify it under the terms of the GNU General Public License
51
 * as published by the Free Software Foundation; either version 2
52
 * of the License, or (at your option) any later version.
53
 *
54
 * This program is distributed in the hope that it will be useful,
55
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
56
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
57
 * GNU General Public License for more details.
58
 *
59
 * You should have received a copy of the GNU General Public License
60
 * along with this program; if not, write to the Free Software
61
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
62
 *
63
 * For more information, contact:
64
 *
65
 *  Generalitat Valenciana
66
 *   Conselleria d'Infraestructures i Transport
67
 *   Av. Blasco Ib??ez, 50
68
 *   46010 VALENCIA
69
 *   SPAIN
70
 *
71
 *      +34 963862235
72
 *   gvsig@gva.es
73
 *      www.gvsig.gva.es
74
 *
75
 *    or
76
 *
77
 *   IVER T.I. S.A
78
 *   Salamanca 50
79
 *   46005 Valencia
80
 *   Spain
81
 *
82
 *   +34 963163400
83
 *   dac@iver.es
84
 */
85
/* CVS MESSAGES:
86
 *
87
 * $Id: WFSProtocolHandlerFactory.java 39768 2013-02-20 14:16:29Z jldominguez $
88
 * $Log$
89
 * Revision 1.2  2007-02-09 14:11:01  jorpiell
90
 * Primer piloto del soporte para WFS 1.1 y para WFS-T
91
 *
92
 * Revision 1.1  2006/04/19 12:51:35  jorpiell
93
 * A?adidas algunas de las clases del servicio WFS
94
 *
95
 *
96
 */
97
/**
98
 * @author Jorge Piera Llodr? (piera_jor@gva.es)
99
 */
100
public class WFSProtocolHandlerFactory {
101
        public WFSProtocolHandler wFSProtocolHandler;
102
        private static final StringUtils stringUtils = CompatLocator.getStringUtils();
103
        private static ArrayList supportedVersions = new ArrayList();
104
        
105
        static {
106
        supportedVersions.add("1.1.0");
107
                supportedVersions.add("1.0.0");
108
        }
109
        
110
        /**
111
         * M?todo que dada una respuesta de getCapabilities y un iterador sobre una
112
         * coleccion de WFSClient's ordenada descendentemente devuelve el cliente
113
         * cuya version es igual o inmediatamente inferior
114
         *
115
         * @param caps Capabilities con la respuesta del servidor
116
         * @param clients Iterador de conjunto ordenado descendientemente
117
         *
118
         * @return cliente cuya version es igual o inmediatamente inferior
119
         * @throws IllegalAccessException
120
         * @throws InstantiationException
121
         * 
122
         */
123
        private static String getDriverVersion(String version, Iterator clients) throws InstantiationException, IllegalAccessException {
124
                while (clients.hasNext()) {
125
                        String clientVersion = (String)clients.next();
126
                        int ret = version.compareTo(clientVersion);
127
                        
128
                        if (ret >= 0) {
129
                                return clientVersion;
130
                        }
131
                }
132
                return null;
133
        }
134
        
135
        /**
136
         * Establece la versi?n con la que se comunicar? con el servidor y devuelve
137
         * el objeto Capabilities obtenido con dicha versi?n
138
         *
139
         * @param host maquina con la que se negocia
140
         *
141
         * @return instancia de un cliente capaz de negociar con el host que se
142
         *         pasa como par?metro
143
         */
144
        public static WFSProtocolHandler negotiate(String host) throws ConnectException, IOException {
145
                
146
                if (supportedVersions.size() == 0){
147
                        return null;
148
                }
149
                
150
                try        {                
151
                        String highestVersionSupportedByServer  = getSuitableWFSVersion(host,"");
152
                        if (supportedVersions.contains(highestVersionSupportedByServer))
153
                        {
154
                                // we support the highest version supported by the server
155
                                // this is the best case 
156
                                return createVersionDriver(highestVersionSupportedByServer);
157
                        }
158
                        else
159
                        {
160
                                // in case we dont support the highest version from the server
161
                                // we start the negotiation process in which we have to get the higest version
162
                                // the WFS supports and we are able to read.
163
                                Iterator iVersion = supportedVersions.iterator();
164
                                String wfsVersion;
165
                                String gvSIGVersion;
166
                                
167
                                while (iVersion.hasNext()) { 
168
                                        gvSIGVersion = (String)iVersion.next();
169
                                        wfsVersion = getSuitableWFSVersion(host,gvSIGVersion);
170
                                        //TODO:
171
                                        //compare with the version returned by the WMS!!!!!
172
                                        // send GetCapabilities and read the version to compare.
173
                                        int res = wfsVersion.compareTo(gvSIGVersion);
174
                                        
175
                                        if (res == 0) { //Si es la misma que nuestra version                
176
                                                return createVersionDriver(gvSIGVersion);
177
                                        } else if (res > 0) { //Si es mayor que nuestra version
178
                                                throw new Exception("Server Version too high: " + wfsVersion);
179
                                        } else { //Si es menor que nuestra version
180
                                                //Obtenemos la primera version menor o igual que tengamos
181
                                                String lowerVersion = WFSProtocolHandlerFactory.getDriverVersion(wfsVersion, iVersion);
182
                                                
183
                                                if (lowerVersion == null) { //Si no hay ninguna
184
                                                        throw new Exception("Lowest server version is " + wfsVersion);
185
                                                } else {
186
                                                        if (lowerVersion.equals(wfsVersion)) { 
187
                                                                return createVersionDriver(lowerVersion);
188
                                                        } else { //Si hay una version menor que la que retorno el servidor
189
                                                                //iV = lower;
190
                                                        }
191
                                                }
192
                                        }
193
                                }
194
                        }//case we had to start the negotiation process.
195
                        return null; // if it did not find any suitable version.        
196
                }
197
                catch(ConnectException conEx)
198
                {
199
                        throw conEx;
200
                }
201
                catch(IOException ioEx)
202
                {
203
                        throw ioEx;
204
                }        
205
                catch(Exception e)
206
                {
207
                        e.printStackTrace();
208
                        return null;
209
                }
210
        }
211
        
212
        /**
213
         * Sends a GetCapabilities to the WFS server to get the version
214
         * if the version parameter is null, the WFS will return the highest version supported
215
         * if not it will return the lower highest version than the one requested.
216
         * @param host
217
         * @param version
218
         * @return suitable version supported by the server 
219
         */
220
        private static String getSuitableWFSVersion(String host, String _version) throws ConnectException, IOException {             
221
                String request = WFSProtocolHandler.buildCapabilitiesSuitableVersionRequest(host, _version);
222
                String version = new String(); 
223
                Reader reader = null;
224
                try {           
225
                        File file = Utilities.downloadFile(new URL(request), "wfs-suitable-version", null);
226
                                                
227
                        reader = new FileReader(file);
228
                        EncodingXMLParser kxmlParser = new EncodingXMLParser();
229
                        kxmlParser.setInput(reader);                
230
                        kxmlParser.nextTag();
231
                        if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) {                    
232
                                String tag = kxmlParser.getName();
233
                                if (stringUtils.split(tag, ":").length == 2){
234
                                        tag = stringUtils.split(tag, ":")[1];
235
                                }
236
                                if ((tag.compareTo(CapabilitiesTags.WFS_CAPABILITIES_ROOT1_0_0)==0)) {
237
                                        version = kxmlParser.getAttributeValue("", CapabilitiesTags.VERSION);
238
                                }
239
                        }
240
                        // do not forget to close the Stream.                    
241
                        reader.close();                         
242
                        return version;                
243
                } catch(ConnectException conEx) {
244
                        throw new ConnectException(conEx.getMessage());                         
245
                } catch(IOException ioEx) {
246
                        throw new IOException(ioEx.getMessage());         
247
                } catch(XmlPullParserException xmlEx) {
248
                        xmlEx.printStackTrace();
249
                        return "";
250
                } finally {                
251
                        if (reader != null) {
252
                                try {
253
                                        reader.close();
254
                                } catch(Exception ex) {
255
                                        ex.printStackTrace(); 
256
                                }
257
                        }
258
                } 
259
        }
260
        
261
        /**
262
         * Gets the intersection between the versions supported by the server
263
         * and the versions supported by the application 
264
         * @throws IOException 
265
         * @throws ConnectException 
266
         */
267
        public static List getRequestableVersions(String host) throws
268
        ConnectException, IOException {
269
            
270
            Iterator iVersion = supportedVersions.iterator();
271
        String wfsVersion;
272
        String gvSIGVersion;
273
        
274
        ArrayList resp = new ArrayList();
275
        
276
        while (iVersion.hasNext()) { 
277
            gvSIGVersion = (String)iVersion.next();
278
            wfsVersion = getSuitableWFSVersion(host,gvSIGVersion);
279
            if (gvSIGVersion.compareTo(wfsVersion) == 0) {
280
                resp.add(gvSIGVersion);
281
            }
282
        }
283
        return resp;
284
        }
285
        
286
        /**
287
         * It creates an instance of a WFSDriver class.
288
         *
289
         * @param String, with the version of the driver to be created
290
         * @return WFSDriver.
291
         */
292
        public static WFSProtocolHandler createVersionDriver(String version) {               
293
                try {
294
                        Class driver;
295
                        version = version.replace('.', '_');
296
                        driver = Class.forName("org.gvsig.remoteclient.wfs.wfs_"+version+".WFSProtocolHandler" + version);
297
                        return (WFSProtocolHandler)driver.newInstance();
298
                } catch (Exception e) {
299
                        e.printStackTrace();
300
                        //throw new Exception("WFSDriverFactory. Unknown driver version " + e);
301
                        return null;
302
                }
303
        }    
304
        
305
        
306
        
307
}