Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libRemoteServices / src / org / gvsig / remoteclient / wfs / WFSProtocolHandlerFactory.java @ 33738

History | View | Annotate | Download (7.95 KB)

1
package org.gvsig.remoteclient.wfs;
2

    
3
import java.io.File;
4
import java.io.FileReader;
5
import java.io.IOException;
6
import java.io.Reader;
7
import java.net.ConnectException;
8
import java.net.URL;
9
import java.util.ArrayList;
10
import java.util.Iterator;
11

    
12
import org.kxml2.io.KXmlParser;
13
import org.xmlpull.v1.XmlPullParserException;
14

    
15
import org.gvsig.compat.CompatLocator;
16
import org.gvsig.compat.lang.StringUtils;
17
import org.gvsig.remoteclient.utils.CapabilitiesTags;
18
import org.gvsig.remoteclient.utils.EncodingXMLParser;
19
import org.gvsig.remoteclient.utils.Utilities;
20

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