Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libRemoteServices / src / org / gvsig / remoteclient / wms / WMSProtocolHandlerFactory.java @ 29658

History | View | Annotate | Download (8.26 KB)

1

    
2
package org.gvsig.remoteclient.wms;
3

    
4
import java.io.DataInputStream;
5
import java.io.IOException;
6
import java.io.StringReader;
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.kxml2.io.KXmlParser;
14
import org.xmlpull.v1.XmlPullParserException;
15

    
16
/**
17
 * <p></p>
18
 *
19
 */
20
public class WMSProtocolHandlerFactory {
21
/**
22
 * <p></p>
23
 *
24
 */
25
    public org.gvsig.remoteclient.wms.WMSProtocolHandler wMSProtocolHandler;
26

    
27
    private static ArrayList supportedVersions = new ArrayList();
28

    
29
    static {
30
        /*
31
         * Se meten en el array versions las distintas versiones
32
         * del protocolo en orden descendente
33
         */
34
            //versions.add(WMSProtocolHandler1_3_0.class);
35
        //versions.add(WMSProtocolHandler1_1_1.class);
36
            supportedVersions.add("1.3.0");
37
            supportedVersions.add("1.1.1");
38
            supportedVersions.add("1.1.0");
39
     }
40

    
41
    /**
42
     * M?todo que dada una respuesta de getCapabilities y un iterador sobre una
43
     * coleccion de WMSClient's ordenada descendentemente devuelve el cliente
44
     * cuya version es igual o inmediatamente inferior
45
     *
46
     * @param caps Capabilities con la respuesta del servidor
47
     * @param clients Iterador de conjunto ordenado descendientemente
48
     *
49
     * @return cliente cuya version es igual o inmediatamente inferior
50
     * @throws IllegalAccessException
51
     * @throws InstantiationException
52
     *
53
     */
54
    private static String getDriverVersion(String version, Iterator clients) throws InstantiationException, IllegalAccessException {
55
        while (clients.hasNext()) {
56
            String clientVersion = (String)clients.next();
57
            int ret = version.compareTo(clientVersion);
58

    
59
            if (ret >= 0) {
60
                return clientVersion;
61
            }
62
        }
63
        return null;
64
    }
65

    
66
    /**
67
     * Establece la versi?n con la que se comunicar? con el servidor y devuelve
68
     * el objeto Capabilities obtenido con dicha versi?n
69
     *
70
     * @param host maquina con la que se negocia
71
     *
72
     * @return instancia de un cliente capaz de negociar con el host que se
73
     *         pasa como par?metro
74
     */
75
     public static WMSProtocolHandler negotiate(String host) throws ConnectException, IOException {
76

    
77
        if (supportedVersions.size() == 0)
78
        {
79
                return null;
80
        }
81

    
82
        try
83
        {
84
                String highestVersionSupportedByServer  = getSuitableWMSVersion(host,"");
85
                if (supportedVersions.contains(highestVersionSupportedByServer))
86
                {
87
                        //we support the highest version supported by the server
88
                        // this is the best case
89
                        return createVersionDriver(highestVersionSupportedByServer);
90
                }
91

    
92

    
93
        else
94
                {
95
                        // in case we dont support the highest version from the server
96
                        // we start the negotiation process in which we have to get the higest version
97
                        // the WMS supports and we are able to read.
98
                        Iterator iVersion = supportedVersions.iterator();
99
                        String wmsVersion;
100
                        String gvSIGVersion;
101

    
102
                        while (iVersion.hasNext()) {
103
                                gvSIGVersion = (String)iVersion.next();
104
                                wmsVersion = getSuitableWMSVersion(host,gvSIGVersion);
105
                                //TODO:
106
                                //compare with the version returned by the WMS!!!!!
107
                                // send GetCapabilities and read the version to compare.
108
                                int res = wmsVersion.compareTo(gvSIGVersion);
109

    
110
                                if (res == 0) { //Si es la misma que nuestra version
111
                                    return createVersionDriver(gvSIGVersion);
112
                                } else if (res > 0) { //Si es mayor que nuestra version
113
                                    throw new Exception("Server Version too high: " + wmsVersion);
114
                                } else { //Si es menor que nuestra version
115
                                         //Obtenemos la primera version menor o igual que tengamos
116
                                    String lowerVersion = WMSProtocolHandlerFactory.getDriverVersion(wmsVersion, iVersion);
117

    
118
                                    if (lowerVersion == null) { //Si no hay ninguna
119
                                        throw new Exception("Lowest server version is " + wmsVersion);
120
                                    } else {
121
                                        if (lowerVersion.equals(wmsVersion)) {
122
                                            return createVersionDriver(lowerVersion);
123
                                        } else { //Si hay una version menor que la que retorno el servidor
124
                                            //iV = lower;
125
                                        }
126
                                    }
127
                                }
128
                        }
129
                }//case we had to start the negotiation process.
130
                return null; // if it did not find any suitable version.
131
        }
132
        catch(ConnectException conEx)
133
        {
134
                throw conEx;
135
        }
136
        catch(IOException ioEx)
137
        {
138
                throw ioEx;
139
        }
140
        catch(Exception e)
141
        {
142
                e.printStackTrace();
143
                return null;
144
        }
145
    }
146

    
147
     /**
148
      * Sends a GetCapabilities to the WMS server to get the version
149
      * if the version parameter is null, the WMS will return the highest version supported
150
      * if not it will return the lower highest version than the one requested.
151
      * @param host
152
      * @param version
153
      * @return suitable version supported by the server
154
      */
155
     private static String getSuitableWMSVersion(String host, String _version) throws ConnectException, IOException
156
     {
157
            String request = WMSProtocolHandler.buildCapabilitiesSuitableVersionRequest(host, _version);
158
            String version = new String();
159
            StringReader reader = null;
160
            //InputStreamReader reader;
161
            //InputStream is = null;
162
            DataInputStream dis = null;
163
                try
164
                {
165
                        URL url = new URL(request);
166
            byte[] buffer = new byte[1024];//new byte[1024*256];
167
//            is = url.openStream();
168
//            reader = new InputStreamReader(is);
169
            //int numberOfBytes = is.read(buffer);
170
            //String readed = new String(buffer);
171
            dis = new DataInputStream(url.openStream());
172
            dis.readFully(buffer);
173
            String string = new String(buffer);
174

    
175
            // patch for ArcIMS + WMS connector > 9.0 bug
176
            int a = string.toLowerCase().indexOf("<?xml");
177
            if (a !=-1)
178
                    string = string.substring(a, string.length());
179
            // end patch
180

    
181

    
182
            reader = new StringReader(string);
183
                    KXmlParser kxmlParser = null;
184
                    kxmlParser = new KXmlParser();
185
                    kxmlParser.setInput(reader);
186
                        kxmlParser.nextTag();
187
                    if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT )
188
                    {
189
                            if ((kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITIES_ROOT1_1_0)==0)
190
                                    ||(kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITIES_ROOT1_1_1)==0)
191
                                    ||(kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITIES_ROOT1_3_0)==0))
192
                            {
193
                                    version = kxmlParser.getAttributeValue("", CapabilitiesTags.VERSION);
194
                            }
195
                    }
196
                    // do not forget to close the Stream.
197
                    reader.close();
198
                    dis.close();
199
                        return version;
200
                }
201
                catch(ConnectException conEx)
202
                {
203
                        throw new ConnectException(conEx.getMessage());
204
                }
205
                catch(IOException ioEx)
206
                {
207
                        throw new IOException(ioEx.getMessage());
208
                }
209
                catch(XmlPullParserException xmlEx)
210
                {
211
                        xmlEx.printStackTrace();
212
                        return "";
213
                }
214
                finally{
215
                        if (reader != null)
216
                        {
217
                                try{
218
                                        reader.close();
219
                                }catch(Exception ex){
220
                                        ex.printStackTrace();
221
                                }
222
                        }
223
                        if (dis != null)
224
                        {
225
                                try {
226
                                        dis.close();
227
                                } catch(Exception ex) {
228
                                        ex.printStackTrace();
229
                                }
230
                        }
231
                }
232
     }
233

    
234
     /**
235
      * It creates an instance of a WMSDriver class.
236
      *
237
      * @param String, with the version of the driver to be created
238
      * @return WMSDriver.
239
      */
240
       private static WMSProtocolHandler createVersionDriver(String version)
241
       {
242
         try
243
         {
244
           Class driver;
245
           version = version.replace('.', '_');
246
           driver = Class.forName("org.gvsig.remoteclient.wms.wms_"+version+".WMSProtocolHandler" + version);
247
           return (WMSProtocolHandler)driver.newInstance();
248
         }
249
         catch (Exception e)
250
         {
251
                 e.printStackTrace();
252
           //throw new Exception("WMSDriverFactory. Unknown driver version " + e);
253
                 return null;
254
         }
255
       }
256

    
257
 }