Statistics
| Revision:

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

History | View | Annotate | Download (9.19 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

    
25
package org.gvsig.remoteclient.wms;
26

    
27
import java.io.DataInputStream;
28
import java.io.IOException;
29
import java.io.StringReader;
30
import java.net.ConnectException;
31
import java.net.URL;
32
import java.util.ArrayList;
33
import java.util.Iterator;
34

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

    
38
import org.gvsig.remoteclient.utils.CapabilitiesTags;
39

    
40
/**
41
 * <p></p>
42
 *
43
 */
44
public class WMSProtocolHandlerFactory {
45
/**
46
 * <p></p>
47
 *
48
 */
49
    public org.gvsig.remoteclient.wms.WMSProtocolHandler wMSProtocolHandler;
50

    
51
    private static ArrayList supportedVersions = new ArrayList();
52

    
53
    static {
54
        /*
55
         * Se meten en el array versions las distintas versiones
56
         * del protocolo en orden descendente
57
         */
58
            //versions.add(WMSProtocolHandler1_3_0.class);
59
        //versions.add(WMSProtocolHandler1_1_1.class);
60
            supportedVersions.add("1.3.0");
61
            supportedVersions.add("1.1.1");
62
            supportedVersions.add("1.1.0");
63
     }
64

    
65
    /**
66
     * M?todo que dada una respuesta de getCapabilities y un iterador sobre una
67
     * coleccion de WMSClient's ordenada descendentemente devuelve el cliente
68
     * cuya version es igual o inmediatamente inferior
69
     *
70
     * @param caps Capabilities con la respuesta del servidor
71
     * @param clients Iterador de conjunto ordenado descendientemente
72
     *
73
     * @return cliente cuya version es igual o inmediatamente inferior
74
     * @throws IllegalAccessException
75
     * @throws InstantiationException
76
     *
77
     */
78
    private static String getDriverVersion(String version, Iterator clients) throws InstantiationException, IllegalAccessException {
79
        while (clients.hasNext()) {
80
            String clientVersion = (String)clients.next();
81
            int ret = version.compareTo(clientVersion);
82

    
83
            if (ret >= 0) {
84
                return clientVersion;
85
            }
86
        }
87
        return null;
88
    }
89

    
90
    /**
91
     * Establece la versi?n con la que se comunicar? con el servidor y devuelve
92
     * el objeto Capabilities obtenido con dicha versi?n
93
     *
94
     * @param host maquina con la que se negocia
95
     *
96
     * @return instancia de un cliente capaz de negociar con el host que se
97
     *         pasa como par?metro
98
     */
99
     public static WMSProtocolHandler negotiate(String host) throws ConnectException, IOException {
100

    
101
        if (supportedVersions.size() == 0)
102
        {
103
                return null;
104
        }
105

    
106
        try
107
        {
108
                String highestVersionSupportedByServer  = getSuitableWMSVersion(host,"");
109
                if (supportedVersions.contains(highestVersionSupportedByServer))
110
                {
111
                        //we support the highest version supported by the server
112
                        // this is the best case
113
                        return createVersionDriver(highestVersionSupportedByServer);
114
                }
115

    
116

    
117
        else
118
                {
119
                        // in case we dont support the highest version from the server
120
                        // we start the negotiation process in which we have to get the higest version
121
                        // the WMS supports and we are able to read.
122
                        Iterator iVersion = supportedVersions.iterator();
123
                        String wmsVersion;
124
                        String gvSIGVersion;
125

    
126
                        while (iVersion.hasNext()) {
127
                                gvSIGVersion = (String)iVersion.next();
128
                                wmsVersion = getSuitableWMSVersion(host,gvSIGVersion);
129
                                //TODO:
130
                                //compare with the version returned by the WMS!!!!!
131
                                // send GetCapabilities and read the version to compare.
132
                                int res = wmsVersion.compareTo(gvSIGVersion);
133

    
134
                                if (res == 0) { //Si es la misma que nuestra version
135
                                    return createVersionDriver(gvSIGVersion);
136
                                } else if (res > 0) { //Si es mayor que nuestra version
137
                                    throw new Exception("Server Version too high: " + wmsVersion);
138
                                } else { //Si es menor que nuestra version
139
                                         //Obtenemos la primera version menor o igual que tengamos
140
                                    String lowerVersion = WMSProtocolHandlerFactory.getDriverVersion(wmsVersion, iVersion);
141

    
142
                                    if (lowerVersion == null) { //Si no hay ninguna
143
                                        throw new Exception("Lowest server version is " + wmsVersion);
144
                                    } else {
145
                                        if (lowerVersion.equals(wmsVersion)) {
146
                                            return createVersionDriver(lowerVersion);
147
                                        } else { //Si hay una version menor que la que retorno el servidor
148
                                            //iV = lower;
149
                                        }
150
                                    }
151
                                }
152
                        }
153
                }//case we had to start the negotiation process.
154
                return null; // if it did not find any suitable version.
155
        }
156
        catch(ConnectException conEx)
157
        {
158
                throw conEx;
159
        }
160
        catch(IOException ioEx)
161
        {
162
                throw ioEx;
163
        }
164
        catch(Exception e)
165
        {
166
                e.printStackTrace();
167
                return null;
168
        }
169
    }
170

    
171
     /**
172
      * Sends a GetCapabilities to the WMS server to get the version
173
      * if the version parameter is null, the WMS will return the highest version supported
174
      * if not it will return the lower highest version than the one requested.
175
      * @param host
176
      * @param version
177
      * @return suitable version supported by the server
178
      */
179
     private static String getSuitableWMSVersion(String host, String _version) throws ConnectException, IOException
180
     {
181
            String request = WMSProtocolHandler.buildCapabilitiesSuitableVersionRequest(host, _version);
182
            String version = new String();
183
            StringReader reader = null;
184
            //InputStreamReader reader;
185
            //InputStream is = null;
186
            DataInputStream dis = null;
187
                try
188
                {
189
                        URL url = new URL(request);
190
            byte[] buffer = new byte[1024];//new byte[1024*256];
191
//            is = url.openStream();
192
//            reader = new InputStreamReader(is);
193
            //int numberOfBytes = is.read(buffer);
194
            //String readed = new String(buffer);
195
            dis = new DataInputStream(url.openStream());
196
            dis.readFully(buffer);
197
            String string = new String(buffer);
198

    
199
            // patch for ArcIMS + WMS connector > 9.0 bug
200
            int a = string.toLowerCase().indexOf("<?xml");
201
            if (a !=-1)
202
                    string = string.substring(a, string.length());
203
            // end patch
204

    
205

    
206
            reader = new StringReader(string);
207
                    KXmlParser kxmlParser = null;
208
                    kxmlParser = new KXmlParser();
209
                    kxmlParser.setInput(reader);
210
                        kxmlParser.nextTag();
211
                    if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT )
212
                    {
213
                            if ((kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITIES_ROOT1_1_0)==0)
214
                                    ||(kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITIES_ROOT1_1_1)==0)
215
                                    ||(kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITIES_ROOT1_3_0)==0))
216
                            {
217
                                    version = kxmlParser.getAttributeValue("", CapabilitiesTags.VERSION);
218
                            }
219
                    }
220
                    // do not forget to close the Stream.
221
                    reader.close();
222
                    dis.close();
223
                        return version;
224
                }
225
                catch(ConnectException conEx)
226
                {
227
                        throw new ConnectException(conEx.getMessage());
228
                }
229
                catch(IOException ioEx)
230
                {
231
                        throw new IOException(ioEx.getMessage());
232
                }
233
                catch(XmlPullParserException xmlEx)
234
                {
235
                        xmlEx.printStackTrace();
236
                        return "";
237
                }
238
                finally{
239
                        if (reader != null)
240
                        {
241
                                try{
242
                                        reader.close();
243
                                }catch(Exception ex){
244
                                        ex.printStackTrace();
245
                                }
246
                        }
247
                        if (dis != null)
248
                        {
249
                                try {
250
                                        dis.close();
251
                                } catch(Exception ex) {
252
                                        ex.printStackTrace();
253
                                }
254
                        }
255
                }
256
     }
257

    
258
     /**
259
      * It creates an instance of a WMSDriver class.
260
      *
261
      * @param String, with the version of the driver to be created
262
      * @return WMSDriver.
263
      */
264
       private static WMSProtocolHandler createVersionDriver(String version)
265
       {
266
         try
267
         {
268
           Class driver;
269
           version = version.replace('.', '_');
270
           driver = Class.forName("org.gvsig.remoteclient.wms.wms_"+version+".WMSProtocolHandler" + version);
271
           return (WMSProtocolHandler)driver.newInstance();
272
         }
273
         catch (Exception e)
274
         {
275
                 e.printStackTrace();
276
           //throw new Exception("WMSDriverFactory. Unknown driver version " + e);
277
                 return null;
278
         }
279
       }
280

    
281
 }