Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRemoteServices / src / org / gvsig / remoteClient / wfs / WFSProtocolHandlerFactory.java @ 15505

History | View | Annotate | Download (7.77 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.gvsig.remoteClient.utils.CapabilitiesTags;
13
import org.gvsig.remoteClient.utils.EncodingXMLParser;
14
import org.gvsig.remoteClient.utils.Utilities;
15
import org.kxml2.io.KXmlParser;
16
import org.xmlpull.v1.XmlPullParserException;
17

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