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 @ 40596

History | View | Annotate | Download (8.22 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
/**
46
 * @author Jorge Piera Llodr? (piera_jor@gva.es)
47
 */
48
public class WFSProtocolHandlerFactory {
49
        public WFSProtocolHandler wFSProtocolHandler;
50
        private static final StringUtils stringUtils = CompatLocator.getStringUtils();
51
        private static ArrayList supportedVersions = new ArrayList();
52
        
53
        static {
54
        supportedVersions.add("1.1.0");
55
                supportedVersions.add("1.0.0");
56
        }
57
        
58
        /**
59
         * M?todo que dada una respuesta de getCapabilities y un iterador sobre una
60
         * coleccion de WFSClient's ordenada descendentemente devuelve el cliente
61
         * cuya version es igual o inmediatamente inferior
62
         *
63
         * @param caps Capabilities con la respuesta del servidor
64
         * @param clients Iterador de conjunto ordenado descendientemente
65
         *
66
         * @return cliente cuya version es igual o inmediatamente inferior
67
         * @throws IllegalAccessException
68
         * @throws InstantiationException
69
         * 
70
         */
71
        private static String getDriverVersion(String version, Iterator clients) throws InstantiationException, IllegalAccessException {
72
                while (clients.hasNext()) {
73
                        String clientVersion = (String)clients.next();
74
                        int ret = version.compareTo(clientVersion);
75
                        
76
                        if (ret >= 0) {
77
                                return clientVersion;
78
                        }
79
                }
80
                return null;
81
        }
82
        
83
        /**
84
         * Establece la versi?n con la que se comunicar? con el servidor y devuelve
85
         * el objeto Capabilities obtenido con dicha versi?n
86
         *
87
         * @param host maquina con la que se negocia
88
         *
89
         * @return instancia de un cliente capaz de negociar con el host que se
90
         *         pasa como par?metro
91
         */
92
        public static WFSProtocolHandler negotiate(String host) throws ConnectException, IOException {
93
                
94
                if (supportedVersions.size() == 0){
95
                        return null;
96
                }
97
                
98
                try        {                
99
                        String highestVersionSupportedByServer  = getSuitableWFSVersion(host,"");
100
                        if (supportedVersions.contains(highestVersionSupportedByServer))
101
                        {
102
                                // we support the highest version supported by the server
103
                                // this is the best case 
104
                                return createVersionDriver(highestVersionSupportedByServer);
105
                        }
106
                        else
107
                        {
108
                                // in case we dont support the highest version from the server
109
                                // we start the negotiation process in which we have to get the higest version
110
                                // the WFS supports and we are able to read.
111
                                Iterator iVersion = supportedVersions.iterator();
112
                                String wfsVersion;
113
                                String gvSIGVersion;
114
                                
115
                                while (iVersion.hasNext()) { 
116
                                        gvSIGVersion = (String)iVersion.next();
117
                                        wfsVersion = getSuitableWFSVersion(host,gvSIGVersion);
118
                                        //TODO:
119
                                        //compare with the version returned by the WMS!!!!!
120
                                        // send GetCapabilities and read the version to compare.
121
                                        int res = wfsVersion.compareTo(gvSIGVersion);
122
                                        
123
                                        if (res == 0) { //Si es la misma que nuestra version                
124
                                                return createVersionDriver(gvSIGVersion);
125
                                        } else if (res > 0) { //Si es mayor que nuestra version
126
                                                throw new Exception("Server Version too high: " + wfsVersion);
127
                                        } else { //Si es menor que nuestra version
128
                                                //Obtenemos la primera version menor o igual que tengamos
129
                                                String lowerVersion = WFSProtocolHandlerFactory.getDriverVersion(wfsVersion, iVersion);
130
                                                
131
                                                if (lowerVersion == null) { //Si no hay ninguna
132
                                                        throw new Exception("Lowest server version is " + wfsVersion);
133
                                                } else {
134
                                                        if (lowerVersion.equals(wfsVersion)) { 
135
                                                                return createVersionDriver(lowerVersion);
136
                                                        } else { //Si hay una version menor que la que retorno el servidor
137
                                                                //iV = lower;
138
                                                        }
139
                                                }
140
                                        }
141
                                }
142
                        }//case we had to start the negotiation process.
143
                        return null; // if it did not find any suitable version.        
144
                }
145
                catch(ConnectException conEx)
146
                {
147
                        throw conEx;
148
                }
149
                catch(IOException ioEx)
150
                {
151
                        throw ioEx;
152
                }        
153
                catch(Exception e)
154
                {
155
                        e.printStackTrace();
156
                        return null;
157
                }
158
        }
159
        
160
        /**
161
         * Sends a GetCapabilities to the WFS server to get the version
162
         * if the version parameter is null, the WFS will return the highest version supported
163
         * if not it will return the lower highest version than the one requested.
164
         * @param host
165
         * @param version
166
         * @return suitable version supported by the server 
167
         */
168
        private static String getSuitableWFSVersion(String host, String _version) throws ConnectException, IOException {             
169
                String request = WFSProtocolHandler.buildCapabilitiesSuitableVersionRequest(host, _version);
170
                String version = new String(); 
171
                Reader reader = null;
172
                try {           
173
                        File file = Utilities.downloadFile(new URL(request), "wfs-suitable-version", null);
174
                                                
175
                        reader = new FileReader(file);
176
                        EncodingXMLParser kxmlParser = new EncodingXMLParser();
177
                        kxmlParser.setInput(reader);                
178
                        kxmlParser.nextTag();
179
                        if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) {                    
180
                                String tag = kxmlParser.getName();
181
                                if (stringUtils.split(tag, ":").length == 2){
182
                                        tag = stringUtils.split(tag, ":")[1];
183
                                }
184
                                if ((tag.compareTo(CapabilitiesTags.WFS_CAPABILITIES_ROOT1_0_0)==0)) {
185
                                        version = kxmlParser.getAttributeValue("", CapabilitiesTags.VERSION);
186
                                }
187
                        }
188
                        // do not forget to close the Stream.                    
189
                        reader.close();                         
190
                        return version;                
191
                } catch(ConnectException conEx) {
192
                        throw new ConnectException(conEx.getMessage());                         
193
                } catch(IOException ioEx) {
194
                        throw new IOException(ioEx.getMessage());         
195
                } catch(XmlPullParserException xmlEx) {
196
                        xmlEx.printStackTrace();
197
                        return "";
198
                } finally {                
199
                        if (reader != null) {
200
                                try {
201
                                        reader.close();
202
                                } catch(Exception ex) {
203
                                        ex.printStackTrace(); 
204
                                }
205
                        }
206
                } 
207
        }
208
        
209
        /**
210
         * Gets the intersection between the versions supported by the server
211
         * and the versions supported by the application 
212
         * @throws IOException 
213
         * @throws ConnectException 
214
         */
215
        public static List getRequestableVersions(String host) throws
216
        ConnectException, IOException {
217
            
218
            Iterator iVersion = supportedVersions.iterator();
219
        String wfsVersion;
220
        String gvSIGVersion;
221
        
222
        ArrayList resp = new ArrayList();
223
        
224
        while (iVersion.hasNext()) { 
225
            gvSIGVersion = (String)iVersion.next();
226
            wfsVersion = getSuitableWFSVersion(host,gvSIGVersion);
227
            if (gvSIGVersion.compareTo(wfsVersion) == 0) {
228
                resp.add(gvSIGVersion);
229
            }
230
        }
231
        return resp;
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
        public 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
}