Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRemoteServices / src / org / gvsig / remoteClient / wms / WMSProtocolHandler.java @ 3505

History | View | Annotate | Download (11.6 KB)

1

    
2
package org.gvsig.remoteClient.wms;
3

    
4
import java.io.BufferedOutputStream;
5
import java.io.DataOutputStream;
6
import java.io.File;
7
import java.io.FileOutputStream;
8
import java.io.IOException;
9
import java.io.InputStream;
10
import java.io.OutputStream;
11
import java.net.ConnectException;
12
import java.net.URL;
13
import java.net.UnknownHostException;
14
import java.util.TreeMap;
15
import java.util.Vector;
16
import org.gvsig.remoteClient.utils.Utilities;
17

    
18
import com.devx.io.TempFileManager;
19

    
20

    
21
/**
22
 * <p> Abstract class that represents handlers to comunicate via WMS protocol.
23
 * </p>
24
 * 
25
 */
26
public abstract class WMSProtocolHandler {
27

    
28
        /**
29
         * procotol handler name
30
         */
31
    protected String name;
32
    /**
33
     * protocol handler version
34
     */
35
    protected String version;
36
    /**
37
     * host of the WMS to connect
38
     */
39
    protected String host;
40
    /**
41
     *  port number of the comunication channel of the WMS to connect
42
     */
43
    protected String port;    
44
    /**
45
     * WMS metadata
46
     */
47
    protected ServiceInformation serviceInfo;
48
    public TreeMap layers;
49
    public WMSLayer rootLayer;
50
    public Vector srs;
51
    
52

    
53
    // abstract methods to implement by the handlers that implement
54
    // the connection to a WMS with certain version.
55
    //    public abstract String getName();   
56
    //    public abstract String getVersion();
57
    
58
    /**
59
     * parses the data retrieved by the WMS in XML format. 
60
     * It will be mostly the WMS Capabilities, but the implementation
61
     * will be placed in the handler implementing certain version of the protocol.
62
     * 
63
     */
64
    public abstract void parse(File f);
65

    
66
    public String getName() {        
67
            return name;
68
    } 
69

    
70
    public String getVersion() {        
71
            return version;
72
    }    
73
    
74
    public ServiceInformation getServiceInformation() {        
75
        return serviceInfo;
76
    }  
77
    public String getHost ()
78
    {
79
            return host;
80
    }
81
    public void setHost(String _host)
82
    {
83
            host = _host;
84
    }
85
    public String getPort()
86
    {
87
            return port;
88
    }
89
    public void setPort(String _port)
90
    {
91
            port = _port;
92
    }
93

    
94
    /**
95
     * <p>Builds a GetMap request that is sent to the WMS
96
     * the response (image) will be redirect to the
97
     * WMS client</p>
98
     */
99
    
100
    public byte[] getMap(WMSStatus status)
101
    {        
102
            URL request = null;
103
                try
104
                {
105
                        //TODO:
106
                        //pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
107
                        request = new URL(buildMapRequest(status));
108
            System.out.println(request.toString());
109
                    byte[] buffer = new byte[1024*256];
110
                    byte[] imageBytes = null;
111
                    InputStream is = request.openStream();
112
                    int readed = 0;
113
                    
114
                    for (int i = is.read(buffer); i>0; i = is.read(buffer)){
115
                // Creates a new buffer to contain the previous readed bytes and the next bunch of bytes
116
                            byte[] buffered = new byte[readed+i];
117
                            for (int j = 0; j < buffered.length; j++) {
118
                                    if (j<readed){
119
                        // puts the previously downloaded bytes into the image buffer
120
                                            buffered[j] = imageBytes[j];
121
                                    }
122
                                    else {
123
                        // appends the recently downloaded bytes to the image buffer.
124
                                            buffered[j] = buffer[j-readed];
125
                                    }
126
                                }
127
                            imageBytes = (byte[]) buffered.clone();
128
                            readed += i;
129
                            
130
                    }
131
                        
132
                        return imageBytes;
133
                    
134
                }
135
                catch(Exception e)
136
                {
137
                        e.printStackTrace();
138
                }
139
                
140
                return null;
141
    } 
142

    
143
        /**
144
         * <p>Builds a GetCapabilities request that is sent to the WMS
145
         * the response will be parse to extract the data needed by the
146
         * WMS client</p>
147
         */
148
    public void getCapabilities()
149
    {                
150
            URL request = null;
151
                try
152
                {
153
                        request = new URL(buildCapabilitiesRequest());
154
                }
155
                catch(Exception e)
156
                {
157
                        e.printStackTrace();
158
                }
159
                
160
//                   File f = null;
161
//                   f = new File("tochangethis.txt");
162
//            
163
//            if (!f.exists())
164
//            {
165
//                    try
166
//                    {
167
//                            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)));
168
//                            byte[] buffer = new byte[1024*256];
169
//                            InputStream is = request.openStream();
170
//                            long readed = 0;
171
//                            for (int i = is.read(buffer); i>0; i = is.read(buffer)){
172
//                                    dos.write(buffer, 0, i);
173
//                                    readed += i;
174
//                            }
175
//                            dos.close();
176
//                    }
177
//                    catch(Exception e)
178
//                    {}
179
//            }
180
                try
181
                {
182
                File f = downloadFile(request,"wms_capabilities.xml");
183
            parse(f);
184
                }
185
                catch(Exception e)
186
                {
187
                        //TODO
188
                        e.printStackTrace();
189
                }
190
    }
191

    
192
/**
193
 * <p>It will send a GetFeatureInfo request to the WMS
194
 * Parsing the response and redirecting the info to the WMS client</p>
195
 */
196
    public String getFeatureInfo(WMSStatus status, int x, int y, int featureCount)
197
    {
198
            URL request = null;
199
                try
200
                {
201
                        //TODO:
202
                        //pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
203
                        request = new URL(buildGetFeatureInfoRequest(status, x, y));
204
                }
205
                catch(Exception e)
206
                {
207
                        // TODO something about the exceptionsssss....!!!
208
                }
209
                
210
            try
211
            {            
212
                    System.out.println(request.toString());
213
                    File f = new File("featureInfo.xml");
214
                    DataOutputStream dos = new DataOutputStream(new FileOutputStream(f));
215
                    
216
                    OutputStream bos = null;
217

    
218
                    byte[] buffer = new byte[1024*256];
219
                    InputStream is = request.openStream();
220
                    //long readed = 0;
221
                    for (int i = is.read(buffer); i>0; i = is.read(buffer)){
222
                            dos.write(buffer, 0, i);
223
                            //readed += i;
224
                    }
225
                    dos.close();
226
                    
227
            return null;
228
            }
229
            catch(Exception e)
230
            {
231
                    e.printStackTrace();
232
            return null;
233
            }
234
    }
235

    
236
    /**
237
     * Builds the GetCapabilitiesRequest according to the OGC WMS Specifications
238
     */
239
    private String buildCapabilitiesRequest()
240
    {
241
                String req = new String();
242
                String host = getHost();
243
                if (!host.endsWith("?"))
244
                        req = req + getHost() + "?REQUEST=GetCapabilities&SERVICE=WMS&";
245
                else
246
                        req = req + getHost() + "REQUEST=GetCapabilities&SERVICE=WMS&";
247
                req = req + "VERSION=" + getVersion();
248
                req += ("&EXCEPTIONS=XML");
249
                return req;
250
    }
251

    
252
    /**
253
     * Builds the GetFeatureInfoRequest according to the OGC WMS Specifications
254
     */
255
    private String buildGetFeatureInfoRequest(WMSStatus status, int x, int y)
256
    {
257
                String req = new String();
258
                if (!host.endsWith("?"))
259
                        req = req + getHost() + "?REQUEST=GetFeatureInfo&SERVICE=WMS&";
260
                else
261
                        req = req + getHost() + "REQUEST=GetFeatureInfo&SERVICE=WMS&";
262
                req = req + "QUERY_LAYERS="+Utilities.Vector2CS(status.getLayerNames()); 
263
                req = req + "&VERSION=" + getVersion() + "&";
264
                req = req + getPartialQuery(status);
265
                req = req + "&x="+x + "&y="+y;
266
       if (status.getExceptionFormat() != null) {
267
            req += ("&EXCEPTIONS=" + status.getExceptionFormat());
268
        } else {
269
            req += ("&EXCEPTIONS=XML");
270
        }
271
                return req;
272
    }    
273
    
274
    /**
275
     * Builds the GetMapRequest according to the OGC WMS Specifications
276
     */
277
    private String buildMapRequest(WMSStatus status)
278
    {
279
                String req = new String();
280
                if (!host.endsWith("?"))
281
                        req = req + getHost() + "?REQUEST=GetMap&SERVICE=WMS&";
282
                else
283
                        req = req + getHost() + "REQUEST=GetMap&SERVICE=WMS&";
284
                req = req + "VERSION=" + getVersion() + "&";
285
                req = req + getPartialQuery(status);
286
       if (status.getExceptionFormat() != null) {
287
            req += ("&EXCEPTIONS=" + status.getExceptionFormat());
288
        } else {
289
            req += ("&EXCEPTIONS=XML");
290
        }
291
                return req;
292
    }
293

    
294
    /**
295
     * Gets the part of the OGC request that share GetMap and GetFeatureInfo
296
     * @return String request
297
     */
298
    public String getPartialQuery(WMSStatus status)
299
    {            
300
        String req = "LAYERS=" + Utilities.Vector2CS(status.getLayerNames()) + "&STYLES=" +
301
        Utilities.Vector2CS(status.getStyles()) + "&SRS=" + status.getSrs() +
302
            "&BBOX=" + status.getExtent().getMinX()+ "," +
303
                                    status.getExtent().getMinY()+ "," +
304
                                    status.getExtent().getMaxX()+ "," +
305
                                    status.getExtent().getMaxY() +
306
            "&WIDTH=" + status.getWidth() +
307
            "&HEIGHT=" + status.getHeight() + "&FORMAT=" + status.getFormat();
308

    
309
//        if (status.getTransparency()) {
310
//            req += "&TRANSPARENT=TRUE";
311
//        }
312
//
313
//        if (status.getBGColor() != null) {
314
//            req += ("&COLOR=" + status.getBGColor());
315
//        }
316
//
317
//        if (time != null) {
318
//            req += ("&TIME=" + time);
319
//        }
320
//
321
//        if (elevation != -1) {
322
//            req += ("&ELEVATION=" + elevation);
323
//        }
324

    
325
        return req.replaceAll(" ", "%20");
326
    }
327

    
328
    
329
    
330
    public void close() {        
331
        // your code here
332
    } 
333
    
334
    /**
335
     * Inner class that represents the description of the WMS metadata.
336
     * The first part of the capabilities will return the service information
337
     * from the WMS, this class will hold this information. 
338
     * 
339
     */
340
    public class ServiceInformation {
341

    
342
        public String online_resource;
343
        public String version;
344
        public String name;
345
        public String scope;
346
        public String title;
347
        public String abstr;
348
        public String keywords;
349
        public String fees;
350
        public String operationsInfo;
351
        public String personname;
352
        public String organization;
353
        public String function;
354
        public String addresstype;
355
        public String address;
356
        public String place;
357
        public String province;
358
        public String postcode;
359
        public String country;
360
        public String phone;
361
        public String fax;
362
        public String email;
363
        public Vector formats;
364
        
365
        public ServiceInformation()
366
        {
367
                online_resource = new String();
368
            version = new String();
369
            name = new String();
370
            scope = new String();
371
            title = new String();
372
            abstr = new String();
373
            keywords = new String();
374
            fees = new String();
375
            operationsInfo = new String();
376
            personname = new String();
377
            organization = new String();
378
            function = new String();
379
            addresstype = new String();
380
            address = new String();
381
            place = new String();
382
            province = new String();
383
            postcode = new String();
384
            country = new String();
385
            phone = new String();
386
            fax = new String();
387
            email = new String();
388
            formats = new Vector();               
389
        }
390
     }   
391
    
392
    /**
393
     * Downloads an URL into a temporary file that is removed the next time the 
394
     * tempFileManager class is called, which means the next time gvSIG is launched.
395
     * 
396
     * @param url
397
     * @param name
398
     * @return
399
     * @throws IOException
400
     * @throws ServerErrorResponseException
401
     * @throws ConnectException
402
     * @throws UnknownHostException
403
     */
404
    private File downloadFile(URL url, String name) throws IOException,ConnectException, UnknownHostException{
405
            File f = null;
406

    
407
            try{
408
                    f = TempFileManager.createTempFile(name, "tmp");
409
                    System.out.println("downloading '"+url.toString()+"' to: "+f.getAbsolutePath());
410
                         
411
                    f.deleteOnExit();
412
                    
413
            } catch (IOException io) {
414
                    io.printStackTrace();
415
            }
416
            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)));
417
            byte[] buffer = new byte[1024*256];
418
            InputStream is = url.openStream();
419
            long readed = 0;
420
            for (int i = is.read(buffer); i>0; i = is.read(buffer)){
421
                    dos.write(buffer, 0, i);
422
                    readed += i;
423
            }
424
            dos.close();
425
            /*if (!isNotAnException(f))
426
                    // SI que es una excepci?n
427
                    throw new ServerErrorResponseException();*/
428
            return f;
429
        }
430

    
431
 }