Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1011 / libraries / libRemoteServices / src / org / gvsig / remoteClient / wms / WMSProtocolHandlerFactory.java @ 12904

History | View | Annotate | Download (8.45 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
                else
92
                {
93
                        // in case we dont support the highest version from the server
94
                        // we start the negotiation process in which we have to get the higest version
95
                        // the WMS supports and we are able to read.
96
                        Iterator iVersion = supportedVersions.iterator();
97
                        String wmsVersion;
98
                        String gvSIGVersion;
99
                
100
                        while (iVersion.hasNext()) { 
101
                                gvSIGVersion = (String)iVersion.next();
102
                                wmsVersion = getSuitableWMSVersion(host,gvSIGVersion);
103
                                //TODO:
104
                                //compare with the version returned by the WMS!!!!!
105
                                // send GetCapabilities and read the version to compare.
106
                                int res = wmsVersion.compareTo(gvSIGVersion);
107
                
108
                                if (res == 0) { //Si es la misma que nuestra version                
109
                                    return createVersionDriver(gvSIGVersion);
110
                                } else if (res > 0) { //Si es mayor que nuestra version
111
                                    throw new Exception("Server Version too high: " + wmsVersion);
112
                                } else { //Si es menor que nuestra version
113
                                         //Obtenemos la primera version menor o igual que tengamos
114
                                    String lowerVersion = WMSProtocolHandlerFactory.getDriverVersion(wmsVersion, iVersion);
115
                
116
                                    if (lowerVersion == null) { //Si no hay ninguna
117
                                        throw new Exception("Lowest server version is " + wmsVersion);
118
                                    } else {
119
                                        if (lowerVersion.equals(wmsVersion)) { 
120
                                            return createVersionDriver(lowerVersion);
121
                                        } else { //Si hay una version menor que la que retorno el servidor
122
                                            //iV = lower;
123
                                        }
124
                                    }
125
                                }
126
                        }
127
                }//case we had to start the negotiation process.
128
                return null; // if it did not find any suitable version.        
129
        }
130
        catch(ConnectException conEx)
131
        {
132
                throw conEx;
133
        }
134
        catch(IOException ioEx)
135
        {
136
                throw ioEx;
137
        }        
138
        catch(Exception e)
139
        {
140
                e.printStackTrace();
141
                return null;
142
        }
143
    }
144
    
145
     /**
146
      * Sends a GetCapabilities to the WMS server to get the version
147
      * if the version parameter is null, the WMS will return the highest version supported
148
      * if not it will return the lower highest version than the one requested.
149
      * @param host
150
      * @param version
151
      * @return suitable version supported by the server 
152
      */
153
     private static String getSuitableWMSVersion(String host, String _version) throws ConnectException, IOException 
154
     {             
155
            String request = WMSProtocolHandler.buildCapabilitiesSuitableVersionRequest(host, _version);
156
            String version = new String(); 
157
            StringReader reader = null;
158
            //InputStreamReader reader;
159
            //InputStream is = null;
160
            DataInputStream dis = null;
161
                try
162
                {           
163
                        URL url = new URL(request);
164
            byte[] buffer = new byte[1024];//new byte[1024*256];
165
//            is = url.openStream();            
166
//            reader = new InputStreamReader(is);            
167
            //int numberOfBytes = is.read(buffer);            
168
            //String readed = new String(buffer);
169
            dis = new DataInputStream(url.openStream()); 
170
            dis.readFully(buffer);
171
                       String string = new String(buffer);
172

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

    
179

    
180
            reader = new StringReader(string);
181
                    
182
            KXmlParser kxmlParser = null;
183
                    kxmlParser = new KXmlParser();
184
                    kxmlParser.setInput(reader);                
185
                        kxmlParser.nextTag();
186
                    if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) 
187
                    {                    
188
                            if ((kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITIES_ROOT1_1_0)==0)
189
                                    ||(kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITIES_ROOT1_1_1)==0)
190
                                    ||(kxmlParser.getName().compareTo(CapabilitiesTags.CAPABILITIES_ROOT1_3_0)==0))
191
                            {
192
                                    version = kxmlParser.getAttributeValue("", CapabilitiesTags.VERSION);
193
                            }
194
                    }
195
                    // do not forget to close the Stream.                    
196
                    reader.close();                    
197
                    dis.close();
198
                        return version;                
199
                }
200
                catch(ConnectException conEx)
201
                {
202
                        throw new ConnectException(conEx.getMessage());                         
203
                }
204
                catch(IOException ioEx)
205
                {
206
                        throw new IOException(ioEx.getMessage());         
207
                }
208
                catch(XmlPullParserException xmlEx)
209
                {
210
                        xmlEx.printStackTrace();
211
                        return "";
212
                }
213
                finally{                
214
                        if (reader != null)
215
                        {
216
                                try{
217
                                        reader.close();
218
                                }catch(Exception ex){
219
                                        ex.printStackTrace(); 
220
                                }
221
                        }
222
                        if (dis != null)
223
                        {
224
                                try {
225
                                        dis.close();
226
                                } catch(Exception ex) {
227
                                        ex.printStackTrace(); 
228
                                }
229
                        }
230
                }             
231
     }
232
     
233
     /**
234
      * It creates an instance of a WMSDriver class.
235
      *
236
      * @param String, with the version of the driver to be created
237
      * @return WMSDriver.
238
      */
239
       private static WMSProtocolHandler createVersionDriver(String version)             
240
       {               
241
         try
242
         {
243
           Class driver;
244
           version = version.replace('.', '_');
245
           driver = Class.forName("org.gvsig.remoteClient.wms.wms_"+version+".WMSProtocolHandler" + version);
246
           return (WMSProtocolHandler)driver.newInstance();
247
         }
248
         catch (Exception e)
249
         {
250
                 e.printStackTrace();
251
           //throw new Exception("WMSDriverFactory. Unknown driver version " + e);
252
                 return null;
253
         }
254
       }     
255
  
256
 }