Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.remoteclient / src / main / java / org / gvsig / remoteclient / wcs / WCSProtocolHandlerFactory.java @ 41316

History | View | Annotate | Download (8.29 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.wcs;
25

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

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

    
37
import org.gvsig.remoteclient.utils.CapabilitiesTags;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

    
41
/**
42
 *
43
 * @author jaume dominguez faus
44
 *
45
 */
46
public class WCSProtocolHandlerFactory {
47
        private static final Logger logger = LoggerFactory.getLogger(WCSProtocolHandlerFactory.class);
48

    
49
        public org.gvsig.remoteclient.wcs.WCSProtocolHandler wCSProtocolHandler;
50

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

    
53
        static {
54
                supportedVersions.add("1.0.0");
55
        }
56

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

    
75
                        if (ret >= 0) {
76
                                return clientVersion;
77
                        }
78
                }
79
                return null;
80
        }
81

    
82
        /**
83
         * Establece la versi?n con la que se comunicar? con el servidor y devuelve
84
         * el objeto Capabilities obtenido con dicha versi?n
85
         *
86
         * @param host maquina con la que se negocia
87
         *
88
         * @return instancia de un cliente capaz de negociar con el host que se
89
         *         pasa como par?metro
90
         */
91
        public static WCSProtocolHandler negotiate(String host) throws ConnectException, IOException {
92

    
93
                if (supportedVersions.size() == 0)
94
                {
95
                        return null;
96
                }
97

    
98
                try
99
                {
100
                        String highestVersionSupportedByServer  = getSuitableWCSVersion(host,"");
101
                        if (supportedVersions.contains(highestVersionSupportedByServer))
102
                        {
103
                                // we support the highest version supported by the server
104
                                // this is the best case
105
                                return createVersionDriver(highestVersionSupportedByServer);
106
                        }
107
                        else
108
                        {
109
                                // in case we dont support the highest version from the server
110
                                // we start the negotiation process in which we have to get the higest version
111
                                // the WCS supports and we are able to read.
112
                                Iterator iVersion = supportedVersions.iterator();
113
                                String wcsVersion;
114
                                String gvSIGVersion;
115

    
116
                                while (iVersion.hasNext()) {
117
                                        gvSIGVersion = (String)iVersion.next();
118
                                        wcsVersion = getSuitableWCSVersion(host,gvSIGVersion);
119
                                        //TODO:
120
                                        //compare with the version returned by the WMS!!!!!
121
                                        // send GetCapabilities and read the version to compare.
122
                                        int res = wcsVersion.compareTo(gvSIGVersion);
123

    
124
                                        if (res == 0) { //Si es la misma que nuestra version
125
                                                return createVersionDriver(gvSIGVersion);
126
                                        } else if (res > 0) { //Si es mayor que nuestra version
127
                                                throw new Exception("Server Version too high: " + wcsVersion);
128
                                        } else { //Si es menor que nuestra version
129
                                                //Obtenemos la primera version menor o igual que tengamos
130
                                                String lowerVersion = WCSProtocolHandlerFactory.getDriverVersion(wcsVersion, iVersion);
131

    
132
                                                if (lowerVersion == null) { //Si no hay ninguna
133
                                                        throw new Exception("Lowest server version is " + wcsVersion);
134
                                                } else {
135
                                                        if (lowerVersion.equals(wcsVersion)) {
136
                                                                return createVersionDriver(lowerVersion);
137
                                                        } else { //Si hay una version menor que la que retorno el servidor
138
                                                                //iV = lower;
139
                                                        }
140
                                                }
141
                                        }
142
                                }
143
                        }//case we had to start the negotiation process.
144
                        return null; // if it did not find any suitable version.
145
                }
146
                catch(ConnectException conEx)
147
                {
148
                        throw conEx;
149
                }
150
                catch(IOException ioEx)
151
                {
152
                        throw ioEx;
153
                }
154
                catch(Exception e)
155
                {
156
//                        e.printStackTrace();
157
                        return null;
158
                }
159
        }
160

    
161
        /**
162
         * Sends a GetCapabilities to the WCS server to get the version
163
         * if the version parameter is null, the WCS will return the highest version supported
164
         * if not it will return the lower highest version than the one requested.
165
         * @param host
166
         * @param version
167
         * @return suitable version supported by the server
168
         */
169
     private static String getSuitableWCSVersion(String host, String _version) throws ConnectException, IOException
170
     {
171
         int sizes[] = new int[] { 1024, 1024*10, 1024*50, 1024*100 };
172
         XmlPullParserException  xmlEx = null;
173
         for( int i=0; i<sizes.length; i++ ) {
174
             String version;
175
             try {
176
                 version = getSuitableWCSVersion(host, _version, sizes[i]);
177
                 return version;
178
             } catch (XmlPullParserException ex) {
179
                 xmlEx = ex;
180
                 // Try with other size
181
             }
182
         }
183
         logger.warn("Can't determine server version",xmlEx);
184
         return "";
185
     }
186
             
187
        private static String getSuitableWCSVersion(String host, String _version, int size) throws ConnectException, IOException, XmlPullParserException {
188
                String request = WCSProtocolHandler.buildCapabilitiesSuitableVersionRequest(host, _version);
189
                String version = new String();
190
                StringReader reader = null;
191
                //InputStreamReader reader;
192
                //InputStream is = null;
193
                DataInputStream dis = null;
194
                try {
195
                        URL url = new URL(request);
196
                        byte[] buffer = new byte[size];//new byte[1024*256];
197
//                        is = url.openStream();
198
//                        reader = new InputStreamReader(is);
199
                        //int numberOfBytes = is.read(buffer);
200
                        //String readed = new String(buffer);
201
                        dis = new DataInputStream(url.openStream());
202
                        dis.readFully(buffer);
203

    
204
                        reader = new StringReader(new String(buffer));
205
                        KXmlParser kxmlParser = null;
206
                        kxmlParser = new KXmlParser();
207
                        kxmlParser.setInput(reader);
208
                        kxmlParser.nextTag();
209
                        if ( kxmlParser.getEventType() != KXmlParser.END_DOCUMENT ) {
210
                                if ((kxmlParser.getName().compareTo(CapabilitiesTags.WCS_CAPABILITIES_ROOT1_0_0)==0)) {
211
                                        version = kxmlParser.getAttributeValue("", CapabilitiesTags.VERSION);
212
                                }
213
                        }
214
                        // do not forget to close the Stream.
215
                        reader.close();
216
                        dis.close();
217
                        return version;
218
                } catch(ConnectException conEx) {
219
                        throw new ConnectException(conEx.getMessage());
220
                } catch(IOException ioEx) {
221
                        throw new IOException(ioEx.getMessage());
222
                } catch(XmlPullParserException xmlEx) {
223
                        throw  xmlEx;
224
//                        xmlEx.printStackTrace();
225
//                        return "";
226
                } finally {
227
                        if (reader != null) {
228
                                try {
229
                                        reader.close();
230
                                } catch(Exception ex) {
231
                                        ex.printStackTrace();
232
                                }
233
                        } if (dis != null) {
234
                                try {
235
                                        dis.close();
236
                                } catch(Exception ex){
237
                                        ex.printStackTrace();
238
                                }
239
                        }
240
                }
241
        }
242

    
243
        /**
244
         * It creates an instance of a WCSDriver class.
245
         *
246
         * @param String, with the version of the driver to be created
247
         * @return WCSDriver.
248
         */
249
        private static WCSProtocolHandler createVersionDriver(String version) {
250
                try {
251
                        Class driver;
252
                        version = version.replace('.', '_');
253
                        driver = Class.forName("org.gvsig.remoteclient.wcs.wcs_"+version+".WCSProtocolHandler" + version);
254
                        return (WCSProtocolHandler)driver.newInstance();
255
                } catch (Exception e) {
256
                        e.printStackTrace();
257
                        //throw new Exception("WCSDriverFactory. Unknown driver version " + e);
258
                        return null;
259
                }
260
        }
261

    
262

    
263
}