Statistics
| Revision:

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

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

    
17
import org.gvsig.remoteClient.exceptions.ServerErrorException;
18
import org.gvsig.remoteClient.exceptions.WMSException;
19
import org.gvsig.remoteClient.utils.Utilities;
20

    
21
import com.devx.io.TempFileManager;
22

    
23

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

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

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

    
69
    public String getName() {        
70
            return name;
71
    } 
72

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

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

    
151
        /**
152
     * Parses a WMS exception XML document.
153
     * @param imageBytes
154
     * @return
155
     */
156
    protected abstract String parseException(byte[] imageBytes) ;
157

    
158
    /**
159
         * <p>Builds a GetCapabilities request that is sent to the WMS
160
         * the response will be parse to extract the data needed by the
161
         * WMS client</p>
162
         */
163
    public void getCapabilities()
164
    {                
165
            URL request = null;
166
                try
167
                {
168
                        request = new URL(buildCapabilitiesRequest());
169
                }
170
                catch(Exception e)
171
                {
172
                        e.printStackTrace();
173
                }
174
                
175
//                   File f = null;
176
//                   f = new File("tochangethis.txt");
177
//            
178
//            if (!f.exists())
179
//            {
180
//                    try
181
//                    {
182
//                            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)));
183
//                            byte[] buffer = new byte[1024*256];
184
//                            InputStream is = request.openStream();
185
//                            long readed = 0;
186
//                            for (int i = is.read(buffer); i>0; i = is.read(buffer)){
187
//                                    dos.write(buffer, 0, i);
188
//                                    readed += i;
189
//                            }
190
//                            dos.close();
191
//                    }
192
//                    catch(Exception e)
193
//                    {}
194
//            }
195
                try
196
                {
197
                File f = downloadFile(request,"wms_capabilities.xml");
198
            parse(f);
199
                } catch(Exception e)
200
                {
201
                        //TODO
202
                        e.printStackTrace();
203
                }
204
    }
205

    
206
/**
207
 * <p>It will send a GetFeatureInfo request to the WMS
208
 * Parsing the response and redirecting the info to the WMS client</p>
209
 */
210
    public String getFeatureInfo(WMSStatus status, int x, int y, int featureCount)
211
    {
212
            URL request = null;
213
                try
214
                {
215
                        //TODO:
216
                        //pass this buildXXXRequest to the WMSProtocolHandlerXXX: The request can depend on the WMS version.
217
                        request = new URL(buildGetFeatureInfoRequest(status, x, y));
218
                }
219
                catch(Exception e)
220
                {
221
                        // TODO something about the exceptionsssss....!!!
222
                }
223
                
224
            try
225
            {            
226
                    System.out.println(request.toString());
227
                    File f = new File("featureInfo.xml");
228
                    DataOutputStream dos = new DataOutputStream(new FileOutputStream(f));
229
                    
230
                    OutputStream bos = null;
231

    
232
                    byte[] buffer = new byte[1024*256];
233
                    InputStream is = request.openStream();
234
                    //long readed = 0;
235
                    for (int i = is.read(buffer); i>0; i = is.read(buffer)){
236
                            dos.write(buffer, 0, i);
237
                            //readed += i;
238
                    }
239
                    dos.close();
240
                    
241
            return null;
242
            }
243
            catch(Exception e)
244
            {
245
                    e.printStackTrace();
246
            return null;
247
            }
248
    }
249

    
250
    /**
251
     * Builds the GetCapabilitiesRequest according to the OGC WMS Specifications
252
     */
253
    private String buildCapabilitiesRequest()
254
    {
255
                String req = new String();
256
                String host = getHost();
257
                if ((!host.endsWith("?"))&&(host.indexOf("?")==-1))                        
258
                        req = req + getHost() + "?REQUEST=GetCapabilities&SERVICE=WMS&";
259
                else
260
                {
261
                        String symbol = (host.endsWith("&")) ? "" : "&";
262
                        req = req + getHost() + symbol + "REQUEST=GetCapabilities&SERVICE=WMS&";
263
                }
264
                req = req + "VERSION=" + getVersion();
265
                req += ("&EXCEPTIONS=XML");
266
                return req;
267
    }
268

    
269
    /**
270
     * Builds the GetFeatureInfoRequest according to the OGC WMS Specifications
271
     */
272
    private String buildGetFeatureInfoRequest(WMSStatus status, int x, int y)
273
    {
274
                String req = new String();
275
                if (!host.endsWith("?"))
276
                        req = req + getHost() + "?REQUEST=GetFeatureInfo&SERVICE=WMS&";
277
                else
278
                        req = req + getHost() + "REQUEST=GetFeatureInfo&SERVICE=WMS&";
279
                req = req + "QUERY_LAYERS="+Utilities.Vector2CS(status.getLayerNames()); 
280
                req = req + "&VERSION=" + getVersion() + "&";
281
                req = req + getPartialQuery(status);
282
                req = req + "&x="+x + "&y="+y;
283
       if (status.getExceptionFormat() != null) {
284
            req += ("&EXCEPTIONS=" + status.getExceptionFormat());
285
        } else {
286
            req += ("&EXCEPTIONS=XML");
287
        }
288
                return req;
289
    }    
290
    
291
    /**
292
     * Builds the GetMapRequest according to the OGC WMS Specifications
293
     */
294
    private String buildMapRequest(WMSStatus status)
295
    {
296
                String req = new String();
297
                if (!host.endsWith("?"))
298
                        req = req + getHost() + "?REQUEST=GetMap&SERVICE=WMS&";
299
                else
300
                        req = req + getHost() + "REQUEST=GetMap&SERVICE=WMS&";
301
                req = req + "VERSION=" + getVersion() + "&";
302
                req = req + getPartialQuery(status);
303
       if (status.getExceptionFormat() != null) {
304
            req += ("&EXCEPTIONS=" + status.getExceptionFormat());
305
        } else {
306
            req += ("&EXCEPTIONS=XML");
307
        }
308
                return req;
309
    }
310

    
311
    /**
312
     * Gets the part of the OGC request that share GetMap and GetFeatureInfo
313
     * @return String request
314
     */
315
    public String getPartialQuery(WMSStatus status)
316
    {            
317
        String req = "LAYERS=" + Utilities.Vector2CS(status.getLayerNames()) + "&STYLES=" +
318
        Utilities.Vector2CS(status.getStyles()) + "&SRS=" + status.getSrs() +
319
            "&BBOX=" + status.getExtent().getMinX()+ "," +
320
                                    status.getExtent().getMinY()+ "," +
321
                                    status.getExtent().getMaxX()+ "," +
322
                                    status.getExtent().getMaxY() +
323
            "&WIDTH=" + status.getWidth() +
324
            "&HEIGHT=" + status.getHeight() + "&FORMAT=" + status.getFormat();
325

    
326
//        if (status.getTransparency()) {
327
//            req += "&TRANSPARENT=TRUE";
328
//        }
329
//
330
//        if (status.getBGColor() != null) {
331
//            req += ("&COLOR=" + status.getBGColor());
332
//        }
333
//
334
//        if (time != null) {
335
//            req += ("&TIME=" + time);
336
//        }
337
//
338
//        if (elevation != -1) {
339
//            req += ("&ELEVATION=" + elevation);
340
//        }
341

    
342
        return req.replaceAll(" ", "%20");
343
    }
344

    
345
    
346
    
347
    public void close() {        
348
        // your code here
349
    } 
350
    
351
    /**
352
     * Inner class that represents the description of the WMS metadata.
353
     * The first part of the capabilities will return the service information
354
     * from the WMS, this class will hold this information. 
355
     * 
356
     */
357
    public class ServiceInformation {
358

    
359
        public String online_resource;
360
        public String version;
361
        public String name;
362
        public String scope;
363
        public String title;
364
        public String abstr;
365
        public String keywords;
366
        public String fees;
367
        public String operationsInfo;
368
        public String personname;
369
        public String organization;
370
        public String function;
371
        public String addresstype;
372
        public String address;
373
        public String place;
374
        public String province;
375
        public String postcode;
376
        public String country;
377
        public String phone;
378
        public String fax;
379
        public String email;
380
        public Vector formats;
381
        
382
        public ServiceInformation()
383
        {
384
                online_resource = new String();
385
            version = new String();
386
            name = new String();
387
            scope = new String();
388
            title = new String();
389
            abstr = new String();
390
            keywords = new String();
391
            fees = new String();
392
            operationsInfo = new String();
393
            personname = new String();
394
            organization = new String();
395
            function = new String();
396
            addresstype = new String();
397
            address = new String();
398
            place = new String();
399
            province = new String();
400
            postcode = new String();
401
            country = new String();
402
            phone = new String();
403
            fax = new String();
404
            email = new String();
405
            formats = new Vector();               
406
        }
407
     }   
408
    
409
    /**
410
     * Downloads an URL into a temporary file that is removed the next time the 
411
     * tempFileManager class is called, which means the next time gvSIG is launched.
412
     * 
413
     * @param url
414
     * @param name
415
     * @return
416
     * @throws IOException
417
     * @throws ServerErrorResponseException
418
     * @throws ConnectException
419
     * @throws UnknownHostException
420
     */
421
    private File downloadFile(URL url, String name) throws IOException,ConnectException, UnknownHostException{
422
            File f = null;
423

    
424
            try{
425
                if ((f=Utilities.getPreviousDownloadedURL(url))==null){
426
                    f = TempFileManager.createTempFile(name, "tmp");
427
                    System.out.println("downloading '"+url.toString()+"' to: "+f.getAbsolutePath());
428
                    
429
                    f.deleteOnExit();
430
                DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)));
431
                byte[] buffer = new byte[1024*256];
432
                InputStream is = url.openStream();
433
                long readed = 0;
434
                for (int i = is.read(buffer); i>0; i = is.read(buffer)){
435
                    dos.write(buffer, 0, i);
436
                    readed += i;
437
                }
438
                dos.close();
439
                Utilities.addDownloadedURL(url, f.getAbsolutePath());
440
                }
441
            } catch (IOException io) {
442
                    io.printStackTrace();
443
            }
444
            
445
            return f;
446
        }
447

    
448
 }